it编程 > 硬件开发 > fpga开发

VIVADO中FFT核的使用(FPGA计算FFT和IFFT)

72人参与 2024-08-03 fpga开发

         关于这方面的内容,有些文章已经写的很好很详细了。不过我在使用的过程中,还是踩了一些坑,我在这里详细的介绍了ip核每一个设置的作用,然后写了个fft计算和ifft计算的环路的测试程序。应该可以帮大家学会使用fft的同时,也对它有个较为全面的理解。

fpga计算fft和matlab计算fft

        利用fpga计算fft和matlab的结果是一样的,可以获得同样的实部和虚部,还可以获得相应的频率坐标,虽然由于字节有限长的影响,精度会差些,但可以设置32位,一般也够用了。

        下面是我用matlab和fpga分布做fft和ifft得到的一些结果,原始信号是一个正弦一个余弦的单频信号,时域如下图

        下面是分别利用matlab和fpga做fft的结果,可以看到形状是一致的,然后最大值的数值也基本一致。具体哪个点对应哪个频率可以通过,点数(m_axis_data_tuser)/n*fs来计算,和matlab是一致的,不过fpga中没有fftshift函数可以用。

        

对其做ifft,结果如下:

         这是我画这些图对应的matlab程序,大家后面做测试的时候可以直接用,fpga部分在讲完ip核后再给出。

vivado的fft核详解

        如果不想看说明,可以直接按我图上的进行配置就行。

        ip核的调出,选fft就行。

        下面这个是lte(long-term evolution)无线通信技术的标准而设计。该ip核是为了满足lte系统中特殊的fft大小(如lte信道带宽所需的fft点数),以及ure(资源元素)或子载波间隔等lte参数优化的,一般不需要用这个。

 1.第一页设置

(1)number of channels:这个参数可以选择做fft的通道数,也就是这个ip核同时对几组数据做fft/ifft。我在其他地方用的时候需要做两组fft,然后把它们相乘后做ifft,设置通道为2,这还方便我解决数据同步的问题。

(2)transform length:fft的点数,一般输入的信号长度要和这个数值相同,不足的情况下,ip核会在末尾自动补零.

(3)target clock frequency (目标时钟频率):按我的理解这是ip核的工作频率,它得和下面的数据吞吐量相适应。

(4)target data throughput (目标数据吞吐量):这个参数指的是fft ip核期望处理的数据吞吐量,表明ip核应该能够每秒处理多少样本数,从而保证fft变换的输出与输入能够按照一定速率进行,以匹配系统其他部分的处理速率,如adc(digital-to-analog converter)数据捕捉率或后续数据处理模块。(3)和(4)是给自动选择架构时计算时延做参考的,ip核不能保证达到相应的吞吐率。

(5)architecture choice(fpag架构的选择):从上面到下面的架构,速度依次降低,复杂度也依次降低。选好后可以在左上角的选项卡里看到一次fft的计算时间。

(6)run time configurable transform length(fpga长度实时改变):选这个意味着可以在运行过程中改变fft的计算长度。例如,你可能有一个无线通信系统,在其中需要针对不同的信道带宽进行fft操作,这会要求fft变换的长度根据情况进行调整。若fft ip核支持运行时配置,那么可以在软件控制下更改其变换长度,如从1024点切换到2048点或其他任何支持的长度。

2.第二页设置

(1)data format:选择输入输出数据采样是采用定点格式(fixed point),还是采用ieee-754单精度(floating point)(32位)浮点格式。当内核处于多通道配置中时,浮点格式不可用。

下面两个选项是用来解决fpga计算的有限字符问题,指数字系统中数值的表示、操作和运算由于位宽限制导致的问题。由于fpga中的资源有限,对于数字电路设计而言,我们不能使用无限位宽来表示一个数,而是需要根据应用需求和资源限制使用固定的位数。

(2)scaling opitons:

       unscaled: 所有的整数位增长都携带到输出中,会使用更多的fpga资源。这里我踩过一个坑:因为我的测试程序是把fft得到的数据直接给到ifft的输入端,因为选择了这个选项,数据位扩展了,所以输入的数据有问题,但这种问题vivado是不会报错的。

        scaled:用户定义的缩放计划决定数据如何在fft阶段之间缩放,通过寄存机s_axis_config_data进行配置。

        block floating-point:内核确定需要多少缩放才能充分利用可用的动态范围,并将缩放因子报告为块指数。

(3)rounding model(一般如果你使用的位宽足够时也不用纠结这个)

        截断(truncation):这是最简单的舍入模式,直接舍弃掉所有多余的lsbs,不添加任何额外的逻辑来处理这些位。这意味着数据始终向下舍入至最接近的值,可能会导致系统性偏差或误差累积,特别是在处理大量数据时这种误差的效果可能会被放大。

        收敛舍入(convergent rounding):收敛舍入也被称之为向偶数舍入(round-to-even)或银行家舍入法(bankers rounding)。这种舍入方法相对公平,并且无偏。当一个数字的小数部分正好等于0.5(即一半)时,根据数字的奇偶性来决定是向上还是向下舍入。如果该数字是奇数,那么结果将向上舍入到下一个偶数;如果是偶数,则舍入到最近的偶数。这种方法可以消除随机舍入误差累积的偏差,更平均地分布上舍和下舍的情况,并且在统计上是无偏的。

