-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[plic] full implementation #2
base: master
Are you sure you want to change the base?
Conversation
plic/src/PLIC.scala
Outdated
class PLICFanIn(nDevices: Int, prioBits: Int) extends Module { | ||
val io = IO(new Bundle { | ||
val prio = Flipped(Vec(nDevices, UInt(prioBits.W))) | ||
val ip = Flipped(UInt(nDevices.W)) | ||
val dev = UInt(log2Ceil(nDevices+1).W) | ||
val max = UInt(prioBits.W) | ||
}) | ||
|
||
def findMax(x: Seq[UInt]): (UInt, UInt) = { | ||
if (x.length > 1) { | ||
val half = 1 << (log2Ceil(x.length) - 1) | ||
val left = findMax(x take half) | ||
val right = findMax(x drop half) | ||
MuxT(left._1 >= right._1, left, (right._1, half.U | right._2)) | ||
} else (x.head, 0.U) | ||
} | ||
|
||
val effectivePriority = (1.U << prioBits) +: (io.ip.asBools zip io.prio).map { case (p, x) => Cat(p, x) } | ||
val (maxPri, maxDev) = findMax(effectivePriority) | ||
io.max := maxPri // strips the always-constant high '1' bit | ||
io.dev := maxDev | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please inline this module
plic/src/PLIC.scala
Outdated
val plic = Flipped(axi4.bundle.verilog.irrevocable(parameter.axi4parameter)).asInstanceOf[AXI4RWIrrevocableVerilog] | ||
val source = Input(Vec(parameter.sources, Bool())) | ||
val mip = Output(Vec(parameter.harts, Bool())) | ||
val sip = Output(Vec(parameter.harts, Bool())) | ||
val ip = Output(Vec(parameter.harts, Bool())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
val ip = Output(Vec(parameter.harts, Bool())) | |
val ip = Output(Vec(parameter.contexts, Bool())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And remember reformat.
plic/src/PLIC.scala
Outdated
val priority = if (parameter.nPriorities > 0) Seq.tabulate(parameter.nDevices)(idx => Reg(UInt(parameter.prioBits.W))) | ||
else Seq.tabulate(parameter.nDevices max 1)(idx => WireDefault(1.U)) | ||
val threshold = if (parameter.nPriorities > 0) Seq.tabulate(parameter.nHarts)(idx => Reg(UInt(parameter.prioBits.W))) | ||
else Seq.tabulate(parameter.nHarts)(idx => Reg(0.U)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add suggest name for each.
plic/src/PLIC.scala
Outdated
val firstEnable = parameter.nDevices min 7 | ||
val fullEnables = (parameter.nDevices - firstEnable) / 8 | ||
val tailEnable = parameter.nDevices - firstEnable - 8*fullEnables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move these into parameter.
plic/src/PLIC.scala
Outdated
class PLICFanIn(nDevices: Int, prioBits: Int) extends Module { | ||
val io = IO(new Bundle { | ||
val prio = Flipped(Vec(nDevices, UInt(prioBits.W))) | ||
val ip = Flipped(UInt(nDevices.W)) | ||
val dev = UInt(log2Ceil(nDevices+1).W) | ||
val max = UInt(prioBits.W) | ||
}) | ||
|
||
def findMax(x: Seq[UInt]): (UInt, UInt) = { | ||
if (x.length > 1) { | ||
val half = 1 << (log2Ceil(x.length) - 1) | ||
val left = findMax(x take half) | ||
val right = findMax(x drop half) | ||
MuxT(left._1 >= right._1, left, (right._1, half.U | right._2)) | ||
} else (x.head, 0.U) | ||
} | ||
|
||
val effectivePriority = (1.U << prioBits) +: (io.ip.asBools zip io.prio).map { case (p, x) => Cat(p, x) } | ||
val (maxPri, maxDev) = findMax(effectivePriority) | ||
io.max := maxPri // strips the always-constant high '1' bit | ||
io.dev := maxDev | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use Module here, just move the logic out.
plic/src/PLIC.scala
Outdated
|
||
if(parameter.nDevices > 0) { | ||
for (hart <- 0 until parameter.nHarts) { | ||
val fanin = Module(new PLICFanIn(parameter.nDevices, parameter.prioBits)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use Module here, just move the logic out.
plic/src/PLIC.scala
Outdated
} | ||
|
||
if(parameter.nDevices > 0) { | ||
for (hart <- 0 until parameter.nHarts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Seq.tabulate
plic/src/PLIC.scala
Outdated
def priorityRegField(x: UInt, i: Int) = | ||
if (parameter.nPriorities > 0) { | ||
RegField(parameter.prioBits, x, priorityRegDesc(i)) | ||
} else { | ||
RegField.r(parameter.prioBits, x, priorityRegDesc(i)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since only one place use it, you can inline it.
plic/src/PLIC.scala
Outdated
// were to change, it may no longer be true. | ||
// Note -- PLIC doesn't care which hart writes the register. | ||
val completer = Wire(Vec(parameter.nHarts, Bool())) | ||
assert((completer.asUInt & (completer.asUInt - 1.U)) === 0.U) // One-Hot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert((completer.asUInt & (completer.asUInt - 1.U)) === 0.U) // One-Hot | |
assert(PopCount(completer.asUInt) <= 1.U) // One-Hot |
plic/src/PLIC.scala
Outdated
def nHarts = harts | ||
def contexts = harts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the usage of nHarts
, harts
and nDevices
plic/src/PLIC.scala
Outdated
def findMax(x: Seq[UInt]): (UInt, UInt) = { | ||
if (x.length > 1) { | ||
val half = 1 << (log2Ceil(x.length) - 1) | ||
val left = findMax(x take half) | ||
val right = findMax(x drop half) | ||
MuxT(left._1 >= right._1, left, (right._1, half.U | right._2)) | ||
} else (x.head, 0.U) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally refer using DW_minmax
, but it can be left the future PR.
plic/src/PLIC.scala
Outdated
def thresholdRegField(x: UInt, i: Int) = | ||
if (parameter.nPriorities > 0) { | ||
RegField(parameter.prioBits, x, thresholdRegDesc(i)) | ||
} else { | ||
RegField.r(parameter.prioBits, x, thresholdRegDesc(i)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just inline this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please inline the Module.
plic/src/PLIC.scala
Outdated
class PLICFanIn(nDevices: Int, prioBits: Int) extends Module { | ||
val io = IO(new Bundle { | ||
val prio = Flipped(Vec(nDevices, UInt(prioBits.W))) | ||
val ip = Flipped(UInt(nDevices.W)) | ||
val dev = UInt(log2Ceil(nDevices + 1).W) | ||
val max = UInt(prioBits.W) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please inline the PLICFanIn
Module to provide as simple as possible logic, in traditional Verilog, it should be a function. In chisel, we use an inline Module to provide this feature, however the biggest issue was module linking.
The purpose of rocket-uncore is designed to provide an as simple as possible elaborator for the RISC-V related bus ips. For downstream users of the rocket-uncore, they only need to define the config and get the Verilog+IP-XACT for SoC design, thus minimizing the Module number to simplify the linking burden need to be concerned.
No description provided.