Handle taking offset chunks in uncoalescing logic
TODO: handling different size enums. Currently assumes everything is 4 bytes.
This commit is contained in:
@@ -10,8 +10,7 @@ import freechips.rocketchip.diplomacy._
|
|||||||
import freechips.rocketchip.util.{ShiftQueue, MultiPortQueue}
|
import freechips.rocketchip.util.{ShiftQueue, MultiPortQueue}
|
||||||
import freechips.rocketchip.unittest._
|
import freechips.rocketchip.unittest._
|
||||||
|
|
||||||
class CoalescingUnit(numLanes: Int = 1)(implicit p: Parameters)
|
class CoalescingUnit(numLanes: Int = 1)(implicit p: Parameters) extends LazyModule {
|
||||||
extends LazyModule {
|
|
||||||
|
|
||||||
// Identity node that captures the incoming TL requests and passes them
|
// Identity node that captures the incoming TL requests and passes them
|
||||||
// through the other end, dropping coalesced requests. This node is what
|
// 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)
|
lazy val module = new CoalescingUnitImp(this, numLanes)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int)
|
class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModuleImp(outer) {
|
||||||
extends LazyModuleImp(outer) {
|
val wordSize = 4
|
||||||
class ReqQueueEntry(val sourceWidth: Int, val addressWidth: Int)
|
|
||||||
extends Bundle {
|
class ReqQueueEntry(val sourceWidth: Int, val addressWidth: Int) extends Bundle {
|
||||||
val source = UInt(sourceWidth.W)
|
val source = UInt(sourceWidth.W)
|
||||||
val address = UInt(addressWidth.W)
|
val address = UInt(addressWidth.W)
|
||||||
val data = UInt(64.W /* FIXME hardcoded */ ) // write data
|
val data = UInt(64.W /* FIXME hardcoded */ ) // write data
|
||||||
}
|
}
|
||||||
class RespQueueEntry(val sourceWidth: Int) extends Bundle {
|
class RespQueueEntry(val sourceWidth: Int) extends Bundle {
|
||||||
val source = UInt(sourceWidth.W)
|
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
|
// 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
|
// Look up the table with incoming coalesced responses
|
||||||
inflightTable.io.lookup.ready := tlCoal.d.valid
|
inflightTable.io.lookup.ready := tlCoal.d.valid
|
||||||
inflightTable.io.lookupSourceId := tlCoal.d.bits.source
|
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
|
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
|
// Un-coalesce responses back to individual lanes and queue them up
|
||||||
val found = inflightTable.io.lookup.bits
|
val found = inflightTable.io.lookup.bits
|
||||||
found.lanes.zipWithIndex.foreach { case (l, i) =>
|
found.lanes.zipWithIndex.foreach { case (l, i) =>
|
||||||
@@ -245,7 +260,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int)
|
|||||||
val respQueue = respQueues(i)
|
val respQueue = respQueues(i)
|
||||||
assert(
|
assert(
|
||||||
respQueue.io.enq(respQueueCoalPortOffset).ready,
|
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)
|
dontTouch(respQueue.io.enq(respQueueCoalPortOffset).ready)
|
||||||
respQueue.io.enq(respQueueCoalPortOffset).valid := false.B
|
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).valid := l.valid
|
||||||
respQueue.io.enq(respQueueCoalPortOffset).bits.source := 0.U
|
respQueue.io.enq(respQueueCoalPortOffset).bits.source := 0.U
|
||||||
|
|
||||||
// Un-coalescing logic
|
|
||||||
//
|
|
||||||
// FIXME: disregard size enum for now
|
// FIXME: disregard size enum for now
|
||||||
val sizeMask = (1.U << 4) - 1.U
|
val size = wordSize
|
||||||
val dataWidth = tlCoal.params.dataBits
|
|
||||||
respQueue.io.enq(respQueueCoalPortOffset).bits.data :=
|
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) {
|
when(l.valid) {
|
||||||
@@ -404,8 +417,7 @@ class InflightCoalReqTableEntry(
|
|||||||
val lanes = Vec(numLanes, new PerLane)
|
val lanes = Vec(numLanes, new PerLane)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemTraceDriver(numLanes: Int = 1)(implicit p: Parameters)
|
class MemTraceDriver(numLanes: Int = 1)(implicit p: Parameters) extends LazyModule {
|
||||||
extends LazyModule {
|
|
||||||
// Create N client nodes together
|
// Create N client nodes together
|
||||||
val laneNodes = Seq.tabulate(numLanes) { i =>
|
val laneNodes = Seq.tabulate(numLanes) { i =>
|
||||||
val clientParam = Seq(
|
val clientParam = Seq(
|
||||||
@@ -559,8 +571,7 @@ class CoalConnectTrace(implicit p: Parameters) extends LazyModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoalescingUnitTest(timeout: Int = 500000)(implicit p: Parameters)
|
class CoalescingUnitTest(timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
|
||||||
extends UnitTest(timeout) {
|
|
||||||
val dut = Module(LazyModule(new CoalConnectTrace).module)
|
val dut = Module(LazyModule(new CoalConnectTrace).module)
|
||||||
dut.io.start := io.start
|
dut.io.start := io.start
|
||||||
io.finished := dut.io.finished
|
io.finished := dut.io.finished
|
||||||
|
|||||||
Reference in New Issue
Block a user