Handle taking offset chunks in uncoalescing logic

TODO: handling different size enums. Currently assumes everything is
4 bytes.
This commit is contained in:
Hansung Kim
2023-03-27 14:22:21 -07:00
parent 4daa0cefd8
commit d951de7810

View File

@@ -10,8 +10,7 @@ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util.{ShiftQueue, MultiPortQueue}
import freechips.rocketchip.unittest._
class CoalescingUnit(numLanes: Int = 1)(implicit p: Parameters)
extends LazyModule {
class CoalescingUnit(numLanes: Int = 1)(implicit p: Parameters) extends LazyModule {
// Identity node that captures the incoming TL requests and passes them
// through the other end, dropping coalesced requests. This node is what
@@ -39,17 +38,17 @@ class CoalescingUnit(numLanes: Int = 1)(implicit p: Parameters)
lazy val module = new CoalescingUnitImp(this, numLanes)
}
class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int)
extends LazyModuleImp(outer) {
class ReqQueueEntry(val sourceWidth: Int, val addressWidth: Int)
extends Bundle {
class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModuleImp(outer) {
val wordSize = 4
class ReqQueueEntry(val sourceWidth: Int, val addressWidth: Int) extends Bundle {
val source = UInt(sourceWidth.W)
val address = UInt(addressWidth.W)
val data = UInt(64.W /* FIXME hardcoded */ ) // write data
}
class RespQueueEntry(val sourceWidth: Int) extends Bundle {
val source = UInt(sourceWidth.W)
val data = UInt(64.W /* FIXME hardcoded */ ) // read data
val data = UInt(wordSize.W /* TODO double-word? */ ) // read data
}
// node.in(0) is from coalescer TL master node; 1~N are from cores
@@ -234,9 +233,25 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int)
// Look up the table with incoming coalesced responses
inflightTable.io.lookup.ready := tlCoal.d.valid
inflightTable.io.lookupSourceId := tlCoal.d.bits.source
val coalRespData = Wire(UInt(tlCoal.params.dataBits.W))
val coalDataWidth = tlCoal.params.dataBits
val coalRespData = Wire(UInt(coalDataWidth.W))
coalRespData := tlCoal.d.bits.data
// Un-coalescing logic
//
// FIXME: `size` should be UInt, not Int
def getCoalescedDataChunk(data: UInt, dataWidth: Int, offset: UInt, size: Int): UInt = {
val sizeMask = (1.U << size) - 1.U
assert(dataWidth % size == 0, "coalesced data width not evenly divisible by size")
val chunks = Wire(Vec(dataWidth / size, UInt(size.W)))
val offsets = (0 until dataWidth / size)
(chunks zip offsets).foreach { case (c, o) =>
// Take [(off-1)*size:off*size]
c := (data >> (dataWidth - (o + 1) * size)) & sizeMask
}
chunks(offset)
}
// Un-coalesce responses back to individual lanes and queue them up
val found = inflightTable.io.lookup.bits
found.lanes.zipWithIndex.foreach { case (l, i) =>
@@ -245,7 +260,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int)
val respQueue = respQueues(i)
assert(
respQueue.io.enq(respQueueCoalPortOffset).ready,
s"respQueue: enq port for ${i}-th coalesced response is blocked"
s"respQueue: enq port for 0-th coalesced response is blocked"
)
dontTouch(respQueue.io.enq(respQueueCoalPortOffset).ready)
respQueue.io.enq(respQueueCoalPortOffset).valid := false.B
@@ -255,13 +270,11 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int)
respQueue.io.enq(respQueueCoalPortOffset).valid := l.valid
respQueue.io.enq(respQueueCoalPortOffset).bits.source := 0.U
// Un-coalescing logic
//
// FIXME: disregard size enum for now
val sizeMask = (1.U << 4) - 1.U
val dataWidth = tlCoal.params.dataBits
val size = wordSize
respQueue.io.enq(respQueueCoalPortOffset).bits.data :=
(coalRespData >> (dataWidth - 4)) & sizeMask
getCoalescedDataChunk(coalRespData, coalDataWidth, l.reqs(0).offset, size)
// chunks(l.reqs(0).offset)
}
when(l.valid) {
@@ -404,8 +417,7 @@ class InflightCoalReqTableEntry(
val lanes = Vec(numLanes, new PerLane)
}
class MemTraceDriver(numLanes: Int = 1)(implicit p: Parameters)
extends LazyModule {
class MemTraceDriver(numLanes: Int = 1)(implicit p: Parameters) extends LazyModule {
// Create N client nodes together
val laneNodes = Seq.tabulate(numLanes) { i =>
val clientParam = Seq(
@@ -559,8 +571,7 @@ class CoalConnectTrace(implicit p: Parameters) extends LazyModule {
}
}
class CoalescingUnitTest(timeout: Int = 500000)(implicit p: Parameters)
extends UnitTest(timeout) {
class CoalescingUnitTest(timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
val dut = Module(LazyModule(new CoalConnectTrace).module)
dut.io.start := io.start
io.finished := dut.io.finished