当前位置:   article > 正文

ZYNQ FPGA实验——AD/DA测试

fpga实验


前言

本实验是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脚口对齐,再依次从上至下插入即可。
请添加图片描述


二、添加PLL IP核

用 PLL 产生出25MHz的时钟,用于给ADC提供采样时钟。
先按照下图中的序号依次操作找到Clocking Wizard并双击打开。
在这里插入图片描述
在Output Clocks下添加一个时钟输出,频率设置为25MHz,其他的选项均保持默认,点击OK,然后点击Generate生成即可。
在这里插入图片描述


三、添加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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

文件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 <= 'h51eb;     //1Mhz 20971.52 取整20971
        1:  Fword <= 'ha3d7;     //2Mhz 41943.04 取整41943
        2:  Fword <= 'hf5c2;     //3Mhz 62914.56 取整62914
        //3:  Fword <= 'h33333;    //10Mhz 209715.2 取整209715
    endcase
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

文件da_wave_send.v中写入的代码如下。

//本代码来自正点原子
module da_wave_send(
    input                 clk    ,  //时钟
    input                 rst_n  ,  //复位信号,低电平有效    
    input        [7:0]    rd_data,  //读出的数据
    //DA芯片接口
    output                da_clk ,  //DA(AD9708)驱动时钟,最大支持125Mhz时钟
    output       [7:0]    da_data   //输出给DA的数据  
);

//parameter 频率调节控制
parameter  FREQ_ADJ = 8'd5;  //频率调节,FREQ_ADJ的值越大,最终输出的频率越低,范围0~255

//reg define
reg    [7:0]    freq_cnt  ;  //频率调节计数器

//数据rd_data是在clk的上升沿更新的,所以DA芯片在clk的下降沿锁存数据是稳定的时刻
//而DA实际上在da_clk的上升沿锁存数据,所以时钟取反,这样clk的下降沿相当于da_clk的上升沿
assign  da_clk = ~clk;       
assign  da_data = rd_data;   //将读到的数据赋值给DA数据端口

//频率调节计数器
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)
        freq_cnt <= 8'd0;
    else if(freq_cnt == FREQ_ADJ)    
        freq_cnt <= 8'd0;
    else         
        freq_cnt <= freq_cnt + 8'd1;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

六、管脚分配

ADDA模块——AN108的34针排布的原理图如下。
在这里插入图片描述
黑金开发板的J11扩展口原理图如下。
在这里插入图片描述
其中,J11扩展口所对应的引脚号如下表所示。

J11管脚信号名称ZYNQ引脚名ZYNQ引脚号
PIN1GND--
PIN2+5V--
PIN3EX_IO2_1NIO_L6N_T0_35F17
PIN4EX_IO2_1PIO_L6P_T0_35F16
PIN5EX_IO2_2NIO_L15N_T2_35F20
PIN6EX_IO2_2PIO_L15P_T2_35F19
PIN7EX_IO2_3NIO_L18N_T2_35G20
PIN8EX_IO2_3PIO_L18P_T2_35G19
PIN9EX_IO2_4NIO_L14N_T2_35H18
PIN10EX_IO2_4PIO_L14P_T2_35J18
PIN11EX_IO2_5NIO_L9N_T1_35L20
PIN12EX_IO2_5PIO_L9P_T1_35L19
PIN13EX_IO2_6NIO_L7N_T1_35M20
PIN14EX_IO2_6PIO_L7P_T1_35M19
PIN15EX_IO2_7NIO_L12N_T1_35K18
PIN16EX_IO2_7PIO_L12P_T1_35K17
PIN17EX_IO2_8NIO_L10N_T1_35J19
PIN18EX_IO2_8PIO_L10P_T1_35K19
PIN19EX_IO2_9NIO_L17N_T2_35H20
PIN20EX_IO2_9PIO_L17P_T2_35J20
PIN21EX_IO2_10NIO_L11N_T1_35L17
PIN22EX_IO2_10PIO_L11P_T1_35L16
PIN23EX_IO2_11NIO_L8N_T1_35M18
PIN24EX_IO2_11PIO_L8P_T1_35M17
PIN25EX_IO2_12NIO_L4N_T0_35D20
PIN26EX_IO2_12PIO_L4P_T0_35D19
PIN27EX_IO2_13NIO_L5N_T0_35E19
PIN28EX_IO2_13PIO_L5P_T0_35E18
PIN29EX_IO2_14NIO_L16N_T2_35G18
PIN30EX_IO2_14PIO_L16P_T2_35G17
PIN31EX_IO2_15NIO_L13N_T2_35H17
PIN32EX_IO2_15PIO_L13P_T2_35H16
PIN33EX_IO2_16NIO_L19N_T3_35G15
PIN34EX_IO2_16PIO_L19P_T3_35H15
PIN35EX_IO2_17NIO_L20N_T3_35J14
PIN36EX_IO2_17PIO_L20P_T3_35K14
PIN37GND--
PIN38GND--
PIN39+3.3V--
PIN40+3.3V--

