From 437be0f36a6b708d973d910d41fcd0499fea06fa Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 22 Nov 2016 20:39:38 -0800 Subject: [PATCH] PositionalMultiQueue: use a UInt instead of Reg(Vec(Bool)) This results in much less Verilog to simulate --- src/main/scala/util/PositionalMultiQueue.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/scala/util/PositionalMultiQueue.scala b/src/main/scala/util/PositionalMultiQueue.scala index b9c00b9b..e3879d64 100644 --- a/src/main/scala/util/PositionalMultiQueue.scala +++ b/src/main/scala/util/PositionalMultiQueue.scala @@ -38,23 +38,24 @@ class PositionalMultiQueue[T <: Data](params: PositionalMultiQueueParameters[T], val next = Mem(params.positions, UInt(width = log2Up(params.positions))) val data = Mem(params.positions, params.gen) // optimized away for synthesis; used to confirm invariant - val guard = RegInit(Vec.fill(params.positions) { Bool(false) }) + val guard = RegInit(UInt(0, width = params.positions)) when (io.enq.fire()) { data(io.enq.bits.pos) := io.enq.bits.data // ensure the user never stores to the same position twice assert (!guard(io.enq.bits.pos)) - guard(io.enq.bits.pos) := Bool(true) when (!empty(io.enq.bits.way)) { next(tail(io.enq.bits.way)) := io.enq.bits.pos } } + val setGuard = io.enq.fire() << io.enq.bits.pos val deq = Wire(io.deq) io.deq <> deq val waySelect = UIntToOH(io.enq.bits.way, params.ways) + var clrGuard = UInt(0) for (i <- 0 until params.ways) { val enq = io.enq.fire() && waySelect(i) val last = head(i) === tail(i) @@ -78,13 +79,15 @@ class PositionalMultiQueue[T <: Data](params: PositionalMultiQueueParameters[T], when (deq(i).fire()) { head(i) := Mux(last, io.enq.bits.pos, next(head(i))) - guard(deq(i).bits.pos) := Bool(false) } + clrGuard = clrGuard | (deq(i).fire() << deq(i).bits.pos) when (enq =/= deq(i).fire()) { empty(i) := deq(i).fire() && last } } + + guard := (guard | setGuard) & ~clrGuard } object PositionalMultiQueue