1. 程式人生 > >Vivado HLS實現FIR濾波器(2)——Vivado呼叫HLS生成的FIR IP核

Vivado HLS實現FIR濾波器(2)——Vivado呼叫HLS生成的FIR IP核

系統框圖

器件xq7a50tfg484-2I,兩個DDS,輸入時鐘100MHz,輸出分別為8MHz和12MHz,位寬為16位,相乘後輸出位寬32位,三角函式積化和差得4MHz訊號和20MHz訊號,濾波器設計採用Filter Solutions 2015,截止頻率10MHz,取樣率100MHz,Hamming窗,11階,所得係數同時擴大100倍後四捨五入得到整數存入單口RAM,呼叫VIVADO HLS中生成的FIR濾波器IP核,輸出濾波後的訊號。
在這裡插入圖片描述

DDS IP核引數設定

(1)DDS IP核,IP Catalog->dds
在這裡插入圖片描述
(2)輸入時鐘100MHz,最下面的框中System Parameters中第一個設定不同的dB值獲得不同的m_axis_data_tdata的位寬,此處設成70dB,最開始設成50dB時也是可以的,但是如果90dB位寬也是16位,相乘後濾波出來波形混亂,初步估計是溢位了。根據(3)中設定成輸出Sine後位寬只有8位,設成70dB時位寬為16位,這樣設定的原因是VIVADO HLS中生成的FIR濾波器IP核輸入資料為32位,若兩個DDS均輸出16位,經過乘法器相乘後正好為32位,直接輸入FIR濾波器,否則還需要做位寬處理。
在這裡插入圖片描述


(3)此圖中的Output中算則Sine,如果選擇了Sine and Cosine,那麼位寬至少為16位,而選擇了Sine選項輸出資料位寬最少只需8位。在這裡插入圖片描述
(4)輸出設定成8MHz和12MHz,相乘後得4MHz和20MHz訊號。這樣設定的原因有兩個:一是因為頻率較高時只需要模擬較短的時間即可看到完整的波形,如果設成幾KHz訊號需要模擬很長時間;二是因為濾波效果的原因,這也是我之前一直模擬不成功的原因,在Filter Solution 2015中設計FIR濾波器時有個選項是取樣頻率,之前我一直是按截止頻率10倍設計的,但是考慮到VIVADO中模擬時輸入時鐘100MHz,相當於以100MHz的速率輸入資料,按照100MHz取樣率設計FIR時發現,對於幾百KHz的截止頻率下,11階FIR濾波器濾波效果微乎其微,此處按照截止頻率10MHz截止頻率設計。
在這裡插入圖片描述

乘法器IP引數設定

(1)Mult乘法器
在這裡插入圖片描述
(2)引數設定
輸入均16位,輸出32位,輸入輸出均為有符號數signed
在這裡插入圖片描述

HLS生成的FIR IP核

(1)將HLS生成的IP核新增到VIVADO中。找到https://blog.csdn.net/DengFengLai123/article/details/83934462中提到的生成的.zip壓縮包,將其移到一個新的資料夾下(最好是當前工程下),解壓縮。

(2)在Setting->IP->Repository中點選add(加號),找到剛剛解壓縮的檔案路徑,新增。
在這裡插入圖片描述
(3)此時就和官方自帶的IP核一樣使用了,Fir即為我的HLS生成的FIR濾波器IP核。
在這裡插入圖片描述


(4)如下圖,生成的HLS的IP核會有VIVADO HLS的標註,會有一些多出的引腳和控制訊號。因為在HLS中對輸出的濾波器係數陣列約束成了BRAM,所以會在時鐘來時產生RAM的地址,通過該地址讀取RAM中的濾波器係數,通過c_q0[31:0]輸入。此時ap_start、ap_rst輸入訊號的高低電平需要根據HLS進行C/RTL協同模擬後的波形圖設計。
在這裡插入圖片描述

RAM的IP核引數設定

(1)呼叫Block Memory Generator。
在這裡插入圖片描述
(2)設成單口RAM
在這裡插入圖片描述
(3)設定輸入輸出位寬32,深度11,其他保留預設設定。
在這裡插入圖片描述
(4)載入.coe檔案,生成方法參考網上資料。
在這裡插入圖片描述
如下圖,生成後的.coe檔案第一行的10代表十進位制,第二行是截止頻率為10MHz的11階FIR濾波器係數,該係數為Filter Solution 2015生成(生成方法參考網上資料http://www.mamicode.com/info-detail-2293172.html),對生成的係數擴大100倍後取四捨五入,獲得整數係數。
在這裡插入圖片描述

模擬

(1)將該連線的線連好後,右鍵生成verilog檔案和頂層呼叫。編寫test bench檔案test3。
在這裡插入圖片描述
在這裡插入圖片描述
(2)test3檔案程式碼,兩個dds的輸出等訊號我都引出了引腳檢視波形。C/RTL協同模擬後檢視波形,根據模擬波形的控制訊號時序設定test3中訊號的時序。ap_start訊號先低後高,ap_rst訊號先高後低,時鐘100MHz,ena為RAM使能訊號。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 2018/11/07 13:38:46
// Design Name: 
// Module Name: test3
//////////////////////////////////////////////////////////////////////////////////

module test3(

    );
    
reg ap_clk;
reg ap_rst;
reg ap_start;
reg ena;

wire [15:0] dds_0;
wire [15:0] dds_1;
wire [31:0] P;
wire [31:0] y;
wire [3:0] c_address0;
wire [31:0] douta;
wire [31:0] data_out;
wire y_ap_vld;

initial 
begin 
    ap_clk = 0;
    ap_start = 0;
    ap_rst = 1;
    ena = 0;
    #10;
    ap_start = 1;
    ap_rst = 0;
    ena = 1;
end
                
always #5 ap_clk = ~ap_clk;
    
hls_fir_1_wrapper hls_fir_1_wrapper_1
           (
                   .P(P),
                   .ap_clk(ap_clk),
                   .ap_rst(ap_rst),
                   .ap_start(ap_start),
                   .c_address0(c_address0),
                   .data_out(data_out),
                   .dds_0(dds_0),
                   .dds_1(dds_1),
                   .douta(douta),
                   .ena(ena),
                   .y(y),
                   .y_ap_vld(y_ap_vld)
               );
            
endmodule

在這裡插入圖片描述
在這裡插入圖片描述
(3)檔案結構
在這裡插入圖片描述
(4)設定模擬頂層檔案
在這裡插入圖片描述
在這裡插入圖片描述
(5)點選Run Simulation,進行模擬。應該是輸出y[31:0]一直為高阻態X,細心的如果看到我(3)中的程式結構,會發現有一個ram_out_0一直沒有提到,這個模組是我自己寫的,如果沒有這個模組,輸出y會是高阻態X,下一篇會講為什麼。
在這裡插入圖片描述

提示,注意觀察HLS中c_addr有一段是為高阻態,是因為[3:0]表示0-15,但只用到了0-10,其他為高阻態,高阻態時的c_q0輸出為0。但是在vivado中當給定RAM地址為高阻態時輸出也為高阻態,這樣在計算輸出y時每次都有高阻態存在,導致y輸出為高阻態,從這個方向上去想可以解決問題了。(如何讓輸入Fir IP核的濾波器係數在c_addr為高阻態時輸出為0而不是高阻態)
在這裡插入圖片描述