【问题标题】:verilog synthesis not converging after 2000 iterationsVerilog 合成在 2000 次迭代后未收敛
【发布时间】:2018-10-24 03:28:01
【问题描述】:

我为 2 个 n 位数字(这里 n=16)的简单乘法编写了以下代码。它正在使用所需的输出波形进行模拟,但问题是,即使我编写了 静态“for 循环”(即循环迭代是恒定的),它也没有在 vivado 17.2 中合成。我收到下面提到的错误。

[Synth 8-3380] 循环条件在 2000 次迭代后不收敛

注意:我已经写了

for(i=i;i<n;i=i+1)

而不是

for(i=0;i<n;i=i+1)

因为后者在我到达 n 后再次执行。所以这不是一个错误。请有人帮助。感谢您的宝贵时间

//unsigned integer multiplier
module multiplication(product,multiplier,multiplicand,clk,rset);
parameter n = 16; 
output reg [(n<<1)-1:0]product;
input [n-1:0]multiplier, multiplicand;
input clk,rset;
reg [n:0]i='d0; 
always @( posedge clk or posedge rset)
begin
    if (rset) product <= 'd0;
    else
    begin
        for(i=i;i<n;i=i+1)
        begin
        product =(multiplier[i] == 1'b1)? product + ( multiplicand << i ): product;
        $display("product =%d,i=%d",product,i);
        end
    end
end
endmodule

【问题讨论】:

    标签: verilog hardware xilinx hdl


    【解决方案1】:

    首先,如果您真的想在 FPGA 上实现您的设计(Vivado 已优化为用于在 FPGA 上实现您的设计)。即使您可以成功地综合您的设计,您也可能会面临时序问题或意外错误。

    我想你可以找到答案here

    编辑:我只是想告诉你,通常控制时序在硬件设计中非常重要,特别是当你想将你的设计与其他系统集成时,循环可能是噩梦。

    【讨论】:

      【解决方案2】:

      返回使用您原来的 for (i=0 循环。

      你的错误是你假设 i=0 因为reg [n:0]i='d0; 这只是第一次。因此只有一次,在模拟开始时。

      因为后者在我到达 n 后再次执行。

      是的,循环会一次又一次地重复每个时钟周期。这就是@( posedge clk ...) 所做的。

      更多错误:

      • 您在时钟部分使用阻塞分配,使用非阻塞:

        产品

      • 您的产品仅在重置后第一次正确(从零开始)。复位后的第二个时钟周期,您再次进行乘法运算,但从之前的乘积值开始。

      • 您的i 有点大,您使用 17 位数到 16。全局循环变量也有陷阱。我建议你使用系统 Verilog 语法:`for (int i=0; ....)

      【讨论】:

        【解决方案3】:

        错误消息不是关于循环的迭代,而是关于合成程序内部算法的迭代。它告诉您,Vivado 未能创建一个电路,该电路实际上可以在您选择的 FPGA 上以您选择的时钟速度实现,并且实际上可以满足您的要求。

        让我详细说明一下,在我提到两个一般重要项之后:不要在 always @(posedge clk) 块内使用阻塞分配 (=)。他们几乎从不做你想做的事。只有非阻塞分配 (&lt;=) 应该被计时。其次,合成for 循环的正确方法是使用generate,尽管Vivado 似乎接受了简单的for

        您在这里构建了一个相当大的组合逻辑块。请记住,当您合成组合逻辑时,您要求的电路可以评估您编写的表达式在单个时钟周期内。考虑的实际表达式是展开 for 循环之后的表达式。即,您(有条件地)将 16 位数字添加到 32 位数字 16 次,每次向左移动一位。这些加法中的每一个都有一个进位位。因此,这些加法中的每一个实际上都必须查看前一次加法结果的所有高 16 位,并且每个加法都取决于前一次加法的最低位以外的所有位。一位 + 进位的加法器需要 O(5) 个门。每次添加都是有条件的,即为每个位添加至少一个门。因此,您要求至少 16*16*6 = 1300 个相互依赖的门,它们都必须在单个时钟周期内稳定。 Vivado 告诉您它无法满足这些要求。

        缓解此问题的一种方法是针对较低的时钟频率进行综合,在该频率下,门有更多的时间来稳定,因此您可以构建更长的逻辑链。另一种选择是将操作流水线化,例如仅评估与单个时钟周期内循环的四次迭代相对应的内容,然后在多个时钟周期内构建结果。这将为您的代码添加一些簿记逻辑,但如果想要在高时钟频率下使用有限资源评估复杂表达式,这是不可避免的。它还将向您介绍同步逻辑,如果您想用 FPGA 做任何不平凡的事情,无论如何您都必须学习同步逻辑。请注意,这种流水线不会显着影响吞吐量,因为您的 FPGA 会并行执行多个乘法运算。

        您还可以重写表达式,以更智能的方式处理进位位和相互依赖关系,从而允许 Vivado 通过表达式找到自己的方式(可能有这样一种方式,我假设如果您简单地编写乘法运算符?)。

        最后,许多 FPGA 都带有专用的乘法器单元,因为乘法是一种常见的运算,但在逻辑门中实现它会浪费大量资源。如你所见。

        【讨论】:

          猜你喜欢
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 2019-03-11
          • 1970-01-01
          • 2019-08-06
          • 2019-03-12
          • 2016-08-13
          • 1970-01-01
          相关资源
          最近更新 更多