Relay full trace line info to DPI
This commit is contained in:
@@ -124,14 +124,18 @@ extern "C" void memtracelogger_init(const char *filename) {
|
||||
extern "C" void memtracelogger_log(unsigned char trace_log_valid,
|
||||
unsigned long trace_log_cycle,
|
||||
unsigned long trace_log_address,
|
||||
unsigned int trace_log_lane_id,
|
||||
int trace_log_lane_id,
|
||||
unsigned char trace_log_is_store,
|
||||
int trace_log_size,
|
||||
unsigned long trace_log_data,
|
||||
unsigned char *trace_log_ready) {
|
||||
// printf("memtrace_query(cycle=%ld, tid=%d)\n", trace_read_cycle,
|
||||
// trace_read_lane_id);
|
||||
*trace_log_ready = 1;
|
||||
|
||||
if (trace_log_valid) {
|
||||
printf("%s: [%lu] valid: address=0x%lx, tid=%u\n", __func__,
|
||||
trace_log_cycle, trace_log_address, trace_log_lane_id);
|
||||
printf("%s: [%lu] valid: address=%lx, tid=%u, size=%d\n", __func__,
|
||||
trace_log_cycle, trace_log_address, trace_log_lane_id,
|
||||
trace_log_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIXME hardcoded
|
||||
`define DATA_WIDTH 64
|
||||
`define MAX_NUM_LANES 32
|
||||
`define LOGSIZE_WIDTH 32
|
||||
@@ -81,7 +82,6 @@ module SimMemTrace #(parameter FILENAME = "undefined", NUM_LANES = 4) (
|
||||
memtrace_init(FILENAME);
|
||||
end
|
||||
|
||||
// Evaluate the signals on the positive edge
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
for (integer tid = 0; tid < NUM_LANES; tid = tid + 1) begin
|
||||
|
||||
@@ -607,6 +607,8 @@ class MemTraceDriver(numLanes: Int = 4, filename: String = "vecadd.core1.thread4
|
||||
lazy val module = new MemTraceDriverImp(this, numLanes, filename)
|
||||
}
|
||||
|
||||
// TODO: this is replicated in sim.io.trace_read and sim.io.trace_log; make it
|
||||
// into a trait
|
||||
class TraceReq extends Bundle {
|
||||
val valid = Bool()
|
||||
val address = UInt(64.W)
|
||||
@@ -664,7 +666,7 @@ class MemTraceDriverImp(outer: MemTraceDriver, numLanes: Int, traceFile: String)
|
||||
val (glegal, gbits) = edge.Get(
|
||||
fromSource = sourceIdCounter,
|
||||
toAddress = hashToValidPhyAddr(req.address),
|
||||
lgSize = Log2(size),
|
||||
lgSize = Log2(size)
|
||||
)
|
||||
val legal = Mux(req.is_store, plegal, glegal)
|
||||
val bits = Mux(req.is_store, pbits, gbits)
|
||||
@@ -755,6 +757,11 @@ class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4
|
||||
|
||||
val laneReqs = Wire(Vec(numLanes, new TraceReq))
|
||||
|
||||
assert(
|
||||
numLanes == node.in.length,
|
||||
"`numLanes` does not match the number of TL edges connected to the MemTraceLogger"
|
||||
)
|
||||
|
||||
// snoop on the TileLink edges to log traffic
|
||||
((node.in zip node.out) zip laneReqs).foreach { case (((tlIn, _), (tlOut, _)), req) =>
|
||||
tlOut.a <> tlIn.a
|
||||
@@ -765,7 +772,7 @@ class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4
|
||||
req.address := tlIn.a.bits.address
|
||||
req.data := tlIn.a.bits.data
|
||||
req.is_store := false.B
|
||||
when (tlIn.a.bits.opcode === 0.U || tlIn.a.bits.opcode === 1.U) {
|
||||
when(tlIn.a.bits.opcode === 0.U || tlIn.a.bits.opcode === 1.U) {
|
||||
// 0: PutFullData, 1: PutPartialData
|
||||
req.is_store := true.B
|
||||
}.elsewhen(tlIn.a.bits.opcode === 4.U) {
|
||||
@@ -777,19 +784,36 @@ class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4
|
||||
}
|
||||
req.size := tlIn.a.bits.size
|
||||
|
||||
// responses on TL D channel
|
||||
// TODO
|
||||
when(req.valid) {
|
||||
printf("======== MemTraceLogger: req.size=%d\n", req.size)
|
||||
}
|
||||
|
||||
// responses on TL D channel
|
||||
// TODO
|
||||
}
|
||||
|
||||
// clunky workaround of the fact that Chisel doesn't allow partial
|
||||
// assignment to a bitfield range of a wide signal.
|
||||
val laneValid = Wire(Vec(numLanes, Bool()))
|
||||
val laneAddress = Wire(Vec(numLanes, UInt(64.W))) // FIXME: hardcoded
|
||||
val laneAddress = Wire(Vec(numLanes, chiselTypeOf(laneReqs(0).address)))
|
||||
val laneIsStore = Wire(Vec(numLanes, chiselTypeOf(laneReqs(0).is_store)))
|
||||
val laneSize = Wire(Vec(numLanes, chiselTypeOf(laneReqs(0).size)))
|
||||
val laneData = Wire(Vec(numLanes, chiselTypeOf(laneReqs(0).data)))
|
||||
laneReqs.zipWithIndex.foreach { case (req, i) =>
|
||||
laneValid(i) := req.valid
|
||||
laneAddress(i) := req.address
|
||||
laneIsStore(i) := req.is_store
|
||||
laneSize(i) := req.size
|
||||
laneData(i) := req.data
|
||||
}
|
||||
// flatten per-lane signals to the Verilog blackbox input
|
||||
sim.io.trace_log.valid := laneValid.asUInt
|
||||
sim.io.trace_log.address := laneAddress.asUInt
|
||||
sim.io.trace_log.is_store := laneIsStore.asUInt
|
||||
sim.io.trace_log.size := laneSize.asUInt
|
||||
sim.io.trace_log.data := laneData.asUInt
|
||||
|
||||
assert(sim.io.trace_log.ready === true.B, "MemTraceLogger is expected to be always ready")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -802,17 +826,16 @@ class SimMemTraceLogger(filename: String, numLanes: Int)
|
||||
val clock = Input(Clock())
|
||||
val reset = Input(Bool())
|
||||
|
||||
// Chisel can't interface with Verilog 2D port, so flatten all lanes into
|
||||
// single wide 1D array.
|
||||
val trace_log = new Bundle {
|
||||
val valid = Input(UInt(numLanes.W))
|
||||
val address = Input(UInt((64 * numLanes).W))
|
||||
// val ready = Output(Bool())
|
||||
// Chisel can't interface with Verilog 2D port, so flatten all lanes into
|
||||
// single wide 1D array.
|
||||
// TODO: assumes 64-bit address.
|
||||
// val is_store = Output(UInt(numLanes.W))
|
||||
// val size = Output(UInt((8 * numLanes).W))
|
||||
// val data = Output(UInt((64 * numLanes).W))
|
||||
// val finished = Output(Bool())
|
||||
val address = Input(UInt((64 * numLanes).W))
|
||||
val is_store = Input(UInt(numLanes.W))
|
||||
val size = Input(UInt((32 * numLanes).W))
|
||||
val data = Input(UInt((64 * numLanes).W))
|
||||
val ready = Output(Bool())
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user