diff --git a/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportConfigs.py b/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportConfigs.py index 5d30baed..fa8de170 100644 --- a/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportConfigs.py +++ b/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportConfigs.py @@ -85,6 +85,15 @@ class VerilogVerilatorImportConfigs( BasePassConfigs ): # Expects a boolean value "vl_trace" : False, + # trace format + # Expects a str value + # "Vcd" or "Fst + "vl_trace_format" : "Vcd", + + # --trace-struct + # Expects a boolean value + "vl_trace_struct" : False, + # The output filename of Verilator VCD tracing # default is {component_name}.verilator1 "vl_trace_filename" : "", @@ -138,10 +147,10 @@ class VerilogVerilatorImportConfigs( BasePassConfigs ): Checkers = { ("enable", "verbose", "vl_enable_assert", "vl_line_trace", "vl_W_lint", "vl_W_style", "vl_W_fatal", "vl_trace", "vl_coverage", "vl_line_coverage", "vl_toggle_coverage", - "vl_trace_on_demand"): + "vl_trace_on_demand", "vl_trace_struct"): Checker( lambda v: isinstance(v, bool), "expects a boolean" ), - ("c_flags", "ld_flags", "ld_libs", "vl_trace_filename", "vl_trace_on_demand_portname"): + ("c_flags", "ld_flags", "ld_libs", "vl_trace_filename", "vl_trace_on_demand_portname", "vl_trace_format"): Checker( lambda v: isinstance(v, str), "expects a string" ), "vl_Wno_list": Checker( lambda v: isinstance(v, list) and all(w in VerilogPlaceholderConfigs.Warnings for w in v), @@ -270,7 +279,11 @@ def create_vl_cmd( s ): loop_unroll = "--unroll-count 1000000" stmt_unroll = "--unroll-stmts 1000000" thread = "--threads 1" - trace = "--trace" if s.vl_trace else "" + if s.vl_trace_format == "vcd": + trace = "--trace" if s.vl_trace else "" + else: + trace = "--trace-fst" if s.vl_trace else "" + trace_struct = "-trace-structs" if s.vl_trace_struct else "" coverage = "--coverage" if s.vl_coverage else "" line_cov = "--coverage-line" if s.vl_line_coverage else "" toggle_cov = "--coverage-toggle" if s.vl_toggle_coverage else "" @@ -279,10 +292,9 @@ def create_vl_cmd( s ): all_opts = [ top_module, mk_dir, include, en_assert, opt_level, loop_unroll, # stmt_unroll, trace, warnings, flist, src, coverage, - stmt_unroll, thread, trace, warnings, src, vlibs, coverage, + stmt_unroll, thread, trace, trace_struct, warnings, src, vlibs, coverage, line_cov, toggle_cov, ] - return f"verilator --cc {' '.join(opt for opt in all_opts if opt)}" def create_cc_cmd( s ): diff --git a/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportPass.py b/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportPass.py index 0bda9efb..63b56b2f 100644 --- a/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportPass.py +++ b/pymtl3/passes/backends/verilog/import_/VerilogVerilatorImportPass.py @@ -176,6 +176,21 @@ class VerilogVerilatorImportPass( BasePass ): #: Default value: ``False`` vl_trace = MetadataKey(bool) + #: Set trace format. + #: + #: Type: ``str``; input + #: + #: Default value: ``str`` + vl_trace_format = MetadataKey(str) + + #: Enable Verilator Struct tracing. + #: + #: Type: ``bool``; input + #: + #: Default value: ``False`` + vl_trace_struct = MetadataKey(bool) + + #: Filename of Verilator VCD tracing. #: #: Type: ``str``; input @@ -470,6 +485,8 @@ def create_verilator_c_wrapper( s, m, ph_cfg, ip_cfg, ports, dump=True ): verilator_xinit_value = ip_cfg.get_vl_xinit_value() verilator_xinit_seed = ip_cfg.get_vl_xinit_seed() has_clk = int(ph_cfg.has_clk) + vl_trace_format = ip_cfg.vl_trace_format + header_file_trace_format = ip_cfg.vl_trace_format.lower() # On-demand VCD dumping configs on_demand_dump_vcd = int(ip_cfg.vl_trace_on_demand) @@ -607,6 +624,7 @@ def create_py_wrapper( s, m, ph_cfg, ip_cfg, rtype, ports, port_cdefs, dump=True vl_trace_filename = ip_cfg.vl_trace_filename, external_trace = int(ip_cfg.vl_line_trace), trace_c_def = external_trace_c_def, + vl_trace_format = ip_cfg.vl_trace_format.lower(), ) output.write( py_wrapper ) @@ -671,7 +689,7 @@ def serialize_cfg( s, ip_cfg ): 'vl_line_trace', 'vl_coverage', 'vl_line_coverage', 'vl_toggle_coverage', 'vl_mk_dir', 'vl_enable_assert', 'vl_W_lint', 'vl_W_style', 'vl_W_fatal', 'vl_Wno_list', - 'vl_xinit', 'vl_trace', + 'vl_xinit', 'vl_trace', 'vl_trace_format', 'vl_trace_struct', 'vl_trace_timescale', 'vl_trace_cycle_time', 'vl_trace_on_demand', 'vl_trace_on_demand_portname', 'c_flags', 'c_include_path', 'c_srcs', diff --git a/pymtl3/passes/backends/verilog/import_/verilator_wrapper_c_template.py b/pymtl3/passes/backends/verilog/import_/verilator_wrapper_c_template.py index cc7fbbbe..e48ce296 100644 --- a/pymtl3/passes/backends/verilog/import_/verilator_wrapper_c_template.py +++ b/pymtl3/passes/backends/verilog/import_/verilator_wrapper_c_template.py @@ -11,7 +11,7 @@ #include "stdio.h" #include "stdint.h" #include "verilated.h" -#include "verilated_vcd_c.h" +#include "verilated_{header_file_trace_format}_c.h" // set to true if the model has clk signal #define HAS_CLK {has_clk} @@ -119,7 +119,7 @@ if ( strlen( vcd_filename ) != 0 ) {{ m->_cffi_vcd_en = 1; context_ptr->traceEverOn( true ); - VerilatedVcdC * tfp = new VerilatedVcdC(); + Verilated{vl_trace_format}C * tfp = new Verilated{vl_trace_format}C(); model->trace( tfp, 99 ); tfp->spTrace()->set_time_resolution( "{vcd_timescale}" ); @@ -160,7 +160,7 @@ #if DUMP_VCD if ( m->_cffi_vcd_en ) {{ // printf("DESTROYING %d\\n", m->_cffi_trace_time); - VerilatedVcdC * tfp = (VerilatedVcdC *) m->_cffi_tfp; + Verilated{vl_trace_format}C * tfp = (Verilated{vl_trace_format}C *) m->_cffi_tfp; tfp->close(); delete tfp; }} @@ -226,7 +226,7 @@ #endif // dump current signal values - VerilatedVcdC * tfp = (VerilatedVcdC *) m->_cffi_tfp; + Verilated{vl_trace_format}C * tfp = (Verilated{vl_trace_format}C *) m->_cffi_tfp; tfp->dump( m->_cffi_trace_time ); tfp->flush(); diff --git a/pymtl3/passes/backends/verilog/import_/verilator_wrapper_py_template.py b/pymtl3/passes/backends/verilog/import_/verilator_wrapper_py_template.py index 8ed4d31c..69f13b3d 100644 --- a/pymtl3/passes/backends/verilog/import_/verilator_wrapper_py_template.py +++ b/pymtl3/passes/backends/verilog/import_/verilator_wrapper_py_template.py @@ -126,9 +126,9 @@ def construct( s, *args, **kwargs ): verilator_vcd_file = "" if {dump_vcd}: if {has_vl_trace_filename}: - verilator_vcd_file = "{vl_trace_filename}.verilator1.vcd" + verilator_vcd_file = "{vl_trace_filename}.verilator1.{vl_trace_format}" else: - verilator_vcd_file = "{component_name}.verilator1.vcd" + verilator_vcd_file = "{component_name}.verilator1.{vl_trace_format}" # Convert string to `bytes` which is required by CFFI on python 3 verilator_vcd_file = verilator_vcd_file.encode('ascii')