每一级运算后,输出结果就会多1bit,所以就要处理这种溢出情况,我是应该采用直接截断低权重bit呢还是对高位饱和溢出处理,将超过的数值直接令为边界值,比如156就令为127

每一级运算后,输出结果就会多1bit,所以就要处理这种溢出情况,我是应该采用直接截断低权重bit呢还是对高位饱和溢出处理,将超过的数值直接令为边界值,比如156就令为127

关注引自免费微信小程序:皆我百晓生
在FPGA开发中处理FFT(快速傅里叶变换)中的溢出是一个常见的问题。由于每次 butterflies 运算后数据位宽增加1位,为了防止溢出,你需要选择一种合适的饱和策略。这里有两种主要的方法:截断和饱和。
截断(Truncation): 截断是最简单的方法,它直接丢弃超出范围的位数。这会导致精度损失,但可能会在性能上有所提升,因为不需要额外的硬件资源进行饱和处理。
function truncate(input : signed; width : integer) return signed is
variable output : signed(width-1 downto 0);
begin
if input >= (2**(width-1)-1) then
output := (2**(width-1))-1;
elsif input <= -(2**(width-1)) then
output := -(2**(width-1));
else
output := input;
end if;
return output;
end function;
饱和(Saturation): 饱和处理会在数据超过最大值或最小值时保持其为最大值或最小值,这样可以保持数据的精度,但会稍微增加硬件复杂性。
function saturate(input : signed; width : integer) return signed is
constant max_value : signed(width-1 downto 0) := (2**(width-1))-1;
constant min_value : signed(width-1 downto 0) := -(2**(width-1));
variable output : signed(width-1 downto 0);
begin
if input > max_value then
output := max_value;
elsif input < min_value then
output := min_value;
else
output := input;
end if;
return output;
end function;
在实际应用中,你可以根据系统的需求权衡这两者之间的取舍。如果你的数据精度要求较高,可以选择饱和处理;若追求更高的速度且允许一定程度的精度损失,可以选择截断。
在设计过程中,你可以在每个蝴蝶运算之后调用相应的函数处理溢出。例如,在一个 butterfly 运算单元中,你可能有两路输入 a 和 b,以及两个乘积 c = a * Wn 和 d = b * Mn(其中 Wn 和 Mn 是旋转因子)。计算完这两个乘积后,你可以分别对 c 和 d 使用上述函数处理溢出,然后再执行加法操作。
如果你需要具体的FPGA Verilog或VHDL实现代码,我可以进一步提供,但请注意,完整的代码将取决于你的具体架构和数据宽度。