合成中超出循环迭代限制,但仿真中未超出
Loop iteration limit exceeded in synthesis but not in simulation
我用 verilog 编写了循环通过活动通道的代码。
这个想法是跳过 activity 向量中标记为 0 的通道。
我在模拟器中测试了代码
screen shot from simulatior,它按预期工作和执行。
当我尝试使用 Synplify Pro 综合代码时,出现错误:
"E CS162 Loop iteration limit 4000 exceeded - add '// synthesis loop_limit 8000' before the loop construct test1.v (11)"
错误指向循环条件(i < 6'b100000
)。
在 google 中搜索错误 我发现类似代码中的一个常见错误是 i
与 channel
的长度相同,这使得循环成为 运行不确定,因为 11111 + 1 = 00000
.
此外,Xilinx 软件中存在一些错误,但我没有使用它。
知道为什么我会收到此错误或它与模拟不同的原因吗?
有没有办法不用循环实现这个功能?
这是代码:
module test1 (
input wire [31:0] activity,
input wire RESET,
input wire CLK);
reg [4:0] channel, next_channel;
reg [5:0] i,j;
always @(activity, channel) begin
next_channel = 5'b0;
for (i = 6'b0; i < 6'b100000 ; i = i + 6'b1) begin
j = i + {1'b0, channel} + 6'b1;
if (j>6'b011111)
j = j - 6'b100000;
if (activity[j[4:0]]) begin
next_channel = j[4:0];
i = 6'b101111;
end
end
end
always @(posedge CLK, negedge RESET) begin
if (RESET == 1'b0)
channel = 5'b0;
else
channel = next_channel;
end
endmodule
首先,迭代次数不是循环迭代次数而是编译迭代次数
问题在于尝试在中间(i = 6'b101111
行)退出循环。这不能展开为一系列命令。似乎循环只会让您免于一遍又一遍地重新输入相同的内容,而不能做任何更复杂的事情。
一个可能的解决方案是输入所有 32 个 if...else...if...else...
,这样当找到 activity
中的第一个 1
时,就满足条件,并且您不输入下一个else
。我认为它看起来像这样:
always @(activity, channel) begin
next_channel = 5'b0;
if (activity[channel + 1])
next_channel = channel + 1;
else if (activity[channel + 2])
next_channel = channel + 2;
else if (activity[channel + 3])
next_channel = channel + 3;
else if (activity[channel + 4])
next_channel = channel + 4;
.
.
.
我用一个标志解决了这个问题(正如 EML 建议的那样)。使用标志,代码被展开为具有不同 i
的相同代码的 32 次重复,并且 "stopping" 是通过更改 flas 实现的,以便在进一步的重复中不满足条件。
解决代码:
reg flag;
always @(activity, channel) begin
next_channel = 5'b0;
flag = 1;
for (i = 6'b0; i < 6'b100000 ; i = i + 6'b1) begin
j = i + {1'b0, channel} + 6'b1;
if (j>6'b011111)
j = j - 6'b100000;
if (activity[j[4:0]] && flag) begin
next_channel = j[4:0];
flag = 0;
end
end
end
这通过了综合并在仿真中给出了预期的结果。
我用 verilog 编写了循环通过活动通道的代码。 这个想法是跳过 activity 向量中标记为 0 的通道。
我在模拟器中测试了代码 screen shot from simulatior,它按预期工作和执行。
当我尝试使用 Synplify Pro 综合代码时,出现错误: "E CS162 Loop iteration limit 4000 exceeded - add '// synthesis loop_limit 8000' before the loop construct test1.v (11)"
错误指向循环条件(i < 6'b100000
)。
在 google 中搜索错误 我发现类似代码中的一个常见错误是 i
与 channel
的长度相同,这使得循环成为 运行不确定,因为 11111 + 1 = 00000
.
此外,Xilinx 软件中存在一些错误,但我没有使用它。
知道为什么我会收到此错误或它与模拟不同的原因吗? 有没有办法不用循环实现这个功能?
这是代码:
module test1 (
input wire [31:0] activity,
input wire RESET,
input wire CLK);
reg [4:0] channel, next_channel;
reg [5:0] i,j;
always @(activity, channel) begin
next_channel = 5'b0;
for (i = 6'b0; i < 6'b100000 ; i = i + 6'b1) begin
j = i + {1'b0, channel} + 6'b1;
if (j>6'b011111)
j = j - 6'b100000;
if (activity[j[4:0]]) begin
next_channel = j[4:0];
i = 6'b101111;
end
end
end
always @(posedge CLK, negedge RESET) begin
if (RESET == 1'b0)
channel = 5'b0;
else
channel = next_channel;
end
endmodule
首先,迭代次数不是循环迭代次数而是编译迭代次数
问题在于尝试在中间(i = 6'b101111
行)退出循环。这不能展开为一系列命令。似乎循环只会让您免于一遍又一遍地重新输入相同的内容,而不能做任何更复杂的事情。
一个可能的解决方案是输入所有 32 个 if...else...if...else...
,这样当找到 activity
中的第一个 1
时,就满足条件,并且您不输入下一个else
。我认为它看起来像这样:
always @(activity, channel) begin
next_channel = 5'b0;
if (activity[channel + 1])
next_channel = channel + 1;
else if (activity[channel + 2])
next_channel = channel + 2;
else if (activity[channel + 3])
next_channel = channel + 3;
else if (activity[channel + 4])
next_channel = channel + 4;
.
.
.
我用一个标志解决了这个问题(正如 EML 建议的那样)。使用标志,代码被展开为具有不同 i
的相同代码的 32 次重复,并且 "stopping" 是通过更改 flas 实现的,以便在进一步的重复中不满足条件。
解决代码:
reg flag;
always @(activity, channel) begin
next_channel = 5'b0;
flag = 1;
for (i = 6'b0; i < 6'b100000 ; i = i + 6'b1) begin
j = i + {1'b0, channel} + 6'b1;
if (j>6'b011111)
j = j - 6'b100000;
if (activity[j[4:0]] && flag) begin
next_channel = j[4:0];
flag = 0;
end
end
end
这通过了综合并在仿真中给出了预期的结果。