Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent systemverilog compilation if certain macro isn't set

I am writing a systemverilog module and I need to make sure that a certain macro is set to allow compilation to proceed.

I have tried the below, but it simply gives the syntax error "unexpected SYSTEM_IDENTIFIER" $fatal.

I know that does technically stop the compilation, but does anyone know of a more graceful solution?

* Correction, if the syntax in the `else branch is not correct, none of the branches will compile successfully.

`ifdef MACRO_0
// Some code
`elsif MACRO_1
// Some other code
`else
$fatal("MACRO_0 or MACRO_1 must be set for compilation");
`endif

As per recommendation, adding the below information to the question:

The code is in a module but not inside an initial or always statement. I am hoping to find a solution that will allow me to terminate the compilation i.e. elaboration of hdl. I am designing for FPGA implementation and I need to make sure that no other user of this code can reach the synthesis phase of a design flow without setting one of these macros.

like image 482
miles.sherman Avatar asked Apr 24 '14 14:04

miles.sherman


2 Answers

$fatal is a run-time system call, not a compile-time fatal as mentioned by toolic. I don't think you can stop the compile unless you have a compile error. In your sample code you are getting close to what you want by hiding part of the code, but the compile does not terminate and you don't print the right message.

I am not aware of any standard Verilog/SystemVerilog construct for printing a customized message during the compile time. GCC for example, has #error for this purpose. However, some synthesis tools, like Synopsis Design Compiler do print the output of $display messages during elaboration time. The $display still needs to be inside an always block. If you also deliberately place an elaboration error when MACRO0 and MACRO1 are not defined, you may be able to terminate the synthesis.

For example, in the following, a dummy module is instantiated without defining its body:

`ifdef MACRO_0
// Some code
`elsif MACRO_1
// Some other code
`else
 logic a;
 always $display("MACRO_0 or MACRO_1 must be set for compilation");
 DEFINE_MACRO0_OR_MACRO1 dummy (.in(a));
`endif

this will generate the following elaboration message:

$display output: MACRO_0 or MACRO_1 must be set for compilation
...
Information: Building the design 'DEFINE_MACRO0_OR_MACRO1'. (HDL-193)
Warning: Cannot find the design 'DEFINE_MACRO0_OR_MACRO1' in the library 'WORK'. (LBR-1)
Warning: Unable to resolve reference 'DEFINE_MACRO0_OR_MACRO1' in 'TEST'. (LINK-5)
0
like image 134
Ari Avatar answered Nov 19 '22 20:11

Ari


$fatal is also an elaboration task added in IEEE Std 1800-2009 in section 20.10. See IEEE Std 1800-2012 § 20.11 Elaboration system tasks. It can be used inside an generate block. The follow should work if the simulator is *09+ complaint.

...
`else
//inferred generate block
if (0) $fatal(1,"MACRO_0 or MACRO_1 must be set for compilation");
`endif

I tried it out on edaplaygrond but it looks like ModelSim10.1d does not support it. In the mean time, like others have suggested, you can do the following:

...
`else
CAUSE_ELAB_ERR fatal("MACRO_0 or MACRO_1 must be set for compilation");
`endif
like image 20
Greg Avatar answered Nov 19 '22 21:11

Greg