1. 程式人生 > >FIR濾波器模擬----基於Quartus II的FIR II IP核與ModelSim-Altera的聯合模擬

FIR濾波器模擬----基於Quartus II的FIR II IP核與ModelSim-Altera的聯合模擬

使用工具

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.