一、实验目的
本实验基于Intel Alter CycloneⅣ EP4CE6F17C8N开发板与Verilog HDL语言设计简易数据采集系统。该系统需要实现DDS正常产生波形,通过DAC与ADC转换后的波形数据一致。为实现该目的,需进行的操作细则如下:
1.查阅资料,理解并掌握dds运行原理。
2.阅读ADC和DAC芯片手册理解芯片工作原理及时序要求。
3.进行模块化程序设计,独立进行各个模块的代码设计和仿真调试,完成各个模块设计之后,再进行模块互联,最后测试模块互联后的顶层程序功能是否与预期设计一致。
4.板级测试,将通过仿真调试的程序烧录到开发板上,用Singal Tap联合调试,抓取输入与输回的波形数据,观察二者是否一致。
二、实验原理
本次实验原理将分为理论原理、硬件原理两部分进行阐述。
2.1 理论原理
2.1.1 DDS基本原理
DDS(Direct Digital Synthesis)是一种用于产生可控制频率的数字信号的技术,由于其易于控制,相位连续,输出频率稳定度高,分辨率高, 频率转换速度快等优点,被广泛应用于任意波形发生器。基于DDS技术的任意波形发生器用高速存储器作为查找表,通过高速D/A转换器来合成出存储在存储器内的波形。所以它不仅能产生正弦、余弦、方波、三角波和锯齿波等常见波形,而且还可以利用各种编辑手段,产生传统函数发生器所不能产生的真正意义上的任意波形。DDS的实现原理图如下:

首先ROM中要存放好要显示的信号数据。然后由频率计数器一直累加,根据这个累加器的值作为ROM的地址,然后DAC根据ROM输出的数据输出相应的电压值,即波形。DDS可以通过改变频率控制字和相位控制字,控制ROM的初始地址和ROM地址改变的时间间隔,间接控制输出波形的形状。
2.1.2 SPI协议原理
SPI(Serial Peripheral Interface)是一种串行外设接口,是一种同步、高速、全双工通信总线,用于在数字系统之间进行通信。SPI只需要四根端口线即可,能节约引脚,同时有利于PCB的布局。正是出于这种简单易用的特性,现在越来越多的芯片集成了SPI通信协议,如FLASH、SD卡等,本次设计中所使用到的ADC和DAC芯片也都集成了SPI通信协议。一般有四根端口线,分别是:SCLK(同步时钟线)、MOSI(主设备输出/从设备输入线)、MISO(主设备输入/从设备输出线)、CS_N(片选信号)。SPI主从机通信原理图如下:

SPI通信的基本原理是,主设备通过在时钟信号的边沿(上升沿或下降沿)上发送数据到MOSI线,同时从设备在另一个时钟边沿上将响应数据发送到MISO线。通信开始时,主设备选择一个或多个从设备,拉低相应的SS线。通信结束后,主设备释放CS_N线。
SPI支持四种通信模式,其通信模式的设置由 CPOL(时钟极性)和CPHA(时钟相位)来决定的 。四种通信模式如下:

CPOL决定时钟的空闲电平,CPOL=0时,SCLK空闲为低电平;CPOL=1时,SCLK空闲为高电平。CPHA决定采样的时钟边沿(奇数沿/偶数沿);CPHA=0,采样的时钟边沿为奇数沿;CPHA=1,采样的时钟边沿为偶数沿。
2.2 硬件原理
2.2.1 DAC基本原理
DAC转换基本原理是:将输入的数字量按权的大小,通过电阻网络转化为模拟量,再通过加法电路,转换为与数字量成比例的模拟量。实际上就是二进制转换为十进制的过程。
DAC基本组成包括,锁存器、电子开关、基准源、权电阻网络和求和电路。 各个组件的功能如下表所示:
|-------|----------------------------------|
| 锁存器 | 保存输入的数字量 |
| 电子开关 | 被数字量控制开关,用来决定是否将某一路数字量转换为有效模拟量输出 |
| 基准源 | 给模拟量提供参考电压 |
| 权电阻网络 | 提供每一路数字量的比例 |
| 求和电路 | 将每路数字量转化的模拟量按权相加 |
DAC数模转换电路,基准源和权电阻网络是关键。基准源越大,可输出的模拟量的范围当然也就会越大。
2.2.2 ADC基本原理
ADC就是起到把连续的信号用离散的数字表达出来的功能,其在模拟信号转化为数字信号需要经过采样、保持、量化和编码的过程。常见的ADC有:积分型,逐次逼近型,并行/串行比较型等。ADC的基本组成机构包括,采样器、模数转换器、数字信号处理器。其各个组件的功能如下表所示:
|---------|-------------------------------|
| 采样器 | 从模拟信号源中提取一定数量的样本值 |
| 模数转换器 | 将采样器输出的模拟信号转换为数字信号 |
| 数字信号处理器 | 对ADC输出的数字序列进行进一步处理,如滤波、放大、校正等 |
三、系统设计
3.1 系统整体框架设计
本次项目设计采用模块化的设计思路,将整个工程拆分成五个模块,分别为:按键消抖模块、波形选择模块、dds模块、dac驱动模块、adc驱动模块,依次对五个模块逐一进行设计和仿真调试,最后组成整个简易数据采集系统。系统整体框架设计如图3.1所示。

