ADDA测试
在ZYNQ FPGA实验报告——DDS IP.基础上进行。
实验要求
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核
DDS IP核选择Hardware Parameters,硬件参数这里选择8位的输出宽度,因为ADDA模块最大只能传输8位宽度的数据。使用50MHz时钟频率。
Clock IP核
使用MMCM分频,给ADC提供25MHz采样时钟。
ILA IP核
使用ILA捕获ADC的输出数据,不少于2048样点,本实验输出4096样点。
VIO IP核
VIO IP核与实验“DDS IP 数字波形合成DAC ”设置一致。
程序设计
顶层模块ADDA_test如下:
增加了时钟和DA发送模块的例化。
`timescale 1ns / 1ps
module ADDA_test(
input sys_clk, //系统时钟 50MHz T=20ns
input rst_n, //系统复位
//output locked,
//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 [19: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 [19: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
da_wave_send模块:
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
添加约束文件
set_property IOSTANDARD LVCMOS33 [get_ports da_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[0]}]
set_property PACKAGE_PIN U18 [get_ports sys_clk]
set_property PACKAGE_PIN N15 [get_ports rst_n]
set_property PACKAGE_PIN F19 [get_ports {da_data[7]}]
set_property PACKAGE_PIN G20 [get_ports {da_data[6]}]
set_property PACKAGE_PIN G19 [get_ports {da_data[5]}]
set_property PACKAGE_PIN H18 [get_ports {da_data[4]}]
set_property PACKAGE_PIN J18 [get_ports {da_data[3]}]
set_property PACKAGE_PIN L20 [get_ports {da_data[2]}]
set_property PACKAGE_PIN L19 [get_ports {da_data[1]}]
set_property PACKAGE_PIN M20 [get_ports {da_data[0]}]
set_property PACKAGE_PIN F20 [get_ports da_clk]
set_property PACKAGE_PIN E18 [get_ports {ad_data[7]}]
set_property PACKAGE_PIN E19 [get_ports {ad_data[6]}]
set_property PACKAGE_PIN D19 [get_ports {ad_data[5]}]
set_property PACKAGE_PIN D20 [get_ports {ad_data[4]}]
set_property PACKAGE_PIN M17 [get_ports {ad_data[3]}]
set_property PACKAGE_PIN M18 [get_ports {ad_data[2]}]
set_property PACKAGE_PIN L16 [get_ports {ad_data[1]}]
set_property PACKAGE_PIN L17 [get_ports {ad_data[0]}]
set_property PACKAGE_PIN G18 [get_ports ad_clk]
set_property IOSTANDARD LVCMOS33 [get_ports ad_clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports locked]
比特流文件输出波形
生成比特流文件,PROGRAM AND DEBUG—Generate Bitstream。
1MHz输出
2MHz输出
3MHz输出
DA输出与AD输入的正弦波约相差半个周期。
使用Matlab分析ADC数据频谱
选中要分析的信号,右键Export ILA Data,Format选择CSV,导入到指定目录中。
在Matlab中读出csv文件,并导入。
csv1_row6 = iladata1MHz{:,6}; %iladata_1MHz.csv文件中的第六列数据
csv2_row6 = iladata2MHz{:,6}; %iladata_2MHz.csv文件中的第六列数据
csv3_row6 = iladata3MHz{:,6}; %iladata_3MHz.csv文件中的第六列数据
csv1_row7 = iladata1MHz{:,7}; %iladata_1MHz.csv文件中的第七列数据
csv2_row7 = iladata2MHz{:,7}; %iladata_2MHz.csv文件中的第七列数据
csv3_row7 = iladata3MHz{:,7}; %iladata_3MHz.csv文件中的第七列数据
fs=50000000; %设置采样频率为50MHz
N=4096; %采样点
n=0:N-1;
t=n/fs;
f=n*fs/N; %频率序列
figure;
subplot(2,1,1);plot(t,csv1_row6);grid on;title('1MHz-DA时域波形');
y1=abs(fft(csv1_row6,N));
subplot(2,1,2);plot(f,y1,'r');grid on;title('1MHz-DA频谱');
figure;
subplot(2,1,1);plot(t,csv1_row7);grid on;title('1MHz-AD时域波形');
y2=abs(fft(csv1_row7,N));
subplot(2,1,2);plot(f,y2,'r');grid on;title('1MHz-AD频谱');
figure;
subplot(2,1,1);plot(t,csv2_row6);grid on;title('2MHz-DA时域波形');
y3=abs(fft(csv2_row6,N));
subplot(2,1,2);plot(f,y3,'r');grid on;title('2MHz-DA频谱');
figure;
subplot(2,1,1);plot(t,csv2_row7);grid on;title('2MHz-AD时域波形');
y4=abs(fft(csv2_row7,N));
subplot(2,1,2);plot(f,y4,'r');grid on;title('2MHz-AD频谱');
figure;
subplot(2,1,1);plot(t,csv3_row6);grid on;title('3MHz-DA时域波形');
y5=abs(fft(csv3_row6,N));
subplot(2,1,2);plot(f,y5,'r');grid on;title('3MHz-DA频谱');
figure;
subplot(2,1,1);plot(t,csv3_row7);grid on;title('3MHz-AD时域波形');
y6=abs(fft(csv3_row7,N));
subplot(2,1,2);plot(f,y6,'r');grid on;title('3MHz-AD频谱');
输出1MHz的频谱数据
输出2MHz的频谱数据
输出3MHz的频谱数据