Search code examples
verilogvivadosynthesisgenerate

Verilog cannot synthesize when using external counter inside generate block


I cannot synthesize the Verilog code in Vivado, simulation runs correctly. I declare an array localparam, use an external counting variable cnt1 inside a generate block to get the desired address for parameter. When I remove the cnt1 variable inside module1, it could be synthesized. Please guys give me some suggestion to solve this problem. I really appreciate that.

module multiply_s1(
input clk,
input rst,
input [9:0]in,
input ena,

output [9:0]out);

localparam [0:24] pi_values = {5'h4, 5'h5, 5'h6, 5'h7, 5'h8};
reg [1:0] cnt1;//count CC times of GG coeffcient

always@(posedge clk or negedge rst) begin
    if(rst == 0) begin
        cnt1 <= 0;
    end
    else if(ena == 0) begin
        cnt1 <= 0;
    end
    else begin
        if (cnt1 == 3)
            cnt1 <= 0;
        else            
            cnt1 <= cnt1 + 1;
    end
end

genvar i; 
generate
    for (i=0; i<2; i=i+1) 
    begin: mod1          
        module1 mod1(.clk(clk),
                     .rst(rst),
                     .multiplier(in[i*5 +: 5]),
                     .multiplicand(pi_values[(i + cnt1)*5 +: 5]),                        
                     .result(out[i*5 +: 5]));    
   end 
endgenerate

endmodule


Solution

  • Without knowing what Vivado told you, I guess the error may be here:

    [(i + cnt1)*5 +: 5]
    

    cnt1 is a register whose value is only known at "runtime", therefore, Vivado cannot know which value to use to bitslicing the pi_values vector.

    You would need something like this:

    localparam [0:24] pi_values = {5'h4, 5'h5, 5'h6, 5'h7, 5'h8};
    reg [1:0] cnt1;//count CC times of GG coeffcient
    
    always@(posedge clk or negedge rst) begin
        if(rst == 0)
            cnt1 <= 0;
        else if(ena == 0)
            cnt1 <= 0;
        else
            cnt1 <= cnt1 + 1;
    end
    
    reg [0:24] pi_values_rotated;
    always @* begin
      case (cnt1)
        0: pi_values_rotated = pi_values;
        1: pi_values_rotated = {pi_values[5:24], pi_values[0:4]};
        2: pi_values_rotated = {pi_values[10:24], pi_values[0:9]};
        3: pi_values_rotated = {pi_values[15:24], pi_values[0:14]};
        default: pi_values_rotated = pi_values;
      endcase
    end
    
    genvar i; 
    generate
        for (i=0; i<2; i=i+1) 
        begin: mod1          
            module1 mod1(.clk(clk),
                         .rst(rst),
                         .multiplier(in[i]),
                         .multiplicand(pi_values_rotated[i*5 +: 5]),
                         .result(out[i]));
       end 
    endgenerate
    

    pi_values_rotated would be the pi_values vector, as seen after the current value of cnt1 is applied. Then, you can use i as the sole value to generate your instances, which should be accepted now.