文章目录
前言一、DDS简介二、添加DDS IP核三、添加VIO IP核四、添加ILA IP核五、编写测试程序六、分配管脚七、连接开发板测试八、Simulator仿真九、Matlab中分析输出波形1、导出CSV文件2、使用信号分析仪分析波形3、写脚本文件做FFT
总结
前言
本实验是DDS IP数字波形合成,具体的要求以及开发流程如下。 DDS IP数字波形合成实验流程: 1.使用 Vivado的IPI工具,例化DDS IP。 2.DDS需要能够配置频率字(相位增量)。 3.DDS工作时钟使用PL的板载50MHz时钟。 4.使用ILA工具观察波形,使用VIO设定频率字。 5.在ILA的波形窗口里,观察你设定的波形的周期,验证你频率字设定的正确性。 6.把ILA波形导出到CSV文件,波形样点长度不小于2048点,在Matlab里分析波形的频谱,验证你生成波形的正确性。 7.使用VIO更改频率字,分别生成1MHz和3MHz的正弦波形。 使用以上流程,验证你输出波形的正确性。
一、DDS简介
DDS(Direct Digital Synthesizer)是直接数字式频率合成器的英文缩写,它同DSP(Digital Signal Processing,数字信号处理)一样,也是一项关键的数字化技术,与传统的频率合成器相比,DDS具有低成本、低功耗、高分辨率和快速转换时间等优点,广泛使用在电信与电子仪器领域,是实现设备全数字化的一个关键技术。 DDS是一种把数字信号通过数模(D/A)转换器转换成模拟信号的数字合成技术,其特点是从相位概念出发直接合成所需要的波形。DDS的具体工作过程是由N位相位累加器、N位加法器和N位累加寄存器组成,每来一个时钟脉冲,N位加法器将频率控制字K与N位累加寄存器输出的累加相位数据相加,并把相加后的结果送至累加寄存器的输入端,累加寄存器一方面将上一时钟周期作用后所产生的新的相位数据反馈到加法器的输入端,使加法器在下一时钟的作用下继续与频率控制字K相加;另一方面将这个值作为取样地址送入幅度/相位转换电路,幅度/相位转换电路根据这个地址输出相应的波形数据,最后经D/A转换器和LPF(低通滤波器)将波形数据转换成所需要的模拟波形。
二、添加DDS IP核
首先创建一个名为dds_test的工程,新工程到下图所示的界面后点击Finish即可完成工程的创建。 然后按照下图中序号找到DDS Compiler双击打开。 在Configuration栏目下的设置如下图所示。 Phase Generator and SIN COS LUT:DDS由Phase Generator和SIN/COS组合提供,并且带有可选的相位抖动。(LUT,Look Up Table,即查找表) Phase Generator only:仅仅提供相位输出。 SIN COS LUT only:只提供了带有可选泰勒级数校正电路的SIN/COS LUT。 Frequency Resolution(频率分辨率):这个参数与输出相位数据的宽度和系统时钟频率相关,如果想要得到n bit的输出位宽,且系统输入时钟频率为 f Hz,则:
F
r
e
q
u
e
n
c
y
R
e
s
o
l
u
t
i
o
n
=
f
2
n
Frequency Resolution =\frac{f}{2^n}
FrequencyResolution=2nf 这里的输出位宽可以参考总结栏目。 SFDR(Spurious Free Dynamic Range)与输出宽度的关系如下表所示。 在Implementation栏目下的Phase Increment Programmability(相位增量可编程性)下选择Programmable。 在Output Frequencies下的设置如下图所示。 以上未提及的栏目保持默认设置即可,点击OK,在弹出的框中选择Generate即可生成DDS IP。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/cc1d180ec96745e7acc1732cdbb72085.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KW_5bK46LSk,size_13,color_FFFFFF,t_70,g_se,x_16#pic_center)
三、添加VIO IP核
在IP Catalog搜索栏输入vio并找到VIO(Virtual Input/Output)双击打开。 在General Options栏目下的设置如下图所示。 切换到PROBE_OUT Ports栏目下的设置如下图。 点击OK,在弹出的框中选择Generate即可生成VIO IP。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5ca9b7fa9ff94e29aec5d6907d5e39eb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KW_5bK46LSk,size_12,color_FFFFFF,t_70,g_se,x_16#pic_center)
四、添加ILA IP核
在IP Catalog搜索栏输入ila并找到ILA(Integrated Logic Analyzer)双击打开。 在General Options栏目下的设置如下图所示。 根据代码给每个探针设置位数如下图所示。 点击OK,在弹出的框中选择Generate即可生成ILA IP。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/de20f7702fb24007b9425cf30c3e53d2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KW_5bK46LSk,size_12,color_FFFFFF,t_70,g_se,x_16#pic_center)
五、编写测试程序
新建名为dds_test的Verilog文件,依次按照下图中标注的序号进行即可。 在新建好的dds_test.v文件中写入如下代码。
//该代码来自博客:vivado VIO IP的用法,见总结
`timescale 1ns / 1ps
module dds_test(
input sys_clk, //系统时钟 50MHz T=20ns
input rst_n //系统复位
);
//----------VIO按键控制频率控制字(key_PINC)--------------//
wire [1:0] key_PINC;
vio_0 vio_0_inst (
.clk(sys_clk), // input wire clk
.probe_out0(key_PINC) // output wire [1 : 0] probe_out0
);
//---------------信号频率控制模块--------------//
wire [23:0] Fword ; //频率字
Fword_set Fword_set_inst(
//input
.clk (sys_clk ),
.rst_n (rst_n ),
.key_PINC (key_PINC ),
//output
.Fword (Fword )
);
//---------------DDS模块--------------//
//input
wire [0:0] fre_ctrl_word_en ;
//output
wire [0:0] m_axis_data_tvalid ;
wire [47:0] m_axis_data_tdata ;
wire [0:0] m_axis_phase_tvalid ;
wire [23:0] m_axis_phase_tdata ;
assign fre_ctrl_word_en=1'b1;
//例化DDS IP
dds_compiler_0 dds_compiler_0_inst (
.aclk (sys_clk ), // input wire aclk
.s_axis_config_tvalid (fre_ctrl_word_en ), // input wire s_axis_config_tvalid
.s_axis_config_tdata (Fword ), // input wire [23: 0] s_axis_config_tdata
.m_axis_data_tvalid (m_axis_data_tvalid ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (m_axis_data_tdata ), // output wire [47 : 0] m_axis_data_tdata
.m_axis_phase_tvalid (m_axis_phase_tvalid ), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata (m_axis_phase_tdata ) // output wire [23 : 0] m_axis_phase_tdata
);
ila_0 ila_0_inst (
.clk(sys_clk), // input wire clk
.probe0(key_PINC), // input wire [1:0] probe0
.probe1(Fword), // input wire [23:0] probe1
.probe2(m_axis_data_tdata) // input wire [47:0] probe2
);
endmodule
其中例化dds部分的代码来自dds_compiler_0中的dds_compiler_0.veo文件,不过需要将括号内的参数做一修改。 例化vio部分的代码来自vio_0中的vio_0.veo文件,同样需要将括号内的参数做一修改。 例化ila逻辑分析仪部分的代码来自ila_0中的ila_0.veo文件,同样需要将括号内的参数做一修改。 按下图中序号先右击Fword_set_init选择Add Sources,然后新建Fword_set.v文件。 在Fword_set.v文件中写入如下代码。
//该代码来自博客:vivado VIO IP的用法,见总结
`timescale 1ns / 1ps
module Fword_set(
input clk ,
input rst_n ,
input [1:0] key_PINC ,
output reg [23:0] Fword
);
always@(*)
begin
case(key_PINC)
0: Fword |