在生成块内使用外部计数器时 Verilog 无法综合
Verilog cannot synthesize when using external counter inside generate block
我无法在 Vivado 中综合 Verilog 代码,仿真运行正常。我声明了一个数组 localparam,在生成块中使用外部计数变量 cnt1 来获取所需的参数地址。当我去掉module1里面的cnt1变量时,就可以合成了。请大家给我一些建议来解决这个问题。非常感谢。
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
结束模块
这里注意:
else begin
if (cnt1 == 3)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
它可以是 0
、1
、2
或 3
。这在模拟中效果很好。但在综合中,您在尝试为 mod1
构建逻辑门时不断更改 cnt1
的值,其中 mod1
使用该变化的变量 cnt1
。这是合成逻辑门的冲突。
Synthesis 无法为您的生成块构建门,因为它正在构建实际硬件并想知道 cnt1
的确定性值以便相应地构建门。
我相信你需要开发一个架构来处理 cnt1
的最大值
不知道Vivado告诉你什么,我猜错误可能在这里:
[(i + cnt1)*5 +: 5]
cnt1 是一个寄存器,其值仅在 "runtime" 处已知,因此,Vivado 无法知道使用哪个值来对 pi_values 向量进行位分片。
你需要这样的东西:
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
将是 pi_values
向量,如应用 cnt1
当前值后所见。然后,您可以使用 i
作为唯一值来生成您的实例,现在应该可以接受了。
我无法在 Vivado 中综合 Verilog 代码,仿真运行正常。我声明了一个数组 localparam,在生成块中使用外部计数变量 cnt1 来获取所需的参数地址。当我去掉module1里面的cnt1变量时,就可以合成了。请大家给我一些建议来解决这个问题。非常感谢。
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
结束模块
这里注意:
else begin
if (cnt1 == 3)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
它可以是 0
、1
、2
或 3
。这在模拟中效果很好。但在综合中,您在尝试为 mod1
构建逻辑门时不断更改 cnt1
的值,其中 mod1
使用该变化的变量 cnt1
。这是合成逻辑门的冲突。
Synthesis 无法为您的生成块构建门,因为它正在构建实际硬件并想知道 cnt1
的确定性值以便相应地构建门。
我相信你需要开发一个架构来处理 cnt1
不知道Vivado告诉你什么,我猜错误可能在这里:
[(i + cnt1)*5 +: 5]
cnt1 是一个寄存器,其值仅在 "runtime" 处已知,因此,Vivado 无法知道使用哪个值来对 pi_values 向量进行位分片。
你需要这样的东西:
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
将是 pi_values
向量,如应用 cnt1
当前值后所见。然后,您可以使用 i
作为唯一值来生成您的实例,现在应该可以接受了。