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.
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 ofavg
. 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.