Generalize Req/RespQueueEntry into Response/Request bundle
This commit is contained in:
@@ -135,7 +135,10 @@ class CoalescingUnit(config: CoalescerConfig)(implicit p: Parameters) extends La
|
|||||||
lazy val module = new CoalescingUnitImp(this, config)
|
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")
|
require(dataWidth % 8 == 0, s"dataWidth (${dataWidth} bits) is not multiple of 8")
|
||||||
val op = UInt(1.W) // 0=READ 1=WRITE
|
val op = UInt(1.W) // 0=READ 1=WRITE
|
||||||
val address = UInt(addressWidth.W)
|
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 op = UInt(1.W) // 0=READ 1=WRITE
|
||||||
val size = UInt(sizeWidth.W)
|
val size = UInt(sizeWidth.W)
|
||||||
val source = UInt(sourceWidth.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
|
// If `ignoreInUse`, just keep giving out new IDs without checking if it is in
|
||||||
// use.
|
// use.
|
||||||
class RoundRobinSourceGenerator(sourceWidth: Int, ignoreInUse: Boolean = true) extends Module {
|
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
|
// Software model: coalescer.py
|
||||||
class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
|
class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[Request],
|
||||||
config: CoalescerConfig) extends Module {
|
config: CoalescerConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val window = Input(windowT.io.cloneType)
|
val window = Input(windowT.io.cloneType)
|
||||||
@@ -376,7 +388,7 @@ class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
|
|||||||
|
|
||||||
val size = coalLogSize
|
val size = coalLogSize
|
||||||
val addrMask = (((1 << config.addressWidth) - 1) - ((1 << size) - 1)).U
|
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) &&
|
(req0.op === req1.op) &&
|
||||||
(req0v && req1v) &&
|
(req0v && req1v) &&
|
||||||
((req0.address & this.addrMask) === (req1.address & this.addrMask))
|
((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.
|
// coalesced request out of all possible combinations.
|
||||||
//
|
//
|
||||||
// Software model: coalescer.py
|
// Software model: coalescer.py
|
||||||
class MultiCoalescer(windowT: CoalShiftQueue[ReqQueueEntry], coalReqT: ReqQueueEntry,
|
class MultiCoalescer(windowT: CoalShiftQueue[Request], coalReqT: Request,
|
||||||
config: CoalescerConfig) extends Module {
|
config: CoalescerConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
// coalescing window, connected to the contents of the request queues
|
// 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
|
val sourceWidth = outer.cpuNode.in.head._1.params.sourceBits
|
||||||
// note we are using word size. assuming all coalescer inputs are word sized
|
// 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))
|
config.addressWidth, (config.wordSizeInBytes * 8))
|
||||||
val reqQueues = Module(new CoalShiftQueue(reqQueueEntryT, config.queueDepth, config))
|
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)
|
config.addressWidth, (1 << config.maxCoalLogSize) * 8)
|
||||||
val coalescer = Module(new MultiCoalescer(reqQueues, coalReqT, config))
|
val coalescer = Module(new MultiCoalescer(reqQueues, coalReqT, config))
|
||||||
coalescer.io.window := reqQueues.io
|
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).
|
// coalesced request. Upper bound is min(DEPTH, 2**sourceWidth).
|
||||||
val numPerLaneReqs = config.queueDepth
|
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)
|
(1 << config.maxCoalLogSize) * 8)
|
||||||
val respQueues = Seq.tabulate(config.numLanes) { _ =>
|
val respQueues = Seq.tabulate(config.numLanes) { _ =>
|
||||||
Module(
|
Module(
|
||||||
@@ -821,8 +834,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
uncoalescer.io.newEntry := newEntry
|
uncoalescer.io.newEntry := newEntry
|
||||||
// Cleanup: custom <>?
|
// Cleanup: custom <>?
|
||||||
uncoalescer.io.coalResp.valid := tlCoal.d.valid
|
uncoalescer.io.coalResp.valid := tlCoal.d.valid
|
||||||
uncoalescer.io.coalResp.bits.source := tlCoal.d.bits.source
|
uncoalescer.io.coalResp.bits.fromTLD(tlCoal.d.bits)
|
||||||
uncoalescer.io.coalResp.bits.data := tlCoal.d.bits.data
|
|
||||||
tlCoal.d.ready := uncoalescer.io.coalResp.ready
|
tlCoal.d.ready := uncoalescer.io.coalResp.ready
|
||||||
|
|
||||||
// Connect uncoalescer results back into each lane's response queue
|
// Connect uncoalescer results back into each lane's response queue
|
||||||
@@ -853,24 +865,6 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
dontTouch(tlCoal.d)
|
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 {
|
class Uncoalescer(config: CoalescerConfig) extends Module {
|
||||||
// notes to hansung:
|
// notes to hansung:
|
||||||
// val numLanes: Int, <-> config.NUM_LANES
|
// val numLanes: Int, <-> config.NUM_LANES
|
||||||
@@ -884,15 +878,14 @@ class Uncoalescer(config: CoalescerConfig) extends Module {
|
|||||||
val coalReqValid = Input(Bool())
|
val coalReqValid = Input(Bool())
|
||||||
// FIXME: receive ReqQueueEntry and construct newEntry inside uncoalescer
|
// FIXME: receive ReqQueueEntry and construct newEntry inside uncoalescer
|
||||||
val newEntry = Input(inflightTable.entryT.cloneType)
|
val newEntry = Input(inflightTable.entryT.cloneType)
|
||||||
val coalResp = Flipped(Decoupled(new CoalescedResponseBundle(config)))
|
val coalResp = Flipped(Decoupled(new CoalescedResponse(config)))
|
||||||
val uncoalResps = Output(
|
val uncoalResps = Output(
|
||||||
Vec(
|
Vec(
|
||||||
config.numLanes,
|
config.numLanes,
|
||||||
Vec(
|
Vec(
|
||||||
config.queueDepth,
|
config.queueDepth,
|
||||||
ValidIO(
|
ValidIO(
|
||||||
new RespQueueEntry(log2Ceil(config.numOldSrcIds), config.wordSizeWidth,
|
new NonCoalescedResponse(config)
|
||||||
config.wordSizeInBytes * 8)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -1853,25 +1846,20 @@ class CoalescerXbar(config: CoalescerConfig) (implicit p: Parameters) extends La
|
|||||||
val node = TLIdentityNode()
|
val node = TLIdentityNode()
|
||||||
node :=* outputXbar.node
|
node :=* outputXbar.node
|
||||||
|
|
||||||
val nonCoalEntryT = new ReqQueueEntry(
|
val nonCoalEntryT = new Request(
|
||||||
log2Ceil(config.numOldSrcIds),
|
log2Ceil(config.numOldSrcIds),
|
||||||
config.wordSizeWidth,
|
config.wordSizeWidth,
|
||||||
config.addressWidth,
|
config.addressWidth,
|
||||||
config.wordSizeInBytes * 8
|
config.wordSizeInBytes * 8
|
||||||
)
|
)
|
||||||
val coalEntryT = new ReqQueueEntry(
|
val coalEntryT = new Request(
|
||||||
log2Ceil(config.numOldSrcIds),
|
log2Ceil(config.numOldSrcIds),
|
||||||
log2Ceil(config.maxCoalLogSize),
|
log2Ceil(config.maxCoalLogSize),
|
||||||
config.addressWidth,
|
config.addressWidth,
|
||||||
(1 << config.maxCoalLogSize) * 8
|
(1 << config.maxCoalLogSize) * 8
|
||||||
)
|
)
|
||||||
val respNonCoalEntryT = new RespQueueEntry(
|
val respNonCoalEntryT = new NonCoalescedResponse(config)
|
||||||
log2Ceil(config.numOldSrcIds),
|
val respCoalBundleT = new CoalescedResponse(config)
|
||||||
config.wordSizeWidth,
|
|
||||||
config.wordSizeInBytes * 8
|
|
||||||
)
|
|
||||||
|
|
||||||
val respCoalBundleT = new CoalescedResponseBundle(config)
|
|
||||||
|
|
||||||
|
|
||||||
lazy val module = new CoalescerXbarImpl(
|
lazy val module = new CoalescerXbarImpl(
|
||||||
@@ -1883,10 +1871,10 @@ class CoalescerXbar(config: CoalescerConfig) (implicit p: Parameters) extends La
|
|||||||
|
|
||||||
class CoalescerXbarImpl(outer: CoalescerXbar,
|
class CoalescerXbarImpl(outer: CoalescerXbar,
|
||||||
config: CoalescerConfig,
|
config: CoalescerConfig,
|
||||||
nonCoalEntryT: ReqQueueEntry,
|
nonCoalEntryT: Request,
|
||||||
coalEntryT: ReqQueueEntry,
|
coalEntryT: Request,
|
||||||
respNonCoalEntryT: RespQueueEntry,
|
respNonCoalEntryT: Response,
|
||||||
respCoalBundleT: CoalescedResponseBundle
|
respCoalBundleT: CoalescedResponse
|
||||||
) extends LazyModuleImp(outer){
|
) extends LazyModuleImp(outer){
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user