Search code examples
parametersverilogsystem-verilog

Sizing a parameter value in an assignment of a reset value


The following code is correct as RESET_VAL is extended or truncated to WIDTH automagically:

parameter RESET_VAL = 5;
reg [WIDTH-1:0] data;

always @(posedge clk or negedge nres) begin
    if (!nres) begin
        data <= RESET_VAL;
    end
    ...

However, a synthesis tool is throwing a warning:

Width of left hand side 'data' [6] doesn't match the width of right hand side [32] in assignment

Can anyone help me with the correct syntax for sizing the parameter value?

I would like to pass parameters through hierarchy, specifying their (32-bit) value without having to dive into submodules for determining the correct size of the parameters.


Solution

  • The type of a parameter in Verilog/SV is inferred from its value.
    The post specifies an unsized number literal which is an integer in Verilog whose default is 32 bits.
    Change the number to be 6 bits this way, to form a size 6-bit decimal value of five:

    parameter RESET_VAL = 6'd5;  
    

    Example:

    module testbench ();
      
      parameter RESET_VAL = 6'd5;
      
      initial
        $display("RESET_VAL = %b",RESET_VAL);
      
    endmodule  
    

    Produces:

    RESET_VAL = 000101
    

    Alternate Answer: If you want to have a 32 bit parameter, and eliminate the warning at the assignment, use one of these:

    module testbench ();
      
      parameter RESET_VAL = 5;
      parameter WIDTH     = 6;
      
      initial begin
        $display("RESET_VAL = %b",WIDTH'(RESET_VAL));
        $display("RESET_VAL = %b",RESET_VAL[WIDTH - 1:0]);
      end
      
    endmodule    
    

    Referring to the alternate answer: Pass WIDTH in from the top of various modules to resize differently in different modules (answers the part of the question asked as additional question details in the comments).