It isn't hard to agree that parametrized module design is a good practice and data width is a good starting point.
I have been defining constants 0 and 1 of required bus or operand widths for years. That to avoid compiler warnings and to explicitly communicate the intention. Typically using something like:
parameter WIDTH = 16; // ... parameter ZERO = {WIDTH{1'b0}}; // all zeroes parameter UNO = {{WIDTH-1{1'b0}}, 1'b1}; // all zeroes except LSB This is all fine until I want to define an arbitrary constant with given parametrized WIDTH. I certainly can write a constant with fixed width - but that's not what I want:
parameter FULL = 16'd57; However, analogous construct using the parametric WIDTH fails with syntax error:
parameter LEVEL = WIDTH'd57; // <== *ERROR* What is the proper syntax - if there is one?
1 Answer
This was a problem in Verilog because the RHS of a parameter assignment was used as the self-determined width of the parameter. SystemVerilog addressed this by allowing you to specify a datatype as part of a parameter declaration
parameter WIDTH = 16; // ... parameter bit [WIDTH-1:0] ZERO = '0; // all zeroes parameter bit [WIDTH-1:0] UNO = 1; // all zeroes except LSB parameter bit [WIDTH-1:0] LEVEL = 57; The datatype does not change when overriding.
Another way is using a sizing cast
parameter LEVEL = WIDTH'(56);
But if you do it this way and override the parameter, the datatype becomes the width of the overriding value's type.
2