FIR濾波器模擬----基於Quartus II的FIR II IP核與ModelSim-Altera的聯合模擬
阿新 • • 發佈:2019-02-18
使用工具
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 Catalog2)選中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,檢查錯誤。編寫testbenchtb_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.