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.
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