FPGA:verilog实现直接型巴特沃斯高通IIR滤波器
目录
前言
1、matlab设计滤波器
1.1、通过FDATOOL设计滤波器
1.2、对滤波器系数进行量化
2、verilog设计IIR滤波器
2.1 零点模块
2.2 极点模块
2.3 顶层文件
3、vivado仿真
3.1 matlab生成测试数据
3.2vivado添加测试数据
3.3添加tb文件运行仿真
总结
前言
在matlab设计7阶(8级)高通IIR巴特沃斯滤波器,并实现verilog代码,并在vivado中进行仿真
1、matlab设计滤波器
1.1、通过FDATOOL设计滤波器
打开matlab,在APP这一栏的搜索框中搜索 ’filter‘ 或直接搜索 ’滤波器‘ ,单击打开(matlab版本为2022a)
我们要设计的滤波器的相应类型为高通,设计方法为IIR 巴特沃斯,采样频率Fs设置为1M(1000k),Fc设置为200k。在下面的界面填好这些参数,并点击设计滤波器。
我们可以从当前滤波器信息窗口看到,我们设计的滤波器目前的结构是级联型,七阶(8)级的滤波器被设计为4个节,其中三个节是2阶(3级),一个节是1阶(2级),2*3+1 = 7,组成了我们的七阶滤波器。
为了设计成直接型,我们对滤波器的结构进行转换
打开编辑-转换结构
选择Direct-Form Ⅰ
转化为单节
到这里就完成了到直接型的转化,下一步我们可以看看量化效应,对滤波器效果的影响,根据下图操作,可以看到幅值响应区域出现了量化前后的幅频响应曲线。
可以看到16位量化后,滤波器的性能产生了恶化,但在可接受范围内,实际工程中可以通过级联型的滤波器来减小量化带来的误差。
进行如下操作,将滤波器系数导出到matlab工作区
Den Num这里分别是分母和分子
1.2、对滤波器系数进行量化
在matlab中运行下面代码(来自杜勇老师的《数字滤波器的matlab与fpga实现》)
Qcoe = 16
b = Num;
a = Den;%对滤波器系数进行量化,四舍五入截尾
m=max(max(abs(a),abs(b)));
Qm = floor(log2(m/a(1)))if Qm<log2(m/a(1))Qm = Qm + 1;
end
Qm = 2^Qm;Qb16=round(b/Qm*(2^(Qcoe-1)-1))
Qa16=round(a/Qm*(2^(Qcoe-1)-1))
运行结果如下:
Qb16 =列 1 至 5742 -5197 15590 -25982 25982列 6 至 8-15590 5197 -742Qa16 =列 1 至 516384 -22761 27443 -17266 8332列 6 至 8-2373 430 -33
可以看到零点系数Qb16具有对称性
2、verilog设计IIR滤波器
2.1 零点模块
module Zero(input rst, input clk,input signed [11:0] Xin,output signed [30:0] Xout
);//-------------------------------------------------------
// 将数据移位寄存
//-------------------------------------------------------reg signed [11:0] Xin_Reg[6:0];reg [3:0] i,j; always @(posedge clk or posedge rst)if (rst)begin for (i=0; i<7; i=i+1)Xin_Reg[i]=12'd0;endelsebeginfor (j=0; j<6; j=j+1)Xin_Reg[j+1] <= Xin_Reg[j];Xin_Reg[0] <= Xin;end//-------------------------------------------------------
// 将对称数据相加,结果存储在数组中 2个12bit数据相加,结果为13bit
//------------------------------------------------------- wire signed [12:0] Add_Reg[3:0];assign Add_Reg[0] = {Xin[11],Xin} - {Xin_Reg[6][11],Xin_Reg[6]};assign Add_Reg[1] = {Xin_Reg[0][11],Xin_Reg[0]} - {Xin_Reg[5][11],Xin_Reg[5]};assign Add_Reg[2] = {Xin_Reg[1][11],Xin_Reg[1]} - {Xin_Reg[4][11],Xin_Reg[4]};assign Add_Reg[3] = {Xin_Reg[2][11],Xin_Reg[2]} - {Xin_Reg[3][11],Xin_Reg[3]}; //-------------------------------------------------------
// 将数据与系数相乘,结果存储在数组中 13bit与16bit相乘,结果为28bit
//------------------------------------------------------- wire signed [27:0] Mult_Reg[3:0];wire signed [15:0] coe [3:0];assign coe[0] = 16'd742;assign coe[1] = -16'd5196;assign coe[2] = 16'd15589;assign coe[3] = -16'd25982;
//-------------------------------------------------------
// 调用4个乘法器,设置为13bit有符号数和16bit有符号数相乘
//------------------------------------------------------- mult_gen_0 Umultz0 (.A (Add_Reg[0]),.B (coe[0]),.P (Mult_Reg[0]));mult_gen_0 Umultz1 (.A (Add_Reg[1]),.B (coe[1]),.P (Mult_Reg[1]));mult_gen_0 Umultz2 (.A (Add_Reg[2]),.B (coe[2]),.P (Mult_Reg[2]));mult_gen_0 Umultz3 (.A (Add_Reg[3]),.B (coe[3]),.P (Mult_Reg[3]));assign Xout = {{3{Mult_Reg[0][27]}},Mult_Reg[0]}+ {{3{Mult_Reg[1][27]}},Mult_Reg[1]}+{{3{Mult_Reg[2][27]}},Mult_Reg[2]}+{{3{Mult_Reg[3][27]}},Mult_Reg[3]};endmodule
这里的乘法器调用了vivado的乘法IP,设置为13bit有符号数和16bit有符号数相乘,输出结果设置为28bit,因为输入数据不可能同时出现最大负值。流水线级数设置为0。
这种做法的缺点是比较浪费资源,在资源比较宝贵的项目中不要采取这种方法。可以采取移位相加法来节省资源,也可以对不同的大小的系数,用不同输入位宽的乘法器,比方说乘以742可以设置IP核的输入为11位,相比于16位,可以节省资源。
但这样做的好处是,移植起来很方便,调用的时候把参数填进coe[]数组就好了,可以节省很多时间
可以按照下图进行设置,如果仿真结果有问题,很有可能就是乘法IP设置出错了。
2.2 极点模块
module Pole(input rst , input clk , input signed [11:0] Yin , output signed [30:0] Yout
);reg signed[11:0] Yin_Reg[6:0];reg [3:0] i,j; //-------------------------------------------------------
// 将数据移位寄存
//-------------------------------------------------------always @(posedge clk or posedge rst)if (rst)begin for (i=0; i<7; i=i+1)Yin_Reg[i]=12'd0;endelsebeginfor (j=0; j<6; j=j+1)Yin_Reg[j+1] <= Yin_Reg[j];Yin_Reg[0] <= Yin;end
//-------------------------------------------------------
// 将数据与系数相乘,结果存储在数组中 12bit与16bit相乘,结果为27bit
//------------------------------------------------------- wire signed [16:0] coe[6:0] ; wire signed [26:0] Mult_Reg[7:0]; assign coe[0]= -16'd22761 ;assign coe[1]= 16'd27443 ;assign coe[2]= -16'd17266 ; assign coe[3]= 16'd8332 ; assign coe[4]= -16'd2373 ;assign coe[5]= 16'd430 ; assign coe[6]= -16'd33 ; //-------------------------------------------------------
// 调用七个乘法器,设置为12bit有符号数和16bit有符号数相乘
//------------------------------------------------------- mult_gen_1 Umult1 (.A (Yin_Reg[0]),.B (coe[0]),.P (Mult_Reg[0])); mult_gen_1 Umult2 (.A (Yin_Reg[1]),.B (coe[1]),.P (Mult_Reg[1]));mult_gen_1 Umult3 (.A (Yin_Reg[2]),.B (coe[2]),.P (Mult_Reg[2]));mult_gen_1 Umult4 (.A (Yin_Reg[3]),.B (coe[3]),.P (Mult_Reg[3])); mult_gen_1 Umult5 (.A (Yin_Reg[4]),.B (coe[4]),.P (Mult_Reg[4])); mult_gen_1 Umult6 (.A (Yin_Reg[5]),.B (coe[5]),.P (Mult_Reg[5])); mult_gen_1 Umult7 (.A (Yin_Reg[6]),.B (coe[6]),.P (Mult_Reg[6]));assign Yout = {{4{Mult_Reg[0][26]}},Mult_Reg[0]}+{{4{Mult_Reg[1][26]}},Mult_Reg[1]}+{{4{Mult_Reg[2][26]}},Mult_Reg[2]}+{{4{Mult_Reg[3][26]}},Mult_Reg[3]}+{{4{Mult_Reg[4][26]}},Mult_Reg[4]}+{{4{Mult_Reg[5][26]}},Mult_Reg[5]}+{{4{Mult_Reg[6][26]}},Mult_Reg[6]};endmodule
这里的乘法IP设计跟零点模块基本相同,就不重复了
2.3 顶层文件
module IIR_Direct (input rst,input clk,input signed [11:0] din,output signed [11:0] dout);wire signed [30:0] Xout;Zero U0 (.rst (rst),.clk (clk),.Xin (din),.Xout (Xout));wire signed [11:0] Yin;wire signed [30:0] Yout;Pole U1 (.rst (rst),.clk (clk),.Yin (Yin),.Yout (Yout));wire signed [30:0] Ysum;assign Ysum = Xout - Yout;//将Ydiv右移14位,相当于除了16384wire signed [30:0] Ydiv;assign Ydiv = {{14{Ysum[30]}},Ysum[30:14]};//直接对结果进行截尾assign Yin = (rst ? 12'd0 : Ydiv[11:0]);assign dout = Yin;endmodule
3、vivado仿真
vivado仿真需要测试数据,以及仿真tb文件,给出代码如下:
3.1 matlab生成测试数据
为了验证高通滤波器,我们生成的测试信号由50k和250k的正弦信号叠加而成。生成的二进制文件为Bin_s.txt
f1=50000; %信号1频率为50KHz
f2=250000; %信号2频率为250KHzFs=1000000; %采样频率为1MHz
N=12; %量化位数%产生信号
t=0:(1/Fs):0.0012;
c1=2*pi*f1*t;
c2=2*pi*f2*t;s1=sin(c1);%产生正弦波
s2=sin(c2);%产生正弦波s=0.5*s1+0.5*s2;
plot(t,s1,t,s);
Q_s=round(s*(2^(N-1)-1));%% 生成txt文件们
%将生成的数据以十进制数据格式写入txt文件中fid=fopen('Int_s.txt','w');
fprintf(fid,'%8d\r\n',Q_s);
fprintf(fid,';');
fclose(fid);%将生成的数据以二进制数据格式写入txt文件中fid=fopen('Bin_s.txt','w');
for i=1:length(Q_s)B_s=dec2bin(Q_s(i)+(Q_s(i)<0)*2^N,N)for j=1:Nif B_s(j)=='1'tb=1;elsetb=0;endfprintf(fid,'%d',tb); endfprintf(fid,'\r\n');
end
fprintf(fid,';');
fclose(fid);
3.2vivado添加测试数据
需要将测试数据添加到vivado环境中,仿真才能正常运行,我的做法如下
3.3添加tb文件运行仿真
tb文件如下
`timescale 1ns / 1psmodule IIR_tb();reg clk;
reg [11:0] din;
reg rst;
wire [11:0] dout;IIR_Direct i1 (.clk(clk),.din(din),.dout(dout),.rst(rst)
);parameter clk_period=626;
parameter clk_half_period=clk_period/2;
parameter data_num=2000;
parameter time_sim=data_num*clk_period/2; initial
beginclk=1;rst=1;#10000 rst=0;#time_sim $finish;din=12'd10;
endalways #clk_half_period clk=~clk;integer Pattern;
reg [11:0] stimulus[1:data_num];
initial
begin$readmemb("Bin_s.txt",stimulus);Pattern=0;repeat(data_num)beginPattern=Pattern+1;din=stimulus[Pattern];#clk_period;end
endinteger file_out;
initial
begin file_out = $fopen("Bin_s_out.txt");if(!file_out)begin$display("could not open file!");$finish;end
end
wire rst_write;
wire signed [11:0] dout_s;
assign dout_s = dout;
assign rst_write = clk& (!rst);
always @(posedge rst_write )$fdisplay(file_out,"%d",dout_s);endmodule
局部放大如下:
总结
本篇文章在matlab设计7阶(8级)高通IIR巴特沃斯滤波器,并实现verilog代码,并在vivado中进行仿真,结果符合预期。
FPGA:verilog实现直接型巴特沃斯高通IIR滤波器相关推荐
- Matlab实现 理想低通、巴特沃斯低通、高斯低通、理想高通、巴特沃斯高通、高斯高通(d=10,50,150)
数字图像处理第二次编程课后作业 理想低通(d=10,50,150): close all; clear all;%% ---------Ideal Lowpass Filters (Fre. Doma ...
- matlab常见的图像增强技术(包括基于幂次变换,对图像进行均衡化处理,巴特沃斯低通,理想低通,梯形低通滤波, 均值滤波,中值滤波,最大,最小值滤波,修正后的阿尔法滤波器)
1.基于幂次变换中的r值,比较不同r 值下图像增强的效果 代码 : I = imread('D:\图片\TH.JFIF');subplot (1,4,1);imshow(I);title('原始图像' ...
- MATLAB巴特沃斯低通滤波图像
clc,clear,close all % 清理命令区.清理工作区.关闭显示图形 warning off % 消除警告 feature jit off % 加速代码运行 D0 = 20; % 阻止的频 ...
- c++ opencv数字图像处理:频率域滤波--低通滤波--巴特沃斯低通滤波
文章目录 前言 一.巴特沃斯低通滤波器(BLPF) 二.代码 三.说明 前言 数字图像处理c++ opencv(VS2019 opencv4.53)持续更新 一.巴特沃斯低通滤波器(BLPF) D2( ...
- 用matlab编程实现数字图像理想低通滤波、高斯低通滤波和巴特沃斯低通滤波去噪算法
1 理想低通滤波 %理想低通 I = imread('fig.png'); I=rgb2gray(I); figure(1); subplot(221),imshow(I); title('原图像') ...
- 设计线性相位高通FIR滤波器
调用MATLAB工具箱函数frl设计线性相位高通FIR滤波器.要求通带截止频奉为0.6 Πrad,限带截止频率为0.45 Πrad,通带最大衰成为0.2 dB.阻带最小衰减为45dB.显示所设计的单位 ...
- PX4中的二阶巴特沃斯低通滤波
源码 const float fr = sample_freq/_cuttof_freq; const float ohm = tanf(M_PI_F, fr); const float c = 1. ...
- python理想低通滤波、巴特沃斯低通滤波、高斯低通滤波实现
代码 代码如下(示例): import numpy as np import cv2 as cv image = cv.imread('2.PNG') # print(image.shape) ima ...
- 计算机视觉(二)-matlab之理想低通滤波器,布特沃斯低通、高斯低通,理想高通、布特沃斯高通、高斯高通滤波器
未整理完! 在滤波器之前,先讲解傅里叶变换 理想低通滤波器 f = imread('Fig0441.tif'); f = im2double(f);% 计算填充图像大小 [M,N] = size(f) ...
- 3.2 Python图像的频域图像增强-高通和低通滤波器
3.2 Python图像的频域图像增强-高通和低通滤波器 文章目录 3.2 Python图像的频域图像增强-高通和低通滤波器 1 算法原理 1.1理想滤波器 1.2巴特沃斯滤波器 1.3指数滤波器 2 ...
最新文章
- 纯python好找工作吗_学西点好找工作吗?
- 1gitolite构建git服务器
- tinyxml学习2
- 有意思的C语言运算符
- vsftpd pam mysql_vsftpd+mysql+pam实现基于数据库的安全的ftp服务
- 安装配置远程工具Xmanager
- IDEA安装“Alibaba Java Coding Guidelines”插件
- BUPT复试专题—统计字母(2008)
- VMware 下安装centos7,无法进入图形化界面
- (转)关于电子书格式比较
- 项目日报模板_中山首个地下综合管廊项目取得重大进展
- 请不要“妖魔化”外包
- 按照日期:蓝桥杯真题、洛谷题单、力扣题单汇总
- 4.11 51单片机-LCD1602显示屏
- mac安装mysql workbench_MAC上安装mysql及workbench
- scpjsv3模组链接_我的世界scpv3下载-我的世界scpv3模组下载-4399J小游戏
- HCIA学习笔记#1
- C语言读取BMP格式图片
- css导航栏很多怎么办,css导航栏的疑问
- SuperMap iDesktop 从零开始创建 C# 类库进行插件开发
热门文章
- 给程序员推荐的一款机械键盘
- 风尘若幻_封装win7_sp3(终于可以和大家见面了,欢迎试用-谢谢支持!!!)
- 怎样用matlab画斜条纹图案,CorelDRAW制作简单的均匀倾斜条纹
- MD5文件加解密工具类 MD5Utils
- html5 for vs2008插件,Chart 控件 for vs2008的安装
- 让老主板更新驱动程序不再拒绝新网卡(转)
- 《松本行弘的程序世界》精彩书摘
- 中标麒麟系统u盘安装_如何用u盘安装中标麒麟桌面操作系统v6.0
- oracle -varchar ,varchar2
- WPS Office 2016 专业增强精简版 附终身授权正版序列号