这一篇在干嘛?

很多同学以为 FPGA 只会处理”0 和 1”,但 EG4S20 的芯片里其实内置了一个 ADC(Analog-to-Digital Converter,模数转换器),可以把外部连续变化的电压变成 FPGA 能算的数字。这一篇我们就把它拆开看:它长什么样、能测多大电压、怎么控制它采样、结果从哪里读出来,以及官方手册里反复强调的那些”坑”。

先弄懂三个名词:ADC、SAR、GPIO

手册开头给了三个缩写,先把它们说人话:

  • ADC(Analog-to-Digital Converter,模数转换器):把”连续的电压值”翻译成”数字”的器件。比如 1.23V 对应某个数,2.5V 对应另一个数。
  • SAR(Successive Approximation Register,逐次逼近):ADC 内部常用的一种工作方式,像”猜数字”一样一位一位逼近真实电压。
  • GPIO(General Purpose Input Output,通用输入/输出):芯片上最普通的引脚,既能输入也能输出。

记住 ADC 和 SAR 这两个词就够了,后面提到”SAR 型 ADC”你就知道它是用逐次逼近的方式做转换。

片上 ADC 长什么样:8 通道 + 引脚复用

EG4S20 这类 EAGLE 系列芯片内嵌了 1 个 8 通道的 SAR 型 ADC 模块。它的结构可以看下面这张模块图:

EG4S 内部 ADC 模块结构框图

这里有两个关键点,零基础同学一定要理解:

  1. 通道和普通 IO 是”复用”的。这 8 个 ADC 通道的输入引脚,平时就是普通 GPIO。你不用 ADC 的时候,它们就是普通 IO;用了 ADC,对应引脚才切换成模拟输入。每个通道的复用设置互相独立,比如只用通道 0,剩下 7 个引脚照样可以当普通 IO 用。
  2. 用 ADC 时对供电有要求:相关 BANK 的 VCCIO 电压不能低于 ADC 的模拟电源电压。这一点在硬件设计阶段就要注意,后面讲注意事项时还会再提。

性能参数一张表:它到底能测多大电压

下面这张表是手册给出的 ADC 性能汇总,是全篇最核心的数据,建议对照记忆:

参数性能
工作电压3.3V 模拟电源(VDDA)和 3.3V 数字电源(VDDD)
最高采样速率1MHz
通道数8
采样范围0.1×VREF ~ 0.9×VREF
动态性能>50dB SFDR,>45dB SINAD
线性度性能INL<1 LSB,DNL<1 LSB(8bit 精度)
最高时钟频率16MHz
ADC 参考电压 VREF0.5~1.0×VDDA
输出数字位宽12bit
有效精度8bit

几个容易困惑的地方,帮你翻译一下:

  • “输出 12bit,但有效精度只有 8bit”:芯片吐出来的结果是 12 位数字,但真正可信、能保证线性度的是高 8 位。别指望 12 位每一位都精确。
  • “采样范围 0.1×VREF ~ 0.9×VREF”:能正常测量的电压不是从 0 到满量程,而是参考电压 VREF 的 10% 到 90% 这个区间。低于或高于这个区间的信号,读数就不可靠了。
  • “最高时钟 16MHz、最高采样 1MHz”:给 ADC 的时钟不能超过 16MHz,采样动作最快每秒 100 万次,超过就会出错。

VREF 是 ADC 的"尺子",必须又准又干净

手册专门强调:ADC 的精度和参考电压关系非常紧密。板上要给 ADC 提供非常准确、干净的 VREF,精度要控制在 VDDA ±0.2% 以内。尺子不准,量出来的数全都不准——这是硬件问题,写再多代码也救不回来。

VREF 尽量设成 1.0×VDDA

VREF 的可接受范围是 0.5×VDDA ~ 1.0×VDDA,而输入信号范围是由 VREF 决定的。VREF 越高,能测的电压区间越大,所以建议直接把 VREF 设成 1.0×VDDA(即 3.3V),把量程”用满”。

数字接口:6 个端口看懂 ADC 怎么”对话”

FPGA 里不能像操作电脑软件一样”点按钮”,一切靠信号握手。ADC 模块对外就 6 个端口,一一记住它们:

内部端口名方向位宽/bit说明
clkinput1ADC 工作时钟,fmax=16MHz
pdinput1低功耗掉电模式控制
sinput3通道选择信号(3 位正好选 8 个通道)
socinput1采样使能(Start of Conversion),高有效
eocoutput1转换完成标志(End of Conversion),高有效
doutoutput12对应通道的转换结果

