Verilog 在合成中超过循环迭代限制,但在模拟中未超过
我用verilog编写代码,在活动通道中循环。 其思想是跳过活动向量中标记为0的通道 我在模拟器中测试了代码 ,它的工作和性能符合预期 当我尝试使用Synplify Pro合成代码时,我得到一个错误: “超出了E CS162循环迭代限制4000-在循环构造test1.v(11)之前添加'//synthesis Loop_limit 8000'” 错误指向循环的状态(Verilog 在合成中超过循环迭代限制,但在模拟中未超过,verilog,fpga,synthesis,Verilog,Fpga,Synthesis,我用verilog编写代码,在活动通道中循环。 其思想是跳过活动向量中标记为0的通道 我在模拟器中测试了代码 ,它的工作和性能符合预期 当我尝试使用Synplify Pro合成代码时,我得到一个错误: “超出了E CS162循环迭代限制4000-在循环构造test1.v(11)之前添加'//synthesis Loop_limit 8000'” 错误指向循环的状态(i
i<6'b100000
)
在google中搜索这个错误时,我发现了一个常见的错误,那就是I
的长度与channel
的长度相同,这使得循环无法正常运行,因为11111+1=00000
另外,Xilinx软件中有一些bug,但我没有使用它
知道我为什么会出现这个错误,或者为什么它与模拟不同吗?
有没有一种方法可以在没有循环的情况下实现这个函数
代码如下:
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
模块测试1(
输入线[31:0]活动,
输入线复位,
输入线(时钟);
reg[4:0]频道,下一个_频道;
reg[5:0]i,j;
始终@(活动、频道)开始
下一个_通道=5'b0;
对于(i=6'b0;i<6'b100000;i=i+6'b1)开始
j=i+{1'b0,通道}+6'b1;
如果(j>6'b011111)
j=j-6'b100000;
如果(活动[j[4:0]])开始
下一个信道=j[4:0];
i=6'b101111;
结束
结束
结束
始终@(posedge时钟、negedge重置)开始
如果(重置==1'b0)
通道=5'b0;
其他的
信道=下一个信道;
结束
端模
首先,迭代次数不是循环迭代次数,而是编译迭代次数
问题是试图退出中间的循环(<代码> i= 6'B101111行)。这不能展开为一系列命令。似乎循环只会让你避免一遍又一遍地重复输入同样的内容,而不能做更复杂的事情
一种可能的解决方案是键入所有32个if…else…if…else…
,以便在活动中找到第一个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;
.
.
.
我用一个标志(如建议的)解决了这个问题。使用该标志,代码被展开为32个相同代码的不同i
重复,并通过更改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
reg标志;
始终@(活动、频道)开始
下一个_通道=5'b0;
flag=1;
对于(i=6'b0;i<6'b100000;i=i+6'b1)开始
j=i+{1'b0,通道}+6'b1;
如果(j>6'b011111)
j=j-6'b100000;
如果(活动[j[4:0]]&&flag)开始
下一个信道=j[4:0];
flag=0;
结束
结束
结束
这通过了合成,并在模拟中给出了预期的结果。如果循环限制实际上是一个错误,则不应出现此错误(右),你永远不应该修改循环中间的循环迭代器变量,或者使用任何其他方法从中间退出循环。它需要在编译时完全滚动,以便合成成功。+ 1用于修复它。但是请注意,你像程序员一样解决这个问题——你的HARWDARE太大,太慢了,而且你也会。e依靠合成器来理解它。首先,你需要考虑并行-查找优先级编码器。@EML,我发现了优先级编码器的实现,它看起来与我建议的嵌套ifs的解决方案非常相似。你认为这个解决方案更好吗?你能解释一下你是如何看到硬件很小的吗r和更快?我正在研究的模块更类似于循环仲裁器,但它需要跳过非活动通道,而且我还没有在web上找到任何实现。