当前位置: 首页 > news >正文

FIR 数字滤波器 --verilog设计实现

  • FIR数字滤波器设计
    • 在FPGA实现FIR滤波器时,最常用的是直接型结构,简单方便,在实现直接型结构时,可以选择串行结构/并行结构/分布式结构。
    • 串行结构,即串行实现FIR滤波器的乘累加操作,数据的处理速度较慢。N阶串行FIR滤波器,数据的输入速率=系统处理时钟速率/滤波器长度(N+1),本例程使用7阶串行,系统时钟32MHz,这样的数据输入速率(采样率)为4MHz。

串行FIR数字滤波器

  • 信号说明
    • data_in[15:0] :输入信号为0.5MHz叠加1.8MHz信号,采样时钟为4MHz(系统处理时钟/滤波器阶数)16bit量化;
    • h0-h8 :滤波器系数8bit量化,4MHz抽样,低通滤波器(Low Pass Filter,LPF),截止频率为1MHz,窗函数设计。
    • data_out[15:0]:输出信号为0.5MHz信号,16bit。

  • 使用MATLAB获取滤波器系数h0-h7
    • 模拟低通滤波器设计
%设计巴特沃斯模拟滤波器 %通带截止频率: fp(单位Hz) %通带衰减: Rp(单位dB) %阻带截止频率: fs(单位Hz) %阻带衰减: Rs(单位dB) %技术指标要求设置,按自己的需求更改即可。 fp=900;fs=1100; %低通滤波器,理想截止频率在1000Hz左右 %fp=5100;fs=4800; %高通滤波器,理想截止频率在5000Hz左右 %fp=[1100,1900];fs=[900,2100]; %带通实例,理想上限截止频率2000Hz,下限截止频率1000Hz %fp=[900,2100];fs=[1100,1900]; %带阻实例,理想上限截止频率2000Hz,下限截止频率1000Hz Rp=1; %通带衰减1dB Rs=40; %阻带衰减40dB filter_type=1; %1低通,2高通,3带通,4带阻 Wp=2*pi*fp; %转换为角频率,单位rad/s Ws=2*pi*fs; [N,Wc]=buttord(Wp,Ws,Rp,Rs,'s'); %计算巴特沃斯模拟滤波器参数,'s'表示WP WS都是模拟角频率; switch filter_type case 1 [b,a]=butter(N,Wc,'low','s'); %低通 case 2 [b,a]=butter(N,Wc,'high','s'); %高通 case 3 [b,a]=butter(N,Wc,'bandpass','s'); %带通 case 4 [b,a]=butter(N,Wc,'stop','s'); %带阻 end [H,W]=freqs(b,a); %w:模拟角频率,H模拟滤波器的系统函数 mag=abs(H); %幅度 pha=angle(H); %相位 db=20*log10((mag+eps)/max(mag)); %转换为分贝 f=W/(2*pi); %将模拟角频率转换为Hz subplot(2,1,1);plot(f,db); title('模拟滤波器幅频曲线');xlabel('频率(Hz)');ylabel('幅度(dB)'); subplot(2,1,2);plot(f,pha); title('模拟滤波器相频曲线');xlabel('频率(Hz)');ylabel('相位(rad)');

    • 数字滤波器系数设计--利用filterDesigner工具设计数字滤波器
    • 在matlab中输入 filterDesigner 打开滤波器设计工具
>> filterDesigner

  • 参数配置
    • 选择低通滤波器
    • FIR滤波器 -函数
    • 指定阶 -7阶
    • blackman窗函数
    • 频率设定:采样率Fs =4MHz,滤波器截至频率Fc =1MHz

  • 参数量化:
    • 选择左下第三个框
    • 选择定点数
    • 选择8bit
    • 点击应用

  • 导出参数
    • 点击File- Export
    • 点击导出系数
    • 在点击目标-xinlinx系数(coe文件)

  • 生成的coe文件包含h0-h7 ,7阶低通滤波器系数8bit。


  • Verilog代码实现

