概述
ADC和DAC是FPGA与外部信号的接口,从数据接口类型的角度划分,有低速的串行接口和高速的并行接口。FPGA经常用来采集中高频信号,因此使用并行ADC和DAC居多。本文将介绍如何使用FPGA驱动并行ADC和并行DAC芯片。
并行接口包括两种数字编码方式:带符号数signed与无符号数unsigned。本文还将介绍使用不同编码方式的ADC与DAC时需要注意的问题。
接口协议
以ADI公司的32M、8位ADC芯片AD9280和125M、8位DAC芯片AD9708为例(这是淘宝上最容易买到的AD/DA模块)。
AD9280的时序图如下:
AD9708的时序图如下:
由时序图可知,AD9280在每个输入clock的上升沿对输入的模拟信号做一次采集,采集数据由数据总线data输出;AD9708也是在每个输入clock的上升沿读取数据总线DB0-DB7上的数据,将其转换为相应的电流IOUTA/IOUTB输出。
这两个芯片的管脚虽然很多,但大多数都是与硬件设计有关。其实几乎所有的并行ADC和并行DAC与FPGA之间的接口只有一条时钟线与一组数据总线,数据总线的位宽即为ADC/DAC的位数。每个时钟周期ADC都会完成一次采集(DAC完成一次输出),因此时钟频率也就是ADC和DAC的采样频率。
FPGA设计
并行ADC和DAC的接口时序驱动非常简单,只要利用Quartus或Vivado自带的时钟管理IP核生成预期采样频率的时钟信号,驱动时钟线,从数据总线上读出或写入数据即可。
比如下面的代码实现了将ADC采集到的数据再通过DAC输出:
`timescale 1ns / 1ps
//-----------------------------------------------
// 将ADC采集到的数据通过DAC输出
//-----------------------------------------------
module adda_test
(
input clk,
output daclk,
output [7:0] dadata, //DA data
output adclk,
input [7:0] addata //AD data
);
PLL PLL_inst
(
.clk_in1(clk), // IN
// Clock out ports
.clk_out1(adclk), // OUT 32Mhz
.clk_out2(daclk), // OUT 32Mhz
// Status and control signals
.reset(1'b0), // IN
.locked()
);
assign dadata = addata;
endmodule
上述代码中实例化了一个PLL IP核产生ADC和DAC所需频率的时钟,Quartus中该IP核叫做“PLL”,Vivado中该IP核叫做“Clocking Wizard”。
为了保证DAC输出与ADC采集到的信号相同,将两者时钟频率设置相同,且连接二者的数据总线。上述代码可以使用开发板和AD/DA模块进行实际测试。
编码方式问题
上文用到的AD9280和AD9708都是无符号数编码,而我们知道无论是Vivado还是Quartus中大多数的IP核采用的都是带符号数二进制补码的编码方式(这就导致ADC/DAC的数据总线不能与IP核接口直接对接,必须做一定的转换处理。
考虑到上述数字系统的特点,市场上也存在不少以带符号数二进制补码接口的ADC/DAC,比如65M、12位ADC芯片AD9226。如果使用这种编码方式的芯片,数据总线就可以直接与IP核接口对接,不需要做特殊处理。
但是,我们总会不可避免的遇到类似这样的情况:
1. ADC或DAC是无符号数编码,而设计中需要使用一些带符号数接口的IP核;
2. ADC是带符号数编码,而设计中仅需获取测量值,并不需要与其它带符号数接口的模块对接。
当遇到情况1时,需要进行无符号数编码与带符号数编码之间的转换。将ADC采集到的8位无符号数转换为带符号数补码形式的代码如下:
/**** 将addata转化为带符号二进制补码形式 ****/
reg [7:0] ad_data;
always @ (posedge clk or negedge rst_n)
if (!rst_n) ad_data <= 8'd0;
else ad_data <= addata - 128; //AD9280采集输入
将带符号数补码转换为8位无符号数通过DAC输出的代码如下:
/**** 将dadata转化为无符号数形式 ****/
reg [7:0] da_data;
always @ (posedge clk or negedge rst_n)
if (!rst_n) da_data <= 8'd0;
else da_data <= dadata + 128; //AD9708输出
当遇到情况2时,需要将不易直接观察的带符号数补码形式转换为带符号数原码形式,使其更加直观。代码如下:
always @(posedge ad_clk) //AD9226采集
if(ad_ch1[11]==1'b1) begin //如果是负电压
ch1_reg<=12'hfff - ad_ch1 + 1'b1;
ch1_sig <= 45; //'-' asic码
end
else begin
ch1_reg<=ad_ch1;
ch1_sig<=43; //'-' asic码
end
转换的依据是一个简单的运算关系:“补码的整数值”+“原码绝对值的整数值”=2^B,B为位宽。比如带符号数原码1110的补码为1010:1110取绝对值0110为6;1010为10,二者加起来为2^4=16。
上述代码便是利用了这个运算关系。为了节省位宽,先用12’hfff减掉补码,再加1,达到同样的效果,得到带符号数原码的绝对值。根据符号位便可以知道这个原码的正负情况。
原文链接:https://blog.csdn.net/FPGADesigner/article/details/80672231
审核编辑:刘清
-
FPGA
+关注
关注
1614文章
21445浏览量
596947 -
adc
+关注
关注
97文章
6115浏览量
541130 -
二进制
+关注
关注
2文章
730浏览量
41372 -
dac
+关注
关注
43文章
2181浏览量
190068 -
CLK
+关注
关注
0文章
124浏览量
16986 -
DAC芯片
+关注
关注
1文章
30浏览量
14448 -
ADC芯片
+关注
关注
3文章
72浏览量
20138
原文标题:FPGA学习-并行ADC与DAC
文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
基于FPGA的ARM并行总线设计与仿真分析
![基于<b class='flag-5'>FPGA</b>的ARM<b class='flag-5'>并行</b>总线设计与仿真分析](https://file1.elecfans.com//web2/M00/A6/65/wKgZomUMPWiALg-9AABKWFID0bI302.jpg)
请问如何使用fx3芯片来对FPGA进行并行配置?
小试身手——FPGA驱动DAC7621
fpga基础篇(二):三大并行结构
请问是否有并行ADC或并行DAC接口卡让我能够使用FX2 FMC连接器连接到FPGA板?
FPGA电源设计在并行工程中的应用
![<b class='flag-5'>FPGA</b>电源设计在<b class='flag-5'>并行</b>工程中的应用](https://file.elecfans.com/web2/M00/4A/02/pYYBAGKhvIiAXVvAAABR3z51eqw526.png)
评论