Skip to content

Commit

Permalink
[verbatim] refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
FanShupei committed Dec 20, 2024
1 parent 0a533e0 commit 35d2917
Showing 1 changed file with 120 additions and 88 deletions.
208 changes: 120 additions & 88 deletions t1rocketemu/vsrc/VerbatimModule.sv
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package t1_log_pkg;
// plusargs:
// +t1_rtl_event_off (optional) set to 1 to disable rtl event recording

bit log_cond;
int log_fd;

int rtl_event_off = 0;

function automatic void log_open(string log_path);
log_fd = $fopen(log_path, "w");
if (log_fd == 0) $fatal(1, "failed to open rtl event file for write");
log_cond = 1'b1;
$value$plusargs("t1_rtl_event_off=%d", rtl_event_off);
if (rtl_event_off == 0) begin
log_fd = $fopen(log_path, "w");
if (log_fd == 0) $fatal(1, "failed to open rtl event file for write");
log_cond = 1'b1;
end
endfunction

function automatic void log_close();
Expand All @@ -17,42 +25,19 @@ package t1_log_pkg;
endfunction
endpackage

module VerbatimModule #(
parameter integer T1_DLEN,
parameter integer T1_VLEN,
parameter string T1_SPIKE_ISA
)(
output reg clock,
output reg reset,
output reg initFlag,
input wire idle
);

// This module contains everything we can not represent in Chisel currently,
// including clock gen, plusarg parsing, sim control, etc
//
// plusargs: "T" denotes being present only if trace is enabled
// +t1_elf_file (required) path to elf file
// +t1_wave_path (required T) path to wave dump file
// +t1_timeout (optional) max cycle between two AXI DPI call
// +t1_global_timeout (optional) max cycle for whole simulation, for debug only
// +t1_timeout_after_quit (optional)
// +t1_dump_start (optional T) cycle when dump starts, by default it's simulation start, for debug only
// +t1_dump_end (optional T) cycle when dump ends, by default is's simulation end, for debug only
package t1_wavedump_pkg;
// plusargs: present only if trace is enabled
// +t1_wave_path (required) path to wave dump file
// +t1_dump_start (optional) cycle when dump starts, by default it's simulation start, for debug only
// +t1_dump_end (optional) cycle when dump ends, by default is's simulation end, for debug only

longint unsigned cycle = 0;
longint unsigned quit_cycle = 0;
longint unsigned global_timeout = 0;
longint unsigned timeout_after_quit = 10000;
longint unsigned dpi_timeout = 1000000;
string elf_file;
`ifdef T1_ENABLE_TRACE
longint unsigned dump_start = 0;
longint unsigned dump_end = 0;
string wave_path;

function void dump_wave(input string file);
`ifdef T1_ENABLE_TRACE

function void dump_wave(input string file);
`ifdef VCS
$fsdbDumpfile(file);
$fsdbDumpvars("+all");
Expand All @@ -62,20 +47,76 @@ module VerbatimModule #(
$dumpfile(file);
$dumpvars(0);
`endif

endfunction

function void dump_finish();

`ifdef VCS
$fsdbDumpFinish();
`endif
`ifdef VERILATOR
$dumpoff();
`endif
endfunction

function void init_trace();
$value$plusargs("t1_dump_start=%d", dump_start);
$value$plusargs("t1_dump_end=%d", dump_end);
$value$plusargs("t1_wave_path=%s", wave_path);

if (wave_path.len() == 0) $fatal(1, "+t1_elf_file must be set");

if (dump_start == 0) begin
dump_wave(wave_path);
end
endfunction

function void trigger_trace(longint unsigned cycle);
if (cycle == dump_start) begin
dump_wave(wave_path);
end
if (cycle == dump_end) begin
dump_finish();
end
endfunction
`endif

`else // T1_ENABLE_TRACE

function void init_trace();
$value$plusargs("t1_wave_path=%s", wave_path);
if (wave_path.len() != 0) $fatal(1, "trace disabled at compile time, but +t1_elf_file is set");
endfunction

function void trigger_trace(longint unsigned cycle);
endfunction