工作流程用一句话概括:你用 s 选好通道,给 soc 一个高电平”下令采样”,ADC 转换完成后拉高 eoc 通知你,此时去 dout 上读 12 位结果即可。

pd(power down)平时接 0,让 ADC 正常工作;它还有一个特殊用法,在注意事项里会讲到。

IP 例化:把 ADC 加进你的工程

在 TD 软件里,通过 IP generate 的方法就能把这个 ADC 模块生成到自己的工程里,不需要手写它的内部逻辑。模块的 Verilog 接口长这样:

module EG_PHY_ADC(clk, pd, s, soc, eoc, dout);
input clk;          // 时钟
input pd;           // 掉电控制,1'b0 正常工作
input [2:0] s;      // 通道选择
input soc;          // 开始转换
output eoc;         // 转换结束
output [11:0] dout; // 12bit 转换结果
parameter CHO = "DISABLE";
parameter CH1 = "DISABLE";
// ...CH2 ~ CH7 同理
parameter VREF = "DISABLE";
endmodule

除了端口,模块还有一组 参数(parameter),用来告诉工具”你要用哪些资源”:

参数可选值默认值说明
VREF”DISABLE” / “ENABLE""DISABLE”参考电压使能
CH0 ~ CH7”DISABLE” / “ENABLE""DISABLE”通道 0 ~ 7 使能

也就是说,例化时把你要用的通道参数改成 "ENABLE",其他保持 "DISABLE" 就行。比如只用通道 0 和通道 1,就只把 CH0、CH1 打开。在 TD 里操作的样子可以参考下图:

在 TD 软件中通过 IP generate 配置并使用 ADC 模块

采样控制时序:soc 和 eoc 的”一问一答”

最后看怎么驱动它采样。ADC 的采样控制时序如下:

EAGLE ADC 采样控制时序波形图

读时序图的思路很简单,就是一场”问答”:

  1. 先把通道号放到 3 位 s 信号上;
  2. 拉高 soc(高有效),相当于喊一声”开始采样”;
  3. ADC 内部做逐次逼近转换,期间你别动 s
  4. 转换完成后 eoc 输出高电平,说一声”做完了”;
  5. 此时 dout 上的 12 位数据就是结果,读走即可。

写状态机时把 soc/eoc 当作标准握手

实际工程里通常用一个小的状态机:IDLE → 置 s、拉 soc → 等 eoc → 锁存 dout → 回 IDLE。这个”发令—等待—取结果”的模式和很多外设通用,学会一次处处能用。

注意事项:三个最容易翻车的地方

手册虽然短,注意事项却值得单独背下来:

1. 采样间隔别拉太大。 建议 SOC 的采样间隔小于 10us,也就是采样频率不要低于 100kHz。这不是”越快越好”的建议,而是这个 ADC 的工作特性决定的。

2. 真要大间隔采样,先”叫醒”ADC。 如果你确实需要很长间隔才采一次样,必须在 SOC 到来 5 个时钟周期之前,先把 pd 脚拉高一下,然后再进行采样。忘了这一步,采出来的数据可能就是错的。

大间隔采样忘记拉 PD 是最隐蔽的坑

低频采样时程序”看起来能跑”,数据却莫名不对,八成就是漏了”SOC 前 5 个时钟周期拉高 PD”这一步。把这个动作直接写进你的采样状态机里,别靠手动时序。

3. 电源和布局要给 ADC 让路。 除了前面说的 VREF 要准、要干净,使用 ADC 时还要尽量避免使用与 ADC IO 相同 BANK 的数字 IO,以减小数字开关噪声对模拟采样行的干扰;相关 BANK 的 VCCIO 电压也不能低于 ADC 模拟电源电压。

一句话总结硬件侧要点

VREF = 1.0×VDDA、VREF 精度 ±0.2%、ADC 所在 BANK 少放数字 IO、VCCIO ≥ 模拟电源——这四条写进你的硬件检查清单。

回顾:这一篇你学到了什么

  • EG4S20 内置 1 个 8 通道 SAR 型 ADC,通道引脚与普通 IO 复用,不用时可以照常当 GPIO。
  • 性能上:3.3V 供电、最高 16MHz 时钟、最高 1MHz 采样率、输出 12bit 但有效精度 8bit、量程为 0.1×VREF ~ 0.9×VREF。
  • 接口上:s 选通道、soc 启动、eoc 通知完成、dout 给出 12 位结果;例化时通过 CH0~CH7 和 VREF 参数使能所需资源。
  • 避坑上:采样间隔小于 10us;大间隔采样要在 SOC 前 5 个时钟周期拉高 PD;VREF 要准(±0.2%)、要设成 1.0×VDDA;ADC 所在 BANK 尽量别跑数字 IO。