Make SourceGenerator do CAM search for lowest-index free slot

Reduces unnecessary stalls waiting for the next round-robin index to be
reclaimed.
This commit is contained in:
Hansung Kim
2023-05-19 23:52:35 -07:00
parent 9ecace676c
commit 2a0fd24d17

View File

@@ -238,7 +238,7 @@ case class CoalescedResponse(config: CoalescerConfig)
// If `ignoreInUse`, just keep giving out new IDs without checking if it is in // If `ignoreInUse`, just keep giving out new IDs without checking if it is in
// use. // use.
class RoundRobinSourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true) class SourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true)
extends Module { extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val gen = Input(Bool()) val gen = Input(Bool())
@@ -258,11 +258,14 @@ class RoundRobinSourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true)
// true: in use, false: available // true: in use, false: available
val occupancyTable = Mem(numSourceId, Valid(UInt(sourceWidth.W))) val occupancyTable = Mem(numSourceId, Valid(UInt(sourceWidth.W)))
when(reset.asBool) { 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.valid := (if (ignoreInUse) true.B else !lowestFreeRow.valid)
io.id.bits := head io.id.bits := lowestFree
when(io.gen && io.id.valid /* fire */ ) { when(io.gen && io.id.valid /* fire */ ) {
occupancyTable(io.id.bits).valid := true.B // mark in use occupancyTable(io.id.bits).valid := true.B // mark in use
} }
@@ -728,7 +731,7 @@ class CoalescerSourceGen(
val inResp = Flipped(Decoupled(respT.cloneType)) val inResp = Flipped(Decoupled(respT.cloneType))
}) })
val sourceGen = Module( 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.gen := io.outReq.fire // use up a source ID only when request is created
sourceGen.io.reclaim.valid := io.inResp.fire sourceGen.io.reclaim.valid := io.inResp.fire
@@ -1385,7 +1388,7 @@ class MemTraceDriverImp(
} }
val sourceGens = Seq.fill(config.numLanes)(Module( val sourceGens = Seq.fill(config.numLanes)(Module(
new RoundRobinSourceGenerator( new SourceGenerator(
log2Ceil(config.numOldSrcIds), log2Ceil(config.numOldSrcIds),
ignoreInUse = false ignoreInUse = false
) )
@@ -2200,4 +2203,4 @@ class CoalescerXbarImpl(outer: CoalescerXbar,
//Nonthing //Nonthing
} }
} }