如何配置并验证在Vivado使用各种测试信号的FFT IP核
扫描二维码
随时随地手机看文章
介绍
如何配置,并验证在Vivado使用各种测试信号的FFT IP核?
•了解FFT IP核如何处理复杂数据(16位实数和16位虚数组件)
•配置FFT IP核与适当的转换长度,数据宽度和输出顺序
•集成一个信号发生器,产生三种测试信号:复单音、Sinc函数和矩形函数
•正确处理AXI流信号,包括Tvalid和Tlast,以实现正确的数据包处理
•建立了一个完整的仿真设计,包括时钟生成、信号拼接和数据提取
•通过处理实分量和虚分量来计算FFT输出的幅度
•通过观察测试信号的预期变换来验证FFT实现:
单音→单频峰值
Sinc函数→矩形函数
矩形函数→Sinc函数
FFT IP核输入/输出数据格式
该图说明了使用axis - stream接口的FFT IP核的输入和输出数据格式。FFT处理复杂数据,其中每个样本由16位实部和16位虚部组成。这些组件被连接成一个32位数据字,虚数部分占据最高有效位16位,实数部分占据最低有效位16位。
FFT IP使用轴流接口进行通信,这意味着我们必须正确处理Tvalid和Tlast信号。
Tlast信号表示FFT块处理的每个包的结束。本质上,两个Tlast脉冲之间的数据属于单个FFT包。因此,为了确保正确的操作,Tlast信号应该在等于FFT大小(NFFT)的时钟周期数之后断言。
FFT IP核的输出也是复数,每个采样由一个16位实部和一个16位虚部组成。我们可以使用切片IP块来分割每个实部和虚部。
GitHub中提供的信号发生器模块
GitHub存储库中提供的信号生成器根据所选择的模式生成三种类型的信号,该模式在块中设置为通用值。根据模式选择,模式0产生复杂的单音信号,模式1产生正弦信号,模式2产生矩形信号。这允许灵活地测试和验证FFT处理的不同信号类型。
除了生成这些信号外,该模块还处理FFT IP核所需的必要的轴流格式。它在每个FFT大小上生成最后一个脉冲,以指示每个数据包的结束,确保适当的帧对齐。
此外,它还控制tvalid信号,断言数据何时有效并准备好进行处理。
复习:不同信号的FFT变换
该图提供了应用于三种不同类型信号的FFT变换的快速回顾。我们期望在我们的Vivado模拟中看到相同的结果。
复单音的FFT变换是单频分量。这在FFT变换中表现为单个峰值。我们将把实部和虚部都发送给FIR滤波器,但这里只显示实部。
Sinc函数在时域的FFT变换在频域是一个矩形。
最后,时域矩形函数的FFT变换是频域的Sinc函数。
FFT IP核Vivado仿真
首先,在您的设计中添加FFT IP块。在configuration选项卡中,选择您喜欢的任何转换长度。对于这个例子,我将选择一个2048点的FFT。
设置目标频率和目标数据吞吐量以匹配系统的时钟频率。在这个模拟中,我将使用100兆赫的时钟。
接下来,转到Implementation选项卡并将输入数据宽度设置为16位。对于相位因子宽度,您可以将其保留在16位,或者如果您在FFT变换中需要更高的精度,可以选择更高的值。
由于我们在此模拟中使用整数值,因此选择Fixed Point作为数据格式。
对于输出顺序,选择自然顺序以避免使用位反转输出。
您可以在Implementationtab中找到实现细节。如图所示,数据类型是Fixed Point 16-15,这意味着输入数据类型是一个16位整数。
最后,检查Latency选项卡以确保FFT块满足系统的延迟要求。请记住,更大的FFT大小会导致更高的延迟。
在您的设计中添加一个模拟时钟生成器,并将其时钟频率设置为与您为FFT IP块选择的目标频率匹配。这确保了仿真在正确的时间运行,并与FFT处理要求保持一致。然后我们将使用这个时钟来运行模拟中的所有ip。
从GitHub下载提供的信号发生器,并将其作为源代码添加到您的设计中。要集成它,右键单击块设计并选择“添加模块”。
信号发生器模块有两个可配置参数:
FFT大小参数-设置该参数以匹配FFT IP块的变换长度。例如,在本例中,我将选择2048,与FFT IP块相同。
函数类型-这决定了产生的信号的类型。您可以在0和2之间选择一个值,每个值产生不同的波形。
将信号发生器模块的Tlast和Tvalid信号连接到FFT IP块的Tlast和Tvalid输入端。这确保了适当的同步,并为AXI流协议提供了必要的控制信号。
接下来,在您的设计中添加Concat IP块。使用它来连接实数和虚数输出,形成一个32位无符号整数。然后,将连接的输出连接到FFT IP块的tdata端口。
不要忘记将FFT IP块的时钟和复位引脚连接到时钟模拟IP。
将Constant IP块添加到您的设计中并将其值设置为1。然后,将其输出连接到FFT IP块输出端口的trready信号。这确保FFT模块总是准备好传输数据。
要从FFT IP块的输出中分离实部和虚部,请在设计中添加两个Slice IP块:
虚部—添加一个Slice IP块,并将其配置为提取31 ~ 16位作为虚输出。
实数部分-添加另一个Slice IP块,并将其配置为提取15到0位作为实数输出。
这种设置确保FFT输出正确地分为实部和虚部,以便进一步处理。
接下来,我们需要计算FFT输出的绝对值。为此,我们首先计算实分量和虚分量的平方(2的幂):
在设计中添加一个Multiply IP块,并将其输入宽度设置为16位。
将这个乘法器的两个输入端口连接到虚部输出。这个计算虚分量的平方。
通过添加另一个Multiply IP块并将其输入宽度设置为16位,重复该过程。
将第二个乘法器的两个输入端口连接到实部输出。这是计算实分量的平方。
最后,在您的设计中添加一个Adder IP块。将两个Multiply IP块(包含实部和虚部的平方值)的输出连接到加法器的输入端口。
通常,在设计中添加具有清晰且有意义的名称的输出端口是一种很好的做法。这使得重复模拟更容易,并提高了对设计的整体理解。
现在我们已经完成了块设计,是时候为它创建一个HDL包装器了。您可以为信号发生器模块选择三种波类型中的任何一种。对于第一次尝试,我将选择波形类型0,这将产生一个具有实分量和虚分量的复杂单音信号。一旦完成,我们就可以进行行为模拟了。
仿真结果
以单音信号作为输入进行测试
在仿真结果中,您将观察到信号的实部是正弦波,并且由于单音的FFT变换产生峰值,因此这验证了我们对第一种模式的设计。通过分析有效信号,我们可以确定由FFT IP块引入的延迟。经过特定数量的时钟周期后,FFT IP核断言Tvalid并输出与傅里叶变换相对应的峰值。每个FFT大小的时钟周期,IP核生成Tlast,表示每个傅立叶变换包的结束,这意味着两个Tlast信号之间的数据代表一个完整的傅立叶变换包。此外,信号发生器模块还在每个FFT大小的时钟周期内生成Tlast,标志着FFT IP核的每个输入数据包的结束。
测试用Sinc函数作为输入
现在,让我们用第二波重复验证。将模块中的信号类型更改为1,这将生成一个Sinc函数。
在仿真结果中,您将观察到生成的信号的实部遵循Sinc函数,其傅里叶变换产生矩形脉冲形状,再次证实了我们设计的正确性。
测试用Sinc函数作为输入
接下来,让我们用第三个信号测试设计。将模块中的信号类型更改为2,这将为我们的测试台生成矩形波形。
从仿真结果可以看出,它的傅里叶变换是一个Sinc函数,正如预期的那样。
本文编译自hackster.io