(4) precision options:输入数据和相位因子可以独立配置宽度从8到34位,包括。当数据格式为浮点时,输入数据宽度固定为32位,相位因子宽度可设置为24或25位,具体取决于所需的噪声性能和可用资源。

(5)control signals:时钟使能(aclken)和同步清除(aresetn)是可选引脚。如果两者都被选中,同步清除将覆盖时钟启用。如果不选择某个选项,则可以节省一些逻辑资源,并且可以实现更高的时钟频率。

(6)output ordering:这个决定数据是按什么顺序输出的,一般选natural order就行。

(7)optional output fileds :选项输出字段

      xk_index:fft 变幻的结果索引,在m_axis_data_user中有相应的字段。

      ovflo是变换中溢出的指示信号,对应event_fft_overflow。

(8)throttle schemes: 在性能和数据定时需求之间进行权衡。实时模式通常提供更小、更快的设计,但对必须提供和使用数据的时间有严格的限制。非实时模式没有这样的限制,但设计可能更大更慢。

3.第三页设置

这一页是关于数据存储的设置,一般默认就行。

ip核实例化

        ip核使用的是axi协议,它的主要特点是不管是发配置还是数据都会有个握手的过程,通过valid和ready这两个信号,其中发送方控制valid信号,接收方控制ready信号,这两个信号同时拉高时,也就是双方都准备好了,传输的内容才有效。

        实例化之前,先对ip核使用的通信协议的引脚进行介绍 ,主要是配置通道,数据输入通道,数据输出通道

.aclk(aclk),   输入时钟                                             
.aresetn(aresetn),   复位 

配置通道

input[n:0]:  s_axis_config_tdata:

一般用到最低位控制。1fft   0ifft。如果我们只需要fft就直接设置n'b1就ok。前面几位的配置可以去参考手册,是关于缩放和循环前缀的配置。

input:  s_axis_config_tvalid:配置数据有效。这是是我们给ip核输入配置数据,没有特殊要求一直拉高就行拉高两个时钟周期之后,将端口s_axis_data_tvalid和s_axis_data_tready拉高。 
output:  s_axis_config_tready:可以接收配置数据了。复位两个时钟周期后,该口给1输出;若干个时钟周期后,自动归零。没有特殊需要直接出去wire就好。

数据输入通道

input:  s_axis_data_tvalid:输入数据有效。当ip核准备好接收数据,也就是s_axis_data_tready高电平后,将s_axis_data_tvalid拉高n个周期,输入n个数据进行fft;n是fft的点数。

output:   s_axis_data_tready:复位两个时钟周期后,该引脚;此时ip核初始化完成,可进行数据输入。 我们可以通过这个信号来拉高valid信号。

input[m:0]:  s_axis_data_tdata:将数据输入进行fft运算。高一半的位是虚部,低一半的位是实部。输入实数的时候可以把虚部全部置零,注意这里输入的是有符合的二进制数。

input:  s_axis_data_tlast:输入最后一个数据时拉高,停止数据输入。tlast是起到一个输入数据末端指示作用。但根据我的测试,就算不配置这个引脚也不影响fft的计算,看手册上说它会影响后面的event信号,也都是一些指示信号。
 

数据输出通道

output[m1:0]:m_axis_data_tdata:高位为虚部,低位为实部。想看幅值的话,在fpga里不好开方,我们一般看的是幅值的平方,也就是功率谱。

output:  m_axis_data_tvalid:当ip核计算完以后会拉高,输出n个点的数据后拉低。

output[m2:0]:m_axis_data_tuser:输出值*fs/l为对应频点。这里和matlab是一样的,第一个点也是直流的值。

input:    m_axis_data_tready:这是告诉ip核我们准备好接收数据了,我们当然时刻准备着,一直拉高就行。

还有一些引脚相对来说没那么重要,这里就不一一介绍了。

测试程序如下,结合上面的matlab程序是可以直接用的。

写在最后

        写这篇文章还是花了挺多的时间的,希望能对大家有所帮助,有什么问题欢迎一起讨论~

奥利给

        

        

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

FPGA零基础入门学习路线

08-03

【FPGA开发/IC开发之时序约束最全面的归纳总结】时序路径基本概念及时序约束分析方法

08-03

FPGA:我的零基础学习路线(2022秋招已上岸)持续更新中~

08-03

基于FPGA的数字信号处理(15)--定点数的舍入模式(6)向0取整fix

08-03

VMamba: Visual State Space Model论文笔记

08-03

数字IC面经汇总(32篇)

08-03

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论