Generalize Req/RespQueueEntry into Response/Request bundle

This commit is contained in:
Hansung Kim
2023-05-11 15:42:23 -07:00
parent 300eff4f9a
commit 5fed3ef823

View File

@@ -135,7 +135,10 @@ class CoalescingUnit(config: CoalescerConfig)(implicit p: Parameters) extends La
lazy val module = new CoalescingUnitImp(this, config)
}
class ReqQueueEntry(sourceWidth: Int, sizeWidth: Int, addressWidth: Int, dataWidth: Int) extends Bundle {
// Protocol-agnostic bundles that represent a request and a response to the
// coalescer.
class Request(sourceWidth: Int, sizeWidth: Int, addressWidth: Int, dataWidth: Int) extends Bundle {
require(dataWidth % 8 == 0, s"dataWidth (${dataWidth} bits) is not multiple of 8")
val op = UInt(1.W) // 0=READ 1=WRITE
val address = UInt(addressWidth.W)
@@ -163,7 +166,7 @@ class ReqQueueEntry(sourceWidth: Int, sizeWidth: Int, addressWidth: Int, dataWid
}
}
class RespQueueEntry(sourceWidth: Int, sizeWidth: Int, dataWidth: Int) extends Bundle {
class Response(sourceWidth: Int, sizeWidth: Int, dataWidth: Int) extends Bundle {
val op = UInt(1.W) // 0=READ 1=WRITE
val size = UInt(sizeWidth.W)
val source = UInt(sourceWidth.W)
@@ -192,6 +195,15 @@ class RespQueueEntry(sourceWidth: Int, sizeWidth: Int, dataWidth: Int) extends B
}
}
class NonCoalescedResponse(config: CoalescerConfig)
extends Response(sourceWidth = log2Ceil(config.numOldSrcIds),
sizeWidth = config.wordSizeWidth,
dataWidth = config.wordSizeInBytes * 8)
class CoalescedResponse(config: CoalescerConfig)
extends Response(sourceWidth = log2Ceil(config.numNewSrcIds),
sizeWidth = log2Ceil(config.maxCoalLogSize),
dataWidth = (8 * (1 << config.maxCoalLogSize)))
// If `ignoreInUse`, just keep giving out new IDs without checking if it is in
// use.
class RoundRobinSourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true) extends Module {
@@ -340,7 +352,7 @@ class CoalShiftQueue[T <: Data](gen: T, entries: Int, config: CoalescerConfig) e
}
// Software model: coalescer.py
class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[Request],
config: CoalescerConfig) extends Module {
val io = IO(new Bundle {
val window = Input(windowT.io.cloneType)
@@ -376,7 +388,7 @@ class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
val size = coalLogSize
val addrMask = (((1 << config.addressWidth) - 1) - ((1 << size) - 1)).U
def canMatch(req0: ReqQueueEntry, req0v: Bool, req1: ReqQueueEntry, req1v: Bool): Bool = {
def canMatch(req0: Request, req0v: Bool, req1: Request, req1v: Bool): Bool = {
(req0.op === req1.op) &&
(req0v && req1v) &&
((req0.address & this.addrMask) === (req1.address & this.addrMask))
@@ -471,7 +483,7 @@ class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
// coalesced request out of all possible combinations.
//
// Software model: coalescer.py
class MultiCoalescer(windowT: CoalShiftQueue[ReqQueueEntry], coalReqT: ReqQueueEntry,
class MultiCoalescer(windowT: CoalShiftQueue[Request], coalReqT: Request,
config: CoalescerConfig) extends Module {
val io = IO(new Bundle {
// coalescing window, connected to the contents of the request queues
@@ -612,11 +624,11 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
val sourceWidth = outer.cpuNode.in.head._1.params.sourceBits
// note we are using word size. assuming all coalescer inputs are word sized
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, config.wordSizeWidth,
val reqQueueEntryT = new Request(sourceWidth, config.wordSizeWidth,
config.addressWidth, (config.wordSizeInBytes * 8))
val reqQueues = Module(new CoalShiftQueue(reqQueueEntryT, config.queueDepth, config))
val coalReqT = new ReqQueueEntry(log2Ceil(config.numNewSrcIds), log2Ceil(config.maxCoalLogSize),
val coalReqT = new Request(log2Ceil(config.numNewSrcIds), log2Ceil(config.maxCoalLogSize),
config.addressWidth, (1 << config.maxCoalLogSize) * 8)
val coalescer = Module(new MultiCoalescer(reqQueues, coalReqT, config))
coalescer.io.window := reqQueues.io
@@ -703,7 +715,8 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
// coalesced request. Upper bound is min(DEPTH, 2**sourceWidth).
val numPerLaneReqs = config.queueDepth
val respQueueEntryT = new RespQueueEntry(sourceWidth, log2Ceil(config.maxCoalLogSize),
// FIXME: no need to contain maxCoalLogSize data
val respQueueEntryT = new Response(sourceWidth, log2Ceil(config.maxCoalLogSize),
(1 << config.maxCoalLogSize) * 8)
val respQueues = Seq.tabulate(config.numLanes) { _ =>
Module(
@@ -821,8 +834,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
uncoalescer.io.newEntry := newEntry
// Cleanup: custom <>?
uncoalescer.io.coalResp.valid := tlCoal.d.valid
uncoalescer.io.coalResp.bits.source := tlCoal.d.bits.source
uncoalescer.io.coalResp.bits.data := tlCoal.d.bits.data
uncoalescer.io.coalResp.bits.fromTLD(tlCoal.d.bits)
tlCoal.d.ready := uncoalescer.io.coalResp.ready
// Connect uncoalescer results back into each lane's response queue
@@ -853,24 +865,6 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
dontTouch(tlCoal.d)
}
// Protocol-agnostic bundle that represents a coalesced response.
//
// Having this makes it easier to:
// * do unit tests -- no need to deal with TileLink in the chiseltest code
// * adapt coalescer to custom protocols like a custom L1 cache interface.
//
// FIXME: overlaps with RespQueueEntry. Trait-ify
class CoalescedResponseBundle(config: CoalescerConfig) extends Bundle {
val source = UInt(log2Ceil(config.numNewSrcIds).W)
val data = UInt((8 * (1 << config.maxCoalLogSize)).W)
def fromTLD(bundle:TLBundleD): Unit = {
this.source := bundle.source
this.data := bundle.data
}
}
class Uncoalescer(config: CoalescerConfig) extends Module {
// notes to hansung:
// val numLanes: Int, <-> config.NUM_LANES
@@ -884,15 +878,14 @@ class Uncoalescer(config: CoalescerConfig) extends Module {
val coalReqValid = Input(Bool())
// FIXME: receive ReqQueueEntry and construct newEntry inside uncoalescer
val newEntry = Input(inflightTable.entryT.cloneType)
val coalResp = Flipped(Decoupled(new CoalescedResponseBundle(config)))
val coalResp = Flipped(Decoupled(new CoalescedResponse(config)))
val uncoalResps = Output(
Vec(
config.numLanes,
Vec(
config.queueDepth,
ValidIO(
new RespQueueEntry(log2Ceil(config.numOldSrcIds), config.wordSizeWidth,
config.wordSizeInBytes * 8)
new NonCoalescedResponse(config)
)
)
)
@@ -1853,25 +1846,20 @@ class CoalescerXbar(config: CoalescerConfig) (implicit p: Parameters) extends La
val node = TLIdentityNode()
node :=* outputXbar.node
val nonCoalEntryT = new ReqQueueEntry(
val nonCoalEntryT = new Request(
log2Ceil(config.numOldSrcIds),
config.wordSizeWidth,
config.addressWidth,
config.wordSizeInBytes * 8
)
val coalEntryT = new ReqQueueEntry(
val coalEntryT = new Request(
log2Ceil(config.numOldSrcIds),
log2Ceil(config.maxCoalLogSize),
config.addressWidth,
(1 << config.maxCoalLogSize) * 8
)
val respNonCoalEntryT = new RespQueueEntry(
log2Ceil(config.numOldSrcIds),
config.wordSizeWidth,
config.wordSizeInBytes * 8
)
val respCoalBundleT = new CoalescedResponseBundle(config)
val respNonCoalEntryT = new NonCoalescedResponse(config)
val respCoalBundleT = new CoalescedResponse(config)
lazy val module = new CoalescerXbarImpl(
@@ -1883,10 +1871,10 @@ class CoalescerXbar(config: CoalescerConfig) (implicit p: Parameters) extends La
class CoalescerXbarImpl(outer: CoalescerXbar,
config: CoalescerConfig,
nonCoalEntryT: ReqQueueEntry,
coalEntryT: ReqQueueEntry,
respNonCoalEntryT: RespQueueEntry,
respCoalBundleT: CoalescedResponseBundle
nonCoalEntryT: Request,
coalEntryT: Request,
respNonCoalEntryT: Response,
respCoalBundleT: CoalescedResponse
) extends LazyModuleImp(outer){