LabVIEW FPGA番外篇:实验67-基于LabVIEW FPGA的DDS波形发生器原理与实现

1、概述
用于生成具有高精度频率和相位可控的重复任意波形的一种常用方法是直接数字合成 (DDS)。本节实验向大家展示如何轻松地将DDS波形发生器添加到用户自己的LabVIEW FPGA应用程序中,并以mHz或更好的相对频率控制以及多个波形之间的精确相位控制输出波形。
通过在查找表中指定自己的参考波形,大家可以使用本节实验提供的DDS框架生成任意波形。这些波形是逐点生成的,只要是生成信号的硬件所允许范围内的任何形状都行。另外,还可以在信号中加入毛刺、漂移、噪声和其他异常,以便测试设备在不在受控环境中模拟可能遇到的真实条件。
本节实验我们会通过黑金的Spartan6/Artix7 FPGA开发板和AD9767 DAC高速模拟输出模块(最高更新率125MS/s),利用LabVIEW编写FPGA程序产生多路相位和幅度可调的DDS信号。
2、DDS理论
DDS波形发生器的核心组件是累加器。累加器本质上是一个实时计数器,用于存储生成波形的当前相位值。累加器更新的速率和累加器增量值决定了生成的波形频率。
例如,如果累加器每秒更新360次且累加器增量为1度,则生成的波形频率为1Hz(每秒360度)。当累加器相位值达到最大值(360度)时,它会翻转并从0度重新开始。为了更准确地表示相位值,累加器通常使用32位、48位或64位作为计数器。在32位累加器中,相位值的范围为0到4294967295,代表波形的一个完整周期或0到360 度。
当前累加器(相位)值用于在参考波形的查找表中执行查找操作,以确定下一个输出值。查找表包含了要生成的波形的一个完整周期,通常包含代表波形的1024到8192 个采样点(量化点数)。
由于累加器值通常比参考波形具有更高的分辨率,受样本数量的限制,查找操作还可以在参考波形中的两个样本之间执行内插。这是基于累加器值中的额外分辨率完成的,并返回更准确的更新值,从而使生成的信号具备更好的频率控制和更少的谐波失真。
3、FPGA DDS实现
本节实验提供的LabVIEW FPGA项目包含了2个DDS信号生成器下位机FPGA和上位机PC端的程序,分别如图1和图2所示。其中,下位机FPGA里面两个最为核心的两个IP核VI内部的查找表存储的信号波形分别是正弦和三角。


下位机FPGA DDS VI无需更改即可在用户自己的FPGA应用程序中重复使用,也可以根据项目需求进行调整。 其中,FPGA DDS生成器VI(FPGA DDS SineGen IP.vi、FPGA DDS TriangleGen IP.vi)最为核心的是累加器和波形查找两个功能。
4.1、累加器
DDS发生器中的累加器是一个32位计数器。每次调用DDG生成器VI时,累加器都会将当前累加器相位值增加指定的累加器增量。“Saturation Add”函数会自动回绕,以便当达到最大相位值时,累加器值返回到0,如图3所示。另外,DDS生成器VI还有一个重置输入,用于重新初始化累加器值。这可用于同步同一应用程序 VI中使用的多个 DDS 生成器。

4.2、波形查找
DDS发生器的波形查找部分使用当前累加器相位值从参考波形查找表返回当前波形值。使用可配置的LabVIEW FPGA查找表功能可以轻松存储参考波形。双击查找表Express VI,然后在弹出来的查找表配置对话框定义样本波形的大小和波形值,如图4所示。本节实验我们使用了2048个样本的参考波形,作为重复波形的一个周期。

执行查找操作的第一步,是从累加器值应用可选的相位偏移。这就允许我们可以精确控制多个DDS同步发生器之间的相位偏移,程序框图如图5所示。

波形输出的结果对应当前相位,宽度为32位值。本节实验,我们使用了存储在查找表中的2048个样本作为参考波形。2048个样本相当于11位样本分辨率 (2^11 = 2048)。 因此,相位值的前11位确定将使用参考波形中的哪个样本。逻辑移位(移位-5)和分割数函数将前11位作为一个值返回,将接下来的16位作为单独的值返回。例如,前11位可能返回的样本索引是420,如图6所示。

