diff --git a/src/main/scala/util/AsyncQueue.scala b/src/main/scala/util/AsyncQueue.scala index f73b5e85..f2664111 100644 --- a/src/main/scala/util/AsyncQueue.scala +++ b/src/main/scala/util/AsyncQueue.scala @@ -4,17 +4,19 @@ package util import Chisel._ object GrayCounter { - def apply(bits: Int, increment: Bool = Bool(true), clear: Bool = Bool(false)): UInt = { + def apply(bits: Int, increment: Bool = Bool(true), clear: Bool = Bool(false), name: String = "binary"): UInt = { val incremented = Wire(UInt(width=bits)) - val binary = AsyncResetReg(incremented) + val binary = AsyncResetReg(incremented, name) incremented := Mux(clear, UInt(0), binary + increment.asUInt()) incremented ^ (incremented >> UInt(1)) } } object AsyncGrayCounter { - def apply(in: UInt, sync: Int): UInt = { - val syncv = List.fill(sync)(Module (new AsyncResetRegVec(w = in.getWidth, 0))) + def apply(in: UInt, sync: Int, name: String = "gray"): UInt = { + val syncv = List.tabulate(sync) { i => + Module (new AsyncResetRegVec(w = in.getWidth, 0)).suggestName(s"${name}_sync_${i}") + } syncv.last.io.d := in syncv.last.io.en := Bool(true) (syncv.init zip syncv.tail).foreach { case (sink, source) => @@ -39,22 +41,22 @@ class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int) extends Module } // extend the sink reset to a full cycle (assertion latency <= 1 cycle) - val catch_reset_n = AsyncResetReg(Bool(true), clock, !io.sink_reset_n) + val catch_reset_n = AsyncResetReg(Bool(true), clock, !io.sink_reset_n, "catch_sink_reset_n") // reset_n has a 1 cycle shorter path to ready than ridx does - val sink_reset_n = AsyncGrayCounter(catch_reset_n.asUInt, sync)(0) + val sink_reset_n = AsyncGrayCounter(catch_reset_n.asUInt, sync, "sink_reset_n")(0) val mem = Reg(Vec(depth, gen)) //This does NOT need to be asynchronously reset. - val widx = GrayCounter(bits+1, io.enq.fire(), !sink_reset_n) - val ridx = AsyncGrayCounter(io.ridx, sync) + val widx = GrayCounter(bits+1, io.enq.fire(), !sink_reset_n, "widx_bin") + val ridx = AsyncGrayCounter(io.ridx, sync, "ridx_gray") val ready = widx =/= (ridx ^ UInt(depth | depth >> 1)) val index = if (depth == 1) UInt(0) else io.widx(bits-1, 0) ^ (io.widx(bits, bits) << (bits-1)) when (io.enq.fire()) { mem(index) := io.enq.bits } - val ready_reg = AsyncResetReg(ready.asUInt)(0) + val ready_reg = AsyncResetReg(ready.asUInt, "ready")(0) io.enq.ready := ready_reg && sink_reset_n - val widx_reg = AsyncResetReg(widx) + val widx_reg = AsyncResetReg(widx, "widx_gray") io.widx := widx_reg io.mem := mem @@ -77,12 +79,12 @@ class AsyncQueueSink[T <: Data](gen: T, depth: Int, sync: Int) extends Module { } // extend the source reset to a full cycle (assertion latency <= 1 cycle) - val catch_reset_n = AsyncResetReg(Bool(true), clock, !io.source_reset_n) + val catch_reset_n = AsyncResetReg(Bool(true), clock, !io.source_reset_n, "catch_source_reset_n") // reset_n has a 1 cycle shorter path to valid than widx does - val source_reset_n = AsyncGrayCounter(catch_reset_n.asUInt, sync)(0) + val source_reset_n = AsyncGrayCounter(catch_reset_n.asUInt, sync, "source_reset_n")(0) - val ridx = GrayCounter(bits+1, io.deq.fire(), !source_reset_n) - val widx = AsyncGrayCounter(io.widx, sync) + val ridx = GrayCounter(bits+1, io.deq.fire(), !source_reset_n, "ridx_bin") + val widx = AsyncGrayCounter(io.widx, sync, "widx_gray") val valid = ridx =/= widx // The mux is safe because timing analysis ensures ridx has reached the register @@ -96,10 +98,10 @@ class AsyncQueueSink[T <: Data](gen: T, depth: Int, sync: Int) extends Module { // This is safe, because isolation gates brought mem low before the zeroed widx reached us io.deq.bits := RegEnable(io.mem(index), valid) - val valid_reg = AsyncResetReg(valid.asUInt)(0) + val valid_reg = AsyncResetReg(valid.asUInt, "valid_reg")(0) io.deq.valid := valid_reg && source_reset_n - val ridx_reg = AsyncResetReg(ridx) + val ridx_reg = AsyncResetReg(ridx, "ridx_gray") io.ridx := ridx_reg // It is a fatal error to reset half a Queue while it still has data