verilogsystem-verilog

How to reuse the genvar in Verilog?


This question was raised when I tried to create a left shifter in gate level, using verilog. the requirement is to come up with a shifter, that

I use multiplexers to help me do the shifting. Here's the schematic of the mux I'm using, it's a screenshot from a video of my Professor Kaushik Patra https://www.youtube.com/watch?v=-uDFf6bef_U&ab_channel=KaushikPatra%27sSJSUClassroom module's name: MUX1_2x1

Here's a demonstration from Dr.Patra of a shifter supporting a 2 bits shift amount "S0" being the first bit of the shift amount, if the value of the shift amount bit is 1 then we perform the shift at that "stage" (i.e so a four-bit shifter have 4 stages, that "S0",the first shift bit is "stage 1" shift, which shifts 2^0 (1bit) if shifted "S1" the second shift bit is "stage 2" shift, which shifts 2^1 (2bits) if shifted third shift bit is "stage 3" shift, which shifts 2^2 (4bits) forth shift bit is "stage 4" shift, which shifts 2^3 (8bits), so on and so forth)

2 bit left shifter scheme

so, as I was doing the assignment, I want to reuse the genvar that I declared in my generation block

//port list of MUX1_2x1: (Y,I0, I1, S)
// Y: output, I0, I1: input, S: control signal
// st1_result is a wire
//D[] is input of the shifter
//I0 is not shift, I1 is shift
genvar i; //for normal shifting bits
genvar j; //for zero filling bits
generate
    begin: first_stage_shift //shift amount = 1
        // first bit
        MUX1_2x1 inst_0(st1_result[0], D[0], 1'b0, S[0]);
        
        for (i = 1; i<32; i = i+1)
            MUX1_2x1 inst_1(st1_result[i], D[i], D[i-1], S[0]);
    end
// this is the line that has error (81)
    i=0; //reset the genvar
    begin: second_stage_shift //shift amount = 2
        // first bit 
        MUX1_2x1 inst_0(st2_result[0], St1_result[0], 1'b0, S[1]);
        // second bit 
        MUX1_2x1 inst_1(st2_result[1], St1_result[1], 1'b0, S[1]);
        
        for (i = 2; i<32; i = i+1)
            MUX1_2x1 inst_1(st2_result[i], st1_result[i], st1_result[i-2], S[1]);
    end

as in the screenshot, I want to reset the genvar by writing i=0, so that I can use it in the next for loop, however, I get this error at line 81:

** Error: (vlog-13069) D:/barrel_shifter.v(81): near "=": syntax error, unexpected '='.
** Error: D:/barrel_shifter.v(81): (vlog-13205) Syntax error found in the scope following 'i'. Is there a missing '::'?

I search on the web a bit, but I didn't find what what i was looking for. Is it possible to reuse/reset the genvar in verilog, instead of declaring multiple genvars?


Solution

  • Generate statements are not procedural code. Generate-for loops get unrolled and the i gets replaced with a constant.

    You only need multiple genvar declarations if you plan to nest the for loops, which is not the case here. You can also put the genvar declaration as part of the for loop.

    MUX1_2x1 inst_0(st1_result[0], D[0], 1'b0, S[0]);     
    for (genvar i = 1; i<32; i = i+1) begin : first_loop
                MUX1_2x1 inst_1(st1_result[i], D[i], D[i-1], S[0]);
    end
    
    MUX1_2x1 inst_0(st2_result[0], St1_result[0], 1'b0, S[1]);
    MUX1_2x1 inst_1(st2_result[1], St1_result[1], 1'b0, S[1]);
    for (genvar i = 2; i<32; i = i+1) begin : second_loop
       MUX1_2x1 inst_1(st2_result[i], st1_result[i], st1_result[i-2], S[1]);
    end
    

    If you need a value that is a based on the loop variable, declare a parameter.

    for (genvar i = 2; i<32; i = i+1) begin : second_loop
       parameter i_minus_2 = i-2; // could be a function call too
       MUX1_2x1 inst_1(st2_result[i], st1_result[i], st1_result[i_minus_2], S[1]);
    end