zachjs / sv2v

SystemVerilog to Verilog conversion
BSD 3-Clause "New" or "Revised" License
497 stars 50 forks source link

Convert severity tasks to Verilog #273

Open sifferman opened 5 months ago

sifferman commented 5 months ago

Hello!

SystemVerilog added the system tasks $fatal, $error, $warning, and $info (20.10). However, sv2v does not convert them at all, causing Verilog tools to fail. It would be nice to convert them into Verilog-2005 tasks so that they can still be used in pure Verilog tools.

This is my interpretation of the LRM:

This is a description of what should go in the $display:

[Each task should include a tool-specific message with] the following information:

  • The file name and line number of the severity system task call. The file name and line number shall be the same as `__FILE__ and `__LINE__ compiler directives, respectively.
  • The hierarchical name of the scope in which the severity system task call is made.
  • For simulation tools, the simulation run time at which the severity system task is called. The tool-specific message shall include the user-defined message if specified.

It could be helpful to have `__FILE__ and `__LINE__ for both the inputted .sv file and the outputted .v file. Verilog-2005 has no `__FILE__ equivalent, but it does have `line (19.7).

I would be happy to look into this if you'd like. :)

sifferman commented 5 months ago

I ran this example through the big 4 to see what the outputs should be:

module tb;
    initial begin
        $info;
        $info("%b", 1);
        $warning;
        $warning("%b", 2);
        $error;
        $error("%b", 3);
        // $fatal;
        // $fatal(0, "%b", 4);
        // showing results from both fatal calls if each were run individually
    end
endmodule

VCS

Info: "tb.sv", 3: tb: at time 0

Info: "tb.sv", 5: tb: at time 0
00000000000000000000000000000001

Warning: "tb.sv", 7: tb: at time 0

Warning: "tb.sv", 9: tb: at time 0
00000000000000000000000000000010

Error: "tb.sv", 11: tb: at time 0

Error: "tb.sv", 13: tb: at time 0
00000000000000000000000000000011

Fatal: "tb.sv", 15: tb: at time 0

Fatal: "tb.sv", 17: tb: at time 0
00000000000000000000000000000100

ModelSim

# ** Info: Assertion error.
#    Time: 0 ns  Scope: tb File: tb.sv Line: 3
# 
# ** Info: 00000000000000000000000000000001
#    Time: 0 ns  Scope: tb File: tb.sv Line: 5
# 
# ** Warning: Assertion error.
#    Time: 0 ns  Scope: tb File: tb.sv Line: 7
# 
# ** Warning: 00000000000000000000000000000010
#    Time: 0 ns  Scope: tb File: tb.sv Line: 9
# 
# ** Error: Assertion error.
#    Time: 0 ns  Scope: tb File: tb.sv Line: 11
# 
# ** Error: 00000000000000000000000000000011
#    Time: 0 ns  Scope: tb File: tb.sv Line: 13
# 
# ** Fatal: Assertion error.
#    Time: 0 ns  Scope: tb File: tb.sv Line: 15
# 
# ** Fatal: 00000000000000000000000000000100
#    Time: 0 ns  Scope: tb File: tb.sv Line: 17

Xcelium

xmsim: *N,INFSEV (./tb.sv,3): (time 0 FS).
tb

xmsim: *N,INFSEV (./tb.sv,5): (time 0 FS).
tb
00000000000000000000000000000001

xmsim: *W,WARSEV (./tb.sv,7): (time 0 FS).
tb

xmsim: *W,WARSEV (./tb.sv,9): (time 0 FS).
tb
00000000000000000000000000000010

xmsim: *E,ERRSEV (./tb.sv,11): (time 0 FS).
tb

xmsim: *E,ERRSEV (./tb.sv,13): (time 0 FS).
tb
00000000000000000000000000000011

xmsim: *F,FATSEV (./tb.sv,15): (time 0 FS).
tb

xmsim: *F,FATSEV (./tb.sv,17): (time 0 FS).
tb
00000000000000000000000000000100

Verilator

[0] -Info: tb.sv:3: TOP.tb

[0] -Info: tb.sv:5: TOP.tb: 00000000000000000000000000000001

[0] %Warning: tb.sv:7: TOP.tb

[0] %Warning: tb.sv:9: TOP.tb: 00000000000000000000000000000010

[0] %Error: tb.sv:11: Assertion failed in TOP.tb

[0] %Error: tb.sv:13: Assertion failed in TOP.tb: 00000000000000000000000000000011

[0] %Fatal: tb.sv:15: Assertion failed in TOP.tb

[0] %Fatal: tb.sv:17: Assertion failed in TOP.tb: 00000000000000000000000000000100

(Note that this run required the use of +verilator+error+limit+3. I think this is kind of a cool feature, and I wonder if it could be feasible to do something like $value$plusargs("sv2v+error+limit+%d", _sv2v_error_limit). Just a thought...)

Summary

This is what I'm thinking:

$info(message);
$display("[%t] Info: %s", $time, message);
$display("Src File: <PRE_SV2V_FILENAME>:<PRE_SV2V_LINE>, Scope: <PRE_SV2V_SCOPE>");
$display("Sv2v File: <POST_SV2V_FILENAME>:%s, Scope: <POST_SV2V_SCOPE>", "<POST_SV2V_LINE>");

for example:

[10] Info: Handshake received.
Src File: rtl/com.sv:43, Scope: top.com
Sv2v File: sv2v.v:126, Scope: top.com
zachjs commented 5 months ago

I'm very interested in getting this enhancement in, and greatly appreciate your initiative in filing a PR. Thank you!

I think I'm missing an important piece of context: What tools don't support the SystemVerilog severity tasks? I know iverilog and Yosys do. Verilator does, but only in SystemVerilog mode. You've got a good sampling of the commercial simulators here, too. What tool are you using in your flow that doesn't support them?

sifferman commented 5 months ago

As far as I can tell, all commercial tools support the SystemVerilog severity tasks only when in SystemVerilog mode. And I wasn't aware that Yosys had support. So I don't believe that it is crucial for this issue to be completed. Plus, if a tool natively supports SystemVerilog severity tasks, it likely can provide more helpful warnings than what sv2v can offer.

But this change would bring sv2v closer to full 1800→1364 conversion. So I would say it is up to you on whether this change should be used. :smiley: