跳转到主要内容

Xlinx IP Core实现FFT变换——为什么你的matlab数据无法严格比对?

judy 提交于

作者:Mill,来源:<span id="profileBt"><a href="https://mp.weixin.qq.com/s?__biz=MzA5Mzc4OTA4Mw==&amp;mid=2247483878&am…; id="js_name">MYMINIEYE微信公众号</a></span>

<strong>FFT</strong>

<strong>一.Xilinx FFT IP介绍</strong>
1.总体特性
• FFT IP核支持复数的正逆傅里叶变换,可以实时配置变换的长度

• 变换的长度N=2m,m=3-16,即支持的点数范围为8-65536

• 数据和相位因子宽度都为8-34

• 支持三种算法类型

° 定点全精度

° 定点缩减位宽

° 块浮点

• 四种可选择的FFT运算方式

° Pipelined Streaming I/O

° Radix-4 Burst I/O

° Radix-2 Burst I/O

° Radix-2 Lite Burst I/O

四种的主要区别体现在运算速度和所占用的资源上,如下图可见
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91177-tu1…; alt=""></center>
<p align="center"><strong>图1(仅用作标注)</strong></p>

Xilinx的FFT IP有很多端口,但是如果把它分组来看,就很容易理解
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91178-tu2…; alt=""></center>
<p align="center"><strong>图2(仅用作标注)</strong></p>

1). 配置数据接口
配置数据是一个拼接组合的数据包括FFT点数、FFT方向、缩放因子等,命令格式如下
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91179-tu3…; alt=""></center>
<p align="center"><strong>图3(仅用作标注)</strong></p>

① NFFT:FFT变换的长度,其值为log2(变换点数)

② CP_LEN:循环前缀长度,在输出整个变换之前,从变换末尾开始作为循环前缀输出的采样数。此字段仅与循环前缀插入一起出现,位宽为log2(最大点数)。在OFDM中循环前缀能解决时延扩展带来的ISI(符号间干扰)和ICI(码间干扰),因此在一定情况下插入循环前缀是必要的。

③ FWD/INV:FFT变换的方向,其值为1时是FFT,为0是IFFT。

④ SCALE_SCH:缩放因子,对于运算方式为数据流和基-4结构的位宽为2*ceil(),对于基-2和基-2Lite结构的,数据位宽为2*NFFT。缩放策略可以根据自己定义,例如:当N=1024,运算结构为基-4时SCALE_SCH可以为[1 0 2 3 2] 每个数用两位2进制表示,需要注意的是,当N不是4的幂时,第一阶段的缩放只能时1bit,例如:当N=512,运算结构为基-4时,缩放策略[02 2 2 2],[1 2 2 2 2]时可以的,[2 2 22 2]时不被允许的。

2). 数据输入接口
数据输入也是一个拼接组合的数据接口,输入遵循AXI协议,数据的命令格式如下
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91180-tu4…; alt=""></center>
<p align="center"><strong>图4(仅用作标注)</strong></p>

输入最高可以支持12通道的FFT,通道按位,由低位到高位拼接,每一通道的低位是实部,高位时虚部,中间有3bit的空闲位,可用作符号位填充。

3). 时钟和复位输入
用于时钟核复位的输入,还包括时钟使能。

4). 数据输出接口
输出的数据遵循AXI协议,m_axis_data_tdata的格式和输入数据的格式一致。

m_axis_data_tuser={OVFLO,BLK_EXP,XK_INDEX}。BLK_EXP是一个缩放量,仅当使用块浮点时可用,当自己定义缩放因子的话,不用关心;XK_INDEX输出数据的索引;OVFLO溢出标志。

5). 状态信息标记输出

6). 调试接口,FFT计算过程中发生的状态信息,以及一系列非正常现象,都会有一些标记输出

• event_frame_started:每一新的次fft开始时上跳一次。

• event_tlast_unexpected:当s_axis_data_tlast上跳,但IP核认为这并不是最后一个数据时上跳一次。

• event_tlast_missing:当IP核认为这是最后一个数据,但s_axis_data_tlast还是低的时候,该信号上跳。

