您的位置:首页 > 其它

FIR滤波器仿真----基于Quartus II的FIR II IP核与ModelSim-Altera的联合仿真

2017-09-09 16:25 656 查看

使用工具

MATLAB R2014b、Quartus Prime 16.1、 ModelSim-Altera 10.5b

实现过程

第一步 仿真并生成滤波器的系数

在FIR的脚本仿真文章中已介绍过,设计一个10M采样率,200KHz截止频率的FIR低通滤波器,将fir_lpf_200K_10M.txt文件复制到FIR IP核目录中。

第二步 新建Quartus工程,生成IP核

1)Quartus Prime 16.1的界面以及IP核的位置如图。IP核:Tools—IP Catalog



2)选中FIR II,调出参数设置界面,如图。时钟速率Clock Rate设为50MHz,输入采样率Input Sample Rate设为10MSPS;系数位宽Coefficient Width设为12bits,根据频响曲线而定;系数导入生成好的TXT文件,即可看到相应的频响曲线;输入位宽Input Width设为8bits;其它都默认即可。



3)添加设计文件和生成dds所需的RAM

fir_IP.v

module fir_IP(
input	wire			sclk,
input	wire			rst_n,
input	wire		[7:0]	dds_data,
output	reg		[24:0]	lpf_data
);

reg[2:0]	cnt;
reg		fs_pulse;//10MHz的脉冲
always @ (posedge sclk or negedge rst_n)
begin
if(rst_n == 1'b0)
cnt <= 3'd0;
else if(cnt == 3'd4)
cnt <= 3'd0;
else
cnt <= cnt + 1'b1;
end
always @ (posedge sclk or negedge rst_n)
begin
if(rst_n == 1'b0)
fs_pulse <= 1'b0;
else if(cnt == 3'd4)
fs_pulse <= 1'b1;
else
fs_pulse <= 1'b0;
end

//FIR IP核例化
wire            sink_valid;
wire	[24:0]	source_datar;
wire		source_valid;
wire	[1:0]	source_error;
fir  fir_inst(
.clk			(sclk),		//IP核内部工作时钟
.reset_n		(rst_n),        //复位,低有效
.ast_sink_data		(dds_data),	//输入数据
.ast_sink_valid		(sink_valid),	//采样脉冲
.ast_sink_error		(2'd0),		//输入错误,使其无效
.ast_source_data	(source_datar),	//输出数据
.ast_source_valid	(source_valid),	//输出有效
.ast_source_error	(source_error)	//输出错误
);
assign  sink_valid = fs_pulse;

always @ (posedge sclk or negedge rst_n)
begin
if(rst_n == 1'b0)
lpf_data <= 25'd0;
else if(source_valid == 1'b1)
lpf_data <= source_datar;//在valid信号有效的时候才输出数据
end

endmodule

dds.v

module dds(
input	wire			sclk,	//50MHz
input	wire		        rst_n,
output	wire	    [7:0]	o_wave
);

parameter		FRQ_W1 = 32'd8589935;//100K
parameter		FRQ_W2 = 32'd85899346;//1M
reg		[31:0]	phase_sum1,phase_sum2;
wire	        [7:0]	addr1,addr2;
wire		[7:0]	o_wave1,o_wave2;
wire		[8:0]	wave_plus;

//产生2路信号的地址
always @(posedge sclk or negedge rst_n)
begin
if(rst_n == 1'b0)
phase_sum1 <= 32'd0;
else
phase_sum1 <= phase_sum1 + FRQ_W1;
end
assign addr1 = phase_sum1[31:24];

always @(posedge sclk or negedge rst_n)
begin
if(rst_n==1'b0)
phase_sum2 <= 32'd0;
else
phase_sum2 <= phase_sum2 + FRQ_W2;
end
assign addr2 = phase_sum2[31:24];
//2路波形相加输出
assign	wave_plus = {o_wave1[7],o_wave1} + {o_wave2[7],o_wave2};
assign	o_wave = wave_plus[8:1];	//相加结果寄存器是9位,取高8位作为输出结果

//调用2次RAM取数据
ram_8x256_sp	ram_8x256_sp_inst1(
.address	( addr1 ),
.clock		( sclk ),
.data		( 8'd0 ),
.wren		( 1'b0 ),
.q		( o_wave1 )
);
ram_8x256_sp	ram_8x256_sp_inst2(
.address	( addr2 ),
.clock		( sclk ),
.data		( 8'd0 ),
.wren		( 1'b0 ),
.q		( o_wave2 )
);

endmodule


fir_top.v

module fir_top(
input	wire			sclk,   //50MHz
input	wire			rst_n,  //复位低有效
output	wire	    [24:0]	lpf_data//滤波输出数据
);

//DDS例化
wire	    [7:0]	dds_data;
dds	 dds_inst(
.sclk		(sclk),
.rst_n		(rst_n),
.o_wave		(dds_data)
);

//FIR例化
fir_IP	fir_IP_inst(
.sclk		(sclk),
.rst_n		(rst_n),
.dds_data	(dds_data),
.lpf_data	(lpf_data)
);

endmodule

第三步 联合仿真

1) 对工程进行分析和综合:Start Analysis&Synthesis,检查错误。编写testbench
tb_fir.v

`timescale 1ns/1ns
module tb_fir();
reg		        sclk,rst_n;
wire	    [24:0]	lpf_data;

initial begin
sclk = 0;
rst_n = 0;
#200
rst_n = 1;
end

always #10 sclk <= ~sclk;

//例化顶层模块
fir_top  fir_top_inst(
.sclk		(sclk),
.rst_n		(rst_n),
.lpf_data	(lpf_data)
);
endmodule


2)将tb添加到仿真设置里面:Assigments—Settings—Simulation;再次分析综合



3)运行仿真:Tools—Run Simulation Tool—RTL Simulation
将想要看的信号添加进波形窗口,重新运行,设置后各个信号的格式之后,把波形的格式wave.do文件保存下来,下次再看的时候直接运行这个do文件,就不用重复设置了。

仿真截图:

整体



局部



由仿真结果看,把DDS生成的100KHz和1MHz叠加波形中的1MHz滤除掉了,注意采样率要满足奈奎斯特采样率即10M>2*1M.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  FPGA ModelSim FIR