图3.1 系统整体框架设计
3.2 模块说明
3.2.1 按键消抖模块
按键消抖有两种方法:硬件消抖和软件消抖。在需要更快的响应时间和更可靠的消抖效果时,可使用硬件消抖,在精度要求不高时可使用软件消抖。但由于硬件难以改变的原因,软件消抖被广泛运用于各个项目之中,本次项目设计采用的也是软件消抖。
软件消抖有多种算法,本次设计采用的是简单延时算法。延时算法有两种实现方式,第一种为计数器实现即每次检测到按键信号下降沿便计数 20ms;第二种为状态机实现。本项目采用简单计数器的方法实现按键消抖。
3.2.1.1 模块框图
按键消抖模块将输入的按键信号消抖,并输出一个按键按下有效信号。按键消抖模块的整体框图如下图3.2.1所示。

图3.2.1 按键消抖模块
过滤掉抖动时间需要用计数器来实现,所以模块中需要时钟和复位信号,此外还需要输入的按键信号以及消抖后按键有效的标志信号, 按键消抖模块端口信号列表如表 3-2 所示。
|-----------------|-------------|
| 端口信号名 | 描述 |
| clk | 时钟信号 |
| rst_n | 系统复位信号 |
| key_in[3:0] | 按键按下信号 |
| key_flag[3:0] | 经消抖后的按键有效信号 |
表3.2.2 按键消抖模块端口信号
3.2.2 波形选择模块
本设计中使用按键实现各种波形之间的切换。具体原理为,通过按键来选择使用哪一个寄存波形数据的ROM。在设计中,我预先将提前生成好的波形数据分别存入不同的ROM,当检测到按键输入时,根据不同的按键输入,激活相应的ROM,用于后续波形数据的读取。
3.2.2.1 模块框图
波形选择模块,将一个按键输入对应一个波形,当识别到相应的按键输入时,输出对应的波形给DDS模块。波形选择模块的整体框图如下图3.2.3所示。

图 3.2.3 波形选择模块
其中,输⼊端⼝clk为时钟信号,rst_n为复位信号,key_flag是按键输入信号,wave_select是波形信号。 端口信号,如下表3.2.4所示。
|--------------------|--------|
| 端口信号名 | 描述 |
| clk | 时钟信号 |
| rst_n | 系统复位信号 |
| key_flag[3:0] | 按键输入信号 |
| wave_select[3:0] | 波形信号 |
表 3.2.4 波形选择模块端口信号
3.2.3 DDS模块
DDS是一种电子模块,它可以通过数字方法直接合成周期波形信号,如:正弦波、方波、锯齿波等。因此DDS模块只需要有对应的波形信号数据,就可以生成对应的周期波形信号并输出给DAC芯片。由此,根据DDS原理开始设计DDS模块。
3.2.3.1 模块框图
根据DDS原理,DDS模块需要输入对应的波形数据,以及频率控制字、相位偏置和相位累加控制使能,输出波形信号和波形有效信号。DDS模块框图如下图3.2.5所示。

图 3.2.5 DDS模块
3.2.3.2 端口信号
根据DDS模块框图,DDS模块需要输入对应的波形数据,以及频率控制字、相位偏置和相位累加控制使能,输出波形信号和波形有效信号。DDS模块的端口信号,如下表3.2.6所示。
|--------------------|---------|
| 端口信号名 | 描述 |
| clk | 时钟信号 |
| rst_n | 系统复位信号 |
| dds_en | dds启动使能 |
| wave_select[3:0] | 波形选择信号 |
| phase_word[31:0] | 频率控制字 |
| freq_word[7:0] | 相位控制字 |
| wave_out[7:0] | 波形信号 |
| wave_out_vld | 波形有效信号 |
表 3.2.6 DDS模块端口信号
3.2.3.3 时序图设计
DDS模块通过检测dds_en信号,当dds_en信号输⼊时,计数器开启条件add_cnt打开,计数器cnt加⼀,rom的地址是采⽤cnt计数器的⼤⼩来改变,在本次代码设计时我们使⽤的是32位计数器,rom采⽤的是cnt计数器的高8位。当输出数据改变时,输出有效信号拉⾼提示DAC模块此时传输的数据才是有效的。具体的模块时序图如下:

