Support receiving trace filename from VPI for loggers
Useful for testing with different memtraces without having to recompile
design. This worked before for the trace driver but not for trace
logger.
Usage: make CONFIG=MemtraceCoreConfig run-binary-debug BINARY=none \
EXTRA_SIM_FLAGS="+memtracefile=nvbit.vecadd.n100000.filter_sm0.lane4.broken.trace"
This commit is contained in:
@@ -10,7 +10,10 @@
|
||||
#include <unistd.h>
|
||||
#include "SimMemTrace.h"
|
||||
|
||||
// Global singleton instance
|
||||
// Single driver trace file used across the simulation.
|
||||
// Currently doesn't support multiple driver traces.
|
||||
std::string tracefilename{};
|
||||
// Global singleton reader instance
|
||||
static std::unique_ptr<MemTraceReader> reader;
|
||||
|
||||
MemTraceReader::MemTraceReader(const std::string &filename)
|
||||
@@ -72,8 +75,6 @@ void MemTraceReader::parse(const bool has_source) {
|
||||
error(fileline, "failed parsing address..size");
|
||||
}
|
||||
if (infile.get() != '\n') {
|
||||
printf("Error: trailing characters at the end of the line\n");
|
||||
printf("this could also occur if the last line is not an empty line");
|
||||
error(fileline, "trailing characters at the end of the line");
|
||||
}
|
||||
|
||||
@@ -156,6 +157,7 @@ MemTraceLine MemTraceReader::read_trace_at(const long cycle, const int lane_id,
|
||||
|
||||
extern "C" void memtrace_init(const char *filename, bool has_source) {
|
||||
#ifndef NO_VPI
|
||||
// If VPI option is given, override filename set from Chisel/Verilog.
|
||||
s_vpi_vlog_info info;
|
||||
if (!vpi_get_vlog_info(&info)) {
|
||||
fprintf(stderr, "fatal: failed to get plusargs from VCS\n");
|
||||
@@ -166,6 +168,8 @@ extern "C" void memtrace_init(const char *filename, bool has_source) {
|
||||
char *input_arg = info.argv[i];
|
||||
if (strncmp(input_arg, TRACEFILENAME_PLUSARG,
|
||||
strlen(TRACEFILENAME_PLUSARG)) == 0) {
|
||||
printf(
|
||||
"memtrace_init: +memtracefile given, overriding Verilog parameter\n");
|
||||
filename = input_arg + strlen(TRACEFILENAME_PLUSARG);
|
||||
break;
|
||||
}
|
||||
@@ -174,6 +178,8 @@ extern "C" void memtrace_init(const char *filename, bool has_source) {
|
||||
|
||||
printf("memtrace_init: filename=[%s]\n", filename);
|
||||
|
||||
tracefilename = filename;
|
||||
|
||||
reader = std::make_unique<MemTraceReader>(filename);
|
||||
// parse file upfront
|
||||
// driver trace file is assumed to not have source id
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
extern std::string tracefilename;
|
||||
|
||||
struct MemTraceLine {
|
||||
bool valid = false;
|
||||
long cycle = 0;
|
||||
@@ -54,7 +56,8 @@ extern "C" void memtrace_query(unsigned char trace_read_ready,
|
||||
int *trace_read_size,
|
||||
unsigned long *trace_read_data,
|
||||
unsigned char *trace_read_finished);
|
||||
extern "C" int memtracelogger_init(int is_response, const char *filename);
|
||||
extern "C" int memtracelogger_init(int is_response, const char *filename,
|
||||
const char *filename_suffix);
|
||||
extern "C" void memtracelogger_log(int handle,
|
||||
unsigned char trace_log_valid,
|
||||
unsigned long trace_log_cycle,
|
||||
|
||||
@@ -41,8 +41,10 @@ void MemTraceWriter::write_line_to_trace(const MemTraceLine line) {
|
||||
}
|
||||
|
||||
// Returns the "handle" ID for this particular logger instance.
|
||||
extern "C" int memtracelogger_init(int is_response, const char *filename) {
|
||||
extern "C" int memtracelogger_init(int is_response, const char *filename,
|
||||
const char *filename_suffix) {
|
||||
#ifndef NO_VPI
|
||||
// If VPI option is given, override filename set from Chisel/Verilog.
|
||||
s_vpi_vlog_info info;
|
||||
if (!vpi_get_vlog_info(&info)) {
|
||||
fprintf(stderr, "fatal: failed to get plusargs from VCS\n");
|
||||
@@ -59,12 +61,15 @@ extern "C" int memtracelogger_init(int is_response, const char *filename) {
|
||||
}
|
||||
#endif
|
||||
|
||||
auto fullfilename = std::string{filename} + std::string{filename_suffix};
|
||||
|
||||
int handle = loggers.size();
|
||||
loggers.emplace_back(std::make_unique<MemTraceWriter>(is_response, filename));
|
||||
loggers.emplace_back(
|
||||
std::make_unique<MemTraceWriter>(is_response, fullfilename));
|
||||
loggers.back()->handle = handle;
|
||||
|
||||
printf("memtracelogger_init: handle=%d, is_response=%d, filename=[%s]\n",
|
||||
handle, is_response, filename);
|
||||
handle, is_response, fullfilename.c_str());
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
import "DPI-C" function int memtracelogger_init(
|
||||
input bit is_response,
|
||||
input string filename
|
||||
input string filename,
|
||||
input string filename_suffix
|
||||
);
|
||||
|
||||
// Make sure to sync the parameters for:
|
||||
@@ -29,7 +30,8 @@ import "DPI-C" function void memtracelogger_log
|
||||
|
||||
module SimMemTraceLogger #(parameter
|
||||
IS_RESPONSE = 0,
|
||||
FILENAME = "undefined",
|
||||
FILENAME_BASE = "undefined",
|
||||
FILENAME_SUFFIX = ".log",
|
||||
NUM_LANES = 4) (
|
||||
input clock,
|
||||
input reset,
|
||||
@@ -77,7 +79,7 @@ module SimMemTraceLogger #(parameter
|
||||
|
||||
initial begin
|
||||
/* $value$plusargs("uartlog=%s", __uartlog); */
|
||||
logger_handle = memtracelogger_init(IS_RESPONSE, FILENAME);
|
||||
logger_handle = memtracelogger_init(IS_RESPONSE, FILENAME_BASE, FILENAME_SUFFIX);
|
||||
end
|
||||
|
||||
always @(posedge clock) begin
|
||||
|
||||
@@ -1615,11 +1615,11 @@ class MemTraceLogger(
|
||||
|
||||
val simReq =
|
||||
if (reqEnable)
|
||||
Some(Module(new SimMemTraceLogger(false, s"${filename}.${loggerName}.req", numLanes)))
|
||||
Some(Module(new SimMemTraceLogger(false, s"${filename}", s".${loggerName}.req", numLanes)))
|
||||
else None
|
||||
val simResp =
|
||||
if (respEnable)
|
||||
Some(Module(new SimMemTraceLogger(true, s"${filename}.${loggerName}.resp", numLanes)))
|
||||
Some(Module(new SimMemTraceLogger(true, s"${filename}", s".${loggerName}.resp", numLanes)))
|
||||
else None
|
||||
if (simReq.isDefined) {
|
||||
simReq.get.io.clock := clock
|
||||
@@ -1787,11 +1787,16 @@ class MemTraceLogger(
|
||||
// itself whether it's logging the request stream or the response stream. This
|
||||
// is necessary because we have to generate slightly different trace format
|
||||
// depending on this, e.g. response trace will not contain an address column.
|
||||
class SimMemTraceLogger(isResponse: Boolean, filename: String, numLanes: Int)
|
||||
extends BlackBox(
|
||||
class SimMemTraceLogger(
|
||||
isResponse: Boolean,
|
||||
filenameBase: String, // usually the same as `filename` of SimMemTrace
|
||||
filenameSuffix: String, // can be ".req", ".resp", .etc
|
||||
numLanes: Int
|
||||
) extends BlackBox(
|
||||
Map(
|
||||
"IS_RESPONSE" -> (if (isResponse) 1 else 0),
|
||||
"FILENAME" -> filename,
|
||||
"FILENAME_BASE" -> filenameBase,
|
||||
"FILENAME_SUFFIX" -> filenameSuffix,
|
||||
"NUM_LANES" -> numLanes
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user