+ Post New Thread
Results 1 to 4 of 4
  1. #1
    Advanced Member level 2
    Points: 3,588, Level: 14

    Join Date
    Feb 2016
    Posts
    686
    Helped
    1 / 1
    Points
    3,588
    Level
    14

    Verilator width warnings

    Could anyone advise about the verilator width warnings below ?

    verilator -Wall --lint-only in_buf_load.v
    %Warning-WIDTH: in_buf_load.v:35: Operator ADD expects 12 bits on the LHS, but LHS's VARREF 'idx_n' generates 9 bits.
    %Warning-WIDTH: Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.
    %Warning-WIDTH: in_buf_load.v:35: Operator ADD expects 12 bits on the RHS, but RHS's VARREF 'idx_k' generates 9 bits.
    %Warning-WIDTH: in_buf_load.v:35: Operator ASSIGNW expects 7 bits on the Assign RHS, but Assign RHS's ADD generates 12 bits.
    %Warning-WIDTH: in_buf_load.v:51: Operator LT expects 32 or 3 bits on the LHS, but LHS's VARREF 'index_i' generates 2 bits.
    %Warning-WIDTH: in_buf_load.v:73: Operator ADD expects 32 or 12 bits on the LHS, but LHS's SEL generates 8 bits.
    %Warning-WIDTH: in_buf_load.v:73: Operator ADD expects 32 or 12 bits on the RHS, but RHS's VARREF 'index_j' generates 4 bits.
    %Warning-WIDTH: in_buf_load.v:88: Operator ADD expects 32 or 9 bits on the RHS, but RHS's VARREF 'index_k' generates 4 bits.
    %Error: Exiting due to 7 warning(s)
    %Error: Command Failed /usr/bin/verilator_bin -Wall --lint-only in_buf_load.v
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    
    module in_buf_load(clk, reset, buf_address); // generates DDR address for the AWS guy code
     
    localparam MAX_J = 10;
    localparam MAX_K = 10;
    localparam GIGA = (1 << 9); // 10^9
    localparam BITS_PER_BYTE = 8;
    localparam NUM_OF_BITS_IN_TWO_GIGABYTE = (GIGA << 1)*BITS_PER_BYTE;
     
    parameter BUFFER_WIDTH = 16;
    parameter DATA_WIDTH = 4*BUFFER_WIDTH; // ap_uint<64> *i_data which contains 4 different 16-bit data
     
    // 2 Gigabyte of data, each contiguous chunk of data is 64-bit
    parameter NUM_OF_DATA_ENTRIES = NUM_OF_BITS_IN_TWO_GIGABYTE/DATA_WIDTH; 
     
    parameter N = 4; // number of input feature maps
    parameter n = 1; // input feature map index (just to identify map)
    parameter Tn = 4; // number of tiles for input feature maps (divide and conquer due to resource limits)
    parameter r = 256; // FEATURE_SIZE_WIDTH
    parameter c = 256; // FEATURE_SIZE_HEIGHT
     
    parameter IDX_N_WIDTH = ($clog2(N*100));
    parameter IDX_R_WIDTH = ($clog2((r+MAX_J)*10));
    parameter IDX_K_WIDTH = ($clog2(c+MAX_K));
     
    parameter Tn_WIDTH = $clog2(Tn);
    parameter r_WIDTH = $clog2(r);
     
    input clk, reset;
    output [$clog2(NUM_OF_DATA_ENTRIES)-1:0] buf_address;
     
    //wire signed [DATA_WIDTH-1:0] local_i_buf [N-1:0][MAX_J-1:0][MAX_K-1:0];
     
    //assign local_i_buf = ;
     
    assign buf_address = idx_n + idx_r + idx_k;
     
    // used for generating address indexes
     
    reg [IDX_N_WIDTH-1:0] idx_n;
    reg [IDX_R_WIDTH-1:0] idx_r;
    reg [IDX_K_WIDTH-1:0] idx_k;
     
    reg [$clog2(N)-1:0] index_i;
    reg [$clog2(10)-1:0] index_j;
    reg [$clog2(10)-1:0] index_k;
     
    always @(posedge clk)
    begin
        if(reset) index_i <= n;
     
        else if(index_i < N) index_i <= index_i + Tn[0 +: Tn_WIDTH];
    end
     
    always @(posedge clk)
    begin
        if(reset) idx_n <= n*100;
     
        else idx_n <= index_i * 100;
    end
     
     
    always @(posedge clk)
    begin
        if(reset) index_j <= 0;
     
        else if(index_j < 10) index_j <= index_j + 1;
    end
     
    always @(posedge clk)
    begin
        if(reset) idx_r <= (r + 0) * 10;
     
        else idx_r <= (r[0 +: r_WIDTH] + index_j) * 10;
    end
     
     
    always @(posedge clk)
    begin
        if(reset) index_k <= 0;
     
        else if(index_k < 10) index_k <= index_k + 1;
    end
     
    always @(posedge clk)
    begin
        if(reset) idx_k <= c + 0;
     
        else idx_k <= c + index_k;
    end
     
     
    `ifdef FORMAL
     
    initial assert(reset);
     
    reg first_clock_had_passed = 0;
     
    always @(posedge clk) first_clock_had_passed <= 1;
     
    always @(posedge clk) if(first_clock_had_passed) cover($past(reset) && buf_address != 0);
     
    `endif
     
    endmodule

    •   AltAdvertisement

        
       

  2. #2
    Super Moderator
    Points: 31,935, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,393
    Helped
    1733 / 1733
    Points
    31,935
    Level
    43

    Re: Verilator width warnings

    Verilator doesn't seem to adhere to the Verilog's rules on padding that most Verilog simulators do. You will have to perform all the padding with 0's that are required to ensure the bit widths are correct for the assignment. You will also have to get rid of all the integers (32-bit) you are using for adding/comparing/assigning and explicitly declare the width of the values.

    Maybe there is a way to change the behavior of warnings into actual warnings and not errors that make the program exit.

    I also don't get how this even compiles as the declaration of the idx_* comes after the assign that uses them.



    •   AltAdvertisement

        
       

  3. #3
    Advanced Member level 2
    Points: 3,588, Level: 14

    Join Date
    Feb 2016
    Posts
    686
    Helped
    1 / 1
    Points
    3,588
    Level
    14

    Re: Verilator width warnings

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    parameter DDR_ADDR_BITWIDTH = $clog2(NUM_OF_DATA_ENTRIES);
     
    input clk, reset;
     
    output [DDR_ADDR_BITWIDTH-1:0] buf_address;
     
    assign buf_address = {{(DDR_ADDR_BITWIDTH-IDX_N_WIDTH){1'b0}}, idx_n} +
     
    {{(DDR_ADDR_BITWIDTH-IDX_R_WIDTH){1'b0}}, idx_r} +
     
    {{(DDR_ADDR_BITWIDTH-IDX_K_WIDTH){1'b0}}, idx_k};


    If I use the above code segments, verilator give me %Warning-WIDTHCONCAT: in_buf_load.v:34: More than a 8k bit replication is probably wrong: 4294967294


    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    
    module in_buf_load(clk, reset, buf_address); // generates DDR address for the AWS guy code
     
    localparam MAX_J = 10;
    localparam MAX_K = 10;
    localparam GIGA = (1 << 9); // 10^9
    localparam BITS_PER_BYTE = 8;
    localparam NUM_OF_BITS_IN_TWO_GIGABYTE = (GIGA << 1)*BITS_PER_BYTE;
     
    parameter BUFFER_WIDTH = 16;
    parameter DATA_WIDTH = 4*BUFFER_WIDTH; // ap_uint<64> *i_data which contains 4 different 16-bit data
     
    // 2 Gigabyte of data, each contiguous chunk of data is 64-bit
    parameter NUM_OF_DATA_ENTRIES = NUM_OF_BITS_IN_TWO_GIGABYTE/DATA_WIDTH; 
     
    parameter N = 4; // number of input feature maps
    parameter n = 1; // input feature map index (just to identify map)
    parameter Tn = 4; // number of tiles for input feature maps (divide and conquer due to resource limits)
    parameter r = 256; // FEATURE_SIZE_WIDTH
    parameter c = 256; // FEATURE_SIZE_HEIGHT
     
    parameter IDX_N_WIDTH = ($clog2(N*100));
    parameter IDX_R_WIDTH = ($clog2((r+MAX_J)*10));
    parameter IDX_K_WIDTH = ($clog2(c+MAX_K));
     
    parameter Tn_WIDTH = $clog2(Tn);
    parameter r_WIDTH = $clog2(r);
     
    parameter DDR_ADDR_BITWIDTH = $clog2(NUM_OF_DATA_ENTRIES);
     
    input clk, reset;
    output [DDR_ADDR_BITWIDTH-1:0] buf_address;
     
     
    assign buf_address = {{(DDR_ADDR_BITWIDTH-IDX_N_WIDTH){1'b0}}, idx_n} + 
                         {{(DDR_ADDR_BITWIDTH-IDX_R_WIDTH){1'b0}}, idx_r} + 
                         {{(DDR_ADDR_BITWIDTH-IDX_K_WIDTH){1'b0}}, idx_k};
     
    // used for generating address indexes
     
    reg [IDX_N_WIDTH-1:0] idx_n;
    reg [IDX_R_WIDTH-1:0] idx_r;
    reg [IDX_K_WIDTH-1:0] idx_k;
     
    reg [$clog2(N):0] index_i;
    reg [$clog2(10)-1:0] index_j;
    reg [$clog2(10)-1:0] index_k;
     
    always @(posedge clk)
    begin
        if(reset) index_i <= n;
     
        else if(index_i < N) index_i <= index_i + Tn;
    end
     
    always @(posedge clk)
    begin
        if(reset) idx_n <= n*100;
     
        else idx_n <= index_i * 100;
    end
     
     
    always @(posedge clk)
    begin
        if(reset) index_j <= 0;
     
        else if(index_j < MAX_J) index_j <= index_j + 1;
    end
     
    always @(posedge clk)
    begin
        if(reset) idx_r <= (r + 0) * 10;
     
        else idx_r <= (r + index_j) * 10;
    end
     
     
    always @(posedge clk)
    begin
        if(reset) index_k <= 0;
     
        else if(index_k < MAX_K) index_k <= index_k + 1;
    end
     
    always @(posedge clk)
    begin
        if(reset) idx_k <= c + 0;
     
        else idx_k <= c + index_k;
    end
     
     
    `ifdef FORMAL
     
    initial assert(reset);
     
    reg first_clock_had_passed = 0;
     
    always @(posedge clk) first_clock_had_passed <= 1;
     
    always @(posedge clk) if(first_clock_had_passed) cover($past(reset) && buf_address != 0);
     
    `endif
     
    endmodule



    •   AltAdvertisement

        
       

  4. #4
    Super Moderator
    Points: 31,935, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,393
    Helped
    1733 / 1733
    Points
    31,935
    Level
    43

    Re: Verilator width warnings

    Modelsim errors on your code due to issues with using a variable before it's declared.

    Move the assignment to buf_address below the declarations for idx_n, idx_r, and idx_k. A compliant Verilog compiler will create 1-bit wide signals for idx_n, idx_r, and idx_k when they are found on the RHS of the assignment for buf_address (unless you've added `default_nettype none to the top of your code, which it will then issue an error, though I kind of doubt that will even work with Verilator). Once a compliant Verilog compiler has created these single bit idx_* then it finds the declared versions and errors with this:
    Code:
    ** Error: in_buf_load.v(34): (vlog-2730) Undefined variable: 'idx_n'.
    ** Error: in_buf_load.v(35): (vlog-2730) Undefined variable: 'idx_r'.
    ** Error: in_buf_load.v(36): (vlog-2730) Undefined variable: 'idx_k'.
    ** Error (suppressible): in_buf_load.v(40): (vlog-2388) 'idx_n' already declared in this scope (in_buf_load).
    ** Error (suppressible): in_buf_load.v(41): (vlog-2388) 'idx_r' already declared in this scope (in_buf_load).
    ** Error (suppressible): in_buf_load.v(42): (vlog-2388) 'idx_k' already declared in this scope (in_buf_load).
    A good rule of thumb is to have all reg, wire, parameter, and localparam declarations before any code that does any assignments. Code that actually implements the design (assign, always, etc) should be after all the declarations.

    Once that above error is fixed Modelsim reports this
    Code:
    # ** Error (suppressible): (vsim-8607) in_buf_load.v(44): Negative replication multiplier (-2).
    #    Time: 0 ns  Iteration: 0  Instance: /in_buf_load File: in_buf_load.v
    # ** Error (suppressible): (vsim-8607) in_buf_load.v(45): Negative replication multiplier (-5).
    #    Time: 0 ns  Iteration: 0  Instance: /in_buf_load File: in_buf_load.v
    # ** Error (suppressible): (vsim-8607) in_buf_load.v(46): Negative replication multiplier (-2).
    #    Time: 0 ns  Iteration: 0  Instance: /in_buf_load File: in_buf_load.v
    which makes sense as your idx_* bus widths were larger than the buf_address width from what I remember when compiling your original version of the code. Did you ever actually figure out the bit widths of everything to make sure the assignments were not requiring truncation too?


    1 members found this post helpful.

--[[ ]]--