三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

从JSSC经典论文到动手仿真:我是如何用Verilog-A复现一个15位SAR ADC的

从JSSC经典论文到动手仿真:我是如何用Verilog-A复现一个15位SAR ADC的

从JSSC经典论文到动手仿真:我是如何用Verilog-A复现一个15位SAR ADC的

第一次读到JSSC那篇经典论文时,我被其中精妙的自校准技术深深吸引。作为模拟电路设计的新手,我决定用Verilog-A在Cadence Virtuoso中完整复现这个15位SAR ADC。这不仅是对理论知识的验证,更是一次难得的实战机会。本文将分享从论文理解到仿真验证的全过程,特别适合那些已经掌握基础电路知识、渴望通过动手实践深化理解的工程师。

1. 理解SAR ADC的核心架构

SAR ADC的核心在于其逐次逼近的工作机制。与Flash ADC不同,它通过二进制搜索的方式逐步逼近输入电压值,在精度和功耗之间取得了优雅的平衡。论文中的15位设计采用了电容阵列作为DAC,这也是现代高精度SAR ADC的常见选择。

1.1 电容阵列DAC的工作原理

电容阵列DAC是SAR ADC中最关键的部分之一。在15位设计中,电容阵列通常采用分段结构来平衡面积和匹配精度。以下是一个简化的4位电容阵列示例:

// Verilog-A代码示例:4位电容阵列模型 module cap_array (vin, d, vout); input vin; input [3:0] d; output vout; electrical vin, vout; parameter real C = 1e-12; // 单位电容值 parameter real Vref = 1.0; // 参考电压 real cap_values[0:3] = {8*C, 4*C, 2*C, C}; // 二进制权重电容 real total_cap = 16*C; real vx; analog begin vx = (d[3]*8*C*Vref + d[2]*4*C*Vref + d[1]*2*C*Vref + d[0]*C*Vref)/total_cap; V(vout) <+ vx; end endmodule

这个模型展示了电容阵列如何将数字码转换为模拟电压。在实际15位设计中,电容值会按2^14:2^13:...:1的比例配置,但直接实现会导致面积过大,因此论文采用了更智能的分段方案。

1.2 比较器的关键作用

比较器是SAR ADC的另一核心组件,其噪声和失调电压直接影响ADC的精度。在Verilog-A建模时,我们需要特别关注:

  • 输入参考噪声:通常控制在几百μV以内
  • 失调电压:可通过自动校零技术补偿
  • 响应时间:必须小于SAR逻辑的决策周期
// Verilog-A比较器模型关键参数 module comparator (vip, vin, vout); input vip, vin; output vout; electrical vip, vin, vout; parameter real vth = 0; // 阈值电压 parameter real tdelay = 1n; // 传输延迟 parameter real voh = 1.0; // 高电平输出 parameter real vol = 0.0; // 低电平输出 analog begin @(cross(V(vip,vin)-vth, 0)) begin if (V(vip,vin) > vth) V(vout) <+ transition(voh, 0, tdelay); else V(vout) <+ transition(vol, 0, tdelay); end end endmodule

2. 自校准技术的实现细节

论文最精彩的部分莫过于其自校准技术。在15位精度下,电容失配会成为限制因素,而片上自校准完美解决了这一问题。

2.1 校准流程分解

自校准过程可分为三个阶段:

  1. 误差检测阶段:

    • 依次测量每个电容的实际值
    • 与理想值比较得到误差系数
    • 将误差系数存储在片上RAM中
  2. 正常转换阶段:

    • 使用存储的误差系数修正转换结果
    • 动态调整电容权重
  3. 背景校准模式:

    • 在正常转换间隙执行校准
    • 实现实时误差跟踪

2.2 Verilog-A实现校准逻辑

// 校准逻辑核心部分 module calibration_logic (clk, start_cal, cap_select, err_data); input clk, start_cal; input [3:0] cap_select; // 电容选择信号 output [11:0] err_data; // 误差数据 integer state; real cap_ideal[0:15]; // 理想电容值 real cap_actual[0:15]; // 实际电容值 real err_coeff[0:15]; // 误差系数 // 状态机实现 always @(posedge clk) begin case(state) 0: if (start_cal) state <= 1; // 等待校准开始 1: begin measure_cap(cap_select); // 测量选定电容 state <= 2; end 2: begin calculate_err(cap_select); // 计算误差 if (cap_select == 15) state <= 3; else state <= 1; end 3: state <= 0; // 校准完成 endcase end // 误差计算函数 function calculate_err; input [3:0] sel; begin err_coeff[sel] = (cap_actual[sel] - cap_ideal[sel]) / cap_ideal[sel]; err_data = err_coeff[sel] * 4095; // 12位量化 end endfunction endmodule

3. 完整SAR ADC的集成与仿真

将所有模块集成后,我构建了完整的15位SAR ADC Verilog-A模型。仿真过程揭示了几个关键点:

3.1 时序控制的重要性

SAR ADC对时序极为敏感。我设计了严格的时钟方案:

时钟相位持续时间功能描述
φ15ns采样相位
φ210ns保持相位
φ315ns逐次逼近
φ45ns数据输出

3.2 仿真结果分析

通过瞬态仿真,我观察到了几个典型现象:

  1. 电容充电效应:

    • 采样阶段出现的微小电压跌落
    • 通过增加采样开关尺寸改善
  2. 比较器迟滞:

    • 在输入电压接近阈值时的振荡
    • 添加正反馈解决了这一问题
  3. DNL/INL测量:

    • 未校准时INL达到5LSB
    • 校准后降至0.3LSB以内
// 测量INL的Verilog-A代码片段 real ideal_step = Vref/(1<<15); real actual_step; real inl[0:32767]; for (i=0; i<32768; i=i+1) begin actual_step = output_code[i+1] - output_code[i]; inl[i] = (actual_step - ideal_step)/ideal_step; end

4. 实际工程中的优化技巧

经过多次迭代,我总结出几个实用技巧:

4.1 电容阵列布局优化

  • 单位电容选择:

    • 使用MOM电容而非MIM电容
    • 单位电容值选择100fF,平衡噪声和面积
  • 共质心布局:

    // 伪代码描述共质心布局 void place_caps() { cap[0] = position(1,1); cap[1] = position(3,3); cap[2] = position(1,3); cap[3] = position(3,1); // 以此类推... }

4.2 降低电源噪声的影响

  • 电源去耦:

    • 每100μm放置一个去耦电容
    • 使用不同尺寸的电容组合(100fF, 1pF, 10pF)
  • 差分设计:

    • 全差分信号路径
    • 共模反馈稳定共模电压

4.3 校准算法的改进

论文中的校准算法可以进一步优化:

  1. 插值校准:

    • 仅校准关键位
    • 中间位通过插值计算
  2. 背景校准:

    • 利用空闲周期持续校准
    • 动态更新误差系数
// 改进的校准算法伪代码 while(1) { if (idle_cycle) { calibrate_next_cap(); update_coeff(); } else { normal_conversion(); } }

在完成这个项目后,我深刻体会到理论知识与实践的结合有多么重要。最初几次仿真结果与预期相差甚远,通过仔细检查每个模块的参数设置和互连关系,最终才得到了理想的性能指标。特别是校准模块的实现,让我对高精度ADC的设计有了全新的认识。

← 返回列表