Verilog 中的算术除法

Arithmetic Division in Verilog

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。 WARNING:Xst:1336 - (*) 已使用超过 100% 的设备资源 ERROR:Pack:18 - 设计对于给定的设备和封装来说太大了。

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

设计属性:系列:Spartan3E 设备:XC3S500E

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

The for-loop logic is huge when it after it static unrolls. With your current code, you cannot handle the worst case scenario where n=1023. To cover this with your current code you'd need a for loop with 1024 iterations.

Instead of a up counter, you can use a down counter and only examine a slice of the array, where the index represents lsb of the array slice. For example:

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

This for loop unravels to 11 iterations (10 to 0), each iteration only looks at a 10 bit slice of out and only one bit of avg. You might not be familiar with the +: operator. It is a bit-slice operator introduced in IEEE Std 1364-2001. Left side if the start index (dynamic is allowed) and the right side is the bit with offset (must be a static constant). You can read more about it here.

Since it is a count down, we can can safely assume (proven mathematically) the upper bits of the slice are zeros and we will never have underflow with the guarding if condition. So we now have 11 10-bit subtracters each with 1-bit assigners which is much smaller logic then the original 642 (should be 1024) 20-bit subtracters each with 10-bit adder.