ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

深入解析SAR ADC中SAR Logic的设计:算法、时序与排障

深入解析SAR ADC中SAR Logic的设计:算法、时序与排障 做SAR ADC这些年我越来越觉得SAR Logic是整个设计里最容易被低估的模块。不少人一上来就盯着比较器失调、电容阵列分段这些“硬骨头”到了写SAR Logic的时候反而草草了事认为无非就是个状态机能出码就行。但实际流片回来你会发现很多转不出来的片子、或者高频时掉ENOB的片子问题往往就出在这个“不起眼”的数字逻辑上。SAR ADC的采样开关由它控制DAC的每一位电容由它拨动比较器什么时候比较、结果往哪儿存全都由它统一调度。这篇文章我就结合自己从仿真到流片的实际经验把SAR Logic从算法、RTL实现到时序预算、排障思路完整讲一遍适合正在做SAR ADC的模拟/混合信号工程师也适合想搞懂SAR ADC内部逻辑的数字IC设计同学。1. SAR ADC整体架构SAR Logic到底在指挥什么1.1 先理清SAR ADC的核心工作原理SAR ADC的中文全称是逐次逼近型模数转换器它的工作方式可以用一个猜数游戏来理解。假设有一个人在0到1V之间藏了一个电压值让你猜它到底是多少你的策略是先猜0.5V对方说“低了”那目标肯定在0.5V到1V之间你再猜0.75V对方说“高了”那目标就在0.5V到0.75V之间。每次把当前区间折半10次之后你就能把范围缩小到大约1/1024的精度这就是逐次逼近的思想。放在SAR ADC里那个“猜数的人”就是SAR Logic而“猜的数”就是DAC的输出电压。一个N位SAR ADC完成一次完整转换需要一个采样周期再加上N个比较周期总共N1个周期。这个过程里比较器每次只干一件事判断输入信号比DAC输出高还是低然后SAR Logic根据结果决定下一次猜哪个值。硬件上典型的结构就是采样保持电路、比较器、电容DAC阵列和SAR Logic四个部分但很多人没意识到真正的“决策中心”是SAR Logic比较器只是提供一个1bit判决结果。1.2 SAR Logic不是“存储寄存器”而是全系统的控制中枢我经常跟团队里的人强调SAR Logic的设计难度不在于逻辑复杂度而在于它要同时跟几个不同时间常数的模拟模块打交道。采样开关要在信号还没被破坏前精确断开DAC切换之后节点电压要经历RC建立过程才能稳定比较器从使能到输出有效结果需要一段锁存时间。SAR Logic要做的就是把这些物理时间需求翻译成精确的数字控制脉冲序列。具体来说SAR Logic至少要管理四类信号第一是采样使能信号决定采样开关的导通与断开第二是DAC控制码决定每个电容接到参考电压还是接地第三是比较器使能信号决定在DAC建立得差不多的时候再去触发比较避免拿一个还没稳定的电压做判断第四是结果锁存信号确保比较结果无误地写入结果寄存器。如果这些信号的时序配合出现问题哪怕比较器本身性能极佳整个ADC照样会输出错误码。2. 从算法到硬件SAR Logic的核心模块拆解2.1 二分搜索算法如何映射成逐位比较流程逐次逼近的算法本质是二进制搜索但这个搜索过程需要在硬件上实现为严格的逐位收敛流程。以10位SAR ADC为例转换开始时SAR Logic会把DAC控制码的最高位置1其余位置0也就是先把DAC输出设定到1/2Vref然后使能比较器得到第一次比较结果。这个结果就是最高位的输出码如果输入高于1/2Vref最高位保留为1下一次在1/2Vref到Vref之间搜索如果输入低于1/2Vref最高位清0下一次在0到1/2Vref之间搜索。第二位类似在前一轮确定的新区间里取中点再比较。我用6位SAR的前几步给个直观的例子初始猜测100000对应1/2Vref假如比较结果是“输入更高”MSB保留1第二轮把次高位置1变成110000对应3/4Vref再比较如果此时结果是“输入更低”次高位清0第三轮把第三位置1形成101000对应5/8Vref如此反复。每一步都锁定一位已经确定的高位码在接下来的比较中保持不动正在处理的位先置1试探比较完成后决定去留。这就是整个SAR Logic最核心的行为逻辑。2.2 经典实现移位寄存器加结果寄存器的分工与局限传统的SAR Logic实现方式非常巧妙它用一个N位移位寄存器来标记“当前正在处理哪一位”初始值只有最高位是1其余位全是0。每个比较周期结束后这个移位寄存器右移一位1跑到下一位上同时把当前位的比较结果锁存到DAC控制寄存器里。等到移位寄存器里的1从最高位移到最低位一次转换也就结束了。这种实现方式的优势很明显控制思路简洁、每个周期只做一个动作几乎没有译码组合逻辑对同步时序非常友好适合中低速SAR ADC。但它有个很致命的局限——不够灵活。一旦你需要引入冗余电容做误差修正或者采用非二进制权重DAC来优化速度和功耗这套“固定权重、固定顺序”的移位寄存器结构就得推倒重写。这也是为什么现在越来越多的设计选择用FSM加计数器来实现SAR Logic我自己的主力方案也是FSM。2.3 FSM实现思路状态拆分让每个时序脉冲都清晰可控我习惯把SAR Logic的FSM至少拆成四个基本状态IDLE等待状态、SAMPLE采样状态、CONV逐位比较状态和DONE输出状态。SAMPLE状态下采样开关导通输入信号被采样到电容阵列上同时悄悄把DAC最高位预置为1。真正复杂的在CONV状态我会在CONV内部再用一个计数器把每个比特周期切成两个阶段前半个阶段产生DAC切换信号允许电容阵列重新分配电荷并等待建立后半个阶段拉高比较器使能等待锁存比较结果接着更新最终DAC码。这个拆法看起来比移位寄存器多了一点判断逻辑但好处非常直接每个阶段的时间都是可以用参数调整的DAC建立时间不够了我可以把建立阶段拉长比较器速度慢了我可以把比较阶段拉长这在仿真阶段和第一次流片回来debug时会救你命。尤其是跨工艺角时TT角能跑通、SS角跑不通的情况太常见了如果SAR Logic是写死的移位寄存器你连个调整的余地都没有。3. 时序分析与关键工程取舍3.1 一个比特周期的预算建立时间和比较时间必须分清楚SAR Logic所有控制时序的起点是一个比特周期时间到底怎么分配。每个bit cycle由两部分组成DAC建立时间加上比较器比较时间。DAC建立时间的估算公式是t_settle约等于(N1)乘以ln2再乘以时间常数τ。这个公式的推导基础是DAC建立误差需要收敛到小于0.5 LSB而误差按指数衰减所以收敛时间跟位数N成正比。假设一个10位SAR ADC单位电容取10fF整个DAC阵列等效电容到几百fF量级开关导通电阻按1kΩ估算τ大约在0.5到1ns之间最终DAC建立时间大概在4到8ns。比较器比较时间则取决于比较器本身的结构和过驱动电压。要注意的是越接近转换结束时DAC输出与输入之间的差值越小比较器处于亚稳态的概率越大比较时间反而可能越长。所以SAR Logic里比较阶段的预算不能按理想情况取最小值要留出足够余量。否则你会看到仿真里前几位都好好的最后两三位总有偶发跳码这就是比较器没有足够时间完成锁存导致的。3.2 同步还是异步性能和可控性的取舍同步SAR逻辑是相对传统的实现方式所有动作都由一个外部主时钟统一驱动每个bit cycle占用固定数量的时钟周期。它的优点是时序完全可预测、验证简单、行为和仿真结果高度一致尤其在低速高精度应用里非常稳定。但缺点也很明显整个转换过程必须按照最坏角度的比较时间安排周期长度哪怕大多数时候比较器早就出结果了时钟也不会等你白白损失速度。异步SAR逻辑则是现在中高速SAR ADC的主流选择。核心变化是增加了比较器valid信号作为内部事件触发比较器一旦完成锁存就输出一个valid脉冲SAR Logic收到valid后才开始切换下一位DACDAC建立之后再自动触发下一次比较。这样每个bit cycle的时间按需分配比较快的case不用等慢的case。代价是时序复杂性大幅提升valid信号如果出现毛刺或者比较器空翻会直接带崩状态机。我的一般建议是采样率在几MSPS以内优先用同步结构低了风险小超过10MSPS再认真考虑异步方案。3.3 冗余设计在算法层面给SAR Logic容错能力传统二进制权重SAR里逐次逼近的每一次比较都是“一锤定音”一旦某一位被判错后面无论怎么逼近都修正不回来。比较器噪声、DAC建立不足、参考电压毛刺等非理想因素在这个体系下是没有回旋余地的。冗余SAR的思路简单说就是让DAC权重不再是严格的二进制递减而是每步重叠一部分这样就算某一步判断错了后续若干步仍有机会把误差拉回到正确区间。对SAR Logic而言冗余带来的变化是控制逻辑不能再按“当前位结果为1就加该位的权重”这种简单规则累加而是需要维护一组新的非二进制权重表。实现上可以把权重表做成查找表每次比较结束后对这个查找表进行重组更新。冗余位的代价是多花几个比较周期比如10位精度的ADC可能需要做12到13次比较面积和功耗也要相应增加但对于高速高精度场景这个代价非常值得。4. RTL实操一个10位SAR ADC的SAR Logic实现与验证4.1 一个可参考的SAR Logic核心框架直接给一段简化但结构完整的Verilog框架这个代码的风格偏教学向真实产品中还需要围绕它增加毛刺滤波、时钟门控和更细致的状态时序控制。module sar_logic #( parameter N 10 )( input wire clk, input wire rst_n, input wire start, input wire cmp_out, output reg sample_en, output reg cmp_en, output reg [N-1:0] dac_ctrl, output reg [N-1:0] result, output reg conv_done ); localparam IDLE 2d0; localparam SAMPLE 2d1; localparam CONV 2d2; localparam DONE 2d3; reg [1:0] state; reg [3:0] bit_cnt; reg cmp_phase; always (posedge clk or negedge rst_n) begin if (!rst_n) begin state IDLE; sample_en 1b0; cmp_en 1b0; dac_ctrl {N{1b0}}; result {N{1b0}}; conv_done 1b0; bit_cnt 4d0; cmp_phase 1b0; end else begin case (state) IDLE: begin conv_done 1b0; if (start) begin dac_ctrl {{1b1}, {(N-1){1b0}}}; bit_cnt N - 1; state SAMPLE; end end SAMPLE: begin sample_en 1b1; cmp_en 1b0; state CONV; end CONV: begin sample_en 1b0; if (!cmp_phase) begin cmp_en 1b1; cmp_phase 1b1; end else begin cmp_en 1b0; dac_ctrl[bit_cnt] cmp_out; if (bit_cnt 0) begin state DONE; conv_done 1b1; end else begin bit_cnt bit_cnt - 1; dac_ctrl[bit_cnt - 1] 1b1; end cmp_phase 1b0; end end DONE: begin result dac_ctrl; if (!start) state IDLE; end default: state IDLE; endcase end end endmodule这段代码的核心逻辑就两个动作一是每个bit周期先把下一位置1试探DAC输出二是根据比较器输出决定当前位最终是0还是1。但我要强调这个版本为了展示流程把DAC建立时间和比较时间简化成了一个时钟周期内完成实际项目里需要在CONV状态内部再加一个计数器把cmp_en拉高的时机延迟到DAC建立充分之后比较结果的采样时机也要放在比较器真正锁存完以后。4.2 仿真验证方法不光要看输出码还要看时序波形SAR Logic的验证比一般数字模块要复杂因为它的输入比较器结果其实是模拟模块输出的逻辑电平。最常规的做法是验证环境里放一个行为级的理想DAC模型和理想比较器模型用Verilog或者Verilog-A搭都行然后给SAR Logic提供模拟输入量化的链路。TB里把一个斜坡或者正弦信号作为比较器的判断依据每次SAR Logic给出dac_ctrl后行为模型计算DAC实际输出电压再和输入信号比较得到cmp_out反馈给SAR Logic形成闭环。验证时我最常看三个指标首先是输出码的单调性斜坡输入下输出码应该只升不降出现反向跳变说明SAR Logic有bug其次是静态DNL和INL需要统计大量点的码分布最后是动态的频谱指标ENOB、SFDR做法是给正弦信号采样后做FFT分析。不过做FFT的前提是数据要足够多建议至少采集4096个连续转换点。4.3 时序优化以后怎么判断SAR Logic做到了该做的事单纯让SAR Logic能跑通、能出码只能用“功能正确”来形容离“工程可用”还有距离。我在项目里会额外检查几个点。第一是cmp_en信号的有效脉宽是否覆盖了比较器最坏锁存时间这个在波形上直接看比较器输出是否稳定跟随输入差分方向。第二是每个bit cycle内从DAC切换沿到cmp_en上升沿之间的间隔是否留足了DAC建立时间你可以人为把比较时刻提前观察转换结果是否恶化来反推余量。第三是sample_en断开沿的位置稳定性如果采样开关断开瞬间噪声明显输出码会出现随机偏差。我记得第一次做10位SAR ADC项目时功能仿真在理想模型下完美通过但加了DAC寄生电容模型后高位转换结果明显异常。后来查波形发现是dac_ctrl最高位从0跳到1的瞬间DAC建立不够而SAR Logic在同一个时钟周期内就触发了比较器。根本原因是我的状态机把DAC切换和比较触发放到了同一个阶段省了时序余量后来把建立阶段单独拉出来之后问题立刻消失。这段经历让我养成了一个习惯写SAR Logic的时候永远先画时序图把每个阶段的起止沿画清楚再动手写RTL。5. 常见问题与排障实录5.1 高频故障场景速查表流片回来遇到问题第一件事是定位是数字还是模拟的问题。下面这张表是我自己debug时用得最多的排查清单几乎覆盖了SAR ADC最常见的那几类故障故障现象可能原因排查方向输出码单调性差斜坡输入出现负跳变DAC建立时间不足、比较器失调过大检查DAC切换与比较触发之间的时间间隔加长settle时间最后一次转换结果偶尔跳动比较器锁存时间不足、末位过驱动电压太小拉长cmp_en脉宽检查比较器是否处于亚稳态区域采样后信号电压异常采样开关导通时间不够或断开瞬间馈通严重检查sample_en时序确认断开沿是否对齐时钟高温度、慢角下错误率升高时序余量不足建立时间按快角设计把settle_cnt和cmp_cnt改为可配置寄存器留足工艺角余量异步SAR频繁误触发valid信号毛刺、比较器空翻增加毛刺滤波使用双valid握手加同步器输出码出现系统性偏大/偏小DAC基准电压建立不足、控制码切换毛刺观察dac_ctrl切换瞬间参考电压跌落情况加大去耦5.2 多次实战中积累的避坑经验第一个坑是参考电压的毛刺问题。以前我做一块板级测试SAR ADC输出码的水平分布总是有一段异常拱起排查了很久才发现是dac_ctrl切换的时候瞬间从参考电压抽取的电流在参考引脚上产生了尖峰而SAR Logic在尖峰尚未回落的窗口里启动了比较。解决起来其实单纯靠数字逻辑不方便彻底解决但SAR Logic可以配合做一件事把DAC切换动作拆成多个小步骤避免多位电容同时翻转这样参考电压的瞬态电流冲击会小很多。第二个坑是采样开关断开时刻的回踢。高精度SAR ADC的采样开关断开瞬间沟道电荷注入会影响到电容阵列采样值这个电压跳变如果正好出现在SAR Logic启动第一次比较之前就会变成固定偏移。我后来在SAR Logic里做一个小优化采样阶段结束时先给比较器一个复位信号让它在这段时间进入已知状态再在稳定后启动第一次比较能明显改善这个问题。第三个坑是异步SAR里比较器valid被毛刺误触发。比较器输出在亚稳态时可能来回翻转产生窄脉冲这些脉冲如果直接被SAR Logic当作valid事件状态机会直接跳飞。我的做法是给valid信号加一个简单的数字去毛刺电路小于设定宽度的脉冲直接滤除。代价是增加几ns的延迟但稳定性大幅提升。类似的逻辑在所有跨时钟域信号上都建议统一处理不要在时序冒险上赌运气。第四个坑是校准逻辑和SAR Logic的交互。很多SAR ADC会做前台校准在每次上电或者温度变化后由校准状态机接管DAC阵列测量各权重电容的实际值。这个切换过程最容易出现的问题是校准状态机退出后SAR Logic的初始状态没有被正确复位导致第一次正常转换采样的是乱码。解决办法是把SAR Logic的状态与校准完成信号做握手保证校准完成后SAR Logic必须回到IDLE状态再开始工作而不是停留在某个中间状态。再分享一个个人经验拿到一个新的SAR ADC架构时我建议先别急着写RTL花半天时间把状态机和每个信号的时序图画清楚特别是采样、DAC切换、比较器使能、结果锁存这四个事件在时间轴上的相对位置画完再写代码效率会高很多。这个习惯帮我少走了很多弯路也让我在复查别人设计的SAR Logic时能很快找到问题所在。SAR Logic做到最后拼的不只是逻辑设计能力更是对模拟电路时间特性的理解深度。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进