随记
最近由于工程原因用到 ADC 的采样,选用了 ADI 公司的 AD9212 芯片,八通道 10 位 ADC。在进行 ADC 的采样时,看到的想到的几种方法,在这里做个笔记记录一下。
AD9212简介
详细说明可以在ADI 官网上进行搜索查看,具体的一些性能细节这里就不进行详细的介绍了。
ADC 芯片在某一时刻采集到电压数据后会在一个时钟周期内将数据串行的输出,若使用 FPGA 对数据进行接收,所需要做的操作就只是一个串并转换,还是比较简单的对吧。在这里由于 AD9212 的数据传输是使用的 LVDS 输出,也可以使用 Altera 官方(对,我们用的是 A 家的芯片)的 LVDS_RX 的 IP 核进行接收。下面我们把 AD9212 的一个时序图放上来作为镇文之图。
从图中可以看出 DCO 作为数据传出的时钟是上下边沿触发的,在每个边沿数据 D 有效。FCO 作为帧定界的信号且与数据 D 同步,一个时钟周期内 10 位的有效数据 D,且高位在前。主要信息就这些了,信号 FCO、DCO、D 接入FPGA。
方法1 利用官方 LVDS_RX 的 IP 核
简单的说下思路,由于程序均为并行,以下步骤也已并列形式给出。
- 将 D 和 FCO 信号引入 LVDS_RX 中,两位两位的读取,读取时钟为 DCO。
- 使用一个 11 位的 Buffer 寄存器,在每个上升沿的同时不断的将 LVDS_RX 读取到的数据以移位的形式添加到最后。(注意这里是使用了 11 位 Buffer,比数据长度多 1,其用途可参考下方运行辅助理解)
- 在每个 DCO 的上升沿对 LVDS_RX 接收到的 FCO 进行打一拍处理
- 在每个 DCO 的上升沿对当前时刻接收到的 2 位 FCO 数据和前一个上升沿的数据(上述中打一拍)进行比较判定,若前一时刻为 00,当前为 11,则 11 位 Buffer 的[9:0]位接收到的数据;若前一时刻为 01,则 11 位中 Buffer 的[10:1]为采集数据;其余条件 Buffer 保持。
这里最后一个处理中之所以有两种情况是因为 LVDS_RX 在读的过程中无法确保其开始位置,故这里将两种方法都进行考虑后进行综合。下图描述了 LVDS_RX 在读取时的两种可能的状态。
- 状态1
- 状态2
方法2 根据时序自行处理
同样简单的说一下思路,该方法对于 10-bits ADC 需要使用到一个 12-bits 的 Buffer 用于数据的缓存。
- DCO 上升沿进行采样,数据依次存入 Buffer[11,9,7,5,3,1]中。
- DCO 下降沿进行采样,数据依次存于 Buffer[10,8,6,4,2,0]中。
- 类似于上述方法对 FCO 一样双边沿采样存于一个 Reg[3:0]中。
- 在 Reg[3:0] == 0011 时,标志位置1。
- 在 DCO 的上升沿在标志位置于 1 的时候将 Buffer 中的[11:2]提取出来成为 ADC 采集到的数据。
- 根据需要添加 FIFO 进行数据同步。
这一部分后续再时序上可能不如方法1,后期可以通过时序约束进行优化,后续学习后再来添加补充。
补充1:注意在 buffer[11:2] 中数据提取时要注意是在DCO的哪个边沿进行提取的,一定要充分注意,并进行良好的时序约束!
希望对阅读的你有着帮助,欢迎探讨。如果有什么觉得不对的,一定不要客气的留言回复大力拍砖~