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
答案 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位加法器。