verilator / verilator

Verilator open-source SystemVerilog simulator and lint system
https://verilator.org
GNU Lesser General Public License v3.0
2.43k stars 582 forks source link

Feature request: elaboration tasks #1429

Closed veripoolbot closed 5 years ago

veripoolbot commented 5 years ago

Author Name: Udi Finkelstein Original Redmine Issue: 1429 from https://www.veripool.org


While looking for a way to trigger an error on invalid parameter combinations of a parammetrized module, I stumbled upon this hidden gem:

20.11 Elaboration system tasks
It is often necessary to validate the actual parameter values used in a SystemVerilog model and report any
error without generating the executable simulation model. This is achieved by using elaboration system
tasks. These tasks have the same names as the severity system tasks (see 20.10) that can be used during
simulation. However, the elaboration system tasks shall be called outside procedural code and their
activation can be controlled by conditional generate constructs. If such a task is called from within a
procedure, then it becomes a simulation-time severity system task.
elaboration_system_task ::= // from A.1.4
$fatal [ ( finish_number [, list_of_arguments ] ) ] ;
| $error [ ( [ list_of_arguments ] ) ] ;
| $warning [ ( [ list_of_arguments ] ) ] ;
| $info [ ( [ list_of_arguments ] ) ] ;
finish_number ::= 0 | 1 | 2
Syntax 20-11—Elaboration system task syntax (excerpt from Annex A)

So it seems that if you call $error()/$wrning()/$info()/$fatal() directly within a generate section, outside any procedural always/initial block, it is treated as elaboration system atsks, not runtime system tasks!

I've tried the following example, but it triggered no response from Verilator:

module t;
localparam X=1;
generate
if (X == 1)
  $info("X is 1");
else
  $info("X is not 1");
endgenerate
endmodule

Is it possible to add support for these system tasks in elaboration time?

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Udi Finkelstein Original Date: 2019-05-02T13:40:23Z


Sorry, no way to edit posts :-(

The text above is obviously taken from the IEEE1800-2017 LRM.

This is the test case:

module t;
localparam X=1;
generate
if (X == 1)
  $info("X is 1");
else
  $info("X is not 1");
endgenerate
endmodule
veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Udi Finkelstein Original Date: 2019-05-02T18:43:13Z


Searching a github copy of verilator for completely different stuff ($diplay() implementations), I hit upon the Verilator parser section, where it is clearly indicated this is already supported... I then realized that if this was not supported, it would have caused parsing error on my test, which it did not.

So, it seems that elaboration tasks are partially supported (parsed but not correctly executed).

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-05-02T19:51:16Z


As you noted this is (supposedly) supported, can you please edit the e.g. test_regress/t/t_assert_elab_bad.pl test to show the issue, and then ideally debug?

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Udi Finkelstein Original Date: 2019-05-03T00:30:48Z


I'm less familiar with the Verilator codebase, but I';ll try next week. In the meantime, I've worked on: https://github.com/YosysHQ/yosys/pull/983

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Udi Finkelstein Original Date: 2019-05-03T07:14:58Z


OK, I tried looking into it. From the XML I see that the $info/$warning etc. in a function are put directly inside the function. while the same functions inside a generate block are dumped exactly the same (XML-wise) regardless of whether they are part of an initial/always block (runtime task) or directly under the generate block (elaboration time):

Take this code for example:

module t;
generate
if (1)
  $warning;
if (1)
begin
initial
  $info;
end
endgenerate
endmodule

$warning is an elaboration time task, while the $Info is a runtime task.

The XML shows them both on the same level under an tag:

  <netlist>
     <module fl="d1" name="t" origName="t">
       <begin fl="d4" name="genblk1">
         <initial fl="d4">
           <display fl="d4" displaytype="$write">
             <sformatf fl="d4" name="[%0t] %%Warning: t.sv:4: Assertion failed in %m\n" dtype_id="1">
               <time fl="d4" dtype_id="2"/>
               <scopename fl="d4" dtype_id="2"/>
             </sformatf>
           </display>
         </initial>
       </begin>
       <begin fl="d6" name="genblk2">
         <initial fl="d7">
           <display fl="d8" displaytype="$write">
             <sformatf fl="d8" name="[%0t] -Info: t.sv:8: Assertion failed in %m\n" dtype_id="1">
               <time fl="d8" dtype_id="2"/>
               <scopename fl="d8" dtype_id="2"/>
             </sformatf>
           </display>
         </initial>
       </begin>
     </module>
</code>

It yet remains to be seen why the $warning call is created under an tag (I assume that corresponds to an identical AST node).

Going back to the working code for functions, I tried:

module t2;
function logic checkParameter(input logic [31:0] N);
  $info("In function...");
endfunction
localparam x = checkParameter(0);
endmodule

and got:

-Info: In function...
%Error: Internal Error: t2.sv:2: ../V3Simulate.h:261: No value found for node.
%Error: Internal Error: See the manual and http://www.veripool.org/verilator for more assistance.
%Error: Command Failed /home/udif/git/verilator/bin/verilator_bin --xml-only -sv t2.sv

I also noticed that as long as the constant function is used by runtime constructs and not cmpile time constructs, it won't be triggered. e.g., if I change localparam x = checkParameter(0); to ```wire x = checkParameter(0);

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-06-15T13:35:38Z


Did some poking on this, will add it to the soon-to-work on list. If you or someone has time to create a patch it would be welcome.

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-08-05T02:35:20Z


Fixed in git towards 4.018.

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-08-29T23:14:33Z


In 4.018.