`endif // T1_ENABLE_TRACE
endpackage

module VerbatimModule #(
parameter integer T1_DLEN,
parameter integer T1_VLEN,
parameter string T1_SPIKE_ISA
)(
output reg clock,
output reg reset,
output reg initFlag,
input wire idle
);
// This module contains everything we can not represent in Chisel currently,
// including clock gen, plusarg parsing, sim control, etc
//
// plusargs:
// +t1_elf_file (required) path to elf file
// +t1_timeout (optional) max cycle between two AXI DPI call
// +t1_global_timeout (optional) max cycle for whole simulation, for debug only
// +t1_timeout_after_quit (optional)

longint unsigned cycle = 0;
longint unsigned quit_cycle = 0;
longint unsigned global_timeout = 0;
longint unsigned timeout_after_quit = 10000;
longint unsigned dpi_timeout = 1000000;
string elf_file;

// this function captures the scope
// DO NOT move it outside the module
Expand All @@ -89,6 +130,45 @@ module VerbatimModule #(
import "DPI-C" context function void t1_cosim_set_timeout(longint unsigned timeout);
import "DPI-C" context function void t1_cosim_final();
import "DPI-C" context function byte unsigned t1_cosim_watchdog();

function void init_hook();
$value$plusargs("t1_elf_file=%s", elf_file);
$value$plusargs("t1_timeout=%d", dpi_timeout);
$value$plusargs("t1_timeout_after_quit=%d", timeout_after_quit);

if (elf_file.len() == 0) $fatal(1, "+t1_elf_file must be set");
t1_cosim_init(elf_file);
t1_cosim_set_timeout(dpi_timeout);
endfunction

function void cycle_hook();
if (quit_cycle != 0) begin
// cosim already quits

if (idle) begin
$finish;
end else if (cycle > quit_cycle + timeout_after_quit) begin
// cosim already quits, but TestBench does not become idle
$fatal(1, "TestBench idle timeout");
end
end else begin
// do not call watchdog if cosim already quit

automatic byte unsigned st = t1_cosim_watchdog();
if (st == 255) begin
quit_cycle = cycle;
if (idle) begin
// quit successfully, only if both DPI and TestBench finish
$finish;
end
end else if (st == 0) begin
// continue, do nothing here
end else begin
// error
$fatal(1, "watchdog timeout");
end
end
endfunction

initial begin
clock = 1'b0;
Expand All @@ -99,27 +179,11 @@ module VerbatimModule #(
t1_cosim_preinit(T1_DLEN, T1_VLEN, T1_SPIKE_ISA);

t1_log_pkg::log_open("rtl-event.jsonl");
t1_wavedump_pkg::init_trace();

`ifdef T1_ENABLE_TRACE
$value$plusargs("t1_dump_start=%d", dump_start);
$value$plusargs("t1_dump_end=%d", dump_end);
$value$plusargs("t1_wave_path=%s", wave_path);
`endif
$value$plusargs("t1_elf_file=%s", elf_file);
$value$plusargs("t1_timeout=%d", dpi_timeout);
$value$plusargs("t1_global_timeout=%d", global_timeout);
$value$plusargs("t1_timeout_after_quit=%d", timeout_after_quit);

if (elf_file.len() == 0) $fatal(1, "+t1_elf_file must be set");

t1_cosim_init(elf_file);
t1_cosim_set_timeout(dpi_timeout);

`ifdef T1_ENABLE_TRACE
if (dump_start == 0) begin
dump_wave(wave_path);
end
`endif
init_hook();

#10;
forever begin
Expand All @@ -130,45 +194,13 @@ module VerbatimModule #(

cycle += 1;

if (quit_cycle != 0) begin
// cosim already quits

if (idle) begin
$finish;
end else if (cycle > quit_cycle + timeout_after_quit) begin
// cosim already quits, but TestBench does not become idle
$fatal(1, "TestBench idle timeout");
end
end else begin
// do not call watchdog if cosim already quit

automatic byte unsigned st = t1_cosim_watchdog();
if (st == 255) begin
quit_cycle = cycle;
if (idle) begin
// quit successfully, only if both DPI and TestBench finish
$finish;
end
end else if (st == 0) begin
// continue, do nothing here
end else begin
// error
$fatal(1, "watchdog timeout");
end
end
cycle_hook();

if (cycle == global_timeout) begin
$fatal(1, "global timeout reached");
end

`ifdef T1_ENABLE_TRACE
if (cycle == dump_start) begin
dump_wave(wave_path);
end
if (cycle == dump_end) begin
dump_finish();
end
`endif
t1_wavedump_pkg::trigger_trace(cycle);
end
end

Expand Down

0 comments on commit 35d2917

Please sign in to comment.