基于Quartues ii和Modelsim的FIR滤波器仿真

这篇具有很好参考价值的文章主要介绍了基于Quartues ii和Modelsim的FIR滤波器仿真。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Quartues ii和Modelsim的FIR滤波器仿真

设计需求

本设计需要实现基于FPGA的FIR低通滤波,采样频率5MHz,截止频率100kHz,利用Matlab设计FIR滤波器系数,并生成测试数据保存至txt文件。在Quartues ii中编写FIR滤波器模块,联合Modelsim进行功能仿真,观察滤波效果。

设计思路

本设计分为两个部分,一个是MATLAB中测试数据的产生和FIR滤波器的设计及验证;另一部分是Quartues ii中基于Verilog的FIR滤波器模块及testbench编写。

设计过程

MATLAB生成测试数据

用MATLAB产生5kHz和800kHz的混频信号,代码如下:

Fs = 5000000; %采样频率决定了两个正弦波点之间的间隔
N = 8192;     %采样点数
N1 = 0 : 1/Fs : N/Fs-1/Fs; %以频率Fs采8192个点的数据
s = sin(5000*2*pi*N1) + sin(800000*2*pi*N1)+3;

figure(1);
plot(N1,s)

得到的波形如图1所示
基于Quartues ii和Modelsim的FIR滤波器仿真

图1. 混频信号波形
将波形数据进行量化,并转换为十六进制保存到mem.txt中,作为原始数据导入到Modelsim中对所写的FIR滤波器模块进行测试。MATLAB代码如下:
fidc = fopen('E:\fault_detection_code\FIR_test1\mem.txt','wt');  
%将结果写入mem.txt文件,便于modesim使用
for x = 1 : N
   fprintf(fidc,'%x\n',round((s(x)/10)*4096));
end 
fclose(fidc);  

利用filterdesigner工具设计FIR滤波器

在MATLAB中用filterdesigner命令调出滤波器设计工具,界面如图2
基于Quartues ii和Modelsim的FIR滤波器仿真

图2. 滤波器设计工具

选择低通FIR滤波器,选择Hamming窗,设定阶数10阶,采样频率5MHz,截止频率100kHz,点击设计滤波器可以看到滤波器的幅频特性曲线。选择文件->导出,将滤波器系数导出到工作区。设计完成后生成的MATLAB代码,如下:
function Hd = test_filter_kaiser
%TEST_FILTER_KAISER 返回离散时间滤波器对象。

% MATLAB Code
% Generated by MATLAB(R) 9.9 and Signal Processing Toolbox 8.5.
% Generated on: 16-Sep-2022 11:01:37

% FIR Window Lowpass filter designed using the FIR1 function.

% All frequency values are in kHz.
Fs = 5000;  % Sampling Frequency

N    = 10;       % Order
Fc   = 100;      % Cutoff Frequency
flag = 'scale';  % Sampling Flag
Beta = 0.5;      % Window Parameter

% Create the window vector for the design algorithm.
win = kaiser(N+1, Beta);

% Calculate the coefficients using the FIR1 function.
b  = fir1(N, Fc/(Fs/2), 'low', win, flag);
Hd = dfilt.dffir(b);

% [EOF]

调用生成的滤波器函数对前文生成的混频信号进行滤波,

H=test_filter1;
d=filter(H,s);

figure(2);
plot(N1,d)

得到结果如图3所示,对比图1和图3,可以看到高频成分衰减了很多。
基于Quartues ii和Modelsim的FIR滤波器仿真

图3. 滤波后的波形

将设计的FIR滤波器抽头系数导出来。如下:
导出的FIR滤波器抽头系数为
0.0138133379804440 ,
0.0296928583924488 ,
0.0717059583915281 ,
0.124585240157610 ,
0.167915751691329 ,
0.184573706773281 ,
0.167915751691329 ,
0.124585240157610 ,
0.0717059583915281 ,
0.0296928583924488 ,
0.0138133379804440,
对其进行量化处理,乘以2^10后取整,得到抽头系数
14,30,73,128,172,189,172,128,73,30,14

在Quartues ii中编写FIR滤波器模块

代码如下:

