Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Verilator width warnings

Status
Not open for further replies.

promach

Advanced Member level 4
Joined
Feb 22, 2016
Messages
1,199
Helped
2
Reputation
4
Reaction score
5
Trophy points
1,318
Activity points
11,636
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

 

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.
 


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

 

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?
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top