FPGA 中 FIR 滤波器的设计(一)

2017-07-17

FIR 是数字信号处理中一种非常的常见运算。我在学校还在上 VHDL 课时,就被要求写这玩意儿。当然当时我 messed up everything, and no one loves me 就是另外一回事儿了。

一个 $$N$$ 阶的 FIR 滤波器的时域表达式为:

$$y[n] = \sum_{i = 0}^{N}{h_i \cdot x[n-D-i]}$$

其中 $$x[n]$$ 是输入信号,$$y[n]$$ 是输出信号,$$h_i$$ 是 FIR 滤波器的系数。$$D$$ 是一个常数,代表处理的延迟。从公式上来看,FIR 本质上就是一维卷积运算,暴力相乘然后相加。每计算一个 $$y[n]$$ 需要 $$N$$ 次乘法和 $$N-1$$ 次加法。

FIR 的结构取决于很多因素,包括滤波器阶数,时钟速率,吞吐率等等。比较典型的例子是在吞吐率要求非常低时,可以采用 MACC(乘累加)结构;而吞吐率较高时采用多相结构。一般来说 FPGA 中的 FIR 是一个面积敏感的结构,它会消耗比较多 MAC(硬核乘法器)的数量。一个简单的乘法器数量 $$k_{MAC}$$ 的估算公式是:

$$k_{dsp} = ceil(\frac{(N+1)f_t}{f_{clk}})$$

其中 $$f_t$$ 是 FIR 模块的吞吐率,$$f_{clk}$$ 是时钟频率,其比值代表了硬件的过采样倍数。例如一个采样率为 $$100 MHz$$ 的数据采集系统,需要对采集到的信号进行滤波,FIR 的阶数是 7。为了保证能够连续不断的处理,模块的吞吐率至少和采样率相等。如果 FPGA 比较低端,那么时钟可能也会选择 $$100 MHz$$。最终可以得出 $$k_{dsp}=8$$。在不知道滤波器系数特性时,在资源就已经无法优化了。在结构上,FIR 有很多合适的结构,其中一种如下图所示:

脉动式 FIR

这种结构被称为脉动式(Systolic)结构,它在每个乘或加操作之后都有寄存用于改善时序。在 FIR 的设计中有一个计算的方法:每个寄存器都是 $$z^-1$$;当 $$x[n]$$ 经过 $$z^-1$$ 之后就会变成 $$x[n-1]$$。因此可以轻松写出输出:

$$y[n] = h_0 \cdot x[n-11] + h_1 \cdot x[n-12] + \cdots + h_7 \cdot x[n-18]$$

并且 $$D = 11$$。至此我们完成了一个通用 FIR 滤波器。接下来我们可以讨论下一些特殊结构的 FIR(TBD):

  • 线性相位(Linear phase)
  • 半带(Half-band)与 2 倍插值/抽取
  • 分数倍插值/抽取
FPGAFPGADSPFIR
BY-NC-ND

为什么 Markdown 很操蛋

DDS in FPGA

comments powered by Disqus