0
点赞
收藏
分享

微信扫一扫

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章 双路高速DA实验​

双路高速DA实验​

DAC(Digital to Analog Converter,即数模转换器)是大多数系统中必不可少的组成部件,用于将离散的数字信号转换成连续的模拟信号,它们是连接模电电路和数字电路必不可少的桥梁。在很多场合下,DAC的转换速度甚至直接决定了整个系统的运行速度。本章我们将使用高速DA芯片实现数模转换产生正弦波模拟电压信号。

本章包括以下几个部分:

  1. 简介
  2. 实验任务
  3. 硬件设计
  4. 软件设计
  5. 下载验证


简介

本章我们使用的双路DA模块是正点原子推出的一款双路高速数模转换模块(ATK_DUAL_HS_DA高速DA转换芯片是由思瑞浦公司生产的3PD5651E芯片。

ATK_HS_AD_DA模块的硬件结构图如下图所示。

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_数据


24.1.1 ATK_DUAL_HS_DA模块硬件结构图

由上可知,3PD5651E芯片输出的是一对差分电流信号,为了防止受到噪声干扰,电路中接入了低通滤波器,然后通过高性能高带宽的运放电路,实现差分单端以及幅度调节等功能,使整个电路性能得到了最大限度的提升,最终输出模拟电压范围是-5V~+5V

下面来介绍下这款芯片

3PD5651E是3PEAK公司(思瑞浦微电子科技股份有限公司)生产的DAC系列数模转换器具有高性能、低功耗特点。3PD5651E的数模转换位数10位,最大转换速度125MSPS(每秒采样百万次,Million Samples per Second)

3PD5651E的内部功能框图如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_02


24.1.2内部功能框图

3PD5651E在时钟(CLOCK驱动下工作,内部集成了+1.1V参考电压(+1.10V REF)、运算放大器、电流源(CURRENT SOURCE ARRAY)和锁存器(LATCHES。两个电流输出端IOUTA和IOUTB为一对差分电流,输入数据为0(DB9~DB0=10’h000)时,IOUTA的输出电流为0,而IOUTB的输出电流达到最大,最大值的大小跟参考电压有关;当输入数据高点平(DB9~DB0=10’h3ff)时IOUTA的输出电流达到最大,最大值的大小跟参考电压有关,IOUTB的输出电流0。

3PD5651E必须在时钟的驱动下才能把数据入片内的锁存器中,其触发方式为上升沿触发,3PD5651E的时序图如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_差分_03


24.1.3芯片时序图

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_04


24.1.4内部时序

24.1.3中的DBO-DB9和CLOCK是3PD5651E的10位输入数据和为输入时钟,IOUTA和IOUTB为3PD5651E输出的电流信号。由24.1.3可知,数据在时钟的上升沿锁存,因此我们可以在时钟的下降沿发送数据,这样使DA芯片在数据的中央采样,保证数据采样的准确性,如24.1.4所示需要注意的是,CLOCK的时钟频率越快,3PD5651E的数模转换速度越快,3PD5651E的时钟频率最快125Mhz。

IOUTA和IOUTB为3PD5651E输出一对差分电流信号,通过外部电路低通滤波器与运放电路输出模拟电压信号,电压范围是-5V至+5V之间。当输入数据等于0时3PD5651E输出的电压值为5V;输入数据等于10’h3ff时,3PD5651E输出的电压值为-5V。

3PD5651E是一款数字信号转模拟信号的器件,内部没有集成DDS(Direct Digital Synthesizer,直接数字式频率合成器)的功能,但是可以通过控制3PD5651E的输入数据,使其模拟DDS的功能。例如,我们使用3PD5651E输出一个正弦波模拟电压信号那么我们只需要将3PD5651E的数据按照正弦波的波形变化即可,下图为3PD5651E的输入数据和输出电压值按照正弦波变化的波形图。

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_数据_05


24.1.5正弦波数据(左)、电压值(右)

上图可知,数据在0至1023之间按照正弦波的波形变化,最终得到的电压也会按照正弦波波形变化当输入数据重复按照正弦波波形数据变化,那么3PD5651E就可以持续不断的输出正弦波的模拟电压波形。需要注意的是,最终得到的3PD5651E的输出电压变化范围由外部电路决定的,当输入数据为0时3PD5651E输出+5V的电压;当输入数据为1023时3PD5651E输出-5V的电压

由此可以看出,只要输入数据控制的得3PD5651E可以输出任意波形的模拟电压信号,包括正弦波、方波、锯齿波、三角波波形。

实验任务

本节实验任务是使用DFZU2EG/4EV MPSoC开发板及双路高速DA扩展模块(ATK_DUAL_HS_DA模块)实现数模转换。首先利用FPGA产生正弦波变化的数字信号,经过DA芯片后转换成模拟信号,然后通过示波器观察模拟信号波形是否按照正弦波波形变化。

硬件设计

ATK_DUAL_HS_DA模块由2个型号为3PD5651E 的DA转换芯片组成3PD5651E的原理图如下图所示

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_数据_06


24.3.1芯片原理图

上图可知,3PD5651E输出的一对差分电流信号先经过滤波器,再经过运放电路得到一个单端的模拟电压信号。中右侧的RP1为滑动变阻器可以调节输出的电压范围,推荐通过调节滑动变阻器,使输出的电压范围-5V至+5V之间从而达到DA转换芯片的最大转换范围

ATK_DUAL_HS_DA模块的实物图如下图所示

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_07


24.3.2 ATK_DUAL_HS_DA模块实物图

本实验中,各端口信号的管脚分配如下表所示

表格24.3.1双路高速DA转换实验管脚分配

信号名

方向

管脚

端口说明

电平标准

sys_clk_p

input

AE5

系统差分输入时钟

DIFF_HSTL_I_12

sys_clk_n

input

AF5

系统差分输入时钟

DIFF_HSTL_I_12

sys_rst_n

input

AH11

系统复位低有效

LVCMOS33

da_clk

output

D10

DA(3PD5651E)

驱动时钟

LVCMOS33

da_data[0]

output

A12

输出给DA的数据

LVCMOS33

da_data[1]

output

D12

输出给DA的数据

LVCMOS33

da_data[2]

output

A11

输出给DA的数据

LVCMOS33

da_data[3]

output

C12

输出给DA的数据

LVCMOS33

da_data[4]

output

C11

输出给DA的数据

LVCMOS33

da_data[5]

output

B11

输出给DA的数据

LVCMOS33

da_data[6]

output

B10

输出给DA的数据

LVCMOS33

da_data[7]

output

A10

输出给DA的数据

LVCMOS33

da_data[8]

output

E10

输出给DA的数据

LVCMOS33

da_data[9]

output

E12

输出给DA的数据

LVCMOS33

da_clk1

output

B15

DA(3PD5651E)

驱动时钟

LVCMOS33

da_data1[0]

output

F13

输出给DA的数据

LVCMOS33

da_data1[1]

output

E15

输出给DA的数据

LVCMOS33

da_data1[2]

output

D15

输出给DA的数据

LVCMOS33

da_data1[3]

output

E14

输出给DA的数据

LVCMOS33

da_data1[4]

output

D14

输出给DA的数据

LVCMOS33

da_data1[5]

output

E13

输出给DA的数据

LVCMOS33

da_data1[6]

output

B13

输出给DA的数据

LVCMOS33

da_data1[7]

output

C14

输出给DA的数据

LVCMOS33

da_data1[8]

output

A13

输出给DA的数据

LVCMOS33

da_data1[9]

output

C13

输出给DA的数据

LVCMOS33

对应的XDC约束语句如下所示:

#IO管脚约束​
#时钟周期约束​
create_clock -name sys_clk_p -period 10.000 [get_ports sys_clk_p]​
#时钟​
set_property IOSTANDARD DIFF_HSTL_I_12 [get_ports sys_clk_p]​
set_property IOSTANDARD DIFF_HSTL_I_12 [get_ports sys_clk_n]​
set_property PACKAGE_PIN AE5 [get_ports sys_clk_p]​
set_property PACKAGE_PIN AF5 [get_ports sys_clk_n]​
#复位​
set_property -dict {PACKAGE_PIN AH11 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]​

set_property PACKAGE_PIN E12 [get_ports {da_data[9]}]​
set_property PACKAGE_PIN E10 [get_ports {da_data[8]}]​
set_property PACKAGE_PIN A10 [get_ports {da_data[7]}]​
set_property PACKAGE_PIN B10 [get_ports {da_data[6]}]​
set_property PACKAGE_PIN B11 [get_ports {da_data[5]}]​
set_property PACKAGE_PIN C11 [get_ports {da_data[4]}]​
set_property PACKAGE_PIN C12 [get_ports {da_data[3]}]​
set_property PACKAGE_PIN A11 [get_ports {da_data[2]}]​
set_property PACKAGE_PIN D12 [get_ports {da_data[1]}]​
set_property PACKAGE_PIN A12 [get_ports {da_data[0]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[9]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data[8]}]​
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 da_clk]​
set_property PACKAGE_PIN D10 [get_ports da_clk]​

set_property PACKAGE_PIN C13 [get_ports {da_data1[9]}]​
set_property PACKAGE_PIN A13 [get_ports {da_data1[8]}]​
set_property PACKAGE_PIN C14 [get_ports {da_data1[7]}]​
set_property PACKAGE_PIN B13 [get_ports {da_data1[6]}]​
set_property PACKAGE_PIN E13 [get_ports {da_data1[5]}]​
set_property PACKAGE_PIN D14 [get_ports {da_data1[4]}]​
set_property PACKAGE_PIN E14 [get_ports {da_data1[3]}]​
set_property PACKAGE_PIN D15 [get_ports {da_data1[2]}]​
set_property PACKAGE_PIN E15 [get_ports {da_data1[1]}]​
set_property PACKAGE_PIN F13 [get_ports {da_data1[0]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[9]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[8]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[7]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[6]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[5]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[4]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[3]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[2]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[1]}]​
set_property IOSTANDARD LVCMOS33 [get_ports {da_data1[0]}]​
set_property IOSTANDARD LVCMOS33 [get_ports da_clk1]​
set_property PACKAGE_PIN B15 [get_ports da_clk1]

软件设计

根据本章的实验任务,FPGA需要连续输出正弦波波形的数据,才能使3PD5651E连续输出正弦波波形的模拟电压,如果通过编写代码使用三角函数公式运算的方式输出正弦波数据,那么程序设计会变得非常复杂。在工程应用中一般将正弦波波形数据存储在RAM或者ROM中,由于本次实验并不需要数据到RAM中,因此我们将正弦波波形数据存储在只读ROM中,直接读取ROM中的数据发送DA转换芯片即可。

24.4.1根据本章实验任务画出的系统框图。ROM里面事先存储好了正弦波波形的数据,DA数据发送模块从ROM中读取数据,将数据时钟送到3PD5651E芯片的输入数据端口输入时钟端口。

双路高速DA实验的系统框图如24.4.1所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_08


24.4.1双路高速DA系统框图

顶层模块的原理图如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_09


24.4.2顶层模块原理图

FPGA顶层模块(hs_dual_da)例化以下三个模块:DA数据发送模块da_wave_send)、ROM波形存储模块(rom_1024x10b)和时钟模块(clk_wiz_0

DA数据发送模块da_wave_sendDA数据发送模块输出ROM地址,输入的ROM数据发送DA转换芯片的数据端口。

ROM波形存储模块(rom_1024x10b):ROM波形存储模块Vivado软件自带的Block Memory Generator IP实现,其存储的波形数据可以使用波形存储文件的上位机来生成.coe文件。

顶层模块的代码如下:

1 module hs_dual_da(​
2 input sys_clk_p , //系统差分输入时钟​
3 input sys_clk_n , //系统差分输入时钟​
4 input sys_rst_n , //系统复位,低电平有效​
5 //DA接口​
6 output da_clk , //DA采样时钟​
7 output [9:0] da_data , //DA采样数据​
8 output da_clk1 , //DA采样时钟​
9 output [9:0] da_data1 //DA采样数据 ​
10 );​
11 ​
12 //wire define ​
13 wire [9:0] rd_addr; //ROM地址?​
14 wire [9:0] rd_data; //ROM数据​
15 ​
16 //*****************************************************​
17 //** main code​
18 //*****************************************************​
19 ​
20 assign da_clk1 = da_clk;​
21 assign da_data1 = da_data;​
22 ​
23 //时钟模块​
24 clk_wiz_0 instance_name​
25 (​
26 // Clock out ports​
27 .clk_out1 (clk ), // output clk_out1​
28 // Clock in ports​
29 .clk_in1_p (sys_clk_p), // input clk_in1_p​
30 .clk_in1_n (sys_clk_n) // input clk_in1_n​
31 ); ​
32 ​
33 //DA发送模块​
34 da_wave_send u_da_wave_send(​
35 .clk (clk), ​
36 .rst_n (sys_rst_n),​
37 .rd_data (rd_data),​
38 .rd_addr (rd_addr),​
39 .da_clk (da_clk), ​
40 .da_data (da_data)​
41 );​
42 ​
43 //ROM模块 ​
44 rom_1024x10b u_rom_1024x10b(​
45 .addra (rd_addr),​
46 .clka (clk),​
47 .douta (rd_data)​
48 );​
49 ​
50 endmodule

在代码的第2431行例化时钟模块,倍频出125M时钟给DA芯片采样用。

DA数据发送模块输出的读ROM地址(rd_addr)连接ROM模块地址输入端,ROM模块输出的数据(rd_data)连接DA数据发送模块的数据输入端,而完成了从ROM中读取数据的功能。

在代码的第44至48行例化ROM模块,由Block Memory Generator IP核配置生成

我们在前面说过,ROM中存储的波形数据可以使用上位机波形COE软件生成在这里我们介绍一个简单易用波形COE工具的使用方法,该工具位于开发板所随附的资料“6_软件资料/1_软件/WaveToMem”目录下,双击“WaveToMem_V1.2.exe”运行软件。

接下来我们软件进行设置,如24.4.3所示,这里对软件界面做个简单的介绍。

位宽:波形数据的位宽。由于ATK_DUAL_HS_DA模块的DA芯片数据位宽为10位,因此这里将位宽设成10位。

深度:一个波形周期包含了多少个数据量。这里将深度设置成1024。需要说明的是,在用Block Memory Generator IP核生成ROM时,配置ROM的宽度和深度和上位机设置的位宽和深度保持一致。

波形频率设置:对波形倍频,倍数值越大,最终生成的波形频率越快(频率太高,可能导致波形失真),这里保持默认,即设置成1位。

波形类型:软件支持将正弦波、方波、锯齿波和三角波的波形转换成存储波形格式的文件。

生成文件:软件支持将波形转换成COE(Vivado软件支持的存储格式)和MIF(Quartus软件支持的存储格式)格式文件,这里保持默认,即选中COE文件格式。

然后点击“一键生成”按钮,在弹出的界面中选择COE文件的存放路径并输入文件名,这里将COE文件保存在工程的sources_1\new文件夹下。WaveToMem转换过程中的软件界面如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_数据_10


24.4.3软件界面

使用Notepad++代码编辑器打开生成COE文件后如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_数据_11


24.4.4文件打开界面

工程中创建了一个单端口ROM,并命名为“rom_1024x10b”,在调用Block Memory Generator IP核时,“Basic”选项也配置如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_12


24.4.5核的Basic配置页面

我们将其接口类型设置为“Native”、Memory Type设置为“Single Port ROM”,即单端口ROM

“Port A Options”选项页的配置页面如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_差分_13


24.4.6核的PortA Options配置页面

我们将PortA的位宽设置为10,深度设置为1024,以存储上位机生成的1024个数据。此外,将使能引脚的类型设置为“Always Enabled”,即ROM一直处于使能的状态。

接下来配置“Other Options”选项页,加载刚才生成的.coe文件,如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_差分_14


24.4.7核的Other Options配置页面

最后点击“OK”按钮完成IP核的配置。

DA数据发送模块的代码如下:

1 module da_wave_send(​
2 input clk , //时钟​
3 input rst_n , //复位信号,低电平有效​
4 ​
5 input [9:0] rd_data, //ROM读出的数据​
6 output reg [9:0] rd_addr, //读ROM地址​
7 //DA芯片接口​
8 output da_clk , //DA驱动时钟,最大支持125Mhz时钟​
9 output [9:0] da_data //输出给DA的数据 ​
10 );​
11 ​
12 //parameter​
13 //频率调节控制​
14 parameter FREQ_ADJ = 10'd5; //频率调节,FREQ_ADJ的越大,最终输出的频率越低,范围0~255​
15 ​
16 //reg define​
17 reg [9:0] freq_cnt ; //频率调节计数器​
18 ​
19 //*****************************************************​
20 //** main code​
21 //*****************************************************​
22 ​
23 //数据rd_data是在clk的上升沿更新的,所以DA芯片在clk的下降沿锁存数据是稳定的时刻​
24 //而DA实际上在da_clk的上升沿锁存数据,所以时钟取反,这样clk的下降沿相当于da_clk的上升沿​
25 assign da_clk = ~clk; ​
26 assign da_data = rd_data; //将读到的ROM数据赋值给DA数据端口​
27 ​
28 //频率调节计数器​
29 always @(posedge clk or negedge rst_n) begin​
30 if(rst_n == 1'b0)​
31 freq_cnt <= 10'd0;​
32 else if(freq_cnt == FREQ_ADJ) ​
33 freq_cnt <= 10'd0;​
34 else ​
35 freq_cnt <= freq_cnt + 10'd1;​
36 end​
37 ​
38 //读ROM地址​
39 always @(posedge clk or negedge rst_n) begin​
40 if(rst_n == 1'b0)​
41 rd_addr <= 10'd0;​
42 else begin​
43 if(freq_cnt == FREQ_ADJ) begin​
44 rd_addr <= rd_addr + 10'd1;​
45 end ​
46 end ​
47 end​
48 ​
49 endmodule

代码的第14行定义了一个参数FREQ_ADJ(频率调节),可以通过控制频率调节参数的大小控制最终输出正弦波的频率大小,频率调节参数的值越小正弦波频率越大。频率调节参数调节正弦波频率的方法是通过控制ROM的速度实现的,频率调节参数越小,freq_cnt计数频率调节参数值的时间越短,读ROM数据的速度越快,那么正弦波输出频率也就高;反过来频率调节参数越大,freq_cnt计数频率调节参数值的时间越长,读ROM数据的速度越,那么正弦波输出频率也就越低。由于freq_cnt计数器的位宽为10位,计数范围是0~1023,所以频率调节参数FREQ_ADJ支持的调节范围是0~1023,可通过修改freq_cnt计数器的位宽修改FREQ_ADJ支持的调节范围

WaveToMem软件设置ROM深度1024,倍频系数为1,而输入时钟为125Mhz,那么一个完整的正弦波周期长度为1024*8ns = 8192ns,FREQ_ADJ值为0时,即正弦波的最快输出频率为1s/8192ns(1s = 1000000000ns) ≈ 122.0Khz。当我们FREQ_ADJ值设置为5时一个完整的正弦波周期长度8192ns*(5+1) =49152ns,频率约20.35KHz。也可以在WaveToMem软件设置中增加倍频系数或者增加AD的驱动时钟来提高正弦波输出频率

下载验证

将双路高速DA模块插入DFZU2EG/4EV MPSoC开发板的J19扩展口连接时注意扩展口电源引脚方向和开发板电源引脚方向一致,然后将下载器一端连接电脑,另一端与开发板上对应端口连接,最后连接电源线后拨动开关按键给开发板上电。

DFZU2EG/4EV MPSoC开发板硬件连接实物图如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_差分_15


24.5.1 DFZU2EG/4EV MPSoC开发板硬件连接实物图

将工程生成的比特流文件下载到DFZU2EG/4EV MPSoC开发板中后,然后使用示波器测量DA输出通道的波形。首先将示波器带夹子的一端连接到开发板的GND位置使用杜邦线连接至开发板上的任一的GND管脚,然后另一端探针插入双路高速DA模块DA通道中间的金属圆圈内(注意将红色的保护套拿掉24.5.2所示

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_正弦波_16


24.5.2 DA模拟电压测量孔位

此时观察示波器可以看到正弦波的波形,如果观察不到波形,可查看示波器设置是否正确,可以尝试按下示波器的“AUTO”,再次观察示波器波形。示波器显示界面如下图所示:

《DFZU2EG_4EV MPSoc之FPGA开发指南》第二十四章  双路高速DA实验​_数据_17


24.5.3 示波器显示界面


举报

相关推荐

0 条评论