文中應(yīng)用了MATLAB和VHDL聯(lián)合設(shè)計,提出基于電路分割技術(shù)實現(xiàn)通信系統(tǒng)發(fā)送端根升余弦波形成型濾波器查表法的FPGA結(jié)構(gòu),節(jié)省了ROM單元,討論其ROM初始化時波形數(shù)據(jù)的組織方法,完成了該結(jié)構(gòu)VHDL實現(xiàn),最后給出使用查找表在FPGA上實現(xiàn)基帶脈沖成型濾波器的設(shè)計方法和ModelSim環(huán)境下的仿真結(jié)果
方案1:卷積法的原理,是用一系列乘法和加法對信號進行流水線運算,需要消耗大量的乘法器和加法器,設(shè)計較復(fù)雜,并有一定的延時。這是一種分布式算法的設(shè)計結(jié)構(gòu),將傳統(tǒng)的乘法運算和累加運算加以改進,轉(zhuǎn)變?yōu)橐莆弧⒗奂舆\算,降低了硬件消耗,當(dāng)運算數(shù)據(jù)的字寬較小時,極大的降低了硬件電路的復(fù)雜度,提高了響應(yīng)速度;但當(dāng)運算數(shù)據(jù)的字長較長時,則需要更多的移位迭代運算而不適合高速處理的需求。
方案2:查表法的原理,采用二進制基帶信號的連續(xù)查表法實現(xiàn)在FPGA上完成信號的脈沖成型,原理是預(yù)先將所有可能的成形后的基帶波形樣本存入ROM,根據(jù)輸入序列,從ROM中查找對應(yīng)輸出波形,這種方法簡單直觀、速度快,且當(dāng)碼間樣點增加時,僅增長地址電路即可,不影響運行時間,可在一定的精度內(nèi)高效的實現(xiàn)脈沖成型濾波。
總體框圖
框圖.png (5.09 KB, 下載次數(shù): 88)
下載附件
框圖
2019-4-17 13:51 上傳
本次設(shè)計首先利用MATLAB中的FDAtool工具設(shè)計出一個采樣頻率為10MHZ、截止頻率為50KHZ、滾降系數(shù)為0.35的升余弦滾降濾波器,通過FDAtool導(dǎo)出16點系數(shù),然后將系數(shù)進行放大、取整,以便于在FPGA中使用,最后通過QuartusII進行Verilog語言編寫濾波器算法,然后通過Modesim仿真結(jié)果和MATLAB仿真結(jié)果的比較來驗證該濾波器的正確性
(1) 首先,在MATLAB command window 命令窗內(nèi)輸入 FDAtool命令,按Enter,出現(xiàn)FDAtool界面,F(xiàn)DAtool界面如圖所示。
FDAtoll.jpg (144.94 KB, 下載次數(shù): 85)
下載附件
2019-4-17 13:53 上傳
(2)設(shè)置本課題要求的平方根升余弦濾波器的參數(shù),設(shè)置的參數(shù)見界面如圖所示。本次課題采用海明窗,F(xiàn)c設(shè)置為20KHZ,滾降系數(shù)設(shè)置為0.35,采樣頻率設(shè)置為10MHZ,階數(shù)設(shè)置為17,即n=16。然后點擊點擊“designfilter”按鈕。
升余弦.jpg (178.96 KB, 下載次數(shù): 72)
下載附件
2019-4-17 13:54 上傳
(3)查看平方根升余弦濾波器的幅度響應(yīng)圖 (4)接著用MATLAB中simulink,構(gòu)建濾波器仿真模塊,simulink仿真如圖所示。
MATLAB仿真.jpg (84.79 KB, 下載次數(shù): 80)
下載附件
2019-4-17 13:55 上傳
二 FPGA 以下是用FIR核實現(xiàn)平方根升余弦滾降濾波器的步驟: (1)打開Quartus II 軟件,新建一個“project”。點擊“tool”打開“IP Catalog”界面。
(2)在“Import from file”里導(dǎo)入濾波器系其頻譜圖如所示。
FIR核界面.jpg (243.11 KB, 下載次數(shù): 93)
下載附件
2019-4-17 13:57 上傳
導(dǎo)入的系數(shù)是前面MATLAB FDAtool中生成的濾波器系數(shù)。
導(dǎo)入系數(shù)FIR核界面.jpg (252.57 KB, 下載次數(shù): 67)
下載附件
2019-4-17 13:57 上傳
(3)將我們準備好的測試文件FIR_filter_tb.v和DDS .v拷貝至工程目錄文件夾下,文件添加界面如圖所示。
Assignment->setting->EDA tool setting->simulation->testbenches添加仿真文件。
測試文件.jpg (88.11 KB, 下載次數(shù): 60)
下載附件
2019-4-17 13:58 上傳
(4)ModelSim仿真 直接啟動仿真軟件Modelsim-Altera,并顯示仿真波形數(shù)據(jù)(模擬形式顯示) data1 信號為 24KHz 正弦波,量化位寬為 12bit data2 信號為 240KHz 正弦波,量化位寬為 12bit data_in 信號為 data1 和 data2 的疊加信號,量化位寬為13bit
data_out 信號為 data_in信號經(jīng)過 FIR 數(shù)字濾波后的輸出,量化位寬為 28bit。仿真結(jié)果如圖所示。
濾波結(jié)果.jpg (376.02 KB, 下載次數(shù): 68)
下載附件
2019-4-17 13:58 上傳
最后可知 matlab和FPGA的濾波結(jié)果相同。 - 附 錄
- FIR_filter_tb.v
- // --------------------------------------------------------------------
- // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
- // --------------------------------------------------------------------
- // Module: FIR_filter_tb
- //
- // Author: Step
- //
- // Description: FIR_filter_tb
- //
- // --------------------------------------------------------------------
- // Code Revision History :
- // --------------------------------------------------------------------
- `timescale 1ps/1ps
-
- module FIR_filter_tb;
-
- parameter PERIOD = 20;
- reg clk, rst_n;
- wire signed [26:0] data_out;
-
- initial begin
- clk = 0;
- rst_n = 0;
- #100;
- rst_n = 1;
- #6000;
- $stop;
- end
- always #10 clk = ~clk;
-
- wire signed[9:0] data1;
- DDS dds_24k
- (
- .clk_in(clk), //clock in
- .rst_n_in(rst_n), //reset, active low
- .dds_en_in(1), //dds work enable
- .f_increment(24'h60000), //frequency increment
- .p_increment(0), //phase increment
- .dac_data_out(data1) //data out
- );
-
- wire signed[9:0] data2;
- DDS dds_240k
- (
- .clk_in(clk), //clock in
- .rst_n_in(rst_n), //reset, active low
- .dds_en_in(1), //dds work enable
- .f_increment(24'h3c0000), //frequency increment
- .p_increment(0), //phase increment
- .dac_data_out(data2) //data out
- );
-
- wire signed[10:0] data_in = data1 + data2;
- FIR_Filter u0 (
- .ast_sink_data (data_in), // avalon_streaming_sink.data
- .ast_sink_valid (1), // .valid
- .ast_sink_error (0), // .error
- .ast_source_data (data_out), // avalon_streaming_source.data
- .ast_source_valid (), // .valid
- .ast_source_error (), // .error
- .clk (clk), // clk.clk
- .reset_n (rst_n) // rst.reset_n
- );
-
- endmodule
-
- DDS.v
- // --------------------------------------------------------------------
- // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
- // --------------------------------------------------------------------
- // Module: DDS
- //
- // Author: Step
- //
- // Description: DDS
- //
- // --------------------------------------------------------------------
- // Code Revision History :
- // --------------------------------------------------------------------
- module DDS
- (
- input clk_in, //clock in
- input rst_n_in, //reset, active low
- input dds_en_in, //dds work enable
- input [23:0] f_increment, //frequency increment
- input [23:0] p_increment, //phase increment
- output dac_clk_out, //clock out
- output [9:0] dac_data_out //data out
- );
- reg [23:0] phase_accumulator;
- wire [23:0] phase;
- //wire [9:0] dac_data_out;
- assign dac_clk_out = clk_in;
- //next_phase = phase_accumulator + f_increment;
- always @(posedge clk_in or negedge rst_n_in)
- begin
- if(!rst_n_in) phase_accumulator <= 23'b0;
- else if(dds_en_in) phase_accumulator <= phase_accumulator + f_increment;
- end
- assign phase = phase_accumulator + p_increment; // phase is the high 8 bits
- lookup_table lookup_table_uut
- (
- .phase(phase[23:16]),
- .dac_data_out(dac_data_out)
- );
- endmodule
- /**************************************************
- module: lookup_table
- **************************************************/
- module lookup_table
- (
- input [7:0] phase,
- output reg [9:0] dac_data_out
- );
- wire [5:0] address = phase[5:0];
- wire [1:0] sel = phase[7:6];
- wire [9:0] sine;
- always@(sel or sine)
- case (sel)
- 2'b00 : dac_data_out = {1'b0, sine[9:1]};
- 2'b01 : dac_data_out = {1'b0, sine[9:1]};
- 2'b10 : dac_data_out = {1'b1, 9'h1ff-sine[9:1]};
- 2'b11 : dac_data_out = {1'b1, 9'h1ff-sine[9:1]};
- endcase
- sine_table sine_table_uut
- (
- .sel(sel),
- .address(address),
- .sine(sine)
- );
-
- endmodule
- /**************************************************
- module: sine_table
- **************************************************/
- module sine_table
- (
- input [1:0] sel,
- input [5:0] address,
- output reg [9:0] sine
- );
- reg [5:0] table_addr;
- always @(sel or address)
- case (sel)
- 2'b00: table_addr = address;
- 2'b01: table_addr = 6'h3f - address;
- 2'b10: table_addr = address;
- 2'b11: table_addr = 6'h3f - address;
- endcase
- always @(table_addr)
- case(table_addr)
- 6'h0: sine=10'h000;
- 6'h1: sine=10'h019;
- 6'h2: sine=10'h032;
- 6'h3: sine=10'h04B;
- 6'h4: sine=10'h064;
- 6'h5: sine=10'h07D;
- 6'h6: sine=10'h096;
- 6'h7: sine=10'h0AF;
- 6'h8: sine=10'h0C4;
- 6'h9: sine=10'h0E0;
- 6'ha: sine=10'h0F9;
- 6'hb: sine=10'h111;
- 6'hc: sine=10'h128;
- 6'hd: sine=10'h141;
- 6'he: sine=10'h159;
- 6'hf: sine=10'h170;
- 6'h10: sine=10'h187;
- 6'h11: sine=10'h19F;
- 6'h12: sine=10'h1B5;
- 6'h13: sine=10'h1CC;
- 6'h14: sine=10'h1E2;
- 6'h15: sine=10'h1F8;
- 6'h16: sine=10'h20E;
- 6'h17: sine=10'h223;
- 6'h18: sine=10'h238;
- 6'h19: sine=10'h24D;
- 6'h1a: sine=10'h261;
- 6'h1b: sine=10'h275;
- 6'h1c: sine=10'h289;
- 6'h1d: sine=10'h29C;
- 6'h1e: sine=10'h2AF;
- 6'h1f: sine=10'h2C1;
- 6'h20: sine=10'h2D3;
- 6'h21: sine=10'h2E5;
- 6'h22: sine=10'h2F6;
- 6'h23: sine=10'h307;
- 6'h24: sine=10'h317;
- 6'h25: sine=10'h326;
- 6'h26: sine=10'h336;
- 6'h27: sine=10'h344;
- 6'h28: sine=10'h353;
- 6'h29: sine=10'h360;
- 6'h2a: sine=10'h36D;
- 6'h2b: sine=10'h37A;
- 6'h2c: sine=10'h386;
- 6'h2d: sine=10'h392;
- 6'h2e: sine=10'h39C;
- 6'h2f: sine=10'h3A7;
- 6'h30: sine=10'h3B1;
- 6'h31: sine=10'h3BA;
- 6'h32: sine=10'h3C3;
- 6'h33: sine=10'h3CB;
- 6'h34: sine=10'h3D3;
- 6'h35: sine=10'h3DA;
- 6'h36: sine=10'h3E0;
- 6'h37: sine=10'h3E6;
- 6'h38: sine=10'h3EB;
- 6'h39: sine=10'h3F0;
- 6'h3a: sine=10'h3F3;
- 6'h3b: sine=10'h3F7;
- 6'h3c: sine=10'h3FA;
- 6'h3d: sine=10'h3FC;
- 6'h3e: sine=10'h3FE;
- 6'h3f: sine=10'h3FF;
- endcase
- endmodule
復(fù)制代碼
0.png (6.8 KB, 下載次數(shù): 71)
下載附件
2019-4-18 03:23 上傳
全部資料51hei下載地址:
FIR_Filter.zip
(1.14 MB, 下載次數(shù): 28)
2019-4-17 14:01 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|