本文基于xilinx 的IP核設計,源于音頻下采樣這一需求。
創建vivado工程
1. 首先打開vivado,創建一個新的project(勾選create project subdirectory選項),并將工程命填為firfilter。
2.選擇工程創建的類型為RTL project。在設計PCB會用到I/Oplanning這種類型,用在原理圖和封裝兼容性設計。
3.選擇芯片family和封裝,這種基于芯片選型的工程,其能implement的資源量受芯片自身容量限制。
創建design文件
1.創建設計文件,在flow navigator欄里,選中project manager,其展開的子項中,單擊Add Source,并在跳出的框中選擇Add or create desigine sources
2 填寫創建的文件名為fir,類型是verilog。
定制FIR IP 核
1.類似創建design source文件一樣,單擊Project Manager子菜單下的IP catalog,在軟件的右側工作欄顯示一個IP catalog標簽,在search過濾器中選擇fir,雙擊FIR Compiler選項。
2 定制FIR參數第一頁,
a:按如下方式填寫,這里的fdacoe.coe文件由matlab生成,先參考matlab一節,生成該文件。
b:在Filter type中選擇Decimation,抽取方式,抽取因子填3,即將48k采樣率降采樣到16k。
3 定制FIR IP,第二頁
3.第三頁
4.第四頁
5 第五頁
6 第六頁
基于MATLAB的FIR濾波器設計
FIR濾波器設計
a.在command window敲fdatool命令
b.在彈出的窗口中,將Response Type選中Lowpass,Designed Method選中FIR,其后下拉窗口,選中Window,即基于窗函數法設計FIR濾波器。
c.在Filter Order中選中Specify Order,填32這個數字,即32階,窗口設計方法
按如下窗口內容填寫。
FIR濾波器系數量化
先點擊圖中1標號按鈕,進入量化界面,由于FPGA實現,2標號選定點,3標號內容照抄,4在設計有誤時,返回繼續設計有用。
FIR濾波器系數導出
點擊菜單欄上的Target按鈕,有兩個選項,一個是generate c header,一個是XILINX Coefficient (.COE) file。這兩個選項導出的系數都可以使用在xilinx 的fpga上,它們導出的系數是相等的。C語言導出系數如下:
const int BL = 33;
const int16_T B[33] = {
-90,
0, 148, 219,
0, -467, -658,
0, 1220,
1626,
0, -2875, -3909,
0, 8719, 17911, 21851, 17911,
8719,
0, -3909, -2875,
0, 1626, 1220,
0, -658,
-467,
0, 219, 148,
0, -90
};
COE導出的文件內容如下:
; XILINX CORE Generator(tm)Distributed Arithmetic FIR filter coefficient (.COE) File
; Generated by MATLAB(R) 8.6 and the DSP System Toolbox 9.1.
; Generated on: 17-Feb-2016 09:57:13
Radix = 16;
Coefficient_Width = 16;
CoefData = ffa6,
0000,
0094,
00db,
0000,
fe2d,
fd6e,
0000,
04c4,
065a,
0000,
f4c5,
f0bb,
0000,
220f,
45f7,
555b,
45f7,
220f,
0000,
f0bb,
f4c5,
0000,
065a,
04c4,
0000,
fd6e,
fe2d,
0000,
00db,
0094,
0000,
ffa6;
FIR濾波實現
新建fir_test.m文件,文件內容如下:
B = [ -90 0 148 219 0 -467 -658 0 1220 1626 0 -2875 -3909 0 8719 17911 21851 17911 8719 0 -3909 -2875 0 1626 1220 0 -658 -467 0 219 148 0 -90 ];
a=1;
x=[ -1 4 1 8 1 -1 0 8 1 1 2 12 1 2 1 0 21 2 4 8 0 1 32 1 8 1 -35 2 1 65 2 75 0 1];
y=filter(B,a,x)
執行該文件,文件輸出如下:
y =
Columns 1 through 14
90 -360 -238 -347 934 1960 690 -3748 -5923 -1383 9253 14206 3326 -21802
Columns 15 through 28
-35693 -8499 63482 155587 219005 222924 174176 109373 73680 105663 192691 285199 320053 262058
Columns 29 through 34
167516 134487 244845 429404 550320 478771
例化FIR濾波器
依次點擊圖中,1,2,3,4,然后可見窗口5顯示的內容,該內容適用verilog來instanceFIR的template
2.將template內容粘貼到前面創建的Design file,.v文件。
3.添加應有的端口信息:
4,最終的fir.v文件內容如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/16/2016 04:31:37 PM
// Design Name:
// Module Name: fir
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module fir(aclk,s_axis_data_tready,s_axis_data_tvalid,m_axis_data_tvalid,s_axis_data_tdata,
m_axis_data_tdata
);
output s_axis_data_tready;
input aclk;
input s_axis_data_tvalid;
output m_axis_data_tvalid;
output[39:0] m_axis_data_tdata;
input[15:0] s_axis_data_tdata;
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
fir_compiler_0 fir_decimate_by_3 (
.aclk(aclk),
// input wire aclk
.s_axis_data_tvalid(s_axis_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tdata(s_axis_data_tdata), // input wire [23 : 0] s_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata) // output wire [39 : 0] m_axis_data_tdata
);
endmodule
創建test bench 文件
創建文件過程類似Design file,但文件類型要選擇simulation類型,名稱填為fir_tb,并在彈出的窗口中選擇其為頂層module。
2.fir_tb.v文件的內容如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/16/2016 04:40:22 PM
// Design Name:
// Module Name: fir_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module fir_tb;
//Inputs
reg s_axis_data_tvalid;
reg aclk;
reg[15:0] s_axis_data_tdata;
reg[15:0] Mem[37:0];
//Outputs
wire s_axis_data_tready;
wire m_axis_data_tvalid;
wire[39:0] m_axis_data_tdata;
integer k,i;
//Instantiate the Unit Under Test(UUT)
fir uut(
.aclk(aclk),
.s_axis_data_tready(s_axis_data_tready),
.s_axis_data_tvalid(s_axis_data_tvalid),
.m_axis_data_tvalid(m_axis_data_tvalid),
.s_axis_data_tdata(s_axis_data_tdata),
.m_axis_data_tdata(m_axis_data_tdata)
);
initial begin
//Initialize Inputs
// s_axis_data_tvalid = 1;
s_axis_data_tvalid = 0;
for(i=0;i<40;i=i+1)
begin
#90 s_axis_data_tvalid = 1;
#10 s_axis_data_tvalid = 0;
end
end
initial begin
//clock generate
aclk = 0;
forever #5 aclk = !aclk;
end
initial $readmemh("/home/gsc/FIR_1/fir/fir.srcs/sim_1/new/data_in.txt", Mem);
// Add stimulus here
// Data input Generation
initial begin
s_axis_data_tdata = 0;
for(k=0;k<=38;k=k+1)
#100 s_axis_data_tdata = Mem[k];
end
endmodule
3仿真時用到一個輸入文件,data_in.txt,,其文件內容如下,該文件內容就是matlab一節中的x的十六進方式制表示,由于開發基于linux,所以readmemh的路徑是linux下的表示方式。
FFFF
0004
0001
0008
0001
FFFF
0000
0008
0001
0001
0002
000c
0001
0002
0001
0000
0015
0002
0004
0008
0000
0001
0020
0001
0008
0001
FFDD
0002
0001
0041
0002
004B
0000
0001
4 完成后如下圖,注意紅框內文件目錄結構是否和圖中一直。
前仿真
依次點擊1,2,在跳出的窗口中,雙擊類似4的窗口,注意觀察3那行。
0x5a是十進制的90,ffea5是十進制的-347,可以觀察matlab FIR設計輸出結果,90之后的3個就是-347,至此驗證了設計的正確性。
評論
查看更多