Respect downstream TL A ready in MemTraceDriver
This commit is contained in:
@@ -1078,24 +1078,18 @@ class TraceLine extends Bundle with HasTraceLine {
|
|||||||
class MemTraceDriverImp(outer: MemTraceDriver, config: CoalescerConfig, traceFile: String)
|
class MemTraceDriverImp(outer: MemTraceDriver, config: CoalescerConfig, traceFile: String)
|
||||||
extends LazyModuleImp(outer)
|
extends LazyModuleImp(outer)
|
||||||
with UnitTestModule {
|
with UnitTestModule {
|
||||||
|
// Current cycle mark to read from trace
|
||||||
|
val traceReadCycle = RegInit(1.U(64.W))
|
||||||
|
|
||||||
val globalClkCounter = RegInit(1.U(64.W))
|
// If any of the downstream lane is not ready, hold on from advancing
|
||||||
val traceReadCycle = RegInit(1.U(64.W))
|
val downstreamReady = outer.laneNodes.map(_.out(0)._1.a.ready).reduce(_ && _)
|
||||||
val downstreamSQready = WireInit(true.B)
|
|
||||||
|
|
||||||
//make the downstream only ready 1/4 of the time
|
|
||||||
//This is to test Tracer System's ability to hold on requests
|
|
||||||
//FIXME
|
|
||||||
downstreamSQready := (globalClkCounter(1,0) =/= 0.U)
|
|
||||||
//Connect Signals to Verilog BlackBox
|
|
||||||
val sim = Module(new SimMemTrace(traceFile, config.numLanes))
|
val sim = Module(new SimMemTrace(traceFile, config.numLanes))
|
||||||
sim.io.clock := clock
|
sim.io.clock := clock
|
||||||
sim.io.reset := reset.asBool
|
sim.io.reset := reset.asBool
|
||||||
sim.io.trace_read.ready := downstreamSQready
|
sim.io.trace_read.ready := downstreamReady
|
||||||
//FIXME - 1.U hardcoded, currently there is a delay between chisel and verilog
|
|
||||||
sim.io.trace_read.cycle := traceReadCycle
|
sim.io.trace_read.cycle := traceReadCycle
|
||||||
|
|
||||||
|
|
||||||
// Read output from Verilog BlackBox
|
// Read output from Verilog BlackBox
|
||||||
// Split output of SimMemTrace, which is flattened across all lanes,back to each lane's.
|
// Split output of SimMemTrace, which is flattened across all lanes,back to each lane's.
|
||||||
val laneReqs = Wire(Vec(config.numLanes, new TraceLine))
|
val laneReqs = Wire(Vec(config.numLanes, new TraceLine))
|
||||||
@@ -1104,26 +1098,30 @@ class MemTraceDriverImp(outer: MemTraceDriver, config: CoalescerConfig, traceFil
|
|||||||
val dataW = laneReqs(0).data.getWidth
|
val dataW = laneReqs(0).data.getWidth
|
||||||
laneReqs.zipWithIndex.foreach { case (req, i) =>
|
laneReqs.zipWithIndex.foreach { case (req, i) =>
|
||||||
req.valid := sim.io.trace_read.valid(i)
|
req.valid := sim.io.trace_read.valid(i)
|
||||||
// TODO: driver trace doesn't contain source id
|
req.source := 0.U // driver trace doesn't contain source id
|
||||||
req.source := 0.U
|
|
||||||
req.address := sim.io.trace_read.address(addrW * (i + 1) - 1, addrW * i)
|
req.address := sim.io.trace_read.address(addrW * (i + 1) - 1, addrW * i)
|
||||||
req.is_store := sim.io.trace_read.is_store(i)
|
req.is_store := sim.io.trace_read.is_store(i)
|
||||||
req.size := sim.io.trace_read.size(sizeW * (i + 1) - 1, sizeW * i)
|
req.size := sim.io.trace_read.size(sizeW * (i + 1) - 1, sizeW * i)
|
||||||
req.data := sim.io.trace_read.data(dataW * (i + 1) - 1, dataW * i)
|
req.data := sim.io.trace_read.data(dataW * (i + 1) - 1, dataW * i)
|
||||||
}
|
}
|
||||||
|
|
||||||
globalClkCounter := globalClkCounter + 1.U
|
def missedLine = {
|
||||||
val existValidReq = WireInit(false.B)
|
val existsValidLine = WireInit(false.B)
|
||||||
existValidReq := laneReqs.map(_.valid).reduce(_||_)
|
existsValidLine := laneReqs.map(_.valid).reduce(_||_)
|
||||||
val validReqBlocked = WireInit(false.B)
|
val missedLine = WireInit(false.B)
|
||||||
validReqBlocked := !downstreamSQready && existValidReq
|
missedLine := !downstreamReady && existsValidLine
|
||||||
//Debug
|
|
||||||
dontTouch(downstreamSQready)
|
// Debug
|
||||||
dontTouch(existValidReq)
|
dontTouch(downstreamReady)
|
||||||
dontTouch(validReqBlocked)
|
dontTouch(existsValidLine)
|
||||||
// Do Not Update TraceReadCycle if downstream is blocking
|
dontTouch(missedLine)
|
||||||
when(!validReqBlocked){
|
|
||||||
traceReadCycle := traceReadCycle + 1.U
|
missedLine
|
||||||
|
}
|
||||||
|
// Do not increment trace read cycle if we didn't fire a valid line because
|
||||||
|
// downstream was blocking. This prevents missing any line in the trace.
|
||||||
|
when (!missedLine){
|
||||||
|
traceReadCycle := traceReadCycle + 1.U
|
||||||
}
|
}
|
||||||
|
|
||||||
// To prevent collision of sourceId with a current in-flight message,
|
// To prevent collision of sourceId with a current in-flight message,
|
||||||
@@ -1158,19 +1156,6 @@ class MemTraceDriverImp(outer: MemTraceDriver, config: CoalescerConfig, traceFil
|
|||||||
val wordAlignedAddress = req.address & ~((1 << log2Ceil(config.wordSizeInBytes)) - 1).U(addrW.W)
|
val wordAlignedAddress = req.address & ~((1 << log2Ceil(config.wordSizeInBytes)) - 1).U(addrW.W)
|
||||||
val wordAlignedSize = Mux(subword, 2.U, req.size)
|
val wordAlignedSize = Mux(subword, 2.U, req.size)
|
||||||
|
|
||||||
// when(req.valid && subword) {
|
|
||||||
// printf(
|
|
||||||
// "address=%x, size=%d, data=%x, addressMask=%x, wordAlignedAddress=%x, mask=%x, wordData=%x\n",
|
|
||||||
// req.address,
|
|
||||||
// req.size,
|
|
||||||
// req.data,
|
|
||||||
// ~((1 << log2Ceil(config.WORD_SIZE)) - 1).U(addrW.W),
|
|
||||||
// wordAlignedAddress,
|
|
||||||
// mask,
|
|
||||||
// wordData
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
|
|
||||||
val (tlOut, edge) = node.out(0)
|
val (tlOut, edge) = node.out(0)
|
||||||
val (plegal, pbits) = edge.Put(
|
val (plegal, pbits) = edge.Put(
|
||||||
fromSource = sourceIdCounter,
|
fromSource = sourceIdCounter,
|
||||||
|
|||||||
Reference in New Issue
Block a user