1

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

3
  • Please provide more details on the error message provided by Vivado. Commented May 30, 2020 at 11:11
  • and a minimal complete example we can test and verify. What you have posted is part of a module, which in turn instantiates another module which is not detailed here. Commented May 30, 2020 at 11:46
  • I also edited my code, the module1 is only a 5-bit modular multiplier. Commented May 30, 2020 at 12:21

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I totally agree with you, the synthesis cannot stop. I have no idea to calculate the index of pi_values with a pre-declared localparam depend on both i and cnt1 variable.
Thank you very much. It works. What do you think about a general method for larger ranges of pi_values and input?
The module, as it is now, is easy to modify for larger (as in number of bits) ranges. The tricky bit about it is when you have more ranges. In that case, the case statement must be modified to add new cases. I am not sure if that can be parametrized with a for-generate.
Follow your solution, I try to expand for larger parameter and input if it can synthesize or not. Thank you again for your help.
0

Notice here:

    else begin
        if (cnt1 == 3)
            cnt1 <= 0;
        else            
            cnt1 <= cnt1 + 1;
    end

It can be either 0, 1, 2 or 3. This works fine in simulation. But in synthesis, you are constantly changing the value of cnt1 while trying to build logic gates for mod1 where mod1 uses that changing variable cnt1. This is a conflict for synthesizing logic gates.

Synthesis can't build gates for your generate block as it is building actual hardware and wants to know a deterministic value of cnt1 in order to construct the gates accordingly.

I believe you need to develop an architecture that can handle the largest value of cnt1

2 Comments

Oh my mistake sorry will edit the post. The reasoning is similar to @mcleod_ideafix.
yes, my problem is caused by changing variable cnt1 in generate block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.