3.2.4 DAC驱动模块
查阅DAC芯片手册,可知本次设计所使用到的DAC芯片是一块三线8位DAC,需要输入SCLK、CS_N、data,其最高工作频率为10Mhz,支持三种协议进行数据传输。本次设计采用SPI协议的模式0设计DAC的接口,并通过DAC传输时序去DAC芯片进行数模转换。
3.2.4.1 模块框图
将波形信号输入给DAC驱动模块,通过SPI协议将波形信号数据传输给DAC芯片进行数模转换。DAC驱动模块的模块框图如下图3.2.7所示。

图 3.2.7 DAC驱动模块
3.2.4.2 端口信号
DAC驱动模块,要通过SPI协议结合DAC传输时序传输波形数据,所以该模块需要SPI的三个端口信号和波形数据输入及数据传输标志。DAC驱动模块的端口信号如下表3.2.8所示。
|------------|---------------|
| 端口信号名 | 描述 |
| clk | 时钟信号 |
| rst_n | 系统复位信号 |
| din[7:0] | 波形数据输入 |
| din_vld | 输入波形有效信号 |
| busy | 数据传输忙标志 |
| sclk | DAC同步工作时钟 |
| cs_n | 片选信号 |
| dout | 输出给DAC的波形数据信号 |
图 3.2.8 DAC驱动模块端口信号
3.2.4.3 状态机设计
DAC驱动模块的状态机分为四个状态,分别是空闲状态、准备状态、数据传输状态、数据传输结束状态。在空闲状态下,SPI接收到数据有效时,进入准备状态,准备状态再跳转到数据传输状态;在数据传输状态,DAC驱动模块先将原8bit数据按照DAC传输时序拼接成16bit数据,再由高位到低位依次发送数据,直到16bit数据发送完成,即完成一次数据传输,状态机跳转到DONE(数据传输结束状态),最后跳回空闲状态,等待下一次数据传输。DAC驱动模块的状态跳转流程图如图3.2.9所示。

图 3.2.9 DAC驱动模块状态机设计
3.2.4.4 时序图设计
DAC驱动模块通过检测cs_n来检测数据传输是否开始,当cs_n拉低时,din_vld拉高,DAC开启数据传输,状态机从IDLE->READY->TRANS,根据DAC手册,本次设计给予的sclk频率位5Mhz,故需要对系统时钟10分频得到设计的sclk;同时根据DAC手册,在数据传输时,需先将输入的8bit数据拼接成16bit,以满足DAC传输时序要求,同时发送一个busy信号给dds模块,标志数据正在传输,停止数据发送,直到busy拉低。在数据传输完成后状态机跳转到DONE状态,在跳转到IDLE状态,等待下一次数据传输。具体的模块时序图如下:

3.2.5 ADC驱动模块
查阅ADC芯片手册,可知本次设计所使用到的ADC芯片是一块串行8位DAC,需要输入SCLK、CH0(输入数据信号)、CNVST,其串行传输最高工作频率为5Mhz,支持三种协议进行数据传输。本次设计采用SPI协议的模式0设计ADC的接口,并通过ADC传输时序去ADC芯片进行数模转换。
3.2.5.1 模块框图
根据ADC芯片手册,观察ADC传输时序和关键参数,设计ADC驱动模块。ADC驱动模块框图如下图3.2.10所示。

图 3.2.10 ADC驱动模块
3.2.5.2 端口信号
根据ADC芯片手册,去除电源信号端口,设计ADC驱动模块端口信号。ADC驱动模块端口信号如下表3.2.11所示。
|-------|-------------|
| 端口信号名 | 描述 |
| clk | 时钟信号 |
| rst_n | 系统复位信号 |
| sclk | ADC工作时钟信号 |
| cnvst | ADC数模转换标志信号 |
| din | ADC输出波形信号 |
表 3.2.11 ADC驱动模块端口信号
3.2.5.3 状态机设计
ADC驱动模块的状态机分为五个状态,分别是空闲状态、开始状态、A/D转换状态、传输数据状态、传输完成状态。在空闲状态下,状态机自动跳转到开始状态等待开始传输条件满足,即100ns的延时后,跳转到A/D转换状态,等待7.5uA/D转换完成后,跳转到传输数据状态,8bit波形数据传输完成后,跳转到传输完成状态(done),最后自动跳转到空闲状态等待下一次数据传输。ADC驱动模块的状态跳转流程图如图3.2.12所示。

