提交 e9feb4de 编写于 作者: Z Zihao Yu

emu: dump waveform when B <= GTimer <= E

上级 6401a531
...@@ -63,7 +63,6 @@ EMU_CXXFLAGS = -std=c++11 -static -Wall -I$(EMU_CSRC_DIR) ...@@ -63,7 +63,6 @@ EMU_CXXFLAGS = -std=c++11 -static -Wall -I$(EMU_CSRC_DIR)
EMU_CXXFLAGS += -DVERILATOR -Wno-maybe-uninitialized EMU_CXXFLAGS += -DVERILATOR -Wno-maybe-uninitialized
EMU_LDFLAGS = -lpthread -lSDL2 -ldl EMU_LDFLAGS = -lpthread -lSDL2 -ldl
# dump vcd: --debug --trace
VERILATOR_FLAGS = --top-module $(SIM_TOP) \ VERILATOR_FLAGS = --top-module $(SIM_TOP) \
+define+VERILATOR=1 \ +define+VERILATOR=1 \
+define+PRINTF_COND=1 \ +define+PRINTF_COND=1 \
...@@ -72,6 +71,7 @@ VERILATOR_FLAGS = --top-module $(SIM_TOP) \ ...@@ -72,6 +71,7 @@ VERILATOR_FLAGS = --top-module $(SIM_TOP) \
--assert \ --assert \
--savable \ --savable \
--stats-vars \ --stats-vars \
--trace \
--output-split 5000 \ --output-split 5000 \
--output-split-cfuncs 5000 \ --output-split-cfuncs 5000 \
-I$(abspath $(BUILD_DIR)) \ -I$(abspath $(BUILD_DIR)) \
...@@ -115,7 +115,7 @@ else ...@@ -115,7 +115,7 @@ else
SNAPSHOT_OPTION = --load-snapshot=$(REMOTE_PREFIX)/$(SNAPSHOT) SNAPSHOT_OPTION = --load-snapshot=$(REMOTE_PREFIX)/$(SNAPSHOT)
endif endif
EMU_FLAGS = -s $(SEED) -b $(B) -e $(E) $(SNAPSHOT_OPTION) EMU_FLAGS = -s $(SEED) -b $(B) -e $(E) $(SNAPSHOT_OPTION) --dump-wave
emu: $(EMU) emu: $(EMU)
ifeq ($(REMOTE),localhost) ifeq ($(REMOTE),localhost)
......
...@@ -25,10 +25,20 @@ Emulator::Emulator(EmuArgs &args): ...@@ -25,10 +25,20 @@ Emulator::Emulator(EmuArgs &args):
init_difftest(); init_difftest();
enable_waveform = args.enable_waveform;
if (enable_waveform) {
Verilated::traceEverOn(true); // Verilator must compute traced signals
tfp = new VerilatedVcdC;
dut_ptr->trace(tfp, 99); // Trace 99 levels of hierarchy
time_t now = time(NULL);
tfp->open(waveform_filename(now)); // Open the dump file
}
// init core // init core
reset_ncycles(10); reset_ncycles(10);
if (args.snapshot_path != NULL) { if (args.snapshot_path != NULL) {
printf("loading from snapshot `%s`...\n", args.snapshot_path);
snapshot_load(args.snapshot_path); snapshot_load(args.snapshot_path);
hascommit = 1; hascommit = 1;
} }
...@@ -93,9 +103,13 @@ inline void Emulator::single_cycle() { ...@@ -93,9 +103,13 @@ inline void Emulator::single_cycle() {
dut_ptr->clock = 1; dut_ptr->clock = 1;
dut_ptr->eval(); dut_ptr->eval();
#if VM_TRACE if (enable_waveform) {
tfp->dump(cycles); uint64_t cycle = dut_ptr->io_trap_cycleCnt;
#endif uint64_t begin = dut_ptr->io_logCtrl_log_begin;
uint64_t end = dut_ptr->io_logCtrl_log_end;
bool in_range = (begin <= cycle) && (cycle <= end);
if (in_range) { tfp->dump(cycle); }
}
if (dut_ptr->io_uart_out_valid) { if (dut_ptr->io_uart_out_valid) {
printf("%c", dut_ptr->io_uart_out_ch); printf("%c", dut_ptr->io_uart_out_ch);
...@@ -127,14 +141,6 @@ uint64_t Emulator::execute(uint64_t n) { ...@@ -127,14 +141,6 @@ uint64_t Emulator::execute(uint64_t n) {
diff.wdata = wdata; diff.wdata = wdata;
diff.wdst = wdst; diff.wdst = wdst;
#if VM_TRACE
Verilated::traceEverOn(true); // Verilator must compute traced signals
VL_PRINTF("Enabling waves...\n");
tfp = new VerilatedVcdC;
dut_ptr->trace(tfp, 99); // Trace 99 levels of hierarchy
tfp->open("vlt_dump.vcd"); // Open the dump file
#endif
while (trapCode == STATE_RUNNING && n > 0) { while (trapCode == STATE_RUNNING && n > 0) {
single_cycle(); single_cycle();
n --; n --;
...@@ -146,9 +152,6 @@ uint64_t Emulator::execute(uint64_t n) { ...@@ -146,9 +152,6 @@ uint64_t Emulator::execute(uint64_t n) {
eprintf("No instruction commits for %d cycles, maybe get stuck\n" eprintf("No instruction commits for %d cycles, maybe get stuck\n"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)\n", "(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)\n",
stuck_limit, stuck_limit); stuck_limit, stuck_limit);
#if VM_TRACE
tfp->close();
#endif
difftest_display(dut_ptr->io_difftest_priviledgeMode); difftest_display(dut_ptr->io_difftest_priviledgeMode);
trapCode = STATE_ABORT; trapCode = STATE_ABORT;
} }
...@@ -176,9 +179,6 @@ uint64_t Emulator::execute(uint64_t n) { ...@@ -176,9 +179,6 @@ uint64_t Emulator::execute(uint64_t n) {
diff.priviledgeMode = dut_ptr->io_difftest_priviledgeMode; diff.priviledgeMode = dut_ptr->io_difftest_priviledgeMode;
if (difftest_step(&diff)) { if (difftest_step(&diff)) {
#if VM_TRACE
tfp->close();
#endif
trapCode = STATE_ABORT; trapCode = STATE_ABORT;
} }
lastcommit = n; lastcommit = n;
...@@ -197,17 +197,31 @@ uint64_t Emulator::execute(uint64_t n) { ...@@ -197,17 +197,31 @@ uint64_t Emulator::execute(uint64_t n) {
} }
} }
if (enable_waveform) tfp->close();
display_trapinfo(); display_trapinfo();
return cycles; return cycles;
} }
inline char* Emulator::snapshot_filename(time_t t) { inline char* Emulator::timestamp_filename(time_t t, char *buf) {
static char buf[1024];
char buf_time[64]; char buf_time[64];
strftime(buf_time, sizeof(buf_time), "%F@%T", localtime(&t)); strftime(buf_time, sizeof(buf_time), "%F@%T", localtime(&t));
char *noop_home = getenv("NOOP_HOME"); char *noop_home = getenv("NOOP_HOME");
assert(noop_home != NULL); assert(noop_home != NULL);
snprintf(buf, 1024, "%s/build/%s.snapshot", noop_home, buf_time); int len = snprintf(buf, 1024, "%s/build/%s", noop_home, buf_time);
return buf + len;
}
inline char* Emulator::snapshot_filename(time_t t) {
static char buf[1024];
char *p = timestamp_filename(t, buf);
strcpy(p, ".snapshot");
return buf;
}
inline char* Emulator::waveform_filename(time_t t) {
static char buf[1024];
char *p = timestamp_filename(t, buf);
strcpy(p, ".vcd");
return buf; return buf;
} }
......
#include "common.h" #include "common.h"
#include "snapshot.h" #include "snapshot.h"
#include "VXSSimTop.h" #include "VXSSimTop.h"
#if VM_TRACE
#include <verilated_vcd_c.h> // Trace file format header #include <verilated_vcd_c.h> // Trace file format header
#endif
#define DIFFTEST_WIDTH 6 #define DIFFTEST_WIDTH 6
#define SNAPSHOT_INTERVAL 10 // unit: second #define SNAPSHOT_INTERVAL 10 // unit: second
...@@ -15,6 +12,7 @@ struct EmuArgs { ...@@ -15,6 +12,7 @@ struct EmuArgs {
uint64_t log_begin, log_end; uint64_t log_begin, log_end;
const char *image; const char *image;
const char *snapshot_path; const char *snapshot_path;
bool enable_waveform;
EmuArgs() { EmuArgs() {
seed = 0; seed = 0;
...@@ -23,14 +21,14 @@ struct EmuArgs { ...@@ -23,14 +21,14 @@ struct EmuArgs {
log_end = -1; log_end = -1;
snapshot_path = NULL; snapshot_path = NULL;
image = NULL; image = NULL;
enable_waveform = false;
} }
}; };
class Emulator { class Emulator {
VXSSimTop *dut_ptr; VXSSimTop *dut_ptr;
#if VM_TRACE
VerilatedVcdC* tfp; VerilatedVcdC* tfp;
#endif bool enable_waveform;
VerilatedSaveMem snapshot_slot[2]; VerilatedSaveMem snapshot_slot[2];
enum { enum {
...@@ -50,9 +48,11 @@ class Emulator { ...@@ -50,9 +48,11 @@ class Emulator {
inline void reset_ncycles(size_t cycles); inline void reset_ncycles(size_t cycles);
inline void single_cycle(); inline void single_cycle();
void display_trapinfo(); void display_trapinfo();
inline char* timestamp_filename(time_t t, char *buf);
inline char* snapshot_filename(time_t t); inline char* snapshot_filename(time_t t);
void snapshot_save(const char *filename); void snapshot_save(const char *filename);
void snapshot_load(const char *filename); void snapshot_load(const char *filename);
inline char* waveform_filename(time_t t);
public: public:
Emulator(EmuArgs &args); Emulator(EmuArgs &args);
......
...@@ -16,6 +16,8 @@ static inline void print_help(const char *file) { ...@@ -16,6 +16,8 @@ static inline void print_help(const char *file) {
printf(" -i, --image=FILE run with this image file\n"); printf(" -i, --image=FILE run with this image file\n");
printf(" -b, --log-begin=NUM display log from NUM th cycle\n"); printf(" -b, --log-begin=NUM display log from NUM th cycle\n");
printf(" -e, --log-end=NUM stop display log at NUM th cycle\n"); printf(" -e, --log-end=NUM stop display log at NUM th cycle\n");
printf(" --load-snapshot=PATH load snapshot from PATH\n");
printf(" --dump-wave dump waveform when log is enabled\n");
printf(" -h, --help print program help info\n"); printf(" -h, --help print program help info\n");
printf("\n"); printf("\n");
} }
...@@ -25,6 +27,7 @@ static inline EmuArgs parse_args(int argc, const char *argv[]) { ...@@ -25,6 +27,7 @@ static inline EmuArgs parse_args(int argc, const char *argv[]) {
int long_index = 0; int long_index = 0;
const struct option long_options[] = { const struct option long_options[] = {
{ "load-snapshot", 1, NULL, 0 }, { "load-snapshot", 1, NULL, 0 },
{ "dump-wave", 0, NULL, 0 },
{ "seed", 1, NULL, 's' }, { "seed", 1, NULL, 's' },
{ "max-cycles", 1, NULL, 'C' }, { "max-cycles", 1, NULL, 'C' },
{ "image", 1, NULL, 'i' }, { "image", 1, NULL, 'i' },
...@@ -39,9 +42,9 @@ static inline EmuArgs parse_args(int argc, const char *argv[]) { ...@@ -39,9 +42,9 @@ static inline EmuArgs parse_args(int argc, const char *argv[]) {
"-s:C:hi:m:b:e:", long_options, &long_index)) != -1) { "-s:C:hi:m:b:e:", long_options, &long_index)) != -1) {
switch (o) { switch (o) {
case 0: case 0:
if (long_index == 0) { switch (long_index) {
args.snapshot_path = optarg; case 0: args.snapshot_path = optarg; continue;
break; case 1: args.enable_waveform = true; continue;
} }
// fall through // fall through
default: default:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册