Make MemTraceLogger pass-through node
Instead of making MemTraceLogger a TL slave, make it an IdentityNode that simply snoops on the TL edges and generates logs. We can attach a TLRAM at the downstream to actually get response back, rather than MemTraceLogger simply absorbing all requests.
This commit is contained in:
@@ -216,13 +216,16 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
reqQueues(1).io.invalidate := 0x1.U
|
reqQueues(1).io.invalidate := 0x1.U
|
||||||
reqQueues(2).io.invalidate := 0x1.U
|
reqQueues(2).io.invalidate := 0x1.U
|
||||||
reqQueues(3).io.invalidate := 0x1.U
|
reqQueues(3).io.invalidate := 0x1.U
|
||||||
|
printf("coalescing succeeded!\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: write request
|
||||||
val (legal, bits) = edgeCoal.Get(
|
val (legal, bits) = edgeCoal.Get(
|
||||||
fromSource = coalSourceId,
|
fromSource = coalSourceId,
|
||||||
// `toAddress` should be aligned to 2**lgSize
|
// `toAddress` should be aligned to 2**lgSize
|
||||||
toAddress = coalReqAddress,
|
toAddress = coalReqAddress,
|
||||||
// 64 bits = 8 bytes = 2**(3) bytes
|
// 64 bits = 8 bytes = 2**(3) bytes
|
||||||
|
// TODO: parameterize to eg. cache line size
|
||||||
lgSize = 3.U
|
lgSize = 3.U
|
||||||
)
|
)
|
||||||
assert(legal, "unhandled illegal TL req gen")
|
assert(legal, "unhandled illegal TL req gen")
|
||||||
@@ -235,7 +238,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
|
|
||||||
// Construct new entry for the inflight table
|
// Construct new entry for the inflight table
|
||||||
// FIXME: don't instantiate inflight table entry type here. It leaks the table's impl
|
// FIXME: don't instantiate inflight table entry type here. It leaks the table's impl
|
||||||
// detail outside to the coalescer
|
// detail to the coalescer
|
||||||
val offsetBits = 4 // FIXME hardcoded
|
val offsetBits = 4 // FIXME hardcoded
|
||||||
val sizeBits = 2 // FIXME hardcoded
|
val sizeBits = 2 // FIXME hardcoded
|
||||||
val newEntry = Wire(
|
val newEntry = Wire(
|
||||||
@@ -348,7 +351,10 @@ class UncoalescingUnit(
|
|||||||
def getCoalescedDataChunk(data: UInt, dataWidth: Int, offset: UInt, byteSize: Int): UInt = {
|
def getCoalescedDataChunk(data: UInt, dataWidth: Int, offset: UInt, byteSize: Int): UInt = {
|
||||||
val bitSize = byteSize * 8
|
val bitSize = byteSize * 8
|
||||||
val sizeMask = (1.U << bitSize) - 1.U
|
val sizeMask = (1.U << bitSize) - 1.U
|
||||||
assert(dataWidth % bitSize == 0, "coalesced data width not evenly divisible by size")
|
assert(
|
||||||
|
dataWidth > 0 && dataWidth % bitSize == 0,
|
||||||
|
s"coalesced data width ($dataWidth) not evenly divisible by core req size ($bitSize)"
|
||||||
|
)
|
||||||
val numChunks = dataWidth / bitSize
|
val numChunks = dataWidth / bitSize
|
||||||
val chunks = Wire(Vec(numChunks, UInt(bitSize.W)))
|
val chunks = Wire(Vec(numChunks, UInt(bitSize.W)))
|
||||||
val offsets = (0 until numChunks)
|
val offsets = (0 until numChunks)
|
||||||
@@ -434,13 +440,12 @@ class InflightCoalReqTable(
|
|||||||
.map { i => table(i).valid }
|
.map { i => table(i).valid }
|
||||||
.reduce { (v0, v1) => v0 && v1 }
|
.reduce { (v0, v1) => v0 && v1 }
|
||||||
// Inflight table should never be full. It should have enough number of
|
// Inflight table should never be full. It should have enough number of
|
||||||
// entries to keep track of all outstanding core-side requests; otherwise,
|
// entries to keep track of all outstanding core-side requests, i.e.
|
||||||
// it will stall the core issuing logic.
|
// (2 ** oldSrcIdBits) entries.
|
||||||
assert(!full, "table is blocking coalescer")
|
assert(!full, "inflight table is full and blocking coalescer")
|
||||||
dontTouch(full)
|
dontTouch(full)
|
||||||
|
|
||||||
// Enqueue logic
|
// Enqueue logic
|
||||||
//
|
|
||||||
io.enq.ready := !full
|
io.enq.ready := !full
|
||||||
val enqFire = io.enq.ready && io.enq.valid
|
val enqFire = io.enq.ready && io.enq.valid
|
||||||
when(enqFire) {
|
when(enqFire) {
|
||||||
@@ -455,7 +460,6 @@ class InflightCoalReqTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lookup logic
|
// Lookup logic
|
||||||
//
|
|
||||||
io.lookup.valid := table(io.lookupSourceId).valid
|
io.lookup.valid := table(io.lookupSourceId).valid
|
||||||
io.lookup.bits := table(io.lookupSourceId).bits
|
io.lookup.bits := table(io.lookupSourceId).bits
|
||||||
val lookupFire = io.lookup.ready && io.lookup.valid
|
val lookupFire = io.lookup.ready && io.lookup.valid
|
||||||
@@ -723,36 +727,52 @@ class SimMemTrace(filename: String, numLanes: Int)
|
|||||||
addResource("/csrc/SimMemTrace.h")
|
addResource("/csrc/SimMemTrace.h")
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemTraceLogger(numLanes: Int = 5)(implicit p: Parameters) extends LazyModule {
|
class MemTraceLogger(numLanes: Int = 4)(implicit p: Parameters) extends LazyModule {
|
||||||
val beatBytes = 4 // FIXME: hardcoded
|
val node = TLIdentityNode()
|
||||||
val node = TLManagerNode(Seq.tabulate(numLanes) { _ =>
|
|
||||||
TLSlavePortParameters.v1(
|
// val beatBytes = 8 // FIXME: hardcoded
|
||||||
Seq(
|
// val node = TLManagerNode(Seq.tabulate(numLanes) { _ =>
|
||||||
TLSlaveParameters.v1(
|
// TLSlavePortParameters.v1(
|
||||||
address = List(AddressSet(0x0000, 0xffffff)), // FIXME: hardcoded
|
// Seq(
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
// TLSlaveParameters.v1(
|
||||||
supportsPutPartial = TransferSizes(1, beatBytes),
|
// address = List(AddressSet(0x0000, 0xffffff)), // FIXME: hardcoded
|
||||||
supportsPutFull = TransferSizes(1, beatBytes)
|
// supportsGet = TransferSizes(1, beatBytes),
|
||||||
)
|
// supportsPutPartial = TransferSizes(1, beatBytes),
|
||||||
),
|
// supportsPutFull = TransferSizes(1, beatBytes)
|
||||||
beatBytes = beatBytes
|
// )
|
||||||
)
|
// ),
|
||||||
})
|
// beatBytes = beatBytes
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
|
||||||
lazy val module = new Impl
|
lazy val module = new Impl
|
||||||
class Impl extends LazyModuleImp(this) {}
|
class Impl extends LazyModuleImp(this) {
|
||||||
|
(node.in zip node.out).foreach {
|
||||||
|
case ((tlIn, _), (tlOut, _)) =>
|
||||||
|
tlOut.a <> tlIn.a
|
||||||
|
tlIn.d <> tlOut.d
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// synthesizable unit tests
|
// synthesizable unit tests
|
||||||
|
|
||||||
class CoalescerLogger(implicit p: Parameters) extends LazyModule {
|
// tracedriver --> coalescer --> tracelogger --> tlram
|
||||||
|
class TLRAMCoalescerLogger(implicit p: Parameters) extends LazyModule {
|
||||||
// TODO: use parameters for numLanes
|
// TODO: use parameters for numLanes
|
||||||
val numLanes = 4
|
val numLanes = 4
|
||||||
val coal = LazyModule(new CoalescingUnit(numLanes))
|
val coal = LazyModule(new CoalescingUnit(numLanes))
|
||||||
val driver = LazyModule(new MemTraceDriver(numLanes))
|
val driver = LazyModule(new MemTraceDriver(numLanes))
|
||||||
val logger = LazyModule(new MemTraceLogger(numLanes + 1)) // +1 for coalesced edge
|
val logger = LazyModule(new MemTraceLogger(numLanes + 1))
|
||||||
|
val rams = Seq.fill(numLanes + 1)( // +1 for coalesced edge
|
||||||
|
LazyModule(
|
||||||
|
// FIXME: properly propagate beatBytes?
|
||||||
|
new TLRAM(address = AddressSet(0x0000, 0xffffff), beatBytes = 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
logger.node :=* coal.node :=* driver.node
|
logger.node :=* coal.node :=* driver.node
|
||||||
|
rams.foreach { r => r.node := logger.node }
|
||||||
|
|
||||||
lazy val module = new Impl
|
lazy val module = new Impl
|
||||||
class Impl extends LazyModuleImp(this) with UnitTestModule {
|
class Impl extends LazyModuleImp(this) with UnitTestModule {
|
||||||
@@ -761,27 +781,26 @@ class CoalescerLogger(implicit p: Parameters) extends LazyModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoalescerLoggerTest(timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
|
class TLRAMCoalescerLoggerTest(timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
|
||||||
val dut = Module(LazyModule(new CoalescerLogger).module)
|
val dut = Module(LazyModule(new TLRAMCoalescerLogger).module)
|
||||||
dut.io.start := io.start
|
dut.io.start := io.start
|
||||||
io.finished := dut.io.finished
|
io.finished := dut.io.finished
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tracedriver --> coalescer --> tlram
|
||||||
class TLRAMCoalescer(implicit p: Parameters) extends LazyModule {
|
class TLRAMCoalescer(implicit p: Parameters) extends LazyModule {
|
||||||
// TODO: use parameters for numLanes
|
// TODO: use parameters for numLanes
|
||||||
val numLanes = 4
|
val numLanes = 4
|
||||||
val coal = LazyModule(new CoalescingUnit(numLanes))
|
val coal = LazyModule(new CoalescingUnit(numLanes))
|
||||||
val driver = LazyModule(new MemTraceDriver(numLanes))
|
val driver = LazyModule(new MemTraceDriver(numLanes))
|
||||||
|
val rams = Seq.fill(numLanes + 1) ( // +1 for coalesced edge
|
||||||
coal.node :=* driver.node
|
|
||||||
|
|
||||||
val rams = Seq.tabulate(numLanes + 1) { _ =>
|
|
||||||
LazyModule(
|
LazyModule(
|
||||||
// FIXME: properly propagate beatBytes?
|
// FIXME: properly propagate beatBytes?
|
||||||
new TLRAM(address = AddressSet(0x0000, 0xffffff), beatBytes = 8)
|
new TLRAM(address = AddressSet(0x0000, 0xffffff), beatBytes = 8)
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
// Connect all (N+1) outputs of coal to separate TestRAM modules
|
|
||||||
|
coal.node :=* driver.node
|
||||||
rams.foreach { r => r.node := coal.node }
|
rams.foreach { r => r.node := coal.node }
|
||||||
|
|
||||||
lazy val module = new Impl
|
lazy val module = new Impl
|
||||||
|
|||||||
Reference in New Issue
Block a user