module FIR_test1(
	input CLK,
	input RSTn,
	input [11:0]FIR_IN,
	output reg [23:0]FIR_OUT
);
	
	

reg[11:0] delay_pipeline1;
reg[11:0] delay_pipeline2;
reg[11:0] delay_pipeline3;
reg[11:0] delay_pipeline4;
reg[11:0] delay_pipeline5;
reg[11:0] delay_pipeline6;
reg[11:0] delay_pipeline7;
reg[11:0] delay_pipeline8;
reg[11:0] delay_pipeline9;
reg[11:0] delay_pipeline10;
reg[11:0] delay_pipeline11;


wire[7:0] coeff1 = 8'd14;	//抽头系数
wire[7:0] coeff2 = 8'd30;
wire[7:0] coeff3 = 8'd73;
wire[7:0] coeff4 = 8'd128;
wire[8:0] coeff5 = 9'd172;
wire[7:0] coeff6 = 8'd189;
wire[7:0] coeff7 = 8'd172;
wire[7:0] coeff8 = 8'd128;
wire[7:0] coeff9 = 8'd73;
wire[7:0] coeff10 = 8'd30;
wire[7:0] coeff11 = 8'd14;

reg signed [23:0] multi_data1 ;//乘积结果
reg signed [23:0] multi_data2 ;
reg signed [23:0] multi_data3 ;
reg signed [23:0] multi_data4 ;
reg signed [23:0] multi_data5 ;
reg signed [23:0] multi_data6 ;
reg signed [23:0] multi_data7 ;
reg signed [23:0] multi_data8 ;
reg signed [23:0] multi_data9 ;
reg signed [23:0] multi_data10 ;
reg signed [23:0] multi_data11 ;


//每到来一个时钟信号,读入一个数据,更新一次delay_pipeline。
always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
	delay_pipeline1 <= 12'b0 ;
	delay_pipeline2 <= 12'b0 ;
	delay_pipeline3 <= 12'b0 ;
	delay_pipeline4 <= 12'b0 ;
	delay_pipeline5 <= 12'b0 ;
	delay_pipeline6 <= 12'b0 ;
	delay_pipeline7 <= 12'b0 ;
	delay_pipeline8 <= 12'b0 ;
	delay_pipeline9 <= 12'b0 ;
	delay_pipeline10<= 12'b0 ;
	delay_pipeline11<= 12'b0 ;
end
else
begin
	delay_pipeline1 <= FIR_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 ;
	delay_pipeline9 <= delay_pipeline8 ;
	delay_pipeline10 <= delay_pipeline9 ;
	delay_pipeline11 <= delay_pipeline10 ;
end


//将输入经过延时的信号和滤波器系数相乘,每到来一个时钟便将一个新的乘积结果更新到multi_data中。这里直接使用“*”,编译后Quartues ii会自动调用乘法器IP核
always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data1 <= 23'b0 ;
	else
		multi_data1 <= delay_pipeline1*coeff1 ;
end
		
always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data2 <= 23'b0 ;
	else
		multi_data2 <= delay_pipeline2*coeff2 ;
end
		
always@(posedge CLK or negedge RSTn)
begin
	if(!RSTn)
		multi_data3 <= 23'b0 ;
	else
		multi_data3 <= delay_pipeline3*coeff3 ;
end
		
always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data4 <= 23'b0 ;
	else
		multi_data4 <= delay_pipeline4*coeff4 ;
end
		
always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data5 <= 23'b0 ;
	else
		multi_data5 <= delay_pipeline5*coeff5 ;
end
		
always@(posedge CLK or negedge RSTn)
begin
	if(!RSTn)
		multi_data6 <= 23'b0 ;
	else
		multi_data6 <= delay_pipeline6*coeff6 ;
end
		
always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data7 <= 23'b0 ;
	else
		multi_data7 <= delay_pipeline7*coeff7 ;
end
		
always@(posedge CLK or negedge RSTn)
begin
	if(!RSTn)
		multi_data8 <= 23'b0 ;
	else
		multi_data8 <= delay_pipeline8*coeff8 ;
end
		
always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data9 <= 23'b0 ;
	else
		multi_data9 <= delay_pipeline9*coeff9 ;
end

