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.
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
#include <svdpi.h>
|
#include <svdpi.h>
|
||||||
#endif
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -33,10 +33,10 @@ MemTraceLogger::~MemTraceLogger() {
|
|||||||
// Parse trace file in its entirety and store it into internal structure.
|
// 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
|
// TODO: might block for a long time when the trace gets big, check if need to
|
||||||
// be broken down
|
// be broken down
|
||||||
void MemTraceReader::parse() {
|
void MemTraceLogger::parse() {
|
||||||
MemTraceLine line;
|
MemTraceLine line;
|
||||||
|
|
||||||
printf("MemTraceReader: started parsing\n");
|
printf("MemTraceLogger: started parsing\n");
|
||||||
|
|
||||||
while (infile >> line.cycle >> line.loadstore >> line.core_id >>
|
while (infile >> line.cycle >> line.loadstore >> line.core_id >>
|
||||||
line.lane_id >> std::hex >> line.address >> line.data >> std::dec >>
|
line.lane_id >> std::hex >> line.address >> line.data >> std::dec >>
|
||||||
@@ -46,13 +46,13 @@ void MemTraceReader::parse() {
|
|||||||
}
|
}
|
||||||
read_pos = trace.cbegin();
|
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
|
// 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,
|
// given SIMD lane (= "thread"). In case no request happened at that point,
|
||||||
// return an empty line with .valid = false.
|
// 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) {
|
const int lane_id) {
|
||||||
MemTraceLine line;
|
MemTraceLine line;
|
||||||
line.valid = false;
|
line.valid = false;
|
||||||
@@ -120,8 +120,17 @@ extern "C" void memtracelogger_init(const char *filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: accept core_id as well
|
// 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,
|
// printf("memtrace_query(cycle=%ld, tid=%d)\n", trace_read_cycle,
|
||||||
// trace_read_lane_id);
|
// trace_read_lane_id);
|
||||||
*trace_log_ready = 1;
|
*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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -727,7 +727,9 @@ class SimMemTrace(filename: String, numLanes: Int)
|
|||||||
addResource("/csrc/SimMemTrace.h")
|
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 node = TLIdentityNode()
|
||||||
|
|
||||||
// val beatBytes = 8 // FIXME: hardcoded
|
// 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.clock := clock
|
||||||
sim.io.reset := reset.asBool
|
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
|
tlOut.a <> tlIn.a
|
||||||
tlIn.d <> tlOut.d
|
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
|
// io.finished := sim.io.trace_read.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -769,18 +790,18 @@ class SimMemTraceLogger(filename: String, numLanes: Int)
|
|||||||
val clock = Input(Clock())
|
val clock = Input(Clock())
|
||||||
val reset = Input(Bool())
|
val reset = Input(Bool())
|
||||||
|
|
||||||
// val trace_read = new Bundle {
|
// Chisel can't interface with Verilog 2D port, so flatten all lanes into
|
||||||
// val ready = Input(Bool())
|
// single wide 1D array.
|
||||||
// val valid = Output(UInt(numLanes.W))
|
val trace_log = new Bundle {
|
||||||
// // Chisel can't interface with Verilog 2D port, so flatten all lanes into
|
val valid = Input(UInt(numLanes.W))
|
||||||
// // single wide 1D array.
|
val address = Input(UInt((64 * numLanes).W))
|
||||||
// // TODO: assumes 64-bit address.
|
// val ready = Output(Bool())
|
||||||
// val address = Output(UInt((64 * numLanes).W))
|
// TODO: assumes 64-bit address.
|
||||||
// val is_store = Output(UInt(numLanes.W))
|
// val is_store = Output(UInt(numLanes.W))
|
||||||
// val store_mask = Output(UInt((8 * numLanes).W))
|
// val store_mask = Output(UInt((8 * numLanes).W))
|
||||||
// val data = Output(UInt((64 * numLanes).W))
|
// val data = Output(UInt((64 * numLanes).W))
|
||||||
// val finished = Output(Bool())
|
// val finished = Output(Bool())
|
||||||
// }
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
addResource("/vsrc/SimMemTraceLogger.v")
|
addResource("/vsrc/SimMemTraceLogger.v")
|
||||||
@@ -794,17 +815,18 @@ class SimMemTraceLogger(filename: String, numLanes: Int)
|
|||||||
class TLRAMCoalescerLogger(implicit p: Parameters) extends LazyModule {
|
class TLRAMCoalescerLogger(implicit p: Parameters) extends LazyModule {
|
||||||
// TODO: use parameters for numLanes
|
// TODO: use parameters for numLanes
|
||||||
val numLanes = 4
|
val numLanes = 4
|
||||||
val coal = LazyModule(new CoalescingUnit(numLanes))
|
// val coal = LazyModule(new CoalescingUnit(numLanes))
|
||||||
val driver = LazyModule(new MemTraceDriver(numLanes))
|
val driver = LazyModule(new MemTraceDriver(numLanes))
|
||||||
val logger = LazyModule(new MemTraceLogger(numLanes + 1))
|
val logger = LazyModule(new MemTraceLogger(numLanes))
|
||||||
val rams = Seq.fill(numLanes + 1)( // +1 for coalesced edge
|
val rams = Seq.fill(numLanes)( // +1 for coalesced edge
|
||||||
LazyModule(
|
LazyModule(
|
||||||
// FIXME: properly propagate beatBytes?
|
// FIXME: properly propagate beatBytes?
|
||||||
new TLRAM(address = AddressSet(0x0000, 0xffffff), beatBytes = 8)
|
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 }
|
rams.foreach { r => r.node := logger.node }
|
||||||
|
|
||||||
lazy val module = new Impl
|
lazy val module = new Impl
|
||||||
|
|||||||
Reference in New Issue
Block a user