根据上面表中各管脚对应的引脚号,结合AN108的原理图和J11扩展口的原理图,打开管脚配置界面依次分配管脚即可。
在这里插入图片描述


七、连接开发板测试

连接开发板,点击Generate Bitstream生成比特流文件,将其下载到开发板上。
这时候会出现hw_ila_1和hw_vios两个窗口,其中hw_vios窗口是用来调节频率字的,其中00对应1MHz,01对应2MHz,10对应3MHz,hw_ila_1窗口是用来查看输出波形的。
1MHz输出频率在ILA下观察到的输出波形如下图所示。
在这里插入图片描述
放大后如下图所示。
在这里插入图片描述
2MHz输出频率在ILA下观察到的输出波形如下图所示。
在这里插入图片描述
放大后如下图所示。
在这里插入图片描述
3MHz输出频率在ILA下观察到的输出波形如下图所示。
在这里插入图片描述
放大后如下图所示。
在这里插入图片描述
由上面的输出波形图可以看到,DA输出的正弦波比较规整圆滑,没有毛刺,而AD输入的正弦波不是特别的规则,但是大体的轮廓还是比较接近正弦波。


八、Matlab中分析输出波形

将上面ILA下不同输出频率对应的正弦波导出为CSV文件,然后在Matlab中进行分析。
新建脚本文件并写入如下代码。

csv_row6 = iladata{:,6};  %取出csv文件中的第六列数据
csv_row7 = iladata{:,7};  %取出csv文件中的第七列数据
fs=50000000;    %设置采样频率为50MHz
N=4096;         %采样点
n=0:N-1;
t=n/fs;
f=n*fs/N;       %频率序列
figure;
subplot(2,1,1);plot(t,csv_row6);grid on;title('1MHz-DA时域波形');
y1=abs(fft(csv_row6,N)); 
subplot(2,1,2);plot(f,y1,'r');grid on;title('1MHz-DA频谱');
figure;
subplot(2,1,1);plot(t,csv_row7);grid on;title('1MHz-AD时域波形');
y2=abs(fft(csv_row7,N)); 
subplot(2,1,2);plot(f,y2,'r');grid on;title('1MHz-AD频谱');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

输出频率为1MHz的DA输出图如下。
在这里插入图片描述
输出频率为1MHz的AD输出图如下。
在这里插入图片描述
同样的方法得到输出频率为2MHz和3MHz的输出图。
输出频率为2MHz的DA输出图如下。
在这里插入图片描述
输出频率为2MHz的AD输出图如下。
在这里插入图片描述
输出频率为3MHz的DA输出图如下。
在这里插入图片描述
输出频率为3MHz的AD输出图如下。
在这里插入图片描述
通过Matlab分析不同输出频率的频谱可知,1MHz、2MHz和3MHz输出频率所对应的DA输出频率和AD输入频率都是相等的,虽然AD输入端的正弦波不是特别规整,但是通过频谱图中最高的点仍然可以读出其输出频率与DA输出端的频率一致。


总结

以上就是ZYNQ FPGA实验——AD/DA测试的所有内容了,本实验是ZYNQ FPGA实验——DDS IP数字波形合成ZYNQ之高速AD/DA验证实验这两个实验的综合,需要注意的就是在添加DDS IP核时与之前有区别,相位宽度和输出宽度如果设置不当就不会得到预想的结果,ILA探针的数量可以根据自己需要观察的信号数量确定,特别要注意一些细节的改变,否则编译时会出现错误。
本文参考资料:
正点原子–course_s1_ZYNQ那些事儿-FPGA实验篇V1.06.pdf
ALINX黑金AX7020开发板用户手册V2.2.pdf
领航者ZYNQ之FPGA开发指南_V2.0 .pdf
本文参考博文:
vivado VIO IP的用法
FPGA数字信号处理基础----Xilinx DDS IP使用

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/830440
推荐阅读
相关标签
  

闽ICP备14008679号