Search code examples
veriloghdl

What is a LINT/synthesis safe statement to throw an error at compile time?


I have a module that is passed a parameter then instantiates another module corresponding to the defined parameter.

However, in the event that a case isn't defined for a certain combination of parameters, I would like an error to be thrown at compile time to highlight the problem, like so:

generate
if (PARAM1 == 1 && PARAM2 == 2) begin

   // instantiate module logic_A

end else if (PARAM1 == 2 && PARAM2 == 1) begin              

   // instantiate module logic_B

end else begin

   // throw an error at compile time if we haven't
   // defined a case for those parameters 

end
endgenerate

However, this code still needs to be synthesizable (in Verilog, not SystemVerilog) and pass LINTing, despite the inserted error.

Does anyone know what I could use in this situation? Thank you in advance.


Solution

  • I answered very similar question on the sister site, Electronics StackExchange, for "a way of conditionally triggering a compile-time error in verilog." The solution is to conditional an instantiate an modules that does not exist. I recommend the non-existing module have a very long name and meaningful name the explains the error. This also reduces the risk of the non-existing modules accidentally having the same name as an existing module.

    generate
    if (PARAM1 == 1 && PARAM2 == 2) begin : use_logicA
       // instantiate module logic_A
    end
    else if (PARAM1 == 2 && PARAM2 == 1) begin : use_logicB
       // instantiate module logic_B
    end
    else begin : illegal
       illegal_parameter_condition_triggered_will_instantiate_an non_existing_module();
    end
    endgenerate
    

    This works because checking the existence of the non-existing-module isn't done until after the parameter values are evaluated during the elaboration stage.


    The better solution would be to use the SystemVerilog approach; specifically with a simulator complement with the IEEE Std 1800-2009 standard or newer. Then you can use $error() and give a more meaningful message to go with the error (For example, print the parameter values that triggered the error condition). You can read more about it in IEEE Std 1800-2012 20.11 Elaboration system tasks

    generate
    if (PARAM1 == 1 && PARAM2 == 2) begin : use_logicA
       // instantiate module logic_A
    end
    else if (PARAM1 == 2 && PARAM2 == 1) begin : use_logicB
       // instantiate module logic_B
    end
    else begin : illegal
       $error("Expected PRAM1/2 to be 1/2 or 2/1, but was %0d/%0d", PARAM1, PARAM2 );
    end
    endgenerate