首页 > 解决方案 > 综合中超出循环迭代限制但仿真中未超出

问题描述

我在 verilog 中编写了循环通过活动通道的代码。这个想法是跳过活动向量中标记为 0 的通道。

我在 simulator 的模拟器屏幕截图中测试了代码 ,它按预期工作和执行。

当我尝试使用 Synplify Pro 合成代码时,出现错误:“E CS162 Loop iteration limit 4000 exceeded - add '// synthesis loop_limit 8000' before the loop construction 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

标签: verilogfpgasynthesis

解决方案


首先,迭代次数不是循环迭代,而是编译迭代。

问题是试图退出中间(i = 6'b101111行)的循环。这不能展开成一系列命令。似乎循环只能使您免于一遍又一遍地重新输入相同的内容,并且不能做任何更复杂的事情。

一个可能的解决方案是输入所有 32 个if...else...if...else...,这样当找到第一个时1activity条件满足并且您不输入下一个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建议的那样)。使用标志,将代码展开为相同代码的 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

这通过了综合并在仿真中给出了预期的结果。


推荐阅读