本文基于xilinx 的IP核設(shè)計,源于音頻下采樣這一需求。
創(chuàng)建vivado工程
1. 首先打開vivado,創(chuàng)建一個新的project(勾選create project subdirectory選項),并將工程命填為firfilter。
2.選擇工程創(chuàng)建的類型為RTL project。在設(shè)計PCB會用到I/Oplanning這種類型,用在原理圖和封裝兼容性設(shè)計。
3.選擇芯片family和封裝,這種基于芯片選型的工程,其能implement的資源量受芯片自身容量限制。
創(chuàng)建design文件
1.創(chuàng)建設(shè)計文件,在flow navigator欄里,選中project manager,其展開的子項中,單擊Add Source,并在跳出的框中選擇Add or create desigine sources
2 填寫創(chuàng)建的文件名為fir,類型是verilog。
定制FIR IP 核
1.類似創(chuàng)建design source文件一樣,單擊Project Manager子菜單下的IP catalog,在軟件的右側(cè)工作欄顯示一個IP catalog標(biāo)簽,在search過濾器中選擇fir,雙擊FIR Compiler選項。
2 定制FIR參數(shù)第一頁,
a:按如下方式填寫,這里的fdacoe.coe文件由matlab生成,先參考matlab一節(jié),生成該文件。
b:在Filter type中選擇Decimation,抽取方式,抽取因子填3,即將48k采樣率降采樣到16k。
3 定制FIR IP,第二頁
3.第三頁
4.第四頁
5 第五頁
6 第六頁
基于MATLAB的FIR濾波器設(shè)計
FIR濾波器設(shè)計
a.在command window敲fdatool命令
b.在彈出的窗口中,將Response Type選中Lowpass,Designed Method選中FIR,其后下拉窗口,選中Window,即基于窗函數(shù)法設(shè)計FIR濾波器。
c.在Filter Order中選中Specify Order,填32這個數(shù)字,即32階,窗口設(shè)計方法
按如下窗口內(nèi)容填寫。
FIR濾波器系數(shù)量化
先點擊圖中1標(biāo)號按鈕,進(jìn)入量化界面,由于FPGA實現(xiàn),2標(biāo)號選定點,3標(biāo)號內(nèi)容照抄,4在設(shè)計有誤時,返回繼續(xù)設(shè)計有用。
FIR濾波器系數(shù)導(dǎo)出
點擊菜單欄上的Target按鈕,有兩個選項,一個是generate c header,一個是XILINX Coefficient (.COE) file。這兩個選項導(dǎo)出的系數(shù)都可以使用在xilinx 的fpga上,它們導(dǎo)出的系數(shù)是相等的。C語言導(dǎo)出系數(shù)如下:
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導(dǎo)出的文件內(nèi)容如下:
; 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濾波實現(xiàn)
新建fir_test.m文件,文件內(nèi)容如下:
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)
執(zhí)行該文件,文件輸出如下:
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顯示的內(nèi)容,該內(nèi)容適用verilog來instanceFIR的template
2.將template內(nèi)容粘貼到前面創(chuàng)建的Design file,.v文件。
3.添加應(yīng)有的端口信息:
4,最終的fir.v文件內(nèi)容如下:
`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
創(chuàng)建test bench 文件
創(chuàng)建文件過程類似Design file,但文件類型要選擇simulation類型,名稱填為fir_tb,并在彈出的窗口中選擇其為頂層module。
2.fir_tb.v文件的內(nèi)容如下:
`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,,其文件內(nèi)容如下,該文件內(nèi)容就是matlab一節(jié)中的x的十六進(jìn)方式制表示,由于開發(fā)基于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 完成后如下圖,注意紅框內(nèi)文件目錄結(jié)構(gòu)是否和圖中一直。
前仿真
依次點擊1,2,在跳出的窗口中,雙擊類似4的窗口,注意觀察3那行。
0x5a是十進(jìn)制的90,ffea5是十進(jìn)制的-347,可以觀察matlab FIR設(shè)計輸出結(jié)果,90之后的3個就是-347,至此驗證了設(shè)計的正確性。
評論