摘 要: 本文使用VHDL描述了可综合的FIR滤波器,并在Altera公司的EPF10K40器件上实现了设计,在设计中采用了一些硬件实现DSP功能的技巧:分布式设计;流水线结构;查找表实现乘法器。实现了对FIR进行的可综合的行为描述。
关 键 词 :VHDL FIR滤波器 FPGA
在宽带信号处理中,常常利用目标回波的频谱特性进行目标检测和分类,为了保证其准确性,对接收到的回波必须进行频谱分析。实际上常用的方法是通过滤波器组进行处理的。因此在设计上采用同一结构的FIR滤波器,通过调整参数实现不同频率段的滤波。
FIR滤波器在数字信号处理中占有非常重要的地位,这主要是因为FIR滤波器可以很方便地实现线性相位、因此群延迟不随频率变化。此外,由于FIR滤波器为全零点滤波器,因此不存在收敛性问题,因此比IIR滤波器应用的更广泛。
在FIR滤波器实现时采用VHDL语言进行描述,方便在不同的实现方式下的移植和滤波器参数的修改。在设计中,将VHDL描述和滤波器参数分别作为独立的文件进行处理,方便了不同类型滤波器的设计移植。
FIR滤波器的参数
本FIR滤波器的设计参数如下:
中心频率:17.5kHz
通带宽度:1.6kHz
阻带:-30dB
通带:0dB
通带内纹波:1dB
通道间的相位差小于5度。
对于这样的滤波器实现,如果采用模拟滤波器来设计,一方面滤波器的阶数很高,另一方面很难保证不同通道之间的相位要求,给设计和生产带来困难。所以,在本设计中采用了FPGA硬件实现数字FIR滤波器。
图1 状态机状态图(略)
滤波器的系数使用系统仿真分析工具Systemview进行设计,设计的系数保存在coeff.mif文件中。实际滤波器的抽头数应该为120。考虑到滤波器系数的对称性,则滤波器只需要进行一半的乘法运算。输入的数据经过处理之后,设计的规模相当于60阶的滤波器的规模。实际采用的是64抽头的结构,实现128抽头的滤波器。FPGA选择的是Altera公司的产品,采用的开发环境是Quartus
II,用VHDL描述实现设计。
FIR设计
在用硬件实现FIR滤波器的时候,采用的方法有多种,具有代表性的有:直接运算实现;分布式实现。在本文的设计中采用的是分布式实现方式,这是因为Altera公司的FPGA的结构中含有EAB块,该物理结构可以实现高密度的存储器功能。
将N抽头、n位FIR滤波器表示为:
y={\sum_{K=0}^{N-1}}a_{k}x_{k}
其中, 为滤波器的系数,将x用2进制数表示,这时上式为:
y={\sum_{K=0}^{N-1}}{\sum_{i=0}^{n-1}}a_{k}b_{i}(k)2^i={\sum_{i=0}^{n-1}}2^i{\sum_{k=0}^{N-1}}a_{k}b_{i}(k)
其中bi(k)为x(k)的第i位的值,它只取两种值:1或者0。这样可以根据bi(k)的不同,将对应的滤波器系数预先求和,并保存在ROM中;在工作时,用bi(k)作为地址读取ROM中的数据,并进行错位加,得到最后的输出结果。
此外设计中采用了多级流水线的方式实现运算,因为这样的设计在不降低系统速度的情况下,可以降低对ROM存储容量的需求。因为对于数字滤波来说,一般抽头数都很大,因此,作为ROM的地址就有很多位,查找表的规模是随着地址的增加呈指数增加的,所以将它们划分为几个大小不同、内容相同的查找表,可以大大降低设计对ROM的需求。
此外,对于线性相位的FIR滤波器,由于滤波器系数的对称性,同样可以大大降低设计的规模。
在设计过程中,为了实现设计的方便移植,采用VHDL作为设计的输入手段,因此在设计上与传统的方式不同,采用了2状态的状态机来实现串行工作过程。具体状态机的结构如图1所示:
在状态initial阶段,将所有的信号和变量进行初始化,在状态addup阶段,对ROM进行查表,并将结果进行加权累加,直到所有的位(图中的n表示系统采样数据的位数)处理之后,则回到initial状态。这一部分的VHDL描述如下:
process(clk)
variable p1,p2,p3,p4,p5,p6,p7,p8:integer range 0 to fir_taps-1;
variable count:integer range 0 to data_width-1;
begin
if clk'event and clk='1' then
case state is
when s0=>
state<=s1; count:=0;
p1:=0; p2:=0;……p8:=0; d63<=x63; d62<=x62;……xd1<=x1;xd0<=x0;
when s1=>
if count=data_width-1 then
y<=p1/128+p2/64+p3/32+p4/16+p5/8+p6/4+p7/2+p8;
state<=s0;
else
p1:=p1/2+table_out1;p2:=p2/2+table_out2; ……p8:=p8/2+table_out8;
for k in 0 to data_length-2 loop
xd0(k)<=xd0(k+1); xd1(k)<=xd1(k+1); ……xd63(k)<=xd63(k+1);
end loop;
count:=count+1; state<=s1; --table_in是查找表的地址,因此需要将地址划分为8个8位的地址。
table_in1<=(xd0(0) & xd1(0) & xd2(0) & xd3(0) &
xd4(0) & xd5(0) & xd6(0) & xd7(0));
……
table_in7<=(xd48(0) & xd49(0) & xd50(0) & xd51(0)
& xd52(0) & xd53(0) & xd54(0) & xd55(0));
table_in8<=(xd56(0) & xd57(0) & xd58(0) & xd59(0)
& xd60(0) & xd61(0) & xd62(0) & xd63(0));
end if;
end case;
end if;
end process;
数据的输入采用并行输入方式,通过移位寄存器实现移位,此外数据预处理部分也包含在这部分的描述中。这部分的描述如下:
process(clk_d)
begin
if clk_d'event and clk_d='1' then
d127<=d126; d126<=d125; …… d1<=d0; d0<=x_in; x0=d127+d0;
x1=d126+d1; x2=d125+d2;……x63=d64+d63;
end if;
end process;
由于数据是逐字输入的,因此,前面的clk信号和数据输入的时钟信号clk_d之间必须符合一定的时序关系,clk_d信号由clk信号分频得到。这部分的描述如下:
process(clk)
variable cnt:integer range 0 to data_length-1;
begin
if clk'event and clk='1' then
if cnt=data_length+1 then
clk_d<=not clk_d;
cnt:=0;
else
cnt:=cnt+1;
end if;
end if;
end process;
查找表采用Altera公司特有的物理结构嵌入阵列块(EAB)来实现。Altera公司的Quartus II中提供了参数化的ROM模型,因此可以直接使用Altera公司的库进行ROM的设计。这时必须使用下面的库设置:
library lpm;
use lpm.lpm_components.all;
在设计中共有8个这样的ROM,每个ROM的地址为和位宽均为8位,因此,一个ROM的数据为2048位,采用元件例化的方式描述。
lc_table1:LPM_ROM
GENERIC MAP(LPM_WIDTH=>mem_length,
LPM_WIDTHAD=>table_addr,
LPM_OUTDATA=>"UNREGISTERED",
LPM_ADDRESS_CONTROL=>"UNREGISTERED",
LPM_FILE=>"coeff.mif")
PORT MAP(address=>table_in1, q=>mem1);
ROM中的初始化数据保存在独立的文件coeff.mif中,也就是根据前面分布运算方法中,将滤波系数预先计算的结果。下面是该文件的格式:
width=8;
depth=256;
address_radix=dec;
data_radix=dec;
content begin
0: 1;
1: 4;
2: 5;
……
256: 1;
end;
如果需要改变FIR滤波器的类型或者参数,可以只修改coeff.mif文件中的参数,就可以达到目的,因此大大方便了该系统中的其他滤波器的设计,提高了设计效率,同时也为自适应滤波方式提供了一种途径。
以上是128抽头的FIR滤波器的设计描述。
FIR实现
上述描述的滤波器在Altera公司的开发工具Quartus II中进行编译和布局布线,采用的目标器件为EPF10K40芯片。刚好实现一个这样规模的FIR滤波器。具体的性能如下:
总逻辑单元数:1729
总存储器容量:16384
使用的寄存器数:1143
最大的寄存器到寄存器的延迟:40ns
时钟有效到输出的延迟:0.8ns
建立时间:0.7ns
系统运行的最高时钟为23.64MHz
从上述实现的结果来看,系统信号传递的最大延迟大约为40ns,完全满足整个系统对延迟的要求。
值得一提的是,对于规模较大的设计,建议采用Quartus II进行编译实现,它比Maxplus II的性能更好。
滤波器设计的移植
从上述设计和实现的过程来看,滤波器的结构和滤波器的滤波系数(决定了滤波器的类型)是分离的,因此可以很方便地实现不同类型的滤波器的设计移植,只需要将ROM中的初始化参数进行重新设置,也就是改变coeff.mif文件中的数据,重新进行编译和布局布线,就可以得到不同类型的滤波器的实现。
此外,由于设计是采用VHDL语言实现的,因此可以在不同的公司的FPGA器件之间进行移植,这时,只需要将ROM的模型进行更换,则完全可以在不同的器件上实现,这给设计带来很大的灵活性。不必象在采用原理图作为输入的设计中那样,需要采用不同的库单元,重新绘制原理图,才能重新进行编译和布局布线。这样容易造成输入错误。
结论
在该FIR滤波器的设计中,根据FPGA的结构特点和资源,采用了如下的设计技巧:
(1)采用分布方式下的查找表的结构,简化了乘法器的设计;
(2) 采用了流水线结构,减小了查找表ROM的规模;
(3) 滤波器的参数独立于滤波器的结构,方便实现不同类型的滤波器;
(4) 采用了VHDL作为设计输入的手段,增加了设计可移植性;
(5)采用参数化的结构,可以根据应用情况调整设计的规模。
在应用了上述技巧的基础上,在一片EPF10K40上实现了符合系统要求的对信号进行前端预处理的功能,并且多通道之间的相位延迟达到系统的要求,不需要经过困难的调试就可以实现不同通道之间的信号延迟的一致性。该设计已经在某武器系统的信号处理单元中投入使用,运行良好。
|