FPGA数字信号处理(⼗九)VivadoCICIP核实现 该篇是FPGA数字信号处理的第19篇,题接上篇,本⽂详细介绍使⽤Vivado⾃带的CIC IP核进⾏设计的⽅法。关于单级CIC滤波器、多级CIC滤波器的Verilog HDL设计以及Quartus中CIC IP核的使⽤⽅法可以参考前⾯的⽂章。
IP核概述
Xilinx的CIC IP核属于收费IP,但是不需要像 Quartus那样通过修改license⽂件来破解。如果是个⼈学习,现在⽹络上流传的license破解⽂件在破解Vivado的同时也破解了绝⼤多数可以破解的IP核。只要在IP Catalog界⾯中CIC的License状态为“Included”即可正常使⽤。
在IP Catalog中打开CIC(以4.0版本为例),主界⾯如下:天门实验初级中学
左边的Tab可以切换看到CIC的模块图(IP Symbol,管脚)、频率响应(Freq Response)等信息。右边的Tab是对CIC滤波器进⾏设计:
●Filter Type:设置CIC滤波器模式为抽取Decimation或插值Interpolation; flanker
●Number Of Stages:设置级联的CIC滤波器级数;
●Differential Delay:设置差分延时(该值与输出数据位宽有关); Vivado的CIC IP核也⽀持多通道模式,可以在“Number Of Channels”中设置数;此外还⽀持抽取/内插倍数的动态配置。本设计选⽤固定5倍。切换到“Implementation Options”标签卡:
●Input Data Width:设置CIC滤波器输⼊数据的位宽;
●Quantization:设置输出数据的量化⽅式,可以选择全精度输出(Full Precision)或截断模式(Truncation),后者可以⼿动设置输出数据位宽。
该页⾯还可以设置是否使⽤DSP48单元,是否需要时钟使能信号(ACLKEN)、复位信号(ARESETn)和输出的TREADY信号。配置完成后可以在Summary标签中看到IP核的具体信息。
IP核接⼝说明
Vivado的很多IP核采⽤的是AXI4接⼝,主要有数据(tdata)、准备好(tready)、有效(tvalid)⼏种信号,还有主机(m)和从机(s)之分。
接下来介绍⼏个主要的接⼝:
在设置为多通道、可变抽取/内插倍数模式时,还会⽤到其它的接⼝。上表中的接⼝已经⾜够完成⼀次单通道、固定倍数的CIC滤波器设计。其它接⼝在后⾯⽂章的设计中使⽤到CIC滤波器的其它模式时,再做介绍。
需要注意AXI4接⼝的tdata位宽是以字节为单位,即只会是8的倍数,因此需要结合设计的实际位宽做相应处理。
FPGA设计
IP核的接⼝在Verilog HDL中进⾏设计时,⼀定要参考官⽅⽂档中给出的时序图。在IP核的配置界⾯点击“documentation”,可以到IP 核的user guide。 也可以在Xilinx官⽹或DocNav⼯具中搜索pg140,查阅CIC IP核的说明。
将CIC IP核配置为3级CIC滤波器的级联,对输⼊数据进⾏5倍抽取。单通道、固定倍数的CIC接⼝时序⾮常简单,Verilog HDL⽰例代码如下所⽰:
程序中认为输⼊的采样数据始终有效,因此将s_axis_data_tvalid永远置1。由于s_axis_data_tdata为16Bits位宽,但输⼊信号数据为10Bits位宽,因此⽤拼接运算符{}在⾼位填充符号位;由于m_axis_data_tdata为24Bits位宽,但输出信号数据有效位仅有17Bits位宽,因此仅需取低17Bits作为C
asp投票系统IC滤波器的输出。当然不这样操作,直接将信号赋值到实例化接⼝,结果也是正确的,这样做只是为了更严谨。仿真测试
为了能将IP核的仿真结果与Verilog HDL的设计仿真结果进⾏对⽐,本⽂CIC IP核的设置与第17篇相同,仿真及testbench的编写也基本相同。使⽤CIC滤波器对0.25MHz+7.5Mhz的正弦混合信号滤波。
在Vivado中进⾏仿真,结果如下图所⽰:
仿真结果与第17篇的仿真结果基本⼀致。可以看到经过抽取滤波后,0.25MHz的信号分量数据速率降低,但信号频率没有改变。⽽7.5MHz的信号分量被抗混叠滤波器滤除,结果符合预期。`timescale 1ns / 1ps
//------------------------------------------
// 使⽤Xilinx CIC IP 核完成抽取滤波不确定性分析
//------------------------------------------
module Xilinx_CIC_liuqihis系统
(
input clk,
input signed [9:0] Xin,
output signed [16:0] Yout,
output out_valid
);
wire signed [23:0] data;
cic_compiler_0 U0
(
.
aclk(clk), // input wire aclk
.s_axis_data_tdata({{6{Xin[9]}},Xin}), // input wire [15 : 0] s_axis_data_tdata
.s_axis_data_tvalid(1'b1), // input wire s_axis_data_tvalid
.s_axis_data_tready(), // output wire s_axis_data_tready
.m_axis_data_tdata(data), // output wire [23 : 0] m_axis_data_tdata
大运高速.m_axis_data_tvalid(out_valid) // output wire m_axis_data_tvalid
);
assign Yout = data[16:0];
endmodule