当前位置:   article > 正文

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

quartus 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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

得到的波形如图1所示

图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);  

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

利用filterdesigner工具设计FIR滤波器

在MATLAB中用filterdesigner命令调出滤波器设计工具,界面如图2
图2 滤波器设计工具

图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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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

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

figure(2);
plot(N1,d)
  • 1
  • 2
  • 3
  • 4
  • 5

得到结果如图3所示,对比图1和图3,可以看到高频成分衰减了很多。
在这里插入图片描述

图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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179

接下来编写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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

FIR滤波器模块和testbench编译完成后,进行RTL仿真,可以得到滤波后的波形,如图4所示,
在这里插入图片描述

图4. RTL仿真结果
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/945954
推荐阅读
相关标签
  

闽ICP备14008679号