Verilog中的算术部门

时间:2015-04-07 17:22:53

标签: verilog fpga xilinx

module averager(
    clk,
    rst,
    n,
    sum,
    cnt,
    out,
    avg
 );

input  [9:0] n;
input clk;
input rst;
output reg [19:0] out;
output reg [9:0] cnt;
output reg [19:0] sum;
output reg [9:0] avg;

integer i = 0;

always @(posedge clk ) 
    if (rst == 1) begin 
        sum = 20'b0;
        cnt = 10'b0;
        out = 20'b0; 
        avg = 10'b0;
    end else if (rst == 0) begin
        sum = sum + n;
        out = sum;
        cnt = cnt + 1;
        avg = 0;

        for (i=0; i<641; i=i+1) begin
            if(out >= cnt) begin
                out = out - cnt;
                avg = avg + 1;
            end
        end
    end
endmodule

以上是实现累积移动平均滤波器的代码。 for循环用于除法以找到平均值并涉及重复减法。但是我收到以下警告和错误:

警告:Xst:2254 - 阻止无法满足区域约束,最终比率为509。 警告:Xst:1336 - (*)使用超过100%的设备资源 错误:包装:18 - 设计对于给定的设备和包装来说太大了。

这一定是因为我在for循环中使用了大值,因此得到了一个无法实现的大电路。我正在寻找for循环的替代方案,它可以找到我的平均值。我只需要商数值。

设计属性:系列:Spartan3E器件:XC3S500E

1 个答案:

答案 0 :(得分:2)

完整details answer与EE堆栈交换original posted question。这是解决方案的主要要求:

  

在静态展开之后,for循环逻辑非常庞大。跟你的   当前代码,您无法处理n = 1023的最坏情况。   要使用当前代码覆盖这一点,您需要使用1024的for循环   迭代。

     

您可以使用向下计数器而不是向上计数器来代替向上计数器   数组的切片,其中索引表示数组切片的lsb。   例如:

for (i=10; i>=0; i=i-1) begin // lsb index of the slice
  if (out[i+:10] >= cnt) begin // 10-bit slice compare
    out[i+:10] = out[i+:10] - cnt; // 10-bit slice subtraction
    avg[i] = 1'b1; // 1-bit assign
  end
end
     

这个for循环解析为11次迭代(10到0),每次迭代   查看out的10位切片和avg的仅一位。你可能会   不熟悉+:运算符。它是一个位片操作符   在IEEE Std 1364-2001中引入。左侧如果是起始索引   (允许动态),右侧是带偏移的位(必须   是一个静态常数)。您可以阅读更多相关信息   here

     

由于它是倒计时,我们可以安全地假设(证明   数学上)切片的高位是零,我们将   如果条件,保护不会下降。所以我们现在有11个   10位减法器,每个都有1位分配器,小得多   逻辑然后原始642(应该是1024)每个20位减法器   使用10位加法器。