图 3.2.12 ADC驱动模块状态机设计
3.2.5.4 时序图设计
ADC模块通过检测cnvst来判断当前状态及数据转换是否开始,当cnvst拉高100ns后,状态机跳转到转换状态,延时7.5us等待数据转换完成之后,进入数据传输状态,开始传输8bit数据;在数据传输完成后状态机跳转到DONE状态,在跳转到IDLE状态,等待下一次数据传输。具体的模块时序图如下:

3.3 仿真调试
3.3.1 按键消抖
输入一个按键信号,对齐打拍后开始延时计数,如果计完20ms则输出一个对应的按键有效信号, 反之输出0,仿真波形如图3.3.1所示:

图3.3.1 按键消抖仿真图
3.3.2 波形信号选择模块
输入一个按键有效信号,波形选择模块输出一个对应的波形参数,用于后续波形的调用。波形选择模块的仿真波形图如下图3.3.2所示。

图3.3.2 波形信号选择仿真图
3.3.3 DDS模块
如下图3.3.3所示,当dds_en信号拉高后,rom地址计数器开始计数,并输出对应地址存储的数据;当rom地址计满后,rom翻转,开始从高到低计数,以保证输出的波形数据正常。同时在本设计中,可以通过按键改变输入的波形数据,当按下不同的按键时,dds会输出对应不同的波形数据;观察下图可见,该功能与设计预期相符。



图3.3.3 DDS模块仿真
3.3.4 DAC模块仿真调试
如下图3.3.4所示,DAC驱动模块状态机跳转正常;当进入数据传输状态时,DAC驱动模块通过SPI接口传输的数据与预期设计的数据一致,由此可见DAC驱动模块的功能设计正常。


图3.3.4 DAC驱动模块仿真
3.3.5 ADC模块仿真调试
如下图3.3.5所示,ADC模块的状态机跳转正常,各个状态所设计的跳转条件都与预期相符;当给予ADC模块一个模拟仿真输入时,ADC模块正常执行数据传输采样时序,并且所得到采样数据与模拟输入的数据一致。在本次仿真调试中,给予的模拟输入数据全为0或1,这样便于程序的设计及后续调试的波形观察。



图3.3.5 ADC驱动模块仿真
3.4 板级验证与调试
3.4.1 RTL视图
本设计中,先通过按键选择输入DAC模块的波形数据,再通过DDS模块产生对应的波形并输出给DAC驱动模块,DAC驱动模块再通过SPI接口将数据传输给DAC芯片;待DAC处理完后,将数据再输回给ADC芯片,ADC芯片对其进行模数转换重新将模拟信号转换成数字信号;最后将输入与输回的数据比较,一致则说明该设计成功。本设计的RTL视图如下图3.4.1所示。

图3.4.1 RTL视图
3.4.2 上板验证
运行代码,通过singal tap抓取输入与输回的波形数据,如下图3.4.2所示。




图3.4.2 dac2adc波形数据
四、实验总结
本项目实现了一个基于FPGA的简易数据采集系统,并可以通过按键控制输出不同的波形。本项目采用模块化设计思路,将项目分为5个模块,包括:按键消抖模块、波形选择模块、dds模块、dac驱动模块和adc驱动模块。
在各个模块的逐一设计的过程中,也产生了一些问题。诸如,未注意ROM位宽,导致频率控制字位宽设置错误,致使ROM未按预期时间跳转、传输数据错误;DAC的SPI接口,采用模式0传输时,如何避免第一个数据采错;SPI接口反馈的busy信号与dds_en信号之间如何交互传输。在认真思考过后,这些问题也逐一得到了解决。
但还是有一些问题,没有得到妥善解决。如,传输数据位宽不够,导致采样数据精度不高,波形不够平滑,可以清晰看到突起,但这是有DAC和ADC的硬件特性所决定的我们无法改变;在按键切换波形时,波形会出现一瞬间的不正常;在采样锯齿波形时,可以清晰看到采样波形与输入波形不一致,如上图3.4.2,猜想是采样逻辑设计可能有问题,但暂未找出。正如项目名,这只是一个简易的数据采集系统,后续的项目优化方向就是逐一解决这些问题,以实现更好的数据采集。