本实验将采用华升科技的高速AD/DA模块在开发板上实现数模转换和模数转换的功能,AD/DA模块上包含一路8位的模数(DA)转换电路和一路8位的数模(DA)转换电路。模块的实物图如下所示:
模数(AD)转换电路采用AD公司的AD9280芯片,数据宽度为8位,最大采样率位32MSPS。数模(DA)转换电路采样的是AD公司的AD9708芯片,数据宽度为8位,最大采样率为125MSPS。AD/DA模块的详细说明请看模块的相关资料。
一、硬件连接
把AD/DA模块插入到FPGA核心板的外部40针的扩展口(J5)上,另外用跳冒将AD/DA模块的输出和输入链接起来,硬件连接后如下图所示:
AD/DA模块和FPGA核心板连接后,跟FPGA连接的管脚情况如下:
二、程序设计
本实验中,程序要输出8位的正弦波数据使得AD/DA模块的输出一个正弦波信号,这个正弦波信号通过跳冒又输入到AD电路,程序读取AD的数据输出显示在Chipscope中。
1.生成ROM文件
程序中用到一个ROM用于存储512个8位的正弦波数据,首先需要准备ROM的初始化文件(coe文件)。以下为生成正弦波数据coe文件的方法:
-首先打开Guagle_wave工具,选择菜单“查看”->“全局参数设置”,设置参数如下:
-在菜单“设定波形”里选择正弦波。
-保存为mif格式的文件。
的mif文本文件或者excel重新编辑如下的格式(十六进制,512个数据长度):
-修改后保存为sin512.coe。
生成coe文件后,在ISE项目中添加一个ROM IP核,选择Project->New Source,在弹出的窗口选择IP(CORE Generator…),File name 输入ROM。
选择Blocl Memory Generator IP
接下去设置ROM的相关参数,这一页不用修改。
在第二页面中选择Single Port ROM。
一样。
在第四页面中选择刚才我们生成的ROM初始化文件sin512.coe。
第五,六页不用修改,点击Generator按钮生成IP。
2.生成一个PLL IP,产生一个50MHz时钟和25MHz时钟,50MHz时钟用于DA的数据采样输出,而25MHz的时钟用于AD数据的采样输入。因为DA芯片AD9708的最高采样频率为125MSPS,但AD芯片AD9280的最高采样频率只有32MSPS。PLL IP生成的方法和ROM的方法差不多,这里不再重复说明。
3.编写adda_test的顶层verilog程序。
`timescale1ns/1ps
///////////////////////////////////////////////////////////////////// /////////////
///////////////////////////////////////////////////////////////////// /////////////
module adda_test(
clk,//fpga clock
daclk,
dadata,//DA data
adclk,
addata //AD data
);
input clk;//fpga clock
output daclk;
output[7:0] dadata;//DA data
output adclk;
input[7:0] addata;//AD datareg[8:0] rom_addr;
reg[7:0] ad_data;
wire[7:0] rom_data;
wire clk_25;
wire clk_50;
assign dadata = rom_data;
assign daclk = clk_50;
assign adclk = clk_25;
//DA output sin waveform
always@(negedge clk_50)
begin
rom_addr <= rom_addr +1'b1;
end
always@(posedge clk_25)
begin
ad_data <= addata ;
end
ROM ROM_inst (
.clka(clk_50),// input clka
.addra(rom_addr),// input [8 : 0] addra
.douta(rom_data)// output[7 : 0] douta
);
PLL PLL_inst(// Clock in ports
.CLK_IN1(clk),// IN
// Clock out ports
.CLK_OUT1(clk_50),// 50Mhz DA OUT clock
.CLK_OUT2(clk_25),// 25Mhz AD IN CLOCK
// Status and control signals
.RESET(1'b0),// IN
.LOCKED()
);// OUT
wire[35:0] CONTROL0;
wire[255:0] TRIG0;
chipscope_icon icon_debug (
.CONTROL0(CONTROL0)// INOUT BUS [35:0]
);chipscope_ila ila_filter_debug (
.CONTROL(CONTROL0),// INOUT BUS [35:0]
//.CLK(dma_clk), // IN
.CLK(clk_50),// IN
.TRIG0(TRIG0)// IN BUS [255:0]
//.TRIG_OUT(TRIG_OUT0)
);
assign TRIG0[7:0]= ad_data;
assign TRIG0[15:8]= dadata;
endmodule
程序比较简单,就是读取ROM的内容输出到DA数据上,再读取AD的数据到Chipscope
显示。
4.编写UCF文件
Net clk TNM_NET = sys_clk;
TIMESPEC TS_sys_clk = PERIOD sys_clk 50 MHz;
NET clk LOC = P55 | IOSTANDARD = "LVCMOS33"; #DA相关引脚(J5)
NET daclk LOC = P46 | IOSTANDARD = "LVCMOS33"; NET dadata<0> LOC = P33 | IOSTANDARD = "LVCMOS33"; NET dadata<1> LOC = P34 | IOSTANDARD = "LVCMOS33"; NET dadata<2> LOC = P35 | IOSTANDARD = "LVCMOS33"; NET dadata<3> LOC = P40 | IOSTANDARD = "LVCMOS33"; NET dadata<4> LOC = P41 | IOSTANDARD = "LVCMOS33"; NET dadata<5> LOC = P43 | IOSTANDARD = "LVCMOS33"; NET dadata<6> LOC = P44 | IOSTANDARD = "LVCMOS33"; NET dadata<7> LOC = P45 | IOSTANDARD = "LVCMOS33";
#DA相关引脚
NET adclk LOC = P47 | IOSTANDARD = "LVCMOS33"; NET addata<0> LOC = P75 | IOSTANDARD = "LVCMOS33"; NET addata<1> LOC = P74 | IOSTANDARD = "LVCMOS33"; NET addata<2> LOC = P67 | IOSTANDARD = "LVCMOS33"; NET addata<3> LOC = P66 | IOSTANDARD = "LVCMOS33"; NET addata<4> LOC = P62 | IOSTANDARD = "LVCMOS33"; NET addata<5> LOC = P61 | IOSTANDARD = "LVCMOS33"; NET addata<6> LOC = P50 | IOSTANDARD = "LVCMOS33"; NET addata<7> LOC = P48 | IOSTANDARD = "LVCMOS33";
PIN "PLL_inst/clkout2_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;
PIN "PLL_inst/clkout1_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;三、下载和实验
编译程序生成adda_test.bit文件,再下载到开发板中,这时可以用示波器测量ADDA模块上的DA输出端波形(测量模块的J1)。在示波器上会显示大概100KHz左右的正弦波,如下图所示。
理论频率计算:fout=50MHz/512=97.65625KHz
打开Chipscope来查看一下AD输入的数据和波形,连接JTAG后点击Bus Plot,在Bus Plot 中设置如下:
点击触发按钮T!,AD输入和DA输出的正弦波波形就会动态的显示在Bus Plot的窗口。其中红色的是DA输出的数据,也就是FPGA输出给DA芯片的8位数据;紫色的为AD输入的数据,是从AD芯片输入到FPGA的8位数据。
是AD输入的数据的幅度在变化。
将Chipscope抓取的数据导出
AD时域和频域波形
平均频率f=(0.7331+1.222)/2=0.97755e5=97.755KHz 误差:(97.755-97.65625) / 97.65625=0.101%
平均频率=(1.711+2.199)/2=1.955,即约等于195.5KHz
使用16384点FFT做运算。
xlLoadChipScopeData('E:\\PB_proj\\Xilinx_proj\\XC6SLX9_proj2\\ONLY_CORE2\\ 2_adda_test\\ad_150806.prn');
fs=25e6;
freq=linspace(-fs/2,fs/2,length(ADC_D));
ADC_D_F=fftshift(abs(fft(ADC_D)));
figure(1);
subplot(2,1,1)
plot(ADC_D);
subplot(2,1,2)
plot(freq,ADC_D_F);
平均频率:f = (127.4+128.9)/2=128.15KHz
误差:(128.15-128)/ 128 = 0.1171875%下载本文