Verilog并行FIR滤波器设计

fir(finite impulse response)滤波器是一种有限长单位冲激响应滤波器,又称为非递归型滤波器。fir 滤波器具有严格的线性相频特性,同时其单位响应是有限长的,因而是稳定的系统,在数字通信、图像处理等领域都有着广泛的应用。
fir 滤波器原理
fir 滤波器是有限长单位冲击响应滤波器。直接型结构如下:
fir 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下:
fir 滤波器有如下几个特性:
(1) 响应是有限长序列。
(2) 系统函数在 |z| > 0 处收敛,极点全部在 z=0 处,属于因果系统。
(3) 结构上是非递归的,没有输出到输入的反馈。
(4) 输入信号相位响应是线性的,因为响应函数 h(n) 系数是对称的。
(5) 输入信号的各频率之间,相对相位差也是固定不变的。
(6) 时域卷积等于频域相乘,因此该卷积相当于筛选频谱中各频率分量的增益倍数。某些频率分量保留,某些频率分量衰减,从而实现滤波的效果。
并行 fir 滤波器设计
◆设计说明
输入频率为 7.5 mhz 和 250 khz 的正弦波混合信号,经过 fir 滤波器后,高频信号 7.5mhz 被滤除,只保留 250khz 的信号。设计参数如下:
输入频率: 7.5mhz 和 250khz
采样频率: 50mhz
阻带: 1mhz ~ 6mhz
阶数: 15(n-1=15)
由 fir 滤波器结构可知,阶数为 15 时,fir 的实现需要 16 个乘法器,15 个加法器和 15 组延时寄存器。为了稳定第一拍的数据,可以再多用一组延时寄存器,即共用 16 组延时寄存器。由于 fir 滤波器系数的对称性,乘法器可以少用一半,即共使用 8 个乘法器。
并行设计,就是在一个时钟周期内对 16 个延时数据同时进行乘法、加法运算,然后在时钟驱动下输出滤波值。这种方法的优点是滤波延时短,但是对时序要求比较高。
◆并行设计
设计中使用到的乘法器模块代码,可参考之前流水线式设计的乘法器。
为方便快速仿真,也可以直接使用乘号 “*” 完成乘法运算,设计中加入宏定义 safe_design 来选择使用哪种乘法器。
fir 滤波器系数可由 matlab 生成,具体见附录。
/***********************************************************> > v201001 : fs:50mhz, fstop:1mhz-6mhz, order: 15************************************************************/`define safe_designmodule fir_guide ( input rstn, //复位,低有效 input clk, //工作频率,即采样频率 input en, //输入数据有效信号 input [11:0] xin, //输入混合频率的信号数据 output valid, //输出数据有效信号 output [28:0] yout //输出数据,低频信号,即250khz ); //data en delay reg [3:0] en_r ; always @(posedge clk or negedge rstn) begin if (!rstn) begin en_r[3:0] <= 'b0 ; end else begin en_r[3:0] <= {en_r[2:0], en} ; end end //(1) 16 组移位寄存器 reg [11:0] xin_reg[15:0]; reg [3:0] i, j ; always @(posedge clk or negedge rstn) begin if (!rstn) begin for (i=0; i< 15; i=i+1) begin xin_reg[i] <= 12'b0; end end else if (en) begin xin_reg[0] <= xin ; for (j=0; j< 15; j=j+1) begin xin_reg[j+1] <= xin_reg[j] ; //周期性移位操作 end end end //only 8 multipliers needed because of the symmetry of fir filter coefficient //(2) 系数对称,16个移位寄存器数据进行首位相加 reg [12:0] add_reg[7:0]; always @(posedge clk or negedge rstn) begin if (!rstn) begin for (i=0; i< 8; i=i+1) begin add_reg[i] <= 13'd0 ; end end else if (en_r[0]) begin for (i=0; i< 8; i=i+1) begin add_reg[i] <= xin_reg[i] + xin_reg[15-i] ; end end end //(3) 8个乘法器 // 滤波器系数,已经过一定倍数的放大 wire [11:0] coe[7:0] ; assign coe[0] = 12'd11 ; assign coe[1] = 12'd31 ; assign coe[2] = 12'd63 ; assign coe[3] = 12'd104 ; assign coe[4] = 12'd152 ; assign coe[5] = 12'd198 ; assign coe[6] = 12'd235 ; assign coe[7] = 12'd255 ; wire [24:0] mout[7:0]; `ifdef safe_design //流水线式乘法器 wire [7:0] valid_mult ; genvar k ; generate for (k=0; k< 8; k=k+1) begin mult_man #(13, 12) u_mult_paral ( .clk (clk), .rstn (rstn), .data_rdy (en_r[1]), .mult1 (add_reg[k]), .mult2 (coe[k]), .res_rdy (valid_mult[k]), //所有输出使能完全一致 .res (mout[k]) ); end endgenerate wire valid_mult7 = valid_mult[7] ;`else //如果对时序要求不高,可以直接用乘号 always @(posedge clk or negedge rstn) begin if (!rstn) begin for (i=0 ; i< 8; i=i+1) begin mout[i] <= 25'b0 ; end end else if (en_r[1]) begin for (i=0 ; i< 8; i=i+1) begin mout[i] 1组 29bit 数据 //数据有效延时 reg [3:0] valid_mult_r ; always @(posedge clk or negedge rstn) begin if (!rstn) begin valid_mult_r[3:0] <= 'b0 ; end else begin valid_mult_r[3:0] <= {valid_mult_r[2:0], valid_mult7} ; end end`ifdef safe_design //加法运算时,分多个周期进行流水,优化时序 reg [28:0] sum1 ; reg [28:0] sum2 ; reg [28:0] yout_t ; always @(posedge clk or negedge rstn) begin if (!rstn) begin sum1 <= 29'd0 ; sum2 <= 29'd0 ; yout_t <= 29'd0 ; end else if(valid_mult7) begin sum1 <= mout[0] + mout[1] + mout[2] + mout[3] ; sum2 <= mout[4] + mout[5] + mout[6] + mout[7] ; yout_t <= sum1 + sum2 ; end end`else //一步计算累加结果,但是实际中时序非常危险 reg signed [28:0] sum ; reg signed [28:0] yout_t ; always @(posedge clk or negedge rstn) begin if (!rstn) begin sum <= 29'd0 ; yout_t <= 29'd0 ; end else if (valid_mult7) begin sum <= mout[0] + mout[1] + mout[2] + mout[3] + mout[4] + mout[5] + mout[6] + mout[7]; yout_t export
将滤波器参数输出,存到变量 coef 中,如下图所示。
此时 coef 变量应该是浮点型数据。对其进行一定倍数的相乘扩大,然后取其近似的定点型数据作为设计中的 fir 滤波器参数。这里取扩大倍数为 2048,结果如下所示。
◆生成输入的混合信号
利用 matlab 生成混合的输入信号参考代码如下。
信号为无符号定点型数据,位宽宽度为 12bit,存于文件 'cosx0p25m7p5m12bit.txt' 。
clear all;close all;clc;%=======================================================% generating a cos wave data with txt hex format%=======================================================fc = 0.25e6 ; % 中心频率fn = 7.5e6 ; % 杂波频率fs = 50e6 ; % 采样频率t = 1/fc ; % 信号周期num = fs * t ; % 周期内信号采样点数t = (0:num-1)/fs ; % 离散时间cosx = cos(2*pi*fc*t) ; % 中心频率正弦信号cosn = cos(2*pi*fn*t) ; % 杂波信号cosy = mapminmax(cosx + cosn) ; %幅值扩展到(-1,1) 之间cosy_dig = floor((2^11-1) * cosy + 2^11) ; %幅值扩展到 0~4095fid = fopen('cosx0p25m7p5m12bit.txt', 'wt') ; %写数据文件fprintf(fid, '%x\\n', cosy_dig) ;fclose(fid) ;%时域波形figure(1);subplot(121);plot(t,cosx);hold on ;plot(t,cosn) ;subplot(122);plot(t,cosy_dig) ;%频域波形fft_cosy = fftshift(fft(cosy, num)) ;f_axis = (-num/2 : num/2 - 1) * (fs/num) ;figure(5) ;plot(f_axis, abs(fft_cosy)) ;

旋转LED显示屏的制作
AVR USB接口的温度测量系统下位机设计
白酒甲醇快速检测仪的特点及功能
二手车交易市场混乱,商务部将入局监督
PLC的扫描周期_PLC输入/输出滞后时间
Verilog并行FIR滤波器设计
一加 9RT旗舰正式发布 性能拉满全面加料
正点原子开拓者FPGA:ADDA实验(PCF8591)
英飞凌2017业绩回顾及2018展望 致力可持续增长与中国共赢
Dialog半导体将收购Adesto Technologies进一步拓展工业物联网市场
一分钟了解如何使用灵科超声波焊接LED车灯
蓝牙AOA室内定位的精度有多少
Chris_zhangrx的博客
布局物流自动驾驶,物流企业正在下一盘什么棋
致动器的定义
2017年作为iPhone十周年 iPhone8将华丽大变身
苹果正研发下一代Face ID
PLC编程中设备故障了怎么办
从网络供应商的角度看5G,为何能推动虚拟化发展
使用STM32快速开发AliOS Things硬件与软件环境