马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
利用MATLAB的FDATOOL工具,采用窗函数法设计出的FIR滤波器需要700多阶,如图3.1所示。评估FPGA资源,不能够完成滤波的主要原因是无法保存输入的历史数据。即使参数做微调也只能将阶数降到300阶。究其FIR阶数居高不下的原因主要在于,60Hz-64Hz的过渡带相对于采用频率1KHz来说太窄,即滤波器的滚降过快。Fstop=64Hz就是由此公式计算得来。从1024序列中抽取出128的序列,那么M=8,计算得fc<64Hz。所以为了保证不出现混叠,Fstop=64Hz。
经过多次评估得出,在2C8器件基础上对72个通道进行FIR滤波,最多只能运算85阶,为了便于计算采用64阶FIR滤波。图3.1 按照指标设计的FIR滤波器模型
考虑到脑电信号一般低于30Hz,那么我们将通带频率定为20Hz。同时我们考虑到,混叠只要对带内信号不产生影响,混叠也可以产生,那么我们可以计算出Fstop=128-60=68。这样优化的方向就是,使得滤波器的过渡带趋于平坦,我们知道,过渡带直接影响到FIR的阶数。
形成了新的指标如下:
原采样率 :Fs=1024Hz
通带 :Fpass=20Hz 保证30Hz衰减不低于3dB
截止频率 :Fstop=68Hz
利用MATLAB的FADTool工具生成FIR模型如3.2图所示。37Hz左右才衰减3dB,保证率30Hz不衰减3dB。图3.2设计的64阶FIR滤波器模型
具体设置参数如下:
选择:低通(lowpass)、FIR、基于窗口设计(window)、kaiser窗口设计。
设置:采样频率Fs=1024,通带Fpass=20,阻带Fstop=68;
通带衰减Apass=0.2,阻带衰减Astop=50dB。
这些参数中,Fpass、Fstop、Astop等都可以修改,主要目的就是为了使得FIR的阶数为64阶(由于FPGA硬件资源限制,本系统中只能设计64阶的FIR)。当然在保证系统需求的前提下,可以尽量降低FIR的阶数。
FIR阶数确定后,就可以生成FIR系数了,利用FDATOOL如图3.3的系数生成工具,可以生成各种不同类型的系数。图3.3 FDATOOL系数生成工具
此系统中FPGA采用了16位有符号乘法器结构,所以在此生成了Signed 16-bit integer类型的系数。3.2 基于FPGA的72通道FIR滤波器设计 3.2.1 FIR参数和FPGA资源之间的对应关系
1、 FIR的阶数决定了FPGA乘法单元使用次数,阶数的高低影响滤波的效果(频响)。
2、 FIR计算的位宽选择:8bits 、16bits、32bits。影响精度,即滤波效果(小信号)。
3、 运算速度,决定了FPGA的主时钟,即影响功耗。
4、 通道数量,每个ADC器件采集的24路信号轮流滤波,那么滤波过程中需要保存每个通道的阶数个历史数据,影响的存储单元容量的大小。3.2.2 FIR实现结构:1个MAC对应一个ADC器件
利用Quartus II软件中的MegaWizard Plug-In Manager工具生成的MAC单元结构如图3.4所示。设置datab为有符号输入(输入FIR系数),dataa为无符号输入(输入信号序列)。aclr0为异步清零。图3.4 MAC 乘累加单元
利用此MAC单元设计出的64阶FIR滤波器结构如图3.5所示。ADC器件对24路通道进行采样,并将采集到的16bits位宽的数据存入RAM中。在RAM中划分24个通道对应的不同的地址范围。RAM中保存的每个通道输入的历史数据个数有FIR阶数决定,即为64个。在ADC完成当前通道当前采样值后,MAC单元开始从RAM中调入数据、从ROM中调入FIR系数,进行FIR最基本的乘累加运算,运算次数由阶数决定。系数采用16bis无符号整型表示,所以在计算完成后需要做归一化处理。图3.5 64阶FIR滤波器结构
3.2.3双口RAM容量的计算和划分(固定边界的RAM实现循环缓冲机制)
图3.6 4抽头FIR滤波器的数据存储器寻址
首先介绍固定边界的RAM实现循环缓冲机制,如图3.6所示。RAM中保存四个最新数据样本的“时间历史”。将新数据值写入存储器时,覆盖最旧的值,可以在FPGA内部的固定边界RAM中实现这一延迟线。为方便存储器寻址,从存储器读取旧数据值时,应从刚写入值的位置之后的一个位置开始。例如,假设将x(4) 写入存储器位置0 ,则随后应从位置1、2、3、0读取数据值。可以将这个例子推广以支持任意抽头数。以这种方式寻址数据存储器位置时,地址发生器只需要按顺序提供地址,而不用考虑是寄存器读操作还是寄存器写操作。到达最后一个位置时,存储器指针必须复位到缓冲器的起始位置,因此这种数据存储缓冲器是循环的。系数与数据同时取出。所选的寻址方案决定了最旧的数据样本必须最先取出。因此,最后一个系数必须最先取出。系数可以反向存储在存储器中:h(N-1) 是第一个位置,h(0)是最后一个位置,地址发生器提供递增地址。或者,系数也可以正常方式存储,而对系数的访问则是从缓冲器的末端开始,地址发生器递减。在图7.12 所示的例子中,系数以逆序存储。
然后我们确定本设计所需的RAM容量。从结构中知道ADC需要向RAM中写入数据,而MAC单元需要从RAM中读出数据,所以,设计了一个双口RAM。对RAM的读写操作拥有两个独立的地址和数据总线。在操作过程中需要注意读写冲突。RAM所需要的容量可以由下述公式计算得来:
(3-1)
其中maxadd_ram为ram地址最大值,chan_num表示通道数,n为FIR阶数。
那么在本设计中,计算得maxadd_ram=1536,取大于1536最近的2的幂次方2048。这是由于FPGA内部定义的RAM容量必须为2的幂次方。所以双口RAM需要的容量为2048*16bits=8M4K,即需要8个M4K容量。RAM的需要11bits地址线。将11根地址线分成高低两个部分组成。高5位由通道数决定。低6位能够确定64个存储单元,和滤波阶数相对应。如图3.7所示。
图3.7 TwoPort RAM 存储划分
这样为每个通道准备了64个存储单元。RAM读写操作说明:
1、Temp_Add作为指针,每次ADC有新值采集来时,Temp_Add自加1,结合通道值,作为写入地址。
2、在FIR计算时,Temp_Add对应的存储单元为最新值,Temp_Add+1为最旧值,Temp_Add自加64次读出当前通道保存的所以值,参与MAC乘累加运算。
3、必须保证读写不能冲突,所以在ADC模块的data_ok上升沿时执行写入操作,下降沿时开始运算。
3.2.4 基于FPGA的FIR滤波器的实现
分析了MAC单元和RAM单元后,就可以实现具体的FIR滤波器了。
从图3.5可知,实现FIR滤波器,数据经过了哪些资源模块,简单的连接这些模块可以实现数据路径的建立。建立好的数据路径就像是一条完整的生产线,但如何生产需要额外的控制单元,譬如,何时开始滤波,何时向RAM中写入数据,何时从RAM中读出数据,等等。这些关键的指令都需要控制模块在适当的时候发出。显然,现在缺少这些核心的控制模块。如图3.8所示,加入控制模块后的结构多了RAM的写入控制模块、MAC控制模块和数据输出调整模块。
图3.8完整的FIR滤波结构
其中,wr_ram_ctr模块,在检测到adc_data_ok上升沿后向ram中写入新采集到的数据;mac_ctr模块,作为FIR计算控制核心,在检测到adc_data_ok下降沿后开始计算FIR,即从RAM和ROM中读出数据,并决定何时结束FIR的计算;adjust_out主要完成归一化mac输出的结果,并调整数据时序。
设计过程中的注意点:
1、 数据和系数送到MAC单元的两个输入端口需要同步;
2、 每次FIR计算需要64次乘加运算,加上数据在寄存器之间延时,实际运算需要69个CLK系统时钟周期;
3、 每次FIR计算完毕需要对MAC内部寄存器清零。
3 FIR滤波器总结
按照上述设计最终生成的原理图顶层如图3.9所示。我们可以计算出FIR滤波所花费的时间。
图3.9 FIR滤波器顶层
首先介绍adc_ctrl模块和fir模块之间的关系。
adc_ctrl模块:
输出信号data_ok、first、last信号,高电平有效,并且持续1个clk_adc(3M)时间。通道选择adc_ch_sel和数据输出adc_ad_out端口在data_ok等信号有效之前已经准备好,并且注意,adc_ch_sel在data_ok有效时输出1-12Or2-24。同时保证在CS拉低后的6个clk_adc后改变通道值。
fir模块:
在run上升沿发起后,等待ram中存满1536个新数据后,检测到adc_ctrl模块输出的data_ok信号的下降沿后(保证数据完成保存后)开始计算当前通道,当前data_ok信号指定的输入数据的fir值。大约需要不大于70个sys_clk时钟周期计算结果。Fir模块需要的chan_sel信号是0-11 or 0-24,所以由adc_ctrl模块送过来的adc_ch_sel需做调整。
时序对接要求:
假设:sys_clk=100M 10ns
adc_clk=6M 166ns 超频
clk_sample=10k100us 超采
采集时间计算:
adc_ctrl模块需要23个adc_clk时钟周期输出一个采集数据,按照最大通道数24计算,一个采样周期clk_sample,采集需要的时间为:166ns*23*24=91632ns=91.6us<100us, 即需要大约9163个sys_clk周期。那么按照8K超采,adc_clk最低需要多高的时钟?经计算需要adc_clk>4.3M。注意此时间并不包括组帧等其他时间。
FIR运算时间计算:
计算一个数据的64阶fir值,需要不大于70个sys_clk周期。同时,FIR是在每个data_ok信号的下降沿后开始计算的,那么必须在下一次data_ok信号的下降沿来之前计算完成。知道两个data_ok有效信号之间的间隔为23个adc_clk周期。那么必须满足:
70sys_clk<23adc_clk
如果30M的sys_clk,3M的adc_clk,那么可以计算出,FIR最大阶数在200以上。
从以上结论可以看出,利用FPGA设计FIR数字滤波器的瓶颈并不在于FPGA运算速度不够快,而是在计算72个通道FIR时需要保存很多的历史数据,对FPGA内部的存储器提出了更大的要求。那么我们知道,64阶FIR并不能完成来时提出的指标要求,必须寻求其它更加可行的方案。 |