Reputation: 163
The following code implements a n N-bit fixed priority arbiter.
import chisel3._
import chisel3.util._
class fixedPriorityArbiter(val n_reqs:Int = 4) extends Module {
val NO_OF_REQS = n_reqs
val io = IO(new Bundle {
val req = Input(UInt(NO_OF_REQS.W))
val grant = Output(UInt(NO_OF_REQS.W))
})
val higherPriReq = Wire(UInt(NO_OF_REQS.W))
higherPriReq := Cat((higherPriReq(NO_OF_REQS-2, 0) | io.req(NO_OF_REQS-2, 0)), UInt(0,1.W))
io.grant := io.req & ~higherPriReq
}
object main_obj extends App {
val DUT = () => new fixedPriorityArbiter()
val margs = Array("--compiler", "verilog")
chisel3.Driver.execute(args= margs, dut= DUT)
}
Inexistent combinatorial loops are reported for this code. The chisel source mirrors a Verilog implementation of the circuit below which doesn't report any combinatorial loops when synthesized in Synopsys Synplify.
The following compile error is reported by FIRRTL in Eclipse IDE on Windows without any Verilog source being generated by FIRRTL
Upvotes: 2
Views: 440
Reputation: 6064
FIRRTL does not support subword analysis so by using a UInt here you are creating what appears to be a combinational loop even though it actually isn't. To get around this, you can use aggregate types like Vecs to make it explicit to Firrtl that you are doing work on the individual bits. Here's an equivalent implementation using a Vec:
class FixedPriorityArbiter(val n_reqs: Int = 4) extends Module {
val NO_OF_REQS = n_reqs
val io = IO(new Bundle {
val req = Input(UInt(NO_OF_REQS.W))
val grant = Output(UInt(NO_OF_REQS.W))
})
val higherPriReq = Wire(Vec(NO_OF_REQS, Bool()))
// Vec implements scala.collection.Seq so you can use such operations as slice and map
val upperOr = higherPriReq.slice(0, NO_OF_REQS-1).zip(io.req(NO_OF_REQS-2, 0).toBools)
.map { case (l, r) => l | r }
higherPriReq := false.B +: upperOr
io.grant := io.req & ~higherPriReq.asUInt
}
Upvotes: 3