Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify Parameters in Verilog

I have created a module which accepts a single parameter specifying the byte width of the module's data lines. It looks something like:

module wrapper#
(
    parameter DATA_BYTE_WIDTH = 1
)
( 
    din, dout, ..
);
    localparam DATA_BIT_WIDTH = 8*DATA_BYTE_WIDTH;
    input [DATA_BIT_WIDTH-1:0] din;
    output [DATA_BIT_WIDTH-1:0] dout;
    .....
    generate
        if( DATA_BYTE_WIDTH == 1 ) begin
            // Various modules and interconnects for 1-byte data
        else if( DATA_BYTE_WIDTH == 2) begin
            // Various modules and interconnects for 2-byte data
        else if....
            // and so on, for 4, 8, and 16
        else 
           // DATA_BYTE_WIDTH is not a valid value
           // HERE is where I want to throw an error
        end
    endgenerate

    // other code

endmodule

The problem is that the only valid widths are 1, 2, 4, 8 or 16 bytes. If any other value is used for DATA_BYTE_WIDTH, the interconnects will not be generated at all. But Xilinx doesn't seem to care about that. It will happily "generate" nothing if an invalid value is supplied: the resulting design synthesizes but simply does not work.

Is there a way to check the value of a parameter and throw an error if it is invalid? I've tried $error and assert (as discussed here), as well as $display (as mentioned here). Xilinx refuses to use any of these functions, instead throwing syntax errors and refusing to continiue.

Ideally, I'd like something to throw in the final else within the generate, but I'll settle for pretty much anything at this point.

like image 755
Chris Avatar asked Sep 28 '22 04:09

Chris


1 Answers

Verilog does not have a clean solution to validate parameters. At least one is never mentioned in any version of the IEEE Std 1364. The best Verilog only work around is to use a nonexistent module.

generate
  // ...
  else begin // invalid parameter configuration
    nonexistent_module_to_throw_a_custom_error_message_for invalid_parameters();
  end
endgenerate

A false alternative is to replace the nonexistent module line with:

initial begin
  $display("Runtime error for invalid parameter value %b",DATA_BYTE_WIDTH);
  $finish(1);
end

This is a false alternative because most synthesis tools ignore $display (I believe they ignore $finish as well). You also will not know there is a parameter issue until simulation, after compile. The nonexistent module is superior because it is a syntax clean parameter conditional compiling error. It only lacks message showing the value of offending parameter.

A clean solution does exist in SystemVerilog as of IEEE Std 1800-2009 which adding elaboration system tasks. It looks like Xilinx ISE does not support SystemVerilog. Xilinx Vivado does but I'm not sure if it is fully complaint with the the LRM. Try it out if you can. Read the full description in IEEE Std 1800-2012 § 20.11 Elaboration system tasks. (*-2012 is free to download as an effort to promote SV adoption. *-2009 is older and still behind a pay-wall. The section on elaboration system tasks is verbatim between the two versions.)

generate
  // ...
  else begin // invalid parameter configuration
    $error("Elaboration error for invalid parameter value %b in", DATA_BYTE_WIDTH);

    /* alternative $fatal. This prevents further elaboration from 
       happening. $error allows the rest of the design to elaborate.
       Both block simulation. */
    //$fatal(1,"Fatal elab. error for invalid parameter value %b in", DATA_BYTE_WIDTH);
  end
endgenerate
like image 162
Greg Avatar answered Oct 06 '22 01:10

Greg