基于Smart ZYNQ (SP/SP2/SL 版) 的FPGA实验十一 基于双路高速ADC模块的信号采集实验

本文将演示如何在Smart ZYNQ (SP &SP2 &SL)的主板下使用DUAL_HD_ADC双路高速ADC模块来实现信号的采集,并通过ILA观察采集到的波形。

  • 此章节内容适用于Smart ZYNQ SP SP2和 SL 版的板子 ( 不包含Smart ZYNQ 标准版 ),如是标准版或本站其他板子请看对应板子目录
  • 本文在 vivado2018.3版本上演示

之前章节中有介绍过使用片内的XADC功能来采集模拟信号,但是片内的XADC性能有限,尤其是采样率最高只能达到1M,当我们需要采集的信号频率稍高时,用片内XADC采样到的波形就会失真。在这种情况下,外接高性能ADC模块就能给我们更多的选择。

本文将使用本站的双路ADC模块来做演示,模块相关的硬件信息和电路原理分析可以从本站下列链接查看: 双路高速ADC模块—DUAL_HD_ADC 资料汇总 

模块的照片如下:

模块指标:

ADC芯片: 3PA1030
转换速率: 50MSPS
数据位宽: 10位
功能接口: SMA X2
测量范围: -5V 到 +5V (范围误差5V + – 0.2V)

模块所设计的电路 3PA1030是工作在CENTER SPAN 工作模式下,中心电压对应1V,输入和ADC的对应关系是:

  • VI=+5V, ADC的值是 1023
  • VI= 0V, ADC的值是 512
  • VI=-5V, ADC的值是 0
  • 即换算关系是 电压 V =(10 x ADC / 1023) – 5

一 . 创建Vivado工程

1)打开Vivado 新建一个项目, 新建一个VIVADO 工程,打开软件 选中Create Project, 如下图所示

2)点击NEXT ,在出现的第二个对话框“Project name”中输入工程名;在“Project location”中选择保存路径;勾选“Create project subdirectory”(默认),最后点击“Next” 备注,所有的路径均不能出现中文名称

3)点击 RTL PROJECT 选项,点击NEXT

4) 第四步Add Sources 选项直接留空,NEXT

5)第五步Add Constraints 选项直接留空,NEXT

6)选择芯片型号  板子的芯片型号为 XC7Z020 封装是CLG484 所以型号我们选择 xc7z020clg484-1

7)确认所选信息 点击“Finish”,完成vivado的工程创建

之后 工程就新建好了, vivado 进入到开发界面

二、添加一个ILA测试模块

这里我们计划添加一个ILA来观察ADC采集的结果

选择 Native 接口, 探针数量为4 深度可以根据自己的需求选择 ,这里用8192

因为ADC 是10bit的,所以这里我们 位宽选择10,另外一个通道位宽设为1,用来观察OVR (范围超出信号) ,因为板子上有两路ADC芯片,所以这里我们设置两组这样的探针。并选择OK进行保存

三、增加时钟模块来生成50Mhz 时钟

(备注,其实我们Smart Zynq PL端输入的时钟就是50M的,而我们这里所用的ADC模块采样频率也是50M,所以这里也完全可以不增加内部时钟PLL模块,但是为了让这个工程以后可以适配更多频率的ADC模块,所以这里还是增加了内部时钟模块来方便以后的拓展工作)

将输入时钟设置成50M

输出时钟设置成50m,并选择OK 保存配置

四、增加顶层模块

1)选择Add Sources 在弹出的窗口中 选择Add or create design sources

2)点Create File 创建文件,并在弹出窗口中输入verilog模块的文件名,之后按下Finish 完成

3)双击打开刚刚创建的ADC_TEST.V文件,并添加下列代码