module fir( input wire clk, //系统时钟 32MHz input wire rst_n, //系统复位信号 input wire data_clk, //数据时钟 4MHz input signed[15:0] data_in, //输入数据16bit, 0.5MHz+1.8MHz信号叠加 output reg signed[15:0] data_out //输出数据16bit, 0.5MHz信号 ); //移位操作,输入数据寄存 reg signed[15:0] x1; reg signed[15:0] x2; reg signed[15:0] x3; reg signed[15:0] x4; reg signed[15:0] x5; reg signed[15:0] x6; reg signed[15:0] x7; always @ (posedge data_clk or negedge rst_n)begin if(!rst_n)begin x1 <= 16'b0; x2 <= 16'b0; x3 <= 16'b0; x4 <= 16'b0; x5 <= 16'b0; x6 <= 16'b0; x7 <= 16'b0; end else begin x1 <= data_in; x2 <= x1; x3 <= x2; x4 <= x3; x5 <= x4; x6 <= x5; x7 <= x6; end end //滤波器系数h[7:0] 由matlab获得 wire signed[7:0] h0 = 8'h00; wire signed[7:0] h1 = 8'hfe; wire signed[7:0] h2 = 8'h13; wire signed[7:0] h3 = 8'h70; wire signed[7:0] h4 = 8'h70; wire signed[7:0] h5 = 8'h13; wire signed[7:0] h6 = 8'hfe; wire signed[7:0] h7 = 8'h06; //计数器实现延时,7阶滤波器,8拍延时 reg [2:0] counter; always @ (posedge clk or negedge rst_n)begin if(~rst_n)begin counter <= 3'b0; end else begin counter <= counter + 1'b1; end end //数据与滤波器系数相乘 reg signed[15:0] mult_a; //寄存的输入数据 reg signed[7:0] mult_b; //滤波器系数 wire signed[23:0] mult_p; //data_in[15:0] * h[7:0] assign mult_p = mult_a * mult_b; always @ (posedge clk or negedge rst_n)begin if(~rst_n)begin mult_a <= 16'b0; mult_b <= 8'b0; end else begin case(counter) 3'b000:begin mult_a <= data_in; mult_b <= h0; end 3'b001:begin mult_a <= x1; mult_b <= h1; end 3'b010:begin mult_a <= x2; mult_b <= h2; end 3'b011:begin mult_a <= x3; mult_b <= h3; end 3'b100:begin mult_a <= x4; mult_b <= h4; end 3'b101:begin mult_a <= x5; mult_b <= h5; end 3'b110:begin mult_a <= x6; mult_b <= h6; end 3'b111:begin mult_a <= x7; mult_b <= h7; end endcase end end //累加求和32bit reg signed[31:0] data_out_temp; always @ (posedge clk or negedge rst_n)begin if(~rst_n)begin data_out_temp <= 32'b0; data_out <= 16'b0; end else begin data_out_temp <= data_out_temp + mult_p; if(counter == 3'b111)begin data_out <= data_out_temp[31:16]; //数据截断,取前16bit data_out_temp <= 32'b0; end end end endmodule

  • 仿真
    • 波形数据产生--由matlab产生数据16bit数据,4MHz刷新
%%清内存,关闭窗口 准备工作 clear close all clc %%signal % f(x) = A1*sin(w1*t+p1) + A2*sin(w2*t+p2); %三要素 A1 = 1; %幅度1 A2 = 0.5; %幅度2 f1 = 0.5; %信号1频率为 0.5MHz f2 = 1.8; %信号2频率为 1.8MHz Fs = 4; %采样频率为 4MHz N = 16; %量化位数 16bit w1 = 2*pi*f1; %角频率1 w2 = 2*pi*f2; %角频率2 p1 = 0; %相位1 p2 = 0; %相位2 %采样 T = 16; %fs = 20*f; d = 1/Fs; t = -T/2:d:T/2; s1 = A1*sin(w1*t+p1); s2 = A2*sin(w2*t+p2); %s2 = A2*sin(w2*t+p); s = s1 +s2; save sinwave.txt -ascii s; fid= fopen('data_signed.txt','w'); %保存文本文档的文件名 % fprintf(fid,'%d',data_signed); fprintf(fid,'%04x\r\n',typecast(int16(s),'uint16')); fclose(fid); figure(1) subplot(3,1,1); plot(t,s1); xlabel('时间/s'); ylabel('幅度'); subplot(3,1,2); plot(t,s2); xlabel('时间/s'); ylabel('幅度'); subplot(3,1,3); plot(t,s); xlabel('时间/s'); ylabel('幅度');

    • testbench
module tb_fir_filter(); reg clk; reg rst_n; reg data_clk; reg signed[15:0] data_in; wire signed[15:0] data_out; initial begin $dumpfile("wave.vcd"); //生成的vcd文件名称 $dumpvars(0,tb_fir_filter ); //tb模块名称 end initial begin clk = 1'b0; data_clk = 1'b0; rst_n = 1'b0; #100 rst_n = 1'b1; end always #16 clk = ~clk; //32MHz always #128 data_clk = ~data_clk; //4MHz //将matlab生成的数据导入到寄存器中 parameter data_num = 64; //4个周期 reg [5:0] addr; reg [15:0] mem [0:data_num-1]; initial begin # 100; $readmemh("data_signed.txt", mem); addr = 6'b0; end always #10 begin data_in = mem[addr][15:0]; addr = addr + 1'b1; end fir uut( .clk (clk), .rst_n (rst_n), .data_clk (data_clk), .data_in (data_in), .data_out (data_out) ); endmodule

http://www.jsqmd.com/news/1107369/

相关文章:

  • 60 TOPS NPU工业AI部署实战:分得利光选机
  • 高管终面被问到五年内有什么职业规划?留学生用业务生命周期作答「蒸汽求职分享」
  • Python爬虫经典案例031:天气数据爬取:气象数据采集实战
  • 基于着色Petri网的购物系统建模
  • ChanlunX缠论插件终极指南:5分钟实现通达信缠论自动化分析
  • 踩坑总结:Spring @Transactional 事务注解的这几个坑,你踩过几个?
  • 终极隐私保护神器:Boss-Key老板键一键隐藏Windows窗口完整指南
  • MeEdu开源教育系统:如何构建多云协同的视频点播架构
  • OptiStruct自从有了NVHD,整车NVH分析so easy
  • IAP升级方案
  • linux 安装达梦数据库
  • npm 包开发避坑指南:Scope 命名空间管理的 4 种常见错误与修复方案
  • KeyStore Explorer:为什么Java开发者需要告别keytool命令行的五个理由
  • AI + 智能客服系统完整设计方案
  • ONNX模型解析与优化实战指南
  • Jmeter基础知识详解
  • Linux无线网卡兼容性难题:RTL8821CU驱动深度配置指南
  • 电子系统散热管理:从芯片级到系统级的优化策略
  • 2026进口闸阀品牌排行榜
  • 计算机毕业设计之河北经贸大学毕业生就业跟踪系统
  • Agent工作流编排的“可控性”难题:SwarmFlow的解决方案
  • 如何在Windows和Mac电脑上录制特定窗口
  • GitHub Copilot × IDEA效率黑盒拆解(仅限内部技术团队流通的LLM token调度策略)
  • Krita Vision Tools深度解析:AI智能选区工具的创新应用实战指南
  • 铜钟音乐:5分钟掌握纯净无干扰的免费听歌平台终极指南
  • Redis 连接失败对网站的影响:何时该先测网络再查缓存
  • KMX63与PIC18F87J10实现低成本自然交互方案
  • 从工具到思维:2025年,AI模型如何重写产业规则?
  • MANO手部模型完整指南:从零开始构建3D手部动画
  • 终极隐私保护方案:Boss-Key老板键一键隐藏Windows窗口的完整教程