基于vivado的fir ip核的重采样设计与实现

FPGA/ASIC技术

194人已加入

描述

本文基于xilinx 的IP核设计,源于音频下采样这一需求。

创建vivado工程
1. 首先打开vivado,创建一个新的project(勾选create project subdirectory选项),并将工程命填为firfilter。

FIR

2.选择工程创建的类型为RTL project。在设计PCB会用到I/Oplanning这种类型,用在原理图和封装兼容性设计。

FIR

3.选择芯片family和封装,这种基于芯片选型的工程,其能implement的资源量受芯片自身容量限制。

FIR

创建design文件
1.创建设计文件,在flow navigator栏里,选中project manager,其展开的子项中,单击Add Source,并在跳出的框中选择Add or create desigine sources

FIR

2 填写创建的文件名为fir,类型是verilog。

FIR

定制FIR IP 核
1.类似创建design source文件一样,单击Project Manager子菜单下的IP catalog,在软件的右侧工作栏显示一个IP catalog标签,在search过滤器中选择fir,双击FIR Compiler选项。

FIR

2 定制FIR参数第一页,

a:按如下方式填写,这里的fdacoe.coe文件由matlab生成,先参考matlab一节,生成该文件。
b:在Filter type中选择Decimation,抽取方式,抽取因子填3,即将48k采样率降采样到16k。

FIR

3 定制FIR IP,第二页

FIR

3.第三页

FIR

4.第四页

FIR

5 第五页

FIR

6 第六页

FIR

基于MATLAB的FIR滤波器设计
FIR滤波器设计
a.在command window敲fdatool命令

b.在弹出的窗口中,将Response Type选中Lowpass,Designed Method选中FIR,其后下拉窗口,选中Window,即基于窗函数法设计FIR滤波器。

c.在Filter Order中选中Specify Order,填32这个数字,即32阶,窗口设计方法

按如下窗口内容填写。

FIR

FIR滤波器系数量化
先点击图中1标号按钮,进入量化界面,由于FPGA实现,2标号选定点,3标号内容照抄,4在设计有误时,返回继续设计有用。

FIR

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

例化FIR滤波器
依次点击图中,1,2,3,4,然后可见窗口5显示的内容,该内容适用verilog来instanceFIR的template

FIR

2.将template内容粘贴到前面创建的Design file,.v文件。

FIR

3.添加应有的端口信息:

FIR

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。

FIR


FIR

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 完成后如下图,注意红框内文件目录结构是否和图中一直。

FIR

前仿真
依次点击1,2,在跳出的窗口中,双击类似4的窗口,注意观察3那行。

0x5a是十进制的90,ffea5是十进制的-347,可以观察matlab FIR设计输出结果,90之后的3个就是-347,至此验证了设计的正确性。

FIR

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相关推荐
  • FIR

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分