•event_fft_overflow:在从数据输出通道输出的数据样本中发现溢出时上跳。只有当overflow选项被选择有效时才出现。

• event_data_in_channel_halt:当IP核需要新的输入数据但输入口并没有提供足够的数据时拉高。

• event_data_out_channel_halt:当 IP核尝试输出数据但无法输出时(可能时输出对象没有给IP核输出接收使能信号)拉高。只在Non-Realtime 模式下有效。

• event_status_channel_halt:当 IP核尝试输出数据到状态通道但无法输出时拉高。只在Non-Realtime 模式下有效。

2.IP设置
以配置一个可更改变换点数的FFT IP 核为目标,具体说明各个部分。

创建工程、添加IP核,并进行IP核的设置。

第一个选项是同时进行几路数据流并行。

第二个选项是变换的实际点数,需要注意的是我们这里设计可以在线更改变换点数的FFT,所以这里选择的点数是所需要的最大的FFT点数。

下面的五选一选项,选择Redix-4 Burst I/O。可以发现当点数小于64时,不支持Radix-4 Burst I/O模式。

最后勾选Run TimeConfigurable Transform Length,这个就是配置可在线更改的FFT IP核。如果不进行勾选,再怎么这传输配置信号也没有作用
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91181-tu5…; alt=""></center>
<p align="center"><strong>图5(仅用作标注)</strong></p>

第二页选择定点、压缩数据、和取整模式。其他选项如图所示。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91182-tu6…; alt=""></center>
<p align="center"><strong>图6(仅用作标注)</strong></p>

第三页如图所示,在配置完成之后可以看到模块的相关信息,左边一栏时配置内容的相关显示,包括最大最小变换长度,资源的占用情况以及数据的结构。在可选项里,可以选用CLB,3个或者4个DSP资源,一般选择3个DSP资源,当选择CLB的时候,在做FFT的时候不会占用DSP资源,蝶形运算也是同样的可以选择。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91183-tu7…; alt=""></center>
<p align="center"><strong>图7(仅用作标注)</strong></p>

配置完成之后可以看到不同点数的FFT所对应的时间延迟
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91184-tu8…; alt=""></center>
<p align="center"><strong>图8(仅用作标注)</strong></p>

<strong>二.Xilinx FFT 仿真实现</strong>
1.C仿真模型
Xinlinx的FFT IP提供了相应的C仿真模型,并且可以再matlab里调用,主要参数包括以下几个,相应的参数和硬件参数是一致的。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91185-tu9…; alt=""></center>
<p align="center"><strong>图9(仅用作标注)</strong></p>

用matlab产生一个复数正弦序列,信号频率为200Hz,采样频率为1000Hz,点数为2048,幅度为0.5,作为信号的输入。数据量化采用quantizer函数,选择量化的位宽为[12 11],即1位整数,11位小数,对应了输入数据的范围,此数据也作为硬件实现的数据输入。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91186-tu10…; alt=""></center>
<p align="center"><strong>图10(仅用作标注)</strong></p>

需要注意的是,C仿真模型输入数据的范围需要在[-1,1]
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91187-11.p…; alt=""></center>
<p align="center"><strong>图11(仅用作标注)</strong></p>

2.FPGA 实现
对FFT模块进行仿真实现,实现在线可配置变换长度,主要控制参数的配置和数据的输入,如下,具体的数据格式在上面已经介绍,根据命令格式进行数据组帧。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91190-tu12…; alt=""></center>
<p align="center"><strong>图12(仅用作标注)</strong></p>

仿真测试文件如下,输入的数据从txt文件里读入,输出的数据写入到txt文件。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91191-tu13…; alt=""></center>
<p align="center"><strong>图13(仅用作标注)</strong></p>

3.数据比对
通过对比matlab和FPGA的输出数据,可以清楚的看到,两条线是完全重合,并且相减之后数据为零。FFT变换之后的频率计算 fp = fs*n/NFFT = 1000*411/2048 = 200.6Hz,频率结果正确。
<center><img src="http://xilinx.eetrend.com/files/2020-03/wen_zhang_/100047874-91192-tu14…; alt=""></center>
<p align="center"><strong>图14(仅用作标注)</strong></p>