verilogvlsi

how to declare integer variable in verilog to keep track of a value to be used in multiple for loops?


so I have this assignment to make a generic Wallace tree multiplier in Verilog, I wrote the code but didn't test it yet. my problem is in the 2nd stage where I am supposed to bypass some wires which couldn't fit in the current stage into the next stage and the results of the current stages are passed to next stage, so I made a simple for loop to that operation:

/*the logic in this module*/
generate
    for(i = 0; i < size/3; i = i + 1)
    begin
        
        integer k = 0;

        for(j = i; j < size-3; j = j + 3)
        begin
            CSAlike #(2 * size) parallelAdder(intermediateWires[k][i+1], intermediateWires[k+1][i+1], intermediateWires[j][i], intermediateWires[j+1][i], intermediateWires[j+2][i]); 
            k = k + 2;
        end

        /*assign the wires from this stage who couldn't fit into the current stage (0 or 1 or 2 wires)*/
        for(l = size-(size%3); l < size; l = l + 1)
        begin
            assign intermediateWires[k][i+1] = intermediateWires[l][i];
            k = k + 1;
        end

    end
endgenerate

well , ModelSim give me this error :

vlog -work work -stats=none {D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before           synthesis)/verilog codes/multiplierTree.v}
Model Technology ModelSim - Intel FPGA Edition vlog 2020.1 Compiler 2020.02 Feb 28 2020
-- Compiling module multiplierTree
** Warning: D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before synthesis)/verilog codes/multiplierTree.v(17): (vlog-2417) Multiple packed dimensions are not allowed.
-- Compiling module multiplyAllBits
** Warning: D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before synthesis)/verilog codes/multiplierTree.v(46): (vlog-2417) Multiple packed dimensions are not allowed.
-- Compiling module addIntermedaiteWires
** Warning: D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before synthesis)/verilog codes/multiplierTree.v(61): (vlog-2417) Multiple packed dimensions are not allowed.
** Warning: D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before synthesis)/verilog codes/multiplierTree.v(67): (vlog-2417) Multiple packed dimensions are not allowed.
** Error: (vlog-13069) D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before synthesis)/verilog codes/multiplierTree.v(92): near "=": syntax error, unexpected '='.
** Error: D:/PROJECTS/third year/first term/VLSI/mini project 2/codes (before synthesis)/verilog codes/multiplierTree.v(92): (vlog-13205) Syntax error found in the scope following 'k'. Is there a missing '::'?

and this is the full code:

/*resources :   
    https://www.youtube.com/watch?v=4-l_PGPog9o
    https://www.youtube.com/watch?v=lcPIMvI57dM
*/
module multiplierTree #(parameter size = 32) (Res, OVF, A, B, clk);

/*the inputs to be multiplies*/
input [size-1:0] A, B;
input clk;
reg [size-1:0] A_in, B_in;

/*the outputs from the multiplier*/
output reg [(size-1)*2:0] Res;
output wire OVF;        // overflow flag 

/*intermediate wires for clean code*/
wire [size-1:0][(size-1)*2:0] wiresMultiplied;
wire [(size-1)*2:0] secondStage_Res, secondStage_carry, totalRes; 


/*calling necessary modules*/
multiplyAllBits #(size) firstStage(wiresMultiplied, A_in, B_in);
addIntermedaiteWires #(size) secondStage(secondStage_Res, secondStage_carry, wiresMultiplied);
addResWithCarry #(2 * size) thirdStage(totalRes, secondStage_Res, secondStage_carry);

/*important assigns*/
assign OVF = Res[(size-1)*2] ^ A[size-1] & Res[(size-1)*2] ^ B[size-1] ;

/*the logic of the module*/
always@(posedge clk)
begin
    A_in <= A;
    B_in <= B;
    Res <= totalRes;
end

endmodule

/*this is the first stage in the wallace tree*/
module multiplyAllBits #(parameter size = 32) (wiresMultiplied, A, B);

/*inputs to 1st stage of wallace tree*/
input wire [size-1:0] A, B;

/*outputs from the 1st stage*/
output wire [size-1:0][(size-1)*2:0] wiresMultiplied;

/*the actual logic in the circuit*/
genvar i, j;
generate
    for(i = 0; i < size; i = i + 1)
        assign wiresMultiplied[i] = ({size{B[i]}} & A) << i;
endgenerate

endmodule

/*this is the second stage in wallace tree*/
module addIntermedaiteWires #(parameter size = 32) (Res, carry, wiresMultiplied);

/*inputs coming from the 1st stage*/
input wire [size-1:0][(size-1)*2:0] wiresMultiplied;

/*outputs from 2nd stage*/
output wire [(size-1)*2:0] Res, carry;

/*intermediate wires for clean code*/
wire [size+1:0][size+1:0][(size-1)*2:0] intermediateWires;
genvar i, j, l;

/*important assigns*/
generate
    for(i = 0; i < size; i = i + 1)
    begin
        assign intermediateWires[i][0] = wiresMultiplied[i];
    end
endgenerate

/*getting the results*/
assign Res = intermediateWires[size+1][size+1];
assign calling = intermediateWires[size+1][size+1];

/*the logic in this module*/
generate
    for(i = 0; i < size/3; i = i + 1)
    begin
        
        integer k = 0;

        for(j = i; j < size-3; j = j + 3)
        begin
            CSAlike #(2 * size) parallelAdder(intermediateWires[k][i+1], intermediateWires[k+1][i+1], intermediateWires[j][i], intermediateWires[j+1][i], intermediateWires[j+2][i]); 
            k = k + 2;
        end

        /*assign the wires from this stage who couldn't fit into the current stage (0 or 1 or 2 wires)*/
        for(l = size-(size%3); l < size; l = l + 1)
        begin
            assign intermediateWires[k][i+1] = intermediateWires[l][i];
            k = k + 1;
        end

    end
endgenerate

endmodule

/*this is CSA look like to add parallely*/
module CSAlike #(parameter size = 32) (result, carry, A, B, C);

/*list of the inputs*/
input wire [size-1:0] A, B, C;

/*outputs*/
output wire [size-1:0] result, carry;

/*temp genvar*/
genvar i;

/*actual logic of parallel adders*/
for(i = 0; i < size; i = i + 1)
begin
    FA fa(A[i], B[i], C[i], result[i], carry[i]);
end

endmodule


module addResWithCarry #(parameter size = 32) (Res_out, Res_in, carry_in);

/*list of the inputs*/
input wire [size-1:0] Res_in, carry_in;

/*outputs*/
output wire [size-1:0] Res_out;

/*using normar adder (verilog adder (adder plus))*/
assign Res_out = Res_in + carry_in;

endmodule

as it tells me that writing

k = k + 2;

is wrong inside the generate loop, but I don't know why, also it gave me some warnings telling me that writing

wire [size-1:0][(size-1)*2:0] wiresMultiplied;

has something wrong with it but IDK what's wrony with my code.


Solution

  • it tells me that writing

    k = k + 2;

    is wrong inside the generate loop, but I don't know why

    It is a syntax error to make that assignment where you do in the code. It is an error for the same reason as this extreme simplification of your code is an error:

    module dut;
        integer k = 0;
        k = k + 2;
    endmodule
    

    The integer declaration line is legal, but the other assignment line is illegal because it looks like you are trying to make a procedural assignment outside of a procedural block (like an always block).

    When debugging problems with generate loops, it's always helps to "unroll" the loop and start writing out the code the long way. These loops are advanced syntax constructs and are tricky to use. Especially nested loops. Especially for students who are just starting to learn Verilog.