`timescale 1ns / 1ps

module ADC_TEST(
input sys_clk ,
///////////AD1/////////////
input [9:0] ad1_data,
input ad1_ovr,
output ad1_clk,
output ad1_oe,
///////////AD2/////////////
input [9:0] ad2_data,
input ad2_ovr,
output ad2_clk,
output ad2_oe
);

wire clk_50m;

assign ad1_oe = 1'b0;
assign ad1_clk = ~clk_50m;
assign ad2_oe = 1'b0;
assign ad2_clk = ~clk_50m;

clk_wiz_0 u_clk_wiz_0(
.clk_out1(clk_50m),
.reset(1'b0),
.locked(),
.clk_in1(sys_clk));

ila_0 u_ila_0 (
.clk(clk_50m),
.probe0(ad1_ovr),
.probe1(ad1_data),
.probe2(ad2_ovr),
.probe3(ad2_data)
);

endmodule

通过RTL图可以看出,整个系统非常的简单,可以理解为把输入的信号直接丢给ILA来进行观察

五、 管脚约束文件创建

因为涉及到的管脚比较多,所以这里我们直接用创建管脚约束的方式来演示(当然你也可以通过RTL界面来在UI界面下进行约束)

1) 新建一个约束文件

2 )在弹出的窗口依次点create file 并且在file name中填入约束文件的文件名 ,完成后点ok 和finish

3 ) 如下图方式打开约束文件

4 ) 在约束文件中填入约束信息(管脚定义,管脚电压等) 下面的约束内容仅针对Smart ZYNQ SP、 SP2、SL的主板,其他主板请根据连接的IO自行修改。 之后

set_property -dict {PACKAGE_PIN M19  IOSTANDARD LVCMOS33} [get_ports sys_clk]

set_property -dict {PACKAGE_PIN AB15 IOSTANDARD LVCMOS33} [get_ports ad1_clk]
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD LVCMOS33} [get_ports ad1_ovr]
set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports ad1_oe]
set_property -dict {PACKAGE_PIN AA22 IOSTANDARD LVCMOS33} [get_ports {ad1_data[0]}]
set_property -dict {PACKAGE_PIN AB22 IOSTANDARD LVCMOS33} [get_ports {ad1_data[1]}]
set_property -dict {PACKAGE_PIN AA21 IOSTANDARD LVCMOS33} [get_ports {ad1_data[2]}]
set_property -dict {PACKAGE_PIN AB21 IOSTANDARD LVCMOS33} [get_ports {ad1_data[3]}]
set_property -dict {PACKAGE_PIN AB20 IOSTANDARD LVCMOS33} [get_ports {ad1_data[4]}]
set_property -dict {PACKAGE_PIN AB19 IOSTANDARD LVCMOS33} [get_ports {ad1_data[5]}]
set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVCMOS33} [get_ports {ad1_data[6]}]
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports {ad1_data[7]}]
set_property -dict {PACKAGE_PIN AA16 IOSTANDARD LVCMOS33} [get_ports {ad1_data[8]}]
set_property -dict {PACKAGE_PIN AB16 IOSTANDARD LVCMOS33} [get_ports {ad1_data[9]}]
set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports ad1_oe]

set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVCMOS33} [get_ports ad2_oe]
set_property -dict {PACKAGE_PIN AA14 IOSTANDARD LVCMOS33} [get_ports ad2_ovr]
set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports ad2_clk]
set_property -dict {PACKAGE_PIN AA13 IOSTANDARD LVCMOS33} [get_ports {ad2_data[0]}]
set_property -dict {PACKAGE_PIN Y13 IOSTANDARD LVCMOS33} [get_ports {ad2_data[1]}]
set_property -dict {PACKAGE_PIN W13 IOSTANDARD LVCMOS33} [get_ports {ad2_data[2]}]
set_property -dict {PACKAGE_PIN V13 IOSTANDARD LVCMOS33} [get_ports {ad2_data[3]}]
set_property -dict {PACKAGE_PIN W17 IOSTANDARD LVCMOS33} [get_ports {ad2_data[4]}]
set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {ad2_data[5]}]
set_property -dict {PACKAGE_PIN AB17 IOSTANDARD LVCMOS33} [get_ports {ad2_data[6]}]
set_property -dict {PACKAGE_PIN AA17 IOSTANDARD LVCMOS33} [get_ports {ad2_data[7]}]
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports {ad2_data[8]}]
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {ad2_data[9]}]

六、工程编译、综合

1) 编译 RUN

2)综合并生成 bit文件

七、下载并在线测试结果

硬件连接, 将我们的ADC模块连接到Smart Zynq 主板靠近HDMI的一侧 ,并将两路ADC模块的输入端用SMA转BNC信号线分别连接波形发生器(如没有波形发生器,也可以用可调电源来模拟,切记,输入范围是-5V 到 +5V),之后再将板子和电脑进行连接(供电和连接下载器)。

1) 点选 Program Device 然后选择芯片xc7z020_1

2) 点选 program

3) 之后系统会对FPGA进行编程配置,并且vivado 会弹出ila调试界面

4) 如果 ILA界面下没有出现对应的信号,可以点选ILA界面下的加号

5)按下箭头进行数据的采集

6)接下来对采集的数据进行一些简单的设置以方便观察结果,首先将采集的结果定义为无符号整数方便看ADC采集到的值

这里显示的值就是ADC采集到信号的值,对应的电压可以通过 换算关系 V =(10 x ADC / 1023) – 5 来进行反推。

7) 这里也可以将值设置成模拟量来方便观察波形,Waveform Style -> Analog , 可以从图上看到,可以从下图中看出我们采集的波形一个是正弦波,一个是三角波。

八、对观测结果进行验证

观测一 用ADC模块采集波形发生器生成的波形,这里我们将波形发生器设置成(VPP:4.5V, OFFSET : 0V,频率为1Mhz的正弦波)考虑到波形发生器是低阻输出(50欧)而我们的adc 又是高阻抗输入,所以这里实际采集到的波形理论上应该接近于两倍关系 即 VPP:9V,OFFSET:0V (即正弦波的最小值是-4.5V ,正弦波的最大值是+4.5V)。

(备注 因为输入阻抗比较大,所以如果直接用板子去测量50欧阻抗的信号发生器输出的波形,实际测量到的结果可能是两倍信号的大小,这个是正常的,即使在普通示波器上这个现象也是会出现的,大家感兴趣的可以百度搜索下 “为什么示波器采集到的波形是信号发生器的两倍(高端的示波器会有50欧和1M欧两档,这种示波器可以解决这个问题)

这里做试验没有选择VPP:5V,而是选择VPP为4.5V是为了方便进行演示,大家也可以选择VPP等于5V,但是因为部分模块最大的采集范围可能是到4.9V-5.1V之间,而选择5V的正弦波有可能在部分模块上会出现数据超出范围(OVR信号置1)的情况,如遇到这类情况,大家可以适当调小一些范围(如4.8或者4.9),另外如果测量的是方波信号,即使设置波形发生器为5V,实际方波的上升沿也会有一段过冲的现象(用示波器也能观测到),也同样会导致OVR信号置1,这个是正常现象。大家根据实际情况自行调整信号源进行试验。

随后我们用ILA抓取一段波形,并将信号设置成模拟量来方便观察波形,Waveform Style -> Analog

下列两张图是测试结果,可以看到,输入的信号是一个正弦波

通过换算可以得到 正弦波的 最高电压接近 971 (换算得到 971/1023×10-5=4.491V)

通过换算可以得到 正弦波的 最低电压接近 52(换算得到 52/1023×10-5V= – 4.491V)

采集到的波形和信号发生器生成的波形满足两倍关系(设置的VPP是4.5V,实际采集到的VPP是4.49 X 2,接近两倍关系),即数据正确(为什么是两倍关系 上文中有提到)

观察二 用ADC模块 采集数字稳压源的电压

实验分别测试了4.5V, 0.01V 和 -3.0V 电压,通过ila界面 换算 结果都是正确的(有兴趣的也可以测试5V电压,不过部分模块有可能在5V处会OVR报警,如出现这种情况,大家可以适当降低采集信号的电压

1 ) 测量4.5V,实际采集到的数值在971附近波动,根据换算971对应的电压是4.49V,与稳压源的4.5V数值接近。

2 )测量 0.01V,实际采集到的数值在511附近波动,根据换算511对应的电压是 -0.0004V,与稳压源的0.01V接近。

3) 最后再采集一组负电压,因为我的可调电源只能输出正电压, 所以这里我将可调电源输出的两个信号进行交换,实现负电压输出(备注,如果可调电源正负极一边给主板供电,同时又引出另一组电源线给ADC进行采集,此种情况下交换模拟信号的正负极有可能会造成短路损坏主板,所以大家交换前请自行根据实际情况进行评估)

这里我们采集负的3V电压,实际采集到的数值在203附近波动,根据换算203对应的电压是 -3.01V,与稳压源的-3.00V接近。

其他数据大家自行常识, 另外如果OVR信号被置1了,证明有数据超出测量范围了。

  • 本文的完整工程下载:11_PL_ADC_MODULE_TEST
  • VIVADO的版本:2018.3
  • 工程创建目录:E:\Smart_ZYNQ_SP_SL\FPGA\11_PL_ADC_MODULE_TEST
  • 工程适用主板: Smart ZYNQ (SP / SP2 / SL) (不适用于Smart ZYNQ 标准版 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注