From efa2235105fc86d7a727ed2d1a415d76ad1ccbc9 Mon Sep 17 00:00:00 2001 From: Shupei Fan Date: Fri, 20 Dec 2024 06:11:28 +0000 Subject: [PATCH] [verbatim] refactor --- t1rocketemu/vsrc/VerbatimModule.sv | 208 +++++++++++++++++------------ 1 file changed, 120 insertions(+), 88 deletions(-) diff --git a/t1rocketemu/vsrc/VerbatimModule.sv b/t1rocketemu/vsrc/VerbatimModule.sv index 4f4aefc25..dc25b7ed8 100644 --- a/t1rocketemu/vsrc/VerbatimModule.sv +++ b/t1rocketemu/vsrc/VerbatimModule.sv @@ -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(); @@ -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"); @@ -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 @@ -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; @@ -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 @@ -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