diff --git a/src/main/resources/csrc/SimMemTraceLogger.cc b/src/main/resources/csrc/SimMemTraceLogger.cc index db7f920..b685e83 100644 --- a/src/main/resources/csrc/SimMemTraceLogger.cc +++ b/src/main/resources/csrc/SimMemTraceLogger.cc @@ -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); } } diff --git a/src/main/resources/vsrc/SimMemTrace.v b/src/main/resources/vsrc/SimMemTrace.v index ab189e8..a805130 100644 --- a/src/main/resources/vsrc/SimMemTrace.v +++ b/src/main/resources/vsrc/SimMemTrace.v @@ -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 diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 98be3da..d6fb6ff 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -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()) } })