文章目录
前言一、ADDA模块介绍二、添加PLL IP核三、添加ILA IP核四、DDS IP核和VIO IP核五、编写测试程序六、管脚分配七、连接开发板测试八、Matlab中分析输出波形总结
前言
本实验是ADDA测试,具体的要求、注意事项以及开发流程如下。 ADDA测试实验流程: 1.注意,AN108是34针的插头,注意其插装位置,1脚和zynq底板对齐,不要插错。 2.黑金AN108的低通滤波器通带为0-20MHz左右。 3.基于“DDS IP 数字波形合成DAC”实验方案,使用50MHz时钟频率,使用DAC输出正弦波。 4.把DAC输出模拟信号自环给ADC的输入。 5.使用MMCM分频,给ADC提供25MHz采样时钟。 6.使用ILA捕获ADC的输出数据,不少于2048样点。 7.使用Matlab分析ADC数据频谱。 8.用VIO更改频率字,生成1MHz和3MHz的正弦信号,用Matlab分析ILA数据验证频谱正确。 本实验是基于“DDS IP 数字波形合成DAC”的,是在工程dds_test的基础上改动的,涉及到的改动或是添加的文件在文中都会提到,关于DDS IP 数字波形合成实验的具体过程可以参考博文:ZYNQ FPGA实验——DDS IP数字波形合成。 该实验亦是在ZYNQ之高速AD/DA验证实验的基础上进行的,准确的说,该实验是上述两个实验的综合。
一、ADDA模块介绍
本实验中使用的ADDA模块型号为AN108,该模块如下图所示。 其中,ADC的最大采样率为32MHz,精度为8位,DAC的最大采样率为125MHz,精度也为8位。 该ADDA模块不管是AD IN口还是DA OUT口都是通过BNC接口与外界连接的。 AN108的硬件结构图如下图所示。 DA电路由高速DA芯片AD9708、7阶巴特沃斯低通滤波器、幅度调节电路和信号输出接口组成。高速DA芯片AD9708是8位,125MSPS的DA转换芯片,内置1.2V参考电压,差分电流输出。AD9708芯片差分输出以后,为了防止噪声干扰,电路中接入了7阶巴特沃斯低通滤波器,其带宽为40MHz。在滤波器之后,连接了2片高性能的145MHz带宽的运放AD8056,以实现差分变单端、幅度调节等功能,从而使得整个电路性能得到最大限度的提升,幅度调节使用的是5K的电位器,因此最终的输出范围是-5V—5V,即10Vpp。 需要注意的是,由于电路器的精度不是很精确,最终的输出有一定误差,有可能波形幅度不能达到10Vpp,也有可能出现波形削顶等问题,这些都属正常情况。 AD电路由高速AD芯片AD9280、衰减电路和信号输入接口组成。高速DA芯片AD9280是8位,32MSPS的AD转换芯片。在信号进入芯片AD9280之前,使用一片AD8056芯片构建衰减电路,接口的输入范围是-5V至5V,通过衰减电路以后,输入范围满足AD芯片的输入范围,即0~2V,相应的转换公式如下。 黑金7020开发板与ADDA模块的连接如下图所示,开发板排针的1脚2脚和39脚40脚都在开发板上标出来了,ADDA模块的1脚2脚也在ADDA模块上标注出来了,由于AN108是34脚,而开发板的排针是40脚,因此要注意不要插反,先将ADDA模块的1脚2脚和开发板的1脚2脚口对齐,再依次从上至下插入即可。 ![请添加图片描述](https://img-blog.csdnimg.cn/bb57d5ccd5564ff483e9e34b1ee6464d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KW_5bK46LSk,size_80,color_FF0000,t_70,g_se,x_16#pic_center)
二、添加PLL IP核
用 PLL 产生出25MHz的时钟,用于给ADC提供采样时钟。 先按照下图中的序号依次操作找到Clocking Wizard并双击打开。 在Output Clocks下添加一个时钟输出,频率设置为25MHz,其他的选项均保持默认,点击OK,然后点击Generate生成即可。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/c9425fb152384d129d85fa14762282a7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KW_5bK46LSk,size_14,color_FFFFFF,t_70,g_se,x_16#pic_center)
三、添加ILA IP核
ILA下各栏目的设置如下图所示。 这里设置4个探针,分别用来监测频率字控制位(2位)、频率字(24位)、ad数据(8位)和da数据(8位)。 各个探针位数的设置如下图所示。 以上各项设置成功以后点击OK,然后再点击Generate生成即可。
四、DDS IP核和VIO IP核
VIO IP核与实验ZYNQ FPGA实验——DDS IP数字波形合成相同,这里不再做变动。 DDS IP核与上面实验的不同之处在于Parameter Selection这里不再选用System Parameters,而是选择Hardware Parameters,硬件参数这里选择8位的输出宽度,因为ADDA模块最大只能传输8位宽度的数据。相位宽度与DDS IP数字波形合成实验保持一致,设置为20,如果这里位数有所变化,频率字设置代码就得相应的进行调整。 DDS总结栏目如下图所示。 其他的选项设置保持默认即可。
五、编写测试程序
本实验的文件目录结构如下图所示。 文件dds_test.v中写入的代码如下。
//该代码参考自博客:vivado VIO IP的用法,以及正点原子官方文件,见总结
`timescale 1ns / 1ps
module dds_test(
input sys_clk, //系统时钟 50MHz T=20ns
input rst_n, //系统复位
//DA芯片接口
output da_clk, //DA(AD9708)驱动时钟,最大支持125Mhz时钟
output [7:0] da_data, //输出给DA的数据
//AD芯片接口
input [7:0] ad_data, //AD输入数据
//模拟输入电压超出量程标志(本次试验未用到)
//input ad_otr , //0:在量程范围 1:超出量程
output ad_clk //AD(AD9280)驱动时钟,最大支持32Mhz时钟
);
//----------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 [7: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 [7 : 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
);
//例化PLL
clk_wiz_0 pll_inst
(
// Clock out ports
.clk_out1(ad_clk), // 给ad_clk 25MHz的频率
// Status and control signals
.reset(~rst_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(sys_clk) // input clk_in1
);
//DA数据发送
da_wave_send u_da_wave_send(
.clk (sys_clk),
.rst_n (rst_n),
.rd_data (m_axis_data_tdata),
.da_clk (da_clk),
.da_data (da_data)
);
//ILA采集AD数据
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(da_data), // input wire [7:0] probe2
.probe3(ad_data) // input wire [7:0] probe3
);
endmodule
文件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 |