From b53711965ed642d74c1b9b5e3416a7df1b346b3e Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Mon, 10 Apr 2023 20:24:27 -0700 Subject: [PATCH] Connect TL edge data to SimMemTraceLogger TODO: since TileLink rounds all address down to a multiple of its beat size (8 in the current code), we can't directly compare the memory trace input to its output. Need to take masks into account. --- src/main/resources/csrc/SimMemTraceLogger.cc | 21 +++++-- src/main/scala/tilelink/Coalescing.scala | 58 ++++++++++++++------ 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/main/resources/csrc/SimMemTraceLogger.cc b/src/main/resources/csrc/SimMemTraceLogger.cc index 736d0ba..1fce4bd 100644 --- a/src/main/resources/csrc/SimMemTraceLogger.cc +++ b/src/main/resources/csrc/SimMemTraceLogger.cc @@ -3,7 +3,7 @@ #include #endif #include -#include +#include #include #include #include @@ -33,10 +33,10 @@ MemTraceLogger::~MemTraceLogger() { // Parse trace file in its entirety and store it into internal structure. // TODO: might block for a long time when the trace gets big, check if need to // be broken down -void MemTraceReader::parse() { +void MemTraceLogger::parse() { MemTraceLine line; - printf("MemTraceReader: started parsing\n"); + printf("MemTraceLogger: started parsing\n"); while (infile >> line.cycle >> line.loadstore >> line.core_id >> line.lane_id >> std::hex >> line.address >> line.data >> std::dec >> @@ -46,13 +46,13 @@ void MemTraceReader::parse() { } read_pos = trace.cbegin(); - printf("MemTraceReader: finished parsing\n"); + printf("MemTraceLogger: finished parsing\n"); } // Try to read a memory request that might have happened at a given cycle, on a // given SIMD lane (= "thread"). In case no request happened at that point, // return an empty line with .valid = false. -MemTraceLine MemTraceReader::read_trace_at(const long cycle, +MemTraceLine MemTraceLogger::read_trace_at(const long cycle, const int lane_id) { MemTraceLine line; line.valid = false; @@ -120,8 +120,17 @@ extern "C" void memtracelogger_init(const char *filename) { } // TODO: accept core_id as well -extern "C" void memtracelogger_log(unsigned char *trace_log_ready) { +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, + 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); + } } diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 8d318a0..e9a2aed 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -727,7 +727,9 @@ class SimMemTrace(filename: String, numLanes: Int) addResource("/csrc/SimMemTrace.h") } -class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4.trace")(implicit p: Parameters) extends LazyModule { +class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4.trace")(implicit + p: Parameters +) extends LazyModule { val node = TLIdentityNode() // val beatBytes = 8 // FIXME: hardcoded @@ -751,11 +753,30 @@ class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4 sim.io.clock := clock sim.io.reset := reset.asBool - (node.in zip node.out).foreach { case ((tlIn, _), (tlOut, _)) => + val laneReqs = Wire(Vec(numLanes, new TraceReq)) + val laneValid = Wire(Vec(numLanes, Bool())) + val laneAddress = Wire(Vec(numLanes, UInt(64.W))) // FIXME: hardcoded + + // snoop on the TileLink edges to log traffic + ((node.in zip node.out) zip laneReqs).foreach { case (((tlIn, _), (tlOut, _)), req) => tlOut.a <> tlIn.a tlIn.d <> tlOut.d + + req.valid := tlIn.a.valid + req.address := tlIn.a.bits.address + req.data := tlIn.a.bits.data + req.is_store := false.B // FIXME: take is_store from TL + req.mask := tlIn.a.bits.mask } + laneReqs.zipWithIndex.foreach { case (req, i) => + laneValid(i) := req.valid.asUInt + laneAddress(i) := req.address + } + // flatten per-lane signals to the Verilog blackbox input + sim.io.trace_log.valid := laneValid.asUInt + sim.io.trace_log.address := laneAddress.asUInt + // io.finished := sim.io.trace_read.finished } } @@ -769,18 +790,18 @@ class SimMemTraceLogger(filename: String, numLanes: Int) val clock = Input(Clock()) val reset = Input(Bool()) - // val trace_read = new Bundle { - // val ready = Input(Bool()) - // val valid = Output(UInt(numLanes.W)) - // // Chisel can't interface with Verilog 2D port, so flatten all lanes into - // // single wide 1D array. - // // TODO: assumes 64-bit address. - // val address = Output(UInt((64 * numLanes).W)) - // val is_store = Output(UInt(numLanes.W)) - // val store_mask = Output(UInt((8 * numLanes).W)) - // val data = Output(UInt((64 * numLanes).W)) - // val finished = Output(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()) + // TODO: assumes 64-bit address. + // val is_store = Output(UInt(numLanes.W)) + // val store_mask = Output(UInt((8 * numLanes).W)) + // val data = Output(UInt((64 * numLanes).W)) + // val finished = Output(Bool()) + } }) addResource("/vsrc/SimMemTraceLogger.v") @@ -794,17 +815,18 @@ class SimMemTraceLogger(filename: String, numLanes: Int) class TLRAMCoalescerLogger(implicit p: Parameters) extends LazyModule { // TODO: use parameters for numLanes val numLanes = 4 - val coal = LazyModule(new CoalescingUnit(numLanes)) + // val coal = LazyModule(new CoalescingUnit(numLanes)) val driver = LazyModule(new MemTraceDriver(numLanes)) - val logger = LazyModule(new MemTraceLogger(numLanes + 1)) - val rams = Seq.fill(numLanes + 1)( // +1 for coalesced edge + val logger = LazyModule(new MemTraceLogger(numLanes)) + val rams = Seq.fill(numLanes)( // +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 + logger.node :=* driver.node rams.foreach { r => r.node := logger.node } lazy val module = new Impl