Feature request: elaboration tasks
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?
#2 Updated by Udi Finkelstein 6 months ago
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).
#5 Updated by Udi Finkelstein 6 months ago
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 <initial> 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>
It yet remains to be seen why the $warning call is created under an <initial> 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
-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);In that case,
$infowon't trigger on elaboratin time, even though it's a constant function.
Also available in: Atom