From 2a0fd24d178c49a4b741303bd877c8d59c0ab2c2 Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Fri, 19 May 2023 23:52:35 -0700 Subject: [PATCH] Make SourceGenerator do CAM search for lowest-index free slot Reduces unnecessary stalls waiting for the next round-robin index to be reclaimed. --- src/main/scala/tilelink/Coalescing.scala | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 0ac4e14..08e6387 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -238,7 +238,7 @@ case class CoalescedResponse(config: CoalescerConfig) // If `ignoreInUse`, just keep giving out new IDs without checking if it is in // use. -class RoundRobinSourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true) +class SourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true) extends Module { val io = IO(new Bundle { val gen = Input(Bool()) @@ -258,11 +258,14 @@ class RoundRobinSourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true) // true: in use, false: available val occupancyTable = Mem(numSourceId, Valid(UInt(sourceWidth.W))) when(reset.asBool) { - (0 until numSourceId).foreach { i => occupancyTable(i).valid := false.B } + (0 until numSourceId).foreach { occupancyTable(_).valid := false.B } } + val frees = (0 until numSourceId).map(!occupancyTable(_).valid) + val lowestFree = PriorityEncoder(frees) + val lowestFreeRow = occupancyTable(lowestFree) - io.id.valid := (if (ignoreInUse) true.B else !occupancyTable(head).valid) - io.id.bits := head + io.id.valid := (if (ignoreInUse) true.B else !lowestFreeRow.valid) + io.id.bits := lowestFree when(io.gen && io.id.valid /* fire */ ) { occupancyTable(io.id.bits).valid := true.B // mark in use } @@ -728,7 +731,7 @@ class CoalescerSourceGen( val inResp = Flipped(Decoupled(respT.cloneType)) }) val sourceGen = Module( - new RoundRobinSourceGenerator(log2Ceil(config.numNewSrcIds), ignoreInUse = false) + new SourceGenerator(log2Ceil(config.numNewSrcIds), ignoreInUse = false) ) sourceGen.io.gen := io.outReq.fire // use up a source ID only when request is created sourceGen.io.reclaim.valid := io.inResp.fire @@ -1385,7 +1388,7 @@ class MemTraceDriverImp( } val sourceGens = Seq.fill(config.numLanes)(Module( - new RoundRobinSourceGenerator( + new SourceGenerator( log2Ceil(config.numOldSrcIds), ignoreInUse = false ) @@ -2200,4 +2203,4 @@ class CoalescerXbarImpl(outer: CoalescerXbar, //Nonthing } - } \ No newline at end of file + }