如果要充分使用满量程的16位相位值,我们可以通过内插参考波形中的两个相邻点来更准确地计算出输出值。假设接下来的16位相位累加器包含值30609。在LabVIEW FPGA查找表函数中,我们使用的可能范围为0到65535的16位整数表示参考波形的两个相邻样本之间的范围。在本节实验中,所需值 (30609)位于样本 420到样本421之间的比例大约是46%,如图7所示。通过在参考波形的这两个样本点之间进行插值,查找表函数会为DDS 返回更准确的输出值,从而生成的波形也更加精细。

内插输出值在这个VI内部,可以完成信号幅度缩放。从查找表返回的值是一个范围在-32768到32767之间的有符号整数。该值乘以返回I32整数的信号幅度,然后按-15 逻辑移位(除以32768)以返回-Signal Amplitude到+Signal Amplitude范围内的值。
缩放后的输出值从FPGA DDS Generator VI输出,然后传递给AO模拟输出或在FPGA VI中作进一步处理。
5、使用单个FPGA DDS生成器
FPGA DDS Generator VI作为子VI放置在用于生成波形信号的FPGA循环中。每次调用DDS发生器都会增加累加器并返回波形信号的下一个值。DDS生成器VI的输出被传递到DAC模拟输出节点,或者在FPG上进一步处理。
本节实验里面,DDS发生器的输出在更新到模拟输出之前通过一个移位寄存器,如图8所示。这种流水线技术允许DDS发生器和AO模拟输出(比如黑金的AD9767双通道DAC模块)并行运行,可以实现更高的物理输出更新率,当然,还可以将DDS信号通过FIFO传递给其他定时循环使用!

6、同步多个DDS生成器
我们将FPGA DDS生成器VI配置成“可重入子VI”,这样用户就可以在一个FPGA VI里面放置多个DDS生成器。在一个程序中使用多个DDS发生器的一种常见应用是生成大量具有可变幅度和相位偏移的同步波形信号。
在下面图9所示的范例程序里面,分别给3路DDS信号设置了不同的频率(累加器增量)、相移和信号幅度,然后将一个复位按钮同时接到这3个DDS生成VI上,重置一下累加器标志,即可使这3个DDS发生器同步生成具有指定相位偏移的信号。

7、DDS发生器主机接口(上位机PC控制)
为了更加灵活的控制下位机FPGA按照实际的项目需求产生指定的DDS信号,这里有很多中间参数需要进行计算和转换,如果大家使用黑金的Spartan6开发板(AX516),可以直接在上位机通过FPGA Reference引用访问控件的方式来更新控制下位机FPGA VI;如果用户使用的是ARTIX7或者KINTEX7开发板,可以将上位机PC端的参数通过串口、USB、网口或者PCIe下发给下位机FPGA。
下面给出了基于黑金超高性价比的Spartan6 FPGA开发板对应的上位机PC端控制程序前面板,如图10所示;对应的程序框图,如图11所示。


为了计算累加器增量,我们将所需的波形频率乘以累加器的范围,等于每秒的总相位累积,再除以更新循环的频率,即可得到我们每次更新需要的增量。
举例说明:假设我们需要产生频率为20kHz的波形,首先计算出累加器需要每秒向上计数20000×(2^32)>>85899345920000,然后除以前面板上的1MHz更新率,就得到了累加器增量值:85899346。
相移作为一个完整周期的比率,可以看做是累加器的范围。45度相移是一个周期 (45/360)的0.125,所以对于累加器相移,可以换算出结果: 0.125*(2^32)=536870912。
信号幅度与实际的AO模拟输出范围相关,比如16位的DAC模拟输出电压如果是±10V,那么要想输出5V电压,对于的16进制整形DAC数值就是16384。
以上计算过程可以通过下面的程序框图12,一目了然!最后,我们给出基于黑金Spartan6开发板+AD9767双通道高速DAC模块的完整FPGA DDS程序框图,如图13所示。

