There are a few minor issues with this code:
- Generally we name variables starting with a lower-case letter in Scala, this is primarily style, but it does have semantic meaning it certain circumstances (like pattern matching)
- Square brackets are only used for type parameters (like Java generics), indexing uses normal parentheses in Scala
- An input Vec of Bools is normally defined as:
val req = Input(Vec(numInputs, Bool())) (assuming import chisel3._, but this should also work in Chisel._ for Chisel 3.2)
if and else are used for static parameterization (ie. at hardware elaboration time) while when and .otherwise are used for dynamic logic (eg. actual muxes)
UInt is for hardware types, if you have a static parameter (like numInputs), use a Scala Int
Other than the minor syntactical stuff, the trickiest part of getting this code right is understanding the difference between Scala constructs that are only run at elaboration time (ie. when the Scala program generates the hardware), vs. what actually shows up in the hardware. I would suggest reading this thread from the chisel-users mailing list for some more context about some of this stuff: https://groups.google.com/d/msg/chisel-users/gRoNnH-Y5hE/ynDCtmNPCAAJ
I'm a little confused as to what value io.grant is supposed to get, but I'm assuming it should be the index of the highest priority io.req.
Here's an untested version of your code that I think should work and do what you want:
//Priority Encoder
class P_Encoder(numInputs: Int) extends Module {
// We wrap ports in IO
val io = IO(new Bundle {
val req = Input(Vec(numInputs, Bool()))
val rls = Input(Vec(numInputs, Bool()))
val grant = Output(UInt(log2Up(numInputs).W))
})
io.grant := 0.U // default grant value
// Due to Chisel last connect semantics, the last connection wins
// Thus the highest index will have priority
for (i <- 0 to numInputs - 1) {
when (io.req(i) && !io.rls(i)) {
io.grant := i.U
}
}
}
This code is tricky because it's mixing an elaboration time for loop with hardware whens and connections, I'm going to manually unroll this loop to illustrate what it's doing:
io.grant := 0.U
when (io.req(0) && !io.rls(0)) {
io.grant := 0.U
}
when (io.req(1) && !io.rls(1)) {
io.grant := 1.U
}
when (io.req(2) && !io.rls(2)) {
io.grant := 2.U
}
...
Alternatively, we can just reuse the built-in PriorityEncoder utility if we want
import chisel3.util.PriorityEncoder
val enables = io.req.zip(io.rls).map { case (x, y) => x && !y }
// PriorityEncoder gives priority to *lowest* order bit
io.grant := PriorityEncoder(enables)