for-loopindexingverilogbcd

Why does this error in indexing BCD adder appear?


I am not sure, what exactly the error is. I think, my indexing in the for-loop is not Verilog-compatible, but I might be wrong.

Is it allowed to index like this (a[(4*i)+3:4*i]) in a for-loop just like in C/C++?

Here is a piece of my code, so the for-loop would make more sense

module testing( 
    input [399:0] a, b,
    input cin,
    output reg cout,
    output reg [399:0] sum );
    
    // bcd needs 4 bits + 1-bit carry --> 5 bits [4:0]
    reg [4:0] temp_1;
    
    always @(*) begin
        for (int i = 0; i < 100; i++) begin
            if (i == 0) begin // taking care of cin so the rest of the loop works smoothly
                temp_1[4:0] = a[3:0] + b[3:0] + cin;
                sum[3:0]    = temp_1[3:0];
                cout        = temp_1[4];
            end
            else begin
                temp_1[4:0] = a[(4*i)+3:4*i] + b[(4*i)+3:4*i] + cout;
                sum[(4*i)+3:4*i] = temp_1[3:0];
                cout             = temp_1[4];
            end
        end
    end
    
    
endmodule

This might seem obvious. I'm doing the exercises from: HDLBits and got stuck on this one in particular for a long time (This solution isn't the one intended for the exercise).

Error messages Quartus:

Error (10734): Verilog HDL error at testing.v(46): i is not a constant File: ../testing.v Line: 46 Error (10734): Verilog HDL error at testing.v(47): i is not a constant File: ../testing.v Line: 47

But I tried the same way in indexing and got the same error


Solution

  • The error appears because Verilog does not allow variables at both indices of a part select (bus slice indexes). The most dynamic thing that can be done involves the indexed part select.
    Here is a related but not duplicate What is `+:` and `-:`? SO question.
    Variations of this question are common on SO and other programmable logic design forums.

    I took your example and used the -: operator rather than the : and changed the RHS of this to a constant. This version compiles.

    module testing( 
        input [399:0] a, b,
        input cin,
        output reg cout,
        output reg [399:0] sum );
        
        // bcd needs 4 bits + 1-bit carry --> 5 bits [4:0]
        reg [4:0] temp_1;
        
        always @(*) begin
            for (int i = 0; i < 100; i++) begin
                if (i == 0) begin // taking care of cin so the rest of the loop works smoothly
                    temp_1[4:0] = a[3:0] + b[3:0] + cin;
                    sum[3:0]    = temp_1[3:0];
                    cout        = temp_1[4];
                end
                else begin
                  temp_1[4:0]     = a[(4*i)+3-:4] + b[(4*i)+3-:4] + cout;
                  sum[(4*i)+3-:4] = temp_1[3:0];
                  cout            = temp_1[4];
                end
            end
        end
        
    endmodule    
    

    The code will not behave as you wanted it to using the indexed part select.
    You can use other operators that are more dynamic to create the behavior you need.
    For example shifting, and masking.
    Recommend you research what others have done, then ask again if it still is not clear.