always@(posedge CLK or negedge RSTn) 
begin
	if(!RSTn)
		multi_data10 <= 23'b0 ;
	else
		multi_data10 <= delay_pipeline10*coeff10 ;
end

always@(posedge CLK or negedge RSTn)
begin
	if(!RSTn)
		multi_data11 <= 23'b0 ;
	else
		multi_data11 <= delay_pipeline11*coeff11 ;
end


//将乘积累加,累加的结果就是滤波后的信号。
always@(posedge CLK or negedge RSTn)
begin
	if(!RSTn)
		FIR_OUT <= 23'b0 ;
	else
		FIR_OUT <= (multi_data1 + multi_data2 + multi_data3 + multi_data4 +multi_data5 + multi_data6 + multi_data7 + multi_data8 + multi_data9 + multi_data10 + multi_data11)>>10 ;
end
		
endmodule

接下来编写testbench,代码如下:

`timescale 1 ns/ 1 ps
module FIR_test1_tb();
// constants                                           
// general purpose registers
//reg eachvec;
// test vector input registers
reg CLK;
reg [11:0] FIR_IN;
reg RSTn;
reg [11:0] mem[1:8192];//用来存放读入的8192个数据

// wires                                               
wire [23:0]  FIR_OUT;
reg [13:0] i;

// assign statements (if any)                          
FIR_test1 i1 (
// port map - connection between master ports and signals/registers   
	.CLK(CLK),
	.FIR_IN(FIR_IN),
	.FIR_OUT(FIR_OUT),
	.RSTn(RSTn)
);
initial                                                
begin                                                  
// code that executes only once                        
// insert code here --> begin  
	$readmemh("E:/fault_detection_code/FIR_test1/mem.txt",mem);//读入3.1中产生的波形数据文件mem.txt,文件路径注意不要搞错
	RSTn = 0;
	CLK = 0;
	#50 RSTn = 1;
	#1000000 $stop;
                                                       
// --> end                                             
$display("Running testbench");                       
end 

always #100 CLK=~CLK;

always@(posedge CLK or negedge RSTn) //每次时钟到达,给FIR_IN一个输入数据
begin
      if(!RSTn)                                
			FIR_IN <= 12'b0 ;

      else
			FIR_IN <= mem2[i];     
end
 
always@(posedge CLK or negedge RSTn) 
begin
      if(!RSTn)
			i <= 12'd0;
      else
			i <= i + 1'd1;
end
                                                   
//always                                                 
// optional sensitivity list                           
// @(event1 or event2 or .... eventn)                  
//begin                                                  
// code executes for every event on sensitivity list   
// insert code here --> begin                          
                                                       
//@eachvec;                                              
// --> end                                             
//end                                                    
endmodule

FIR滤波器模块和testbench编译完成后,进行RTL仿真,可以得到滤波后的波形,如图4所示,
基于Quartues ii和Modelsim的FIR滤波器仿真文章来源地址https://www.toymoban.com/news/detail-415647.html

图4. RTL仿真结果

到了这里,关于基于Quartues ii和Modelsim的FIR滤波器仿真的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 基于FPGA的FIR滤波器的实现(5)— 并行结构FIR滤波器的FPGA代码实现

    基于FPGA的FIR滤波器的实现(5)— 并行结构FIR滤波器的FPGA代码实现

    并行结构,并行实现滤波器的累加运算,即并行将具有对称系数的输入数据进行相加,而后采用多个乘法器并行实现系数与数据的乘法运算,最后将所有乘积结果相加输出。这种结构具有最高的运行速度,因不需要累加运算,因此系数时钟频率可以与数据输出时钟频率保持一

    2024年02月03日
    浏览(12)
  • 数字信号处理音频FIR去噪滤波器(基于MATLAB GUI的开发)

    数字信号处理音频FIR去噪滤波器(基于MATLAB GUI的开发)

    利用MATLAB GUI设计平台,用窗函数法设计FIR数字滤波器,对所给出的含有噪声的声音信号进行数字滤波处理,得到降噪的声音信号,进行时域频域分析,同时分析不同窗函数的效果。将文件解压至一个目录下,运行m文件即可使用。 读取.wav音频文件函数 :audioread();(老版

    2024年02月08日
    浏览(12)
  • 基于FPGA的FIR数字滤波器设计(quartus和vivado程序都有)。

    基于FPGA的FIR数字滤波器设计(quartus和vivado程序都有)。

    基于FPGA的FIR数字滤波器设计(quartus和vivado程序都有)。 附: 1.配套quartus从MATLAB系数生成直到仿真成功说明文档。 2.配套仿真出波形(图1)的视频。      

    2024年02月10日
    浏览(6)
  • 基于FPGA的FIR低通滤波器实现(附工程源码),matlab+vivado19.2+simulation

    基于FPGA的FIR低通滤波器实现(附工程源码),matlab+vivado19.2+simulation

    本文为FPGA实现FIR滤波器仿真过程,附源代码。 提示:以下是本篇文章正文内容,下面案例可供参考 打开MATLAB在命令行窗口输入: fadtool 回车后在滤波器设计界面设置滤波器参数如下 之后点击如图标志,设置定点,在菜单栏\\\"目标(R)\\\"出选择生成对应滤波器系数.COE文件 mat

    2024年02月11日
    浏览(14)
  • 并行FIR滤波器

    并行FIR滤波器

    FIR 滤波器是有限长单位冲击响应滤波器,又称为非递归型滤波器。FIR 滤波器具有严格的线性相频特性,同时其单位响应是有限长的,因而是稳定的系统。 FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下: 直接型结构如下: FIR 滤波器有如下几个特性:

    2024年02月13日
    浏览(6)
  • 串行FIR滤波器

    串行FIR滤波器

    串行设计,就是在 16 个时钟周期内对 16 个延时数据分时依次进行乘法、加法运算,然后在时钟驱动下输出滤波值。考虑到 FIR 滤波器系数的对称性,计算一个滤波输出值的周期可以减少到 8 个。串行设计时每个周期只进行一次乘法运算,所以设计中只需一个乘法器即可。此时

    2024年02月11日
    浏览(8)
  • FPGA设计FIR滤波器低通滤波器,代码及视频

    FPGA设计FIR滤波器低通滤波器,代码及视频

    名称:FIR滤波器低通滤波器 软件:Quartus 语言:Verilog/VHDL 本资源含有verilog及VHDL两种语言设计的工程,每个工程均可实现以下FIR滤波器的功能。 代码功能: 设计一个8阶FIR滤波器(低通滤波器),要求截止频率为20KHz,使用线性相位结构。 参数设计方法: 使用matlab软件设计滤

    2024年02月08日
    浏览(9)
  • FIR半带滤波器

    FIR半带滤波器

    CIC滤波器是一种适合于工作在高采样率条件下的滤波器。 半带滤波器是一种非常适合于2倍抽取的FIR滤波器。 半带滤波器可以使2倍抽取的每秒乘法次数比一般线性相位的FIR滤波器减少近1/2。 半带滤波器是一种实现数字下变频的高效数字滤波器。 半带滤波器有以下特点: 1、

    2023年04月26日
    浏览(10)
  • FIR数字滤波器设计

    FIR数字滤波器设计

    目标 用Kaiser窗设计一个FIR数字带阻滤波器,对模拟信号 x a ( t ) = c o s ( 2 π f a t ) + c o s ( 2 π f b t ) + c o s ( 2 π f c t ) x_a(t) = cos (2pi f_at) + cos (2pi f_bt) + cos (2pi f_ct) x a ​ ( t ) = cos ( 2 π f a ​ t ) + cos ( 2 π f b ​ t ) + cos ( 2 π f c ​ t ) , f a = 6500 H z , f b = 7000 H z , f c = 9000 H z

    2024年01月24日
    浏览(12)
  • FIR滤波器的Verilog实现

    FIR滤波器的Verilog实现

    FIR滤波器是非递归型滤波器的简称,又叫 有限长单位冲激响应滤波器 。带有常系数的FIR滤波器是一种LTI(线性时不变)数字滤波器。冲激响应是有限的意味着在滤波器中没有发反馈。长度为N的FIR输出对应于输入时间序列x(n)的关系由一种有限卷积和的形式给出,具体形式如下:

    2024年02月11日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包