目录

前言

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滤波器相关推荐

  1. Matlab实现 理想低通、巴特沃斯低通、高斯低通、理想高通、巴特沃斯高通、高斯高通(d=10,50,150)

    数字图像处理第二次编程课后作业 理想低通(d=10,50,150): close all; clear all;%% ---------Ideal Lowpass Filters (Fre. Doma ...

  2. matlab常见的图像增强技术(包括基于幂次变换,对图像进行均衡化处理,巴特沃斯低通,理想低通,梯形低通滤波, 均值滤波,中值滤波,最大,最小值滤波,修正后的阿尔法滤波器)

    1.基于幂次变换中的r值,比较不同r 值下图像增强的效果 代码 : I = imread('D:\图片\TH.JFIF');subplot (1,4,1);imshow(I);title('原始图像' ...

  3. MATLAB巴特沃斯低通滤波图像

    clc,clear,close all % 清理命令区.清理工作区.关闭显示图形 warning off % 消除警告 feature jit off % 加速代码运行 D0 = 20; % 阻止的频 ...

  4. c++ opencv数字图像处理:频率域滤波--低通滤波--巴特沃斯低通滤波

    文章目录 前言 一.巴特沃斯低通滤波器(BLPF) 二.代码 三.说明 前言 数字图像处理c++ opencv(VS2019 opencv4.53)持续更新 一.巴特沃斯低通滤波器(BLPF) D2( ...

  5. 用matlab编程实现数字图像理想低通滤波、高斯低通滤波和巴特沃斯低通滤波去噪算法

    1 理想低通滤波 %理想低通 I = imread('fig.png'); I=rgb2gray(I); figure(1); subplot(221),imshow(I); title('原图像') ...

  6. 设计线性相位高通FIR滤波器

    调用MATLAB工具箱函数frl设计线性相位高通FIR滤波器.要求通带截止频奉为0.6 Πrad,限带截止频率为0.45 Πrad,通带最大衰成为0.2 dB.阻带最小衰减为45dB.显示所设计的单位 ...

  7. PX4中的二阶巴特沃斯低通滤波

    源码 const float fr = sample_freq/_cuttof_freq; const float ohm = tanf(M_PI_F, fr); const float c = 1. ...

  8. python理想低通滤波、巴特沃斯低通滤波、高斯低通滤波实现

    代码 代码如下(示例): import numpy as np import cv2 as cv image = cv.imread('2.PNG') # print(image.shape) ima ...

  9. 计算机视觉(二)-matlab之理想低通滤波器,布特沃斯低通、高斯低通,理想高通、布特沃斯高通、高斯高通滤波器

    未整理完! 在滤波器之前,先讲解傅里叶变换 理想低通滤波器 f = imread('Fig0441.tif'); f = im2double(f);% 计算填充图像大小 [M,N] = size(f) ...

  10. 3.2 Python图像的频域图像增强-高通和低通滤波器

    3.2 Python图像的频域图像增强-高通和低通滤波器 文章目录 3.2 Python图像的频域图像增强-高通和低通滤波器 1 算法原理 1.1理想滤波器 1.2巴特沃斯滤波器 1.3指数滤波器 2 ...

最新文章

  1. 纯python好找工作吗_学西点好找工作吗?
  2. 1gitolite构建git服务器
  3. tinyxml学习2
  4. 有意思的C语言运算符
  5. vsftpd pam mysql_vsftpd+mysql+pam实现基于数据库的安全的ftp服务
  6. 安装配置远程工具Xmanager
  7. IDEA安装“Alibaba Java Coding Guidelines”插件
  8. BUPT复试专题—统计字母(2008)
  9. VMware 下安装centos7,无法进入图形化界面
  10. (转)关于电子书格式比较
  11. 项目日报模板_中山首个地下综合管廊项目取得重大进展
  12. 请不要“妖魔化”外包
  13. 按照日期:蓝桥杯真题、洛谷题单、力扣题单汇总
  14. 4.11 51单片机-LCD1602显示屏
  15. mac安装mysql workbench_MAC上安装mysql及workbench
  16. scpjsv3模组链接_我的世界scpv3下载-我的世界scpv3模组下载-4399J小游戏
  17. HCIA学习笔记#1
  18. C语言读取BMP格式图片
  19. css导航栏很多怎么办,css导航栏的疑问
  20. SuperMap iDesktop 从零开始创建 C# 类库进行插件开发

热门文章

  1. 给程序员推荐的一款机械键盘
  2. 风尘若幻_封装win7_sp3(终于可以和大家见面了,欢迎试用-谢谢支持!!!)
  3. 怎样用matlab画斜条纹图案,CorelDRAW制作简单的均匀倾斜条纹
  4. MD5文件加解密工具类 MD5Utils
  5. html5 for vs2008插件,Chart 控件 for vs2008的安装
  6. 让老主板更新驱动程序不再拒绝新网卡(转)
  7. 《松本行弘的程序世界》精彩书摘
  8. 中标麒麟系统u盘安装_如何用u盘安装中标麒麟桌面操作系统v6.0
  9. oracle -varchar ,varchar2
  10. WPS Office 2016 专业增强精简版 附终身授权正版序列号