diff --git a/src/main/resources/csrc/SimMemTrace.cc b/src/main/resources/csrc/SimMemTrace.cc index 0e3274b..8a636a7 100644 --- a/src/main/resources/csrc/SimMemTrace.cc +++ b/src/main/resources/csrc/SimMemTrace.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include "SimMemTrace.h" @@ -34,10 +35,18 @@ void MemTraceReader::parse() { printf("MemTraceReader: started parsing\n"); + long size = 0; while (infile >> line.cycle >> line.loadstore >> line.core_id >> line.lane_id >> std::hex >> line.address >> line.data >> std::dec >> - line.data_size) { + size) { line.valid = true; + + assert(size > 0 && "invalid size in trace"); + int lgsize = static_cast(log2(size)); + assert((size & ~(~0lu << lgsize)) == 0 && + "non-power-of-2 size detected in trace"); + line.log_data_size = lgsize; + trace.push_back(line); } read_pos = trace.cbegin(); @@ -76,7 +85,7 @@ MemTraceLine MemTraceReader::read_trace_at(const long cycle, return MemTraceLine{}; } else if (line.cycle == cycle && line.lane_id == lane_id) { printf("fire! cycle=%ld, valid=%d, %s addr=%lx, size=%d \n", cycle, line.valid, - line.loadstore, line.address, line.data_size); + line.loadstore, line.address, line.log_data_size); // FIXME! Currently lane_id is assumed to be in round-robin order, e.g. // 0->1->2->3->0->..., both in the trace file and the order the caller calls @@ -137,7 +146,7 @@ extern "C" void memtrace_query(unsigned char trace_read_ready, *trace_read_valid = line.valid; *trace_read_address = line.address; *trace_read_is_store = (strcmp(line.loadstore, "STORE") == 0); - *trace_read_size = line.data_size; + *trace_read_size = line.log_data_size; *trace_read_data = line.data; // This means finished and valid will go up at the same cycle. Need to // handle this without skipping the last line. diff --git a/src/main/resources/csrc/SimMemTrace.h b/src/main/resources/csrc/SimMemTrace.h index 033fc7e..14045b5 100644 --- a/src/main/resources/csrc/SimMemTrace.h +++ b/src/main/resources/csrc/SimMemTrace.h @@ -15,7 +15,7 @@ struct MemTraceLine { int lane_id = 0; unsigned long address = 0; unsigned long data = 0; - int data_size = 0; + int log_data_size = 0; }; class MemTraceReader { diff --git a/src/main/resources/csrc/SimMemTraceLogger.cc b/src/main/resources/csrc/SimMemTraceLogger.cc index 1fce4bd..db7f920 100644 --- a/src/main/resources/csrc/SimMemTraceLogger.cc +++ b/src/main/resources/csrc/SimMemTraceLogger.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "SimMemTraceLogger.h" diff --git a/src/main/resources/vsrc/SimMemTrace.v b/src/main/resources/vsrc/SimMemTrace.v index b18fcab..ab189e8 100644 --- a/src/main/resources/vsrc/SimMemTrace.v +++ b/src/main/resources/vsrc/SimMemTrace.v @@ -1,6 +1,6 @@ `define DATA_WIDTH 64 `define MAX_NUM_LANES 32 -`define SIZE_WIDTH 32 +`define LOGSIZE_WIDTH 32 import "DPI-C" function void memtrace_init( input string filename @@ -27,15 +27,15 @@ module SimMemTrace #(parameter FILENAME = "undefined", NUM_LANES = 4) ( input clock, input reset, - // These have to match the IO port of the Chisel wrapper module. - input trace_read_ready, - output [NUM_LANES-1:0] trace_read_valid, - output [`DATA_WIDTH*NUM_LANES-1:0] trace_read_address, + // These have to match the IO port name of the Chisel wrapper module. + input trace_read_ready, + output [NUM_LANES-1:0] trace_read_valid, + output [`DATA_WIDTH*NUM_LANES-1:0] trace_read_address, - output [NUM_LANES-1:0] trace_read_is_store, - output [`SIZE_WIDTH*NUM_LANES-1:0] trace_read_size, - output [`DATA_WIDTH*NUM_LANES-1:0] trace_read_data, - output trace_read_finished + output [NUM_LANES-1:0] trace_read_is_store, + output [`LOGSIZE_WIDTH*NUM_LANES-1:0] trace_read_size, + output [`DATA_WIDTH*NUM_LANES-1:0] trace_read_data, + output trace_read_finished ); bit __in_valid [NUM_LANES-1:0]; longint __in_address [NUM_LANES-1:0]; @@ -70,7 +70,7 @@ module SimMemTrace #(parameter FILENAME = "undefined", NUM_LANES = 4) ( assign trace_read_address[`DATA_WIDTH*(g+1)-1:`DATA_WIDTH*g] = __in_address_reg[g]; assign trace_read_is_store[g] = __in_is_store_reg[g]; - assign trace_read_size[`SIZE_WIDTH*(g+1)-1:`SIZE_WIDTH*g] = __in_size_reg[g]; + assign trace_read_size[`LOGSIZE_WIDTH*(g+1)-1:`LOGSIZE_WIDTH*g] = __in_size_reg[g]; assign trace_read_data[`DATA_WIDTH*(g+1)-1:`DATA_WIDTH*g] = __in_data_reg[g]; end endgenerate @@ -89,7 +89,7 @@ module SimMemTrace #(parameter FILENAME = "undefined", NUM_LANES = 4) ( __in_address[tid] = `DATA_WIDTH'b0; __in_is_store[tid] = 1'b0; - __in_size[tid] = `SIZE_WIDTH'b0; + __in_size[tid] = `LOGSIZE_WIDTH'b0; __in_data[tid] = `DATA_WIDTH'b0; end @@ -103,7 +103,7 @@ module SimMemTrace #(parameter FILENAME = "undefined", NUM_LANES = 4) ( __in_address_reg[tid] <= `DATA_WIDTH'b0; __in_is_store_reg[tid] = 1'b0; - __in_size_reg[tid] = `SIZE_WIDTH'b0; + __in_size_reg[tid] = `LOGSIZE_WIDTH'b0; __in_data_reg[tid] = `DATA_WIDTH'b0; end diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index bea19ee..98be3da 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -611,7 +611,7 @@ class TraceReq extends Bundle { val valid = Bool() val address = UInt(64.W) val is_store = Bool() - val size = UInt(32.W) + val size = UInt(32.W) // this is log2(bytesize) as in TL A bundle val data = UInt(64.W) } @@ -634,7 +634,6 @@ class MemTraceDriverImp(outer: MemTraceDriver, numLanes: Int, traceFile: String) req.address := sim.io.trace_read.address(64 * i + 63, 64 * i) req.is_store := sim.io.trace_read.is_store(i) req.size := sim.io.trace_read.size(32 * i + 31, 32 * i) - printf("========= req.size=%d\n", req.size) req.data := sim.io.trace_read.data(64 * i + 63, 64 * i) } @@ -761,12 +760,25 @@ class MemTraceLogger(numLanes: Int = 4, filename: String = "vecadd.core1.thread4 tlOut.a <> tlIn.a tlIn.d <> tlOut.d + // requests on TL A channel 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.is_store := false.B + 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) { + // 4: Get + req.is_store := false.B + }.elsewhen(true.B) { + // that's all I know + assert(false.B, "unhandled TL opcode found in MemTraceLogger") + } req.size := tlIn.a.bits.size - printf("========= logger: req.size=%d\n", tlIn.a.bits.size) + + // responses on TL D channel + // TODO } val laneValid = Wire(Vec(numLanes, Bool()))