基于Verilog语言的FIR滤波【程序和理解】
一直想找一个简单、清晰、明了的fir滤波器的设计,终于找到了一个可以应用的,和大家分享一下,有助于FPGA新手入门。
1.说道fir滤波器,滤波系数肯定是最重要的,因为后面程序中涉及到滤波系数问题,所以先来介绍,此处使用matlab来辅助求出。
①打开matlab中的start,toolbox,filter design,filter design & Analysis Tool,具体位置见下图。
②选择想要涉及的滤波器类型,本次以8阶fir滤波器为例。
设计参数:低通fir滤波器,采样精度是根据自己的输入数据来的,本例为25MHz,通过频率2MHz,截止频率8MHz,可以在specify order处选择几阶滤波器。
③把滤波器数据导出,选择export,在随后弹出的框中再次点击Export(本步骤可以改变数据的变量名),就可以看到命名为Num的滤波器系数出现在目录里。
④在matlab框中输入指令Num=Num'
可以看到如下结果,这个就是滤波器的系数了,新建一个txt文件,命名如图,把滤波器系数复制进去。
⑤编写matlab程序,进行系数量化。
运行下面一段程序,生成的COF就是最后的量化数据,记录这组数据。
clc;
clear all ;
load COFFICIENT.dat;%加载系数
a1=COFFICIENT(1:1:length(COFFICIENT));
width = 16;%数据宽度8位
% 量化滤波器系数
COF = round(a1 .* (2^(width-1) - 1));%量化正弦波形数据并取整
2.在quartusII中建立一个工程,新建一个fir_filter模块,把我们计算出来的滤波器系数写在程序里面
整体程序如下:
`timescale 1 ns / 1 ns
module fir_filter
(
i_fpga_clk ,
i_rst_n ,
i_filter_in,
o_filter_out
);
input i_fpga_clk ; //25MHz
input i_rst_n ;
input signed [7:0] i_filter_in ; //数据速率25Mh
output signed [7:0] o_filter_out; //滤波输出
//==============================================================
//8阶滤波器系数,共9个系数,系数对称
//==============================================================
wire signed[15:0] coeff1 = 16'd239 ;
wire signed[15:0] coeff2 = 16'd1507;
wire signed[15:0] coeff3 = 16'd4397;
wire signed[15:0] coeff4 = 16'd7880;
wire signed[15:0] coeff5 = 16'd9493;
//===============================================================
// 延时链
//===============================================================
reg signed [7:0] delay_pipeline1 ;
reg signed [7:0] delay_pipeline2 ;
reg signed [7:0] delay_pipeline3 ;
reg signed [7:0] delay_pipeline4 ;
reg signed [7:0] delay_pipeline5 ;
reg signed [7:0] delay_pipeline6 ;
reg signed [7:0] delay_pipeline7 ;
reg signed [7:0] delay_pipeline8 ;
always@(posedge i_fpga_clk or negedge i_rst_n)
if(!i_rst_n)
begin
delay_pipeline1 <= 8'b0 ;
delay_pipeline2 <= 8'b0 ;
delay_pipeline3 <= 8'b0 ;
delay_pipeline4 <= 8'b0 ;
delay_pipeline5 <= 8'b0 ;
delay_pipeline6 <= 8'b0 ;
delay_pipeline7 <= 8'b0 ;
delay_pipeline8 <= 8'b0 ;
end
else
begin
delay_pipeline1 <= i_filter_in ;
delay_pipeline2 <= delay_pipeline1 ;
delay_pipeline3 <= delay_pipeline2 ;
delay_pipeline4 <= delay_pipeline3 ;
delay_pipeline5 <= delay_pipeline4 ;
delay_pipeline6 <= delay_pipeline5 ;
delay_pipeline7 <= delay_pipeline6 ;
delay_pipeline8 <= delay_pipeline7 ;
end
//================================================================
//加法,对称结构,减少乘法器的数目
//================================================================
reg signed [8:0] add_data1 ;
reg signed [8:0] add_data2 ;
reg signed [8:0] add_data3 ;
reg signed [8:0] add_data4 ;
reg signed [8:0] add_data5 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(0)+x(8)
if(!i_rst_n)
add_data1 <= 9'b0 ;
else
add_data1 <= i_filter_in + delay_pipeline8 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(1)+x(7)
if(!i_rst_n)
add_data2 <= 9'b0 ;
else
add_data2 <= delay_pipeline1 + delay_pipeline7 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(2)+x(6)
if(!i_rst_n)
add_data3 <= 9'b0 ;
else
add_data3 <= delay_pipeline2 + delay_pipeline6 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(3)+x(5)
if(!i_rst_n)
add_data4 <= 9'b0 ;
else
add_data4 <= delay_pipeline3 + delay_pipeline5 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(4)
if(!i_rst_n)
add_data5 <= 9'b0 ;
else
add_data5 <= {delay_pipeline4[7],delay_pipeline4} ;
//===================================================================
//乘法器
//====================================================================
reg signed [24:0] multi_data1 ;
reg signed [24:0] multi_data2 ;
reg signed [24:0] multi_data3 ;
reg signed [24:0] multi_data4 ;
reg signed [24:0] multi_data5 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(0)+x(8))*h(0)
if(!i_rst_n)
multi_data1 <= 24'b0 ;
else
multi_data1 <= add_data1*coeff1 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(1)+x(7))*h(1)
if(!i_rst_n)
multi_data2 <= 24'b0 ;
else
multi_data2 <= add_data2*coeff2 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(2)+x(6))*h(2)
if(!i_rst_n)
multi_data3 <= 24'b0 ;
else
multi_data3 <= add_data3*coeff3 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(0)+x(8))*h(3)
if(!i_rst_n)
multi_data4 <= 24'b0 ;
else
multi_data4 <= add_data4*coeff4 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(4)*h(4)
if(!i_rst_n)
multi_data5 <= 24'b0 ;
else
multi_data5 <= add_data5*coeff5 ;
//========================================================================
//流水线累加
//========================================================================
reg signed[25:0] add_level1_1;//1级
reg signed[25:0] add_level1_2;//1级
reg signed[25:0] add_level1_3;//1级
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(0)+x(8))*h(0)+(x(1)+x(7))*h(1)
if(!i_rst_n)
add_level1_1 <= 26'b0 ;
else
add_level1_1 <= multi_data1+multi_data2 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(2)+x(6))*h(2)+(x(3)+x(5))*h(3)
if(!i_rst_n)
add_level1_2 <= 26'b0 ;
else
add_level1_2 <= multi_data3+multi_data4 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(4)*h(4)
if(!i_rst_n)
add_level1_3 <= 26'b0 ;
else
add_level1_3 <= {multi_data5[24],multi_data5} ;
//==2级加法
reg signed [26:0] add_level2_1 ;
reg signed [26:0] add_level2_2 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //(x(0)+x(8))*h(0)+(x(1)+x(7))*h(1)+(x(2)+x(6))*h(2)+(x(3)+x(5))*h(3)
if(!i_rst_n)
add_level2_1 <= 27'b0 ;
else
add_level2_1 <= add_level1_1+add_level1_2 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(4)*h(4)
if(!i_rst_n)
add_level2_2 <= 27'b0 ;
else
add_level2_2 <= {add_level1_3[25],add_level1_3} ;
//-===3级
reg signed [27:0] add_level3_1 ;
always@(posedge i_fpga_clk or negedge i_rst_n)
if(!i_rst_n)
add_level3_1 <= 27'b0 ;
else
add_level3_1 <= add_level2_1+add_level2_2 ;
//================================================================================
// 5、output
//================================================================================
reg signed [22:0] r_filter_out ;
always@(posedge i_fpga_clk or negedge i_rst_n)
if(!i_rst_n)
r_filter_out <= 23'b0 ;
else
r_filter_out <= (add_level3_1[22:0]+{!add_level3_1[22],{14{add_level3_1[22]}}})>>15 ;//四舍五入输出
//================================================================================
// 6、output 取低8位
//================================================================================
assign o_filter_out = r_filter_out[7:0] ;
endmodule
**************************************总结************************************************
因为输入的数据是AD芯片采样的结果,该AD的采样精度是8位,所以本例使用8阶滤波器,设计的延时链、加法、乘法的程序都是根据8位来的。所以,如果数据输入是16位,或32位等等,需要改变的有设计滤波器的系数等等。
相应的延时链要多添加至reg signed [7:0] delay_pipeline16 ;
加法和乘法也要有相应的改变,举个例子,大家自行修改
always@(posedge i_fpga_clk or negedge i_rst_n) //x(0)+x(16)
if(!i_rst_n)
add_data1 <= 9'b0 ;
else
add_data1 <= i_filter_in + delay_pipeline16 ;
转载自:http://blog.sina.com.cn/s/blog_13b436b340102xfpw.html
关于截位问题:http://bbs.eccn.com/viewthread.php?tid=22773
|
论坛元老
|
|
||
|
新手上路
|
|
|
|
注册会员
|
|
|
|
版主
|
5#
|
|
|
超级版主
|
7#
|
|
|
新手上路
|
9#
|
|
|
新手上路
|
10#
|
|
|
禁止发言
|
|
|
|
新手上路
|
|
|
基于Verilog语言的FIR滤波【程序和理解】的更多相关文章
- 【iCore、iCore2 双核心板】EPCS 实验(SPI Flash)(基于Verilog语言)
_____________________________________ 深入交流QQ群: A: 204255896(1000人超级群,可加入) B: 165201798(500人超级群,满员) C ...
- 基于go语言结合微信小程序开发的微商城系统
最近在慕课网上录制了一门<Golang微信小程序微商城系统原型>,这门免费课程特别适合在校大学生或者刚毕业的大学生,go语言初学者以及想要从事微商城开发项目入门的小伙伴们来学习.在课程当中 ...
- 基于Verilog语言的可维护性设计技术
[注]本文内容主体部分直接翻译参考文献[1]较多内容,因此本文不用于任何商业目的,也不会发表在任何学术刊物上,仅供实验室内部交流和IC设计爱好者交流之用. “曲意而使人喜,不若直节而使人忌:无善而致人 ...
- 【iCore2双核心板】SRAM 读写实验(基于Verilog语言)
_____________________________________ 深入交流QQ群: A: 204255896(1000人超级群,可加入) B: 165201798(500人超级群,满员) C ...
- 基于Verilog的奇数偶数小数分频器设计
今天呢,由泡泡鱼工作室发布的微信公共号“硬件为王”(微信号:king_hardware)正式上线啦,关注有惊喜哦.在这个普天同庆的美好日子里,小编脑洞大开,决定写一首诗赞美一下我们背后伟大的团队,虽然 ...
- 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)
1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...
- 基于php基础语言编写的小程序之计算器
基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...
- 基于MATLAB2016b图形化设计自动生成Verilog语言的积分模块及其应用
在电力电子变流器设备中,常常需要计算发电量,由于电力电子变流器设备一般是高频变流设备,所以发电量的计算几乎时实时功率的积分,此时就会用到一个积分模块.发电量计算的公式如下:Q=∫P. FPGA由于其并 ...
- 概率图模型 基于R语言 这本书中的第一个R语言程序
概率图模型 基于R语言 这本书中的第一个R语言程序 prior <- c(working =0.99,broken =0.01) likelihood <- rbind(working = ...
随机推荐
- C# Sftp操作
SFTP释义-----引自百度百科 sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着 ...
- 普通项目转换成maven项目
参看文档:http://czj4451.iteye.com/blog/1983889 maven仓库:http://mvnrepository.com/ 基本步骤如下: Configue--& ...
- brew 安装PHP的配置文件所在位置
- XenApp应用虚拟化介绍
https://wenku.baidu.com/view/635223c26137ee06eff91864.html
- 二十四种设计模式:工厂方法模式(Factory Method Pattern)
工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...
- 算法之排序Low B三人组
有序区:有的地方的数据已经完全变得有顺序,我们把这部分区域的数据成为有序区无序区:有的地方的数据依旧无序,我们把这部分数据成为无序区时间复杂度:用来估计算法运行时间的一个式子(单位)空间复杂度:用来评 ...
- mysql安装以后无法登陆的的解决方法((ERROR 1698 (28000): Access denied for user 'root'@'localhost'))
mysql安装以后无法登陆的的解决方法((ERROR 1698 (28000): Access denied for user 'root'@'localhost')) 解决步骤: [====> ...
- linux(虚拟机中)与windows共享文件两种方法
Windows 下用 SourceInsight 与 Linux 协作编码 习惯了用SourceInsight 读写代码,在Linux下一时没找到类似的工具,vi的操作也不熟,偶尔看看或小 ...
- 在Oracle 11.2.0.1.0下dbms_stats.gather_table_stats收集直方图不准
SQL> select * from v$version; BANNER ------------------------------------------------------------ ...
- QSignalMapper类的使用
Qt中当定义了非常多的button,而他们的信号都同样时(比方都是点击信号),没有必要给他们每一个都设置信号和槽的链接.QSignalMapper给我们攻克了这个难题. 今天完毕这个相似的功能时,不知 ...


