ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SAR Logic设计核心:逐次逼近状态机与比较器时序协同

SAR Logic设计核心:逐次逼近状态机与比较器时序协同 1. 项目概述SAR ADC里的那个“小脑子”做SAR ADC的人常开玩笑说模拟部分决定你能做到多好数字部分决定你最后能不能真的拿到那个好。这句话在SAR逻辑SAR Logic模块上体现得尤其明显。逐次逼近型ADC的“逐次逼近”四个字并不是模拟前端自己完成的而是靠SAR Logic这个数字状态机一点一点调度出来的。本文要说的就是SAR ADC中最容易“感觉会了但一推敲就露馅”的模块——SAR Logic原理。它负责采样开始、逐位比较、结果存储、CDAC开关切换、转换结束标志输出是整个SAR ADC的“指挥中心”。我会从它到底要干什么讲起再拆解状态机怎么设计、比较器怎么配合、CDAC开关序列怎么生成最后聊几个流片后才能真正体会到的坑。这篇文章适合正在做SAR ADC的在校研究生、刚接触混合信号设计的一线工程师也适合想弄明白“ADC里那个数字块”到底是什么的模拟设计者。我尽量少讲虚的多讲能落到代码和仿真里的东西。2. SAR逻辑到底在忙什么2.1 一句话理解SAR闭环SAR ADC的核心思想是“猜测-比较-修正”的闭环。假设一个N位ADC模拟输入电压Vin经过采样后保持在CDAC上SAR Logic从最高位MSB开始先假设这一位为1然后让CDAC产生相对应的比较电压Vdac比较器对比Vin和Vdac如果Vin更大说明这一位猜对了保留1如果Vin更小说明猜错了改成0。然后进入下一位重复同样的操作。整个过程中SAR Logic干的事情就是三件控制什么时候开始比较、根据比较结果改写CDAC的开关状态、告诉外界转换结果什么时候有效。它不直接参与模拟信号路径但它的每一个边沿、每一段延迟都会直接影响比较器的判决质量和CDAC的建立精度。我见过一些初学者把SAR Logic当成简单的计数器来写觉得“反正就是数N下嘛”。实际做下来会发现最核心的难点不在数数而在于你要精准地让数字状态和模拟行为在同一个时间轴上前进每一个节拍都要对得上。2.2 它和模拟前端的分工边界SAR ADC的模拟前端主要是采样开关、CDAC和比较器。SAR Logic则负责产生以下关键信号采样控制信号sample/clk_s比较器启动信号comp_en比较器输出锁存时钟latch_clkCDAC开关驱动位switch_ctrl[M:0]转换结束标志EOC/valid其中比较器启动信号和latch时钟最容易被人忽略。很多文章只画了“比较器输出比较结果”这个理想行为但真实的动态比较器有预充电阶段和判决阶段SAR Logic必须给出合适的时序窗口不能太早也不能太晚。举一个实际例子在自举开关采样结束后的第一个比较周期CDAC上极板的电压尚在微小扰动中。如果SAR Logic把比较器使能信号开得太早比较器会对没有建立好的电压做判决产生亚稳态甚至错误翻转。这种问题在后仿真里会暴露出很明显的非线性但在前仿真里因为理想开关的存在而完全看不到。2.3 一个常见的错误把SAR Logic当纯组合逻辑有同学会让比较器输出直接通过组合逻辑去控制CDAC开关觉得这样省一个周期速度快。这在行为级仿真里没有问题但落到的真实电路里会出现竞态比较器判决输出毛刺、CDAC开关同时导通、比较器回踢噪声耦合到参考电压上转换曲线会出现直接性错码。SAR Logic必须是“有节拍的时序逻辑”每一个位判决对应一个明确的时钟周期。组合逻辑可以承担译码功能但绝不能承担决策功能。换句话说SAR Logic的骨架是一个移位寄存器或状态机由统一的时钟驱动所有CDAC开关状态变化只允许出现在特定边沿之后。记住这一点设计至少能避开一半的常见问题。3. 逐次逼近状态机的工作模式与设计要点3.1 全串行状态机的状态图我习惯把N位SAR ADC的SAR Logic状态机划分为以下状态采样、保持、逐次逼近B[0]到B[N-1]、转换完成。这个“B[0]到B[N-1]”就是逐次逼近的N个比较周期。有几个示意图是一定要画在笔记本里的采样状态下采样开关导通CDAC跟踪输入信号保持状态下采样开关断开输入信号保持在CDAC上第一个比较周期开始前所有电容下极板都接到共模或参考电压的预设电位从MSB比较开始SAR Logic根据比较器判决结果决定该位最终值并设置下一轮CDAC开关组合循环直到LSB比较结束拉高EOC信号需要注意的一点是这里我使用的是“比较周期”而不是“系统时钟周期”。SAR ADC在高速实现中往往一个系统时钟周期完成一次比较可以把状态机的每个状态计数到1慢速高精度实现中一个比较周期可能需要几个系统时钟周期用来等待CDAC建立。实际工程中我更推荐做法是状态机按“比较周期”推进每个比较周期内部再用分频或延迟链来控制比较器预充电、判决、重置三个阶段。3.2 状态编码与实现结构选择SAR逻辑的实现结构大体有纯FSM、移位寄存器计数器、环形计数器等几种。下面结合取舍讲纯FSM状态清晰每个状态都有明确含义调试方便逻辑综合易于优化。缺点是状态多时写起来繁琐而且各个状态之间的转移路径容易被综合工具频繁优化导致时序难约束。移位寄存器计数器用一个串行移位寄存器产生触发脉冲每个脉冲对应一位比较开始。优点是结构规整、速度高、容易实现自定时。缺点是状态含义不够直观在引入冗余位或校准逻辑时不够灵活。我最常用的方式是“FSM主状态移位寄存器子状态”的组合主状态管采样、保持、转换、结束子状态管逐位逼近。这样代码写起来清晰关键路径也好控制对后续加Correlated Double SamplingCDS校准逻辑、后台校准逻辑都留了扩展空间。3.3 一个可综合的SAR Logic状态机示例下面给一个10位SAR ADC的SAR Logic核心示例采用FSM计数器方式。代码逻辑相对精简重点在控制流走向。module sar_logic #( parameter N 10 )( input wire clk, // 系统时钟 input wire rst_n, // 异步复位 input wire start, // 启动转换 input wire comp_out, // 比较器输出 output reg sample, // 采样开关控制 output reg comp_en, // 比较器使能 output reg [N-1:0] dac_ctrl, // CDAC下极板开关控制 output reg [N-1:0] result, // 转换结果 output reg valid // 转换完成标志 ); localparam IDLE 3d0; localparam SAMPLE 3d1; localparam HOLD 3d2; localparam CONV 3d3; localparam FINISH 3d4; reg [2:0] state, next_state; reg [3:0] bit_cnt; always (posedge clk or negedge rst_n) begin if (!rst_n) state IDLE; else state next_state; end always (*) begin next_state state; case (state) IDLE: if (start) next_state SAMPLE; SAMPLE: next_state HOLD; HOLD: next_state CONV; CONV: if (bit_cnt N) next_state FINISH; FINISH: next_state IDLE; default: next_state IDLE; endcase end always (posedge clk or negedge rst_n) begin if (!rst_n) begin sample 1b0; comp_en 1b0; dac_ctrl {N{1b0}}; result {N{1b0}}; bit_cnt 4d0; valid 1b0; end else begin case (state) IDLE: begin sample 1b0; valid 1b0; bit_cnt 4d0; end SAMPLE: begin sample 1b1; // 采样期间把所有电容下极板接到共模对应Vcm-based开关方案 dac_ctrl {N{1b0}}; end HOLD: begin sample 1b0; // 进入保持后可以立即启动第一次比较 // 但更稳妥的做法是在CONV状态下再开comp_en comp_en 1b1; end CONV: begin // 每个bit周期结束根据比较器输出更新当前位 if (bit_cnt N) begin result[bit_cnt] comp_out; // 这里需要根据比较器结果修改dac_ctrl // 实际工程中用译码逻辑此处给出示意 dac_ctrl[bit_cnt] comp_out; bit_cnt bit_cnt 1b1; end end FINISH: begin comp_en 1b0; valid 1b1; end endcase end end endmodule以上代码不是可以直接流片的完整版本只是一个控制流的骨架。真实的CDAC控制译码逻辑还要考虑电容权重、开关切换方式、冗余位预留等问题。但从这段代码能看出SAR Logic最基本的节拍感什么状态做什么事每个状态之间的迁移有明确条件。我用一个生活化的类比来解释这个过程SAR Logic就像你猜一个数字每次问“比512大还是小”对方回答大或小之后你再继续问“比768大还是小”一步步缩小范围。状态机的每一个循环就是一次提问CDAC就是帮你产生一个“用来对比的刻度”的杠杆。4. 比较器时序与CDAC控制逻辑的协同4.1 动态比较器的三段式控制SAR ADC中最常用的比较器是动态锁存比较器。它的工作过程可分成预充电、判决、复位三个阶段预充电阶段输出节点预充到电源电压判决阶段控制管导通输入差分管对输出节点放电放电快的一边对应输入更高的一侧逐渐产生锁存放大最终输出满摆幅数字电平复位阶段输出节点被拉回预充电平SAR Logic必须精确控制这三个阶段尤其不能省略复位阶段。如果你在某个位判决完后不经过复位就直接启动下一位的比较输出节点还残留着上一次的电荷分布会出现严重的记忆效应直接导致比较器真实失调与输入相关的偏移变化。在时序安排上我通常会在每个比较周期内分出三段t_reset复位、t_decision判决、t_settleCDAC建立等待。到底是先判决还是先开关CDAC需要看具体的电容开关拓扑。4.2 比较器输出如何反馈给CDAC开关SAR ADC的CDAC通常由一组二进制权重的电容阵列构成。每一位电容的下极板接三路开关接Vin采样时、接Vref比较时、接GND比较时。也可以采用接Vcm的方式。SAR Logic把比较器输出判决成“1”后就把对应位电容从GND切换到Vref或者反之。这个切换动作意味着CDAC的转移曲线会向参考电压的高端移动。开关切换必须发生在比较器输出被稳定存入寄存器之后同时要给CDAC留足建立时间否则充电不完全会导致下一位的比较参考电压不准。我建议对每个关键开关信号的传输延迟做一次表格化分析。下面是一个10位SAR ADC在20MHz比较时钟下单周期100ns的时序预算示例。阶段时间分配说明t_reset10ns比较器复位输出节点拉到预充电平t_decision20ns比较器使能判断输入差压方向t_logic_delay5nsSAR逻辑锁存比较结果并译码开关控制信号t_dac_settle60nsCDAC参考电压切换到稳定可开始下一位比较余量5ns工艺角和温度变化的缓冲这个预算只是一个参考示例实际项目中要根据工艺、电源电压、CDAC尺寸、开关导通电阻做完整仿真。4.3 自定时 vs 全局时钟定时高速SAR ADC的一个发展趋势是采用异步自定时架构。比较器一旦完成判决就通过“valid”信号触发SAR逻辑而不是等全局时钟的下一个沿。这可以避免为了等待最差情况而浪费大量时间。异步SAR的SAR Logic设计和同步版本有本质差别它需要处理完成信号沿的异步到达要防止亚稳态传播还要处理多个比较周期在不同时间完成导致的“碰撞”。我个人的建议是除非你确实需要跑在非常高的转换速度上否则同步设计的SAR Logic更容易收敛也更稳后仿的时序收敛成本低很多。如果你是第一次做SAR ADC先老老实实把同步设计的SAR Logic调通把静态时序分析STA约束写好再去碰异步自定时。5. RTL实现与混合仿真配合的关键细节5.1 可综合性写法与示例SAR Logic本质上是一个数字模块但它嵌入在混合信号环境里。RTL编码时有几个细节避免使用initial语句初始化状态统一用异步复位时钟尽量单一如必须使用多相时钟使用时钟控制单元隔离比较器输出跨时钟域时加两级同步器避免亚稳态直接进入状态机对valid等异步握手信号使用电平或脉冲协议要有明确处理下面这个片段展示了比较器输出同步化的常用处理// comp_out来自比较器或芯片引脚先打两拍再使用 reg comp_sync1, comp_sync2; always (posedge clk or negedge rst_n) begin if (!rst_n) begin comp_sync1 1b0; comp_sync2 1b0; end else begin comp_sync1 comp_out; comp_sync2 comp_sync1; end end wire comp_safe comp_sync2;这里的同步器会引入一到两个时钟周期的延迟。你需要把这个延迟计入SAR Logic的位周期总数中。比如10位转换状态机中的比较周期数目可能是12个而不是10个多出的周期就是给同步留余量。5.2 在各种工具里联合仿真的注意事项SAR Logic在纯数字仿真里当然能跑但你验证不了它和CDAC、比较器配合是否有建立性问题。所以完整的验证必须做混合信号仿真常见方案是Cadence AMS或Synopsys NanoTime环境下把数字RTL作为行为模型和晶体管级模拟电路协同仿真。我在做混合仿真时发现最大的瓶颈是速度。如果把整个SAR ADC都换成transistor级一次仿真如蜗牛爬。常用做法是CDAC用理想电容模型或行为级模型、比较器用Verilog-AMS行为级描述、采样开关用理想开关只保留SAR Logic真实RTL。这样仿真速度提升上百倍又能验证数字逻辑和模拟行为的交互。行为级比较器可以写成// Verilog-AMS行为级比较器示意 module comp_behavioral(inp, inn, clk, outp); input inp, inn, clk; output outp; real vin; reg outp; always (posedge clk) begin // 带随机失调和有限增益的模型 if (vin 0) outp 1; else outp 0; end assign vin inp - inn; // 实际行为模型需加建立时间和回踢噪声 endmodule行为级模型需要加多少非理想因素取决于你要验证什么。只想验逻辑功能加理想模型就行想验证比较器失调对DNL/INL的影响就需要在模型里加入失调电压的蒙特卡洛扰动项。5.3 仿真收敛与初始化问题的排查混合仿真中经常遇到“前仿真完全正常后仿真出现随机性错码”的问题。排查该类问题时我建议按下面几个方向逐一排查比较器输出在预充电阶段是否处于中间电平被同步器当成有效电平采样采样结束后CDAC上极板电压是否因为电荷注入发生跳变SAR Logic输出的CDAC开关控制信号是否与参考电压切换动作在同一时刻发生造成短暂直通比较器时钟到来时CDAC建立是否完成尤其在多次位循环后参考电压毛刺累积表格对比前仿和后仿的行为差异可以帮你快速定位问题现象可能原因排查优先级固定某一位错码该位CDAC建立时间严重不足高所有位随机错码比较器使能时序有误高温度升高后错码概率增大参考电压驱动能力不足导致建立变慢中电源纹波敏感SAR Logic开关噪声通过衬底耦合低6. 流片阶段最容易踩的SAR Logic坑6.1 状态机失锁后得不到有效数据流片测试中比功能不对更麻烦的问题是“偶发失锁”大部分时间工作正常偶尔会出现一整帧转换结果完全无效。这种问题在现场很难复现常规测试还看不到毛刺。我遇到过一次类似情况仔细分析后定位到是采样保持状态切换时SAR Logic的采样信号与比较器时钟产生了竞争导致首次比较建立在尚未稳定的采样值上。修法是在采样信号释放之后插入至少一个额外等待周期让CDAC完成电荷重分布再启动第一个比较周期。6.2 数字功耗与模拟性能耦合SAR逻辑翻转时产生的衬底噪声和电源扰动会通过CDAC耦合到比较器输入端表现为转换结果出现“周期性的重复码型”或“输入相关失调变化”。缓解办法不只是版图加保护环数字部分也要做功耗优化。SAR Logic虽然是纯数字但每个位周期的翻转数量是固定的因此它的动态功耗也可以大致预测。关键位翻转的时间点要尽量避开比较器判决窗口可以在逻辑设计时人为插入延迟。6.3 静态时序分析中的约束写法SAR Logic的输入来自比较器是异步信号输出到CDAC是模拟开关控制信号。标准数字工具默认它们全是纯数字翻转这就需要在SDC约束里明确处理对比较器输出设set_false_path或set_max_delay保证它不参与时钟路径收敛计算对CDAC控制输出设set_output_delay把CDAC建立时间要求转化为输出约束对复位信号做异步复位同步释放处理有一个容易被忽略的点SAR Logic在保持状态启动比较器时比较器时钟输出的相位抖动会影响整体信噪比。良好的STA约束不应只关心setup/hold还需要分析时钟jitter对采样瞬间的影响。高级流程里会做jitter-aware STA可以尝试用。6.4 冗余位和校准位的逻辑扩展现在很多SAR ADC为了提升良率会在传统二进制权重CDAC基础上加入冗余位。加入冗余位后SAR Logic的比较周期数也要相应增加而且每一位误差容忍范围不同。比如常规10位需要10个比较周期加了1位冗余后可能需要12个比较周期。比较周期数多了速度自然下降但错码率明显降低。如果你准备在SAR ADC里实现前台校准或后台校准SAR Logic要预留访问内部节点的端口和校准状态机挂载点。设计时把校准相关信号独立出来流片测试阶段会方便很多。7. 从实际调试中总结的实用建议最后分享几个我在流片测试和调试过程中总结下来的实用经验可能对正在看这篇文章的你有些帮助。第一个经验SAR Logic仿真验证中一定要覆盖随机输入下的全码测试。很多人只仿真正弦波输入计算ENOB达标就觉得没问题了。但SAR逻辑的状态切换错乱往往发生在输入刚好处于量化边界附近的特定模式下正弦波不一定能覆盖到所有码型边界。加一轮随机斜坡输入把所有码都扫一遍对比DNL和INL曲线才能暴露状态机跳转异常。第二个经验在小信号输入、接近满量程输入、直流输入三种情况下分别测试SAR逻辑的位循环时序。接近满量程输入时比较器每次都需要极大的CDAC摆动建立时间最紧张。直流输入时比较器的输入差分电压接近零判决时间最长容易触发异步自定时机制的超时问题。这两种边界都能通过设计才算是稳的。第三个经验真值表驱动的CDAC切换译码逻辑看起来好写但一旦修改位数或增加冗余位容易漏改某一位。我后来更倾向于写一个可参数化的开关序列生成函数用循环自动生成所有位控制信号。VHDL的generate和Verilog的parameter配合可以做到只改一个N就能得到新的逻辑。如果你在建自己的SAR ADC数字部分建议从同步FSM开始把采样、保持、比较、结束的真实时序画清楚再写RTL。异步自定时虽然快但调试难度完全不一样。先把同步版本流片成功再去挑战极限速度是性价比最高的路径。
返回列表