带 FIR 滤波器输入的整数 v 小数 ADC 输出

信息处理 有限脉冲响应 模数 固定点
2022-02-01 17:24:11

我正在开发一个系统,将 18 位 ADC 输出输入到 Xilinx FPGA 上的 FIR 滤波器。我有点担心我可能代表错误的数字。我的 ADC 输出一个有符号的 18 位数字。

  • 我将 ADC 输出视为具有一个整数(符号位,MSb)和 17 个小数位的定点十进制。
  • 我将我的 FIR 滤波器系数表示为带符号的小数,范围在 -1 和 1 之间。我不确定要使用什么“正确”精度。
  • 我不希望我的 FIR 滤波器有任何增益,只是在阻带中衰减。

我看到了两种方法来做到这一点 - 将所有内容视为整数或将所有内容视为十进制,每个都用 MSb 符号位签名。如果输出不是很大的位宽,我有很好的灵活性来适应输出上不同的小数/整数宽度。

哪个是正确的方法?我用 Python 生成我的滤波器系数,我应该把它们变成什么格式(整数 v 十进制)?

有没有一种很好的算法方法来选择我用来表示系数的位数?

2个回答

定点处理不适合胆小的人,但幸运的是,单个 FIR 滤波器就很简单。

在这种情况下,最容易以小数形式做任何事情,即假设信号和滤波器系数都打开[1,+1]. 显然,如果您的滤波器系数大于 1,但对于正常的带通则不应该是这种情况。

FIR 滤波器是一种简单的乘法累加运算,因此您需要计算出累加器需要多少位而不溢出。

有两种常见的缩放方式:

A:频域内0dB

缩放滤波器,使通带为 0 dB。不要缩放滤波器系数:直接转换为固定点。例如,如果您有 16 位系数并且滤波器的最大幅度为 0.3,则将转换为 983。根据您的信号,您还可以为偶尔的瞬态过冲增加 1 dB 的裕量。

B:最坏情况缩放

滤波器的最大振幅增益由脉冲响应的绝对和给出。

gmax=|h(n)|

调整累加器的大小,以便可以容纳乘以的最大输入幅度gmax

完成累积后,您可以将输出缩放到您想要的任何精度和缩放比例。

您会发现,为了保持精度并避免溢出,您需要注意在 MAC 操作期间和之后位是如何移动的。

基本操作将类似于

On each clock:
  accumulator <- accumulator + ((fir_tap[i] * input[k]) >> shift_val);

When all is said and done:
 result <- accumulator >> final_shift_val;

在 FPGA 中,这shift_valfinal_shift_val可能是硬编码的——基本上,它会在电线中。

您将不得不通过调整的比例fir_tap的值来调整事物shift_valfinal_shift_val

无论您选择将fir_tap向量指定为整数还是分数,最后,一旦您选择了不会遭受上溢或下溢的值,接线将是相同的

因此,您选择是否希望您的 Python 程序输出fir_tap为整数向量或小数值向量实际上并不是一个深刻的战略决策——这是一个战术问题,选择最能引起您共鸣的表示,并且是最有可能被您之后需要进行设计的其他人理解。