Xilinx DDS Compiler IP 使用教程

作者:碎碎思,来源:OpenFPGA

介绍

直接数字合成器 (DDS) 是软件定义无线电和数字通信系统中的关键工具,因为它们提供了一种在数字域中生成复杂信号的方法,该信号也是可变的。虽然 DDS 背后的理论相当简单,但第一次在 FPGA 中实现它可能有点挑战,这就是为什么我想创建这个项目作为一个简单的示例,说明如何使用Xilinx DDS Compiler IP并把它运行在 Ultra96 板上的可编程逻辑中。

DDS 也称为数控振荡器 (NCO),包含正弦波数据值的查找表,该表接收给定的相位值并输出正弦波的适当数据/幅度值。该输入值决定了输出波形的频率,值越小,DDS 通过正弦查找表的步进越慢,输出波形的频率越低。相反,输入值越高,DDS 步进查找表的速度越快,输出波形的频率也越高。此输入值通常称为调谐字,但在 Xilinx DDS Compiler IP 中,它称为相位增量。

1.gif

2.png

如上图所示,此相位增量值 (Δθ) 越大,DDS 围绕表示复杂波形的单位圆的步进速度越快。当 M 加倍时,生成的复杂波形的频率也加倍,因为它绕单位圆的步进速度是原来的两倍。与该单位圆的相位值相关的数据点存储在 DDS 的查找表中。

在这一点上,我们可以看到 DDS 的主要优势之一:我们可以快速、平滑地改变输出波形的频率,只需告诉 DDS 多快步进查找表的输入值(又名 - 多快绕单位圆移动)。

输入相位增量值不断添加到自身 (A1 & D1) 以生成所需输出波形的每个瞬时值,从而从查找表 (T1) 中获得该瞬时相位值的适当数据值/幅度。

3.png

为了演示 DDS 及其输出波形频率变化的难易程度,我决定使用简单的线性调频波形比较合适。线性调频是指正弦波以一个频率开始,然后在一段时间内线性增加或减少(有时也称为扫描)。

4.png

决定在 26 us的时间内以 1MHz 的步长从 1MHz 到 25MHz 进行简单的线性调频(时钟是 100MHz,每个时钟周期 10 ns,我随机选择让 DDS 编译器输出每个频率 1 us只是为了在逻辑分析器窗口中容易看到它)。

5.png

通过递归地将 1MHz 的相位增量值添加到自身,然后将其作为输入提供给 Xilinx DDS Compiler IP ,这实现了从 1MHz 到 FPGA 结构时钟一半的线性调频(在 ILA 中采样时保留奈奎斯特规则)以 1MHz 为步长。选择只提高到 25MHz,这样整个 chirp 就可以立即显示在我的屏幕上进行截图,但我的结构时钟设置为 100MHz,所以可以降低到 50MHz。

使用 PG141 中的以下等式为 B 列中的每个输出波形频率计算了 C 列中的相位增量值:

6.png

然后我将 C 列中的相位增量值转换为十六进制以去除小数位,因为我是在 Verilog 中编写此代码的。我创建了 E 列和 F 列以表明相位增量的差异确实导致了与 1MHz 相同的十六进制值。

接下来就是搭建工程进行验证,详细的搭建过程就不展示了,可以在最后的工程中找到,在工程中主要有以下IP:

1 - Xilinx DDS Compiler IP;
2 - 连接 DDS 的 AXI Stream 从设备和主设备的逻辑;
3 - 一个集成逻辑分析仪 (ILA) IP,用于查看 DDS 的输出波形。

在 Vivado 的 Flow Navigator 列下,打开 IP 库并搜索“DDS”。当 DDS Compiler IP 出现在 IP 存储库的列表中时双击它,将弹出一个对话框。单击“Customize IP”按钮,将出现 DDS 编译器的配置窗口。

7.png

在如上所示的第一个选项卡中,为了我们的目的,保留所有默认设置。

在第二个选项卡下,为相位增量和偏移可编程性选择AXI Stream 接口。

8.png

同样关于 DDS 编译器的 AXI Stream 接口,在详细实施选项卡下,选中“Output TREADY”框。在处理 AXI Stream 时,TREADY 信号是一个必要的信号。

9.png

在加ILA的时候,一共加了4个探头监测DDS从接口的输入相位增量值和DDS主接口的输出数据和相位值。将芯片的深度设置为 65536。

10.png

实例化 ILA 和 DDS IP 后,编写了简单状态机来创建 AXI Stream 接口,将相位增量值输入到 DDS,然后等待 1 us,然后将 1MHz 步长添加到相位增量值并将其输入到DDS。该状态机还保持计数,在达到 25MHz 的相位增量值后,在下一次迭代中从 1MHz 开始返回。

这个简单的 AXI Stream 接口状态机在许多不同的应用程序中都非常方便。主要逻辑步骤是:

1 - 设置初始值。
2 - 在目标 IP 的从属接口上将 Tvalid 信号设置为高电平。
3 - 设置要在目标 IP 的从接口上输入的数据值(DDS 的相位增量值)。

4 - 检查来自目标 IP 从接口的 Tready 信号,验证它已准备好接收下一个数据值。

11.png

生成新的比特流后,打开 FPGA 开发板的电源并连接到其 JTAG 端口。

在 Vivado 的 Flow Navigator 中,选择Open Hardware Manager ,然后选择Open Target和Autodetect选项。Hardware Manager与 FPGA 建立连接后,选择Program Device选项并指定刚刚生成的比特流。

成功下载后,ILA 窗口将出现,单击即时捕获按钮(带有 >> 字符的蓝色按钮),将看到 DDS 的波形。

12.png

ILA 顶部的图是 DDS 输出的实际正弦波形,下面的图是它的瞬时相位值。第三张图是输入到 DDS 的相位增量值。

底部的十六进制值只是状态机状态,用于演示每个状态如何与 DDS 控制关联。

13.png

参考

https://www.hackster.io/whitney-knitter/xilinx-dds-compiler-ip-tutorial-on-the-ultra96-f820db

https://docs.xilinx.com/v/u/en-US/pg141-dds-compiler

总结

希望这个简单的 DDS 示例对您有所帮助。关于更多信息可以查看官方IP文档(参考链接中),并深入了解其操作理论。

示例工程

https://github.com/wknitter/ultra96v2_chirpPrj 


最新文章

最新文章