ARTICLE DETAIL

资讯详情

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

模拟IC验证必知:相干采样与FFT频谱分析实战指南

模拟IC验证必知:相干采样与FFT频谱分析实战指南 刚接触模拟IC验证的同学多半会在FFT这一步栽跟头。明明电路仿真波形看着挺好正弦波干净得跟画出来似的结果把波形丢进FFT里一按出来的频谱像毛刺堆基波旁边一坨泄漏谐波找半天找不到THD算出来从第一位就开始飘。这不是你的电路有问题而是仿真和FFT之间的联系没有接上。这个联系就叫相干采样Coherent Sampling。这篇文章会把整条链路讲透从相干采样公式怎么算到Virtuoso里瞬态仿真参数怎么配再到Calculator里FFT的每个按钮怎么填最后教你把THD从频谱图上一点一点抠出来。适合做ADC、DAC、运放、滤波器、PLL的模拟设计或验证工程师也适合刚入门、想在Virtuoso里把仿真做扎实的同学。1. 先把整条链路理清楚FFT分析的全局设计思路1.1 为什么说FFT是模拟电路的“照妖镜”时域上一个经过放大的正弦波看起来可能完美无缺但非线性失真、交调产物、电源噪声、时钟馈通全都藏在时域波形的“毫厘之差”里。FFT把时域信号搬到频域之后这些微小误差会以谐波和杂散谱线的形式暴露出来THD总谐波失真、SNR、SINAD、SFDR、ENOB这些关键指标本质上都是频域统计量。举个例子一个输出摆幅2Vpp的运放如果三次谐波比基波低60dB时域波形肉眼完全看不出任何异常但在FFT频谱上1kHz基波旁边3kHz处会立着一根-60dB的谱线。这就是FFT的价值——把电路“看不见”的瑕疵量化成可读的数字。所以搞模拟验证FFT不只是“会按按钮”而是必须理解参数背后的原理。1.2 相干采样FFT之前绕不过的那道坎很多人FFT做完之后频谱一片糊涂最常见的原因就是没有做相干采样。FFT本质上假设你分析的这段信号是周期信号的一个完整周期延拓。如果观测窗口内的信号不是整数个周期截断处就会出现跳变频谱上表现为基波能量向旁边泄漏形成一大片裙边把附近的谐波和噪声基底全部淹没。相干采样的核心思想就是让观测窗口内恰好包含整数个被测信号周期。用生活类比来说切蛋糕时如果刚好把整个蛋糕切成整数份每一块都干干净净如果切偏了最后一块一定带着碎屑。频谱泄漏就是这些“碎屑”。1.3 整体流程从仿真参数到THD指标要走的四步完整的流程可以拆成四步每一步都会影响最终结果。第一步根据目标频率、采样频率和FFT点数算出一组合适的M和N确定输入频率、仿真窗口长度和频率分辨率。第二步在Virtuoso里把瞬态仿真参数配置好重点是仿真时长和最大步长必要时设置等间隔采样输出。第三步跑完仿真后在Calculator或Visualizer里做FFT选对点数、窗口类型和起始时间。第四步从频谱上读取基波和各次谐波幅度代入THD公式算出最终指标。这篇文章后面所有内容都是围绕这四步展开的。先用公式把参数算明白后面每一步都能省很多返工时间。2. 相干采样原理与参数计算不搞懂公式后面全是坑2.1 三个整数搞定一切M、N和采样频率相干采样要求输入频率fin、采样频率fs和FFT点数N满足下面这个关系fin / fs M / N其中M是观测窗口内被测信号的完整周期数必须为正整数。为了减小谐波与基波的重叠风险M通常取奇数或质数。N是FFT点数也等于你在观测窗口内的采样点总数。由这个公式可以推出一组关键参数观测窗口总时长 T N / fs也等于 M / fin。频率分辨率 Δf fs / N fin / M。仿真步长必须满足 Ts 1 / fs也就是每个采样点对应一个时钟周期。这组参数有一个隐含的美妙性质当fin/fs精确等于M/N时你不需要任何窗函数频谱上就不会有泄漏。因为DFT的周期性延拓和信号的真实周期完全对齐了。这也是为什么在Virtuoso里做THD分析推荐优先走相干采样这条路而不是靠加窗去补救。2.2 实操案例算一组能直接用的仿真参数我直接给一组可以照抄的参数你改成自己的频率就行。假设系统采样频率fs 10 MHz希望输入信号频率在1 MHz附近。FFT点数取N 1024那么M需要满足fin (M / 1024) × 10 MHz为了让fin尽可能接近1 MHz同时保证M是质数我取M 127。于是fin (127 / 1024) × 10 1.240234375 MHz观测窗口总时长 T 1024 / 10 MHz 102.4 us。频率分辨率 Δf 10 MHz / 1024 9.765625 kHz。也就是说每根谱线之间的间隔是9.765625kHz基波会精确落在第127根谱线上。谐波位置也可以提前算出来。第k次谐波的频率是k × fin超过奈奎斯特频率fs/2 5 MHz后会发生混叠折叠。比如5次谐波在6.201 MHz折叠后落在3.7988 MHz7次谐波在8.6816 MHz折叠后落在1.3184 MHz。这些折叠后的位置在后面读THD时特别容易踩坑。2.3 非相干采样到底会带来什么后果为了让你有直观感受我描述一下非相干采样的典型症状。假设你把fin设成1.2 MHz而不是精确的1.240234375 MHz同样的N1024、fs10MHz。FFT结果里基波谱线旁边会出现一堆旁瓣能量从基波bin泄漏到相邻十几个bin噪声基底从-100dB抬高到-80dB甚至更高。原本-55dB的三次谐波可能直接被泄漏尾巴盖住读数偏差可能超过10dB。这种情况下加一个汉宁窗能压制旁瓣但代价是主瓣变宽频率分辨率下降而且不同频率分量的幅度会按照窗函数的增益曲线被非均匀缩放。你要测THD这种本身就需要精确幅度的指标加窗后反而很难做准。所以我的建议很直接能在仿真里做相干采样就别指望窗户救场。3. Virtuoso环境下的仿真配置让仿真器精确配合采样计划3.1 瞬态仿真参数时长、最大步长和精度控制参数算好之后回到Virtuoso的ADE窗口配置tran分析。我在IC617和IC618上试过这部分的设置逻辑基本一致。打开Analysis → tran需要关注四个地方Stop Time必须大于观测窗口结束时间。如果从0时刻开始起振还要加上电路的建立时间。比如电路需要50us才能稳定那么Stop Time至少是50us 102.4us 152.4us。稳妥起见我一般留20%余量设到180us。Accuracy Defaults直接选conservative保守模式。Spectre的conservative模式会显著降低积分误差对微弱谐波的仿真更准确。如果你用moderate高频小信号可能被数值噪声淹没。Maxstep这是非常关键的一项。为了让FFT结果可信仿真器输出的波形时间步长不能大于采样周期Ts 0.1us。但仅仅设maxstep 0.1us还不够保险我通常把Maxstep设成5ns到10ns也就是采样周期的1/20到1/10。这样Spectre在每个采样点之间还会有足够密的内部步长能精确捕获信号波形。Strobeperiod如果你希望波形文件保存成严格的等间隔点可以在tran选项中打开strobeperiod设为0.1us。否则Spectre默认保存的是自适应步长的时间点FFT函数需要先对波形重采样重采样过程本身就会引入额外误差。这一点很多老手都会忽略但它对最终结果的干净程度影响非常大。3.2 从电路设计到仿真设置的配套要点仿真参数之外电路和激励源的配置也会影响FFT结果。第一信号源本身的谐波要关掉。以Spectre的sine源或port源为例如果源里带了2次、3次谐波设置FFT出来的谐波到底是电路产生的还是源自带的根本说不清。做失真分析时激励源必须设成纯正弦只保留基波分量。第二如果被测对象是ADC采样时钟的抖动jitter会直接抬高噪声基底。验证电路本身的线性度时时钟源建议用理想源抖动设成0否则你测出来的THD根本分不清是电路的锅还是时钟的锅。等后面需要做系统级验证时再单独加抖动模型。第三很多电路启动时都有一个较长的建立过程。取FFT数据时一定要从稳定后的时刻开始取不要从0时刻开始。否则瞬态建立过程中的大信号摆动会被当成一个巨大的“伪周期分量”频谱上乱到没法看。3.3 仿真前检查清单我把开工前要确认的项目做成一个清单每次做FFT分析前过一遍能省掉90%的返工检查项目标值说明fin/fs是否等于M/NM为质数N为FFT点数相干采样的根本条件Stop Time建立时间 N/fs 余量保证从稳态区取完整窗口Maxstep≤ 采样周期的1/10数值精度与谐波保真度Strobeperiod等于1/fs输出等间隔采样点避免重采样误差信号源谐波关闭测电路自身失真不含源失真取样起始时间瞬态稳定后避开启动阶段的非线性摆动这套清单是我从多次仿真对比中总结出来的。尤其是Strobeperiod一项很多参考手册都没有强调但我实测下来设与不设FFT的噪声基底至少差了5到10个dB。4. FFT操作实战从频谱曲线到THD数值的完整读取4.1 在Calculator里做FFT参数逐个说清楚仿真跑完后在ADE窗口选择输出节点波形打开Tools → Calculator。选中波形后在函数列表里找到fft这时右侧会弹出一排参数逐个说清楚Sample Count填N 1024。FFT函数会从你选定的波形区间内截取1024个点点数越大频率分辨率越高但仿真需要保存的数据也越多。Window Type相干采样已经满足时选Rectangular矩形窗。如果你因为某些原因实在做不了相干采样可以选Hanning但要清楚这会展宽主瓣并带来幅度误差。Begin Time / End Time这两个参数决定你从波形的哪一段取数据。Begin设为稳态建立后的时间点End设为Begin N/fs。继续用前面的例子就是Begin 50usEnd 152.4us。区间长度必须严格等于N × Ts这正是相干采样要求的窗口长度。去直流选项一般建议开启去直流把频谱里的DC分量去掉否则0Hz处一根大谱线会把纵轴坐标压缩谐波看起来都贴到地板上。参数填完后点Apply频谱曲线就会显示出来。横轴是频率纵轴默认是dB度数。如果你用的是新版本Virtuoso在Visualizer窗口里直接点Spectrum图标也能调出同样的FFT工具参数含义是一致的。4.2 从频谱图上找到基波和谐波频谱出来后不要急着乱抓峰值。按前面算好的位置去找谱线。基波在fin 1.240234375 MHz处用Cursor点上去记录幅度值。第k次谐波在k × fin处但如果超过Nyquist频率需要按下式折算k × fin 5 MHz时实际显示位置 fs - (k × fin mod fs)比如我们例子里的5次谐波6.201 MHz显示在10 - 6.201 3.799 MHz。7次谐波显示在10 - 8.682 1.318 MHz。判断谐波位置时我一律先用计算器把每个谐波的预期位置算好再在频谱上用光标逐个确认效率高也不会漏。4.3 THD的计算公式与单位换算技巧THD的标准定义是各次谐波功率之和与基波功率之比换算成电压幅度就是THD sqrt( V2² V3² V4² ... ) / V1 × 100%在Virtuoso的FFT频谱里纵轴通常是dB。dB值到线性幅度比的换算公式是V_linear 10^(dB / 20)这里有一个高频陷阱dB是功率量纲但如果你的FFT纵轴是用幅度amplitude还是功率power表示的换算系数完全不同。Cadence默认的dBf是什么我的经验是看光标读出的单位。如果你读到的是dBV或dB一般按幅度换算用20log如果你读到的是dBm按功率换算用10log。拿不准的时候可以先用一个已知幅度的小信号做FFT看读数是否符合预期校验一次就永远清楚了。下面给一个完整计算示例。假设某个电路的FFT读出的各次分量相对基波的幅度为分量频率相对基波幅度基波1.240 MHz0 dB2次谐波2.481 MHz-50 dBc3次谐波3.721 MHz-55 dBc4次谐波4.961 MHz-62 dBc5次谐波3.799 MHz折叠-60 dBc先转线性幅度2次10^(-50/20) 0.003163次10^(-55/20) 0.001784次10^(-62/20) 0.000795次10^(-60/20) 0.00100平方和0.00316² 0.00178² 0.00079² 0.00100² ≈ 1.5 × 10⁻⁵开根号得0.00387THD 0.387%约等于0.39%。换算成dB形式则是20 × log10(0.00387) -48.2 dB。两个数字表示的是同一个含义一个用百分比一个用dBc项目报告里经常需要互转这个换算关系要刻在脑子里。4.4 用dBc计算和百分比计算的结果一致性校验我习惯每次把两种方法都算一遍。如果百分比和dB的数字对不上说明中间某一环的读数或单位换算出了问题。上面例子中如果某个谐波读错位置比如把7次谐波当成5次THD的最终结果就会有一段很明显的偏差但频谱上很难一眼看出来。所以校验公式是必须的。另一个容易踩的坑是谐波次数取多少。很多测试标准取2到10次谐波有些只取2到5次。高次谐波幅度通常很低但如果你被测电路有比较强的开关噪声10次谐波还是能贡献可观的能量。我建议在报告里明确标注“THD计算到第几次谐波”否则不同人拿到的数字没有可比性。5. 踩坑记录FFT分析里最常见的五个问题5.1 频谱像“栅栏”一样梳齿状问题出在哪有段时间我的FFT结果总是呈现出一根根细密的“梳齿”根本不像是连续噪声基底排查了很久才发现是FFT点数太多而波形保存点数太少导致的。Virtuoso的FFT函数在点数超过波形实际采样点时会做插值补全插值出来的数据在频域里会引入大量虚假的高频分量表现就是一条条齿状的杂散。解决办法是在tran分析里设置strobeperiod等于采样周期Ts确保保存的波形本身就是等间隔的并且点数不小于N。这样一来FFT就不存在插值问题。另外如果把Sample Count设置成比波形保存点数更大也是同样的结果建议核对一下波形文件的实际点数。5.2 谐波位置永远对不上多半是忘了取模做ADC的FFT分析时我见过太多人在这一步卡住。基波明明在1.24MHz按计算5次谐波应该在6.2MHz左右结果频谱上6.2MHz处什么都没有。原因很简单数字频谱只有0到fs/2这一段可见超过Nyquist频率的频率会被“折叠”回0到fs/2区间。6.2MHz折叠后落在3.8MHz而且这是一次折叠如果超过fs甚至有多次折叠。所以谐波位置公式是实际显示频率 (k × fin) mod fs若结果大于fs/2则取 fs - 该结果。这个“若大于取补”的步骤和模运算里的取负一样容易遗漏。建议在Excel或者Python脚本里列一个谐波位置表把1到10次谐波的预期位置全部算出来再对着频谱找。这样就不会出现“指着空气说谐波丢了”的情况。5.3 为什么我的THD总是偏大THD偏大的原因通常有几个。第一信号源自身带了谐波导致测出来的是源失真和电路失真的叠加解决办法是把源设成理想纯正弦。第二Maxstep设置太大Spectre的数值积分误差会表现为高频段的伪谐波和噪声基底抬高这种情况下把Maxstep缩小到采样周期的1/10甚至1/20THD会显著下降。第三FFT的窗口类型选错了非相干采样下用矩形窗泄漏尾巴会把噪声基底抬高几个dB谐波的幅度也随之被污染。还有一种情况是电路本身没进入周期稳态。比如一个高Q值的LC振荡器或环路滤波器建立时间可能长达上百微秒如果取样窗口落在稳态之前谐波含量自然会偏大。这时把取样窗口往后移通常能改善。5.4 仿真跑一天还没完时间参数该优化了Virtuoso做高精度tran仿真确实慢尤其当Maxstep设得很小但Stop Time又设得很大时整个仿真可能跑上几个小时甚至一天。这里有几个优化思路。第一如果电路建立时间很长不要一开始就用最终精度跑全程。先用较粗的Maxstep比如采样周期的一半跑一遍观察波形在哪一时刻进入稳态。然后重新设置tran分析的Stop Time从稳态前一点开始并配合更小的Maxstep这样只有后半段用了高精度仿真时间能缩短一半以上。第二在ADE里只保存需要的节点。默认情况下Spectre会保存所有节点电压但你的FFT只需要输出节点这一个波形。在Outputs设置里把输出节点选上其他节点不保存仿真的I/O压力会小非常多。第三如果项目允许用APS模式下运行tran它在某些电路上的提速非常明显但要注意和传统Spectre的结果做一次对比确认精度没有损失。5.5 该不该加窗矩形窗、汉宁窗怎么选先给结论做THD分析优先用相干采样加矩形窗不做非相干加窗的“曲线救国”。矩形窗主瓣最窄频率分辨率最高且幅度没有额外缩放是测谐波幅度的理想选择。它的缺点是非相干时泄漏严重但相干采样已经解决了泄漏问题。汉宁窗能有效压低旁瓣适合看宽频噪声谱、做非相干FFT的频谱概览但它主瓣比矩形窗宽一倍离得近的谐波会互相重叠幅度还有约1.6dB的损失做THD定量分析会引入额外误差。平顶窗幅度测量精度很高但主瓣更宽频率分辨率极差。如果你的目标是精确测量某一个独立信号的幅度平顶窗可以考虑如果目标是分清密集的谐波平顶窗就完全不适合。6. 进阶玩法用Ocean脚本把FFT和THD分析自动化6.1 最小化手动操作一个脚本跑遍所有工艺角手动在Calculator里点FFT、抓光标、记数据一两个工艺角还能忍受但要跑tt、ss、ff、sf、fs五个工艺角加不同温度手动操作能让人崩溃。Ocean脚本就是解决这个问题的标准方案。Ocean脚本是Cadence ADE内置的脚本语言可以在后台批量操作结果文件调用波形函数计算指标。下面给一个参考骨架你可以根据自家PDK路径和节点名字修改; thd_auto_analysis.ocn ; 只做参考函数名以你使用版本的手册为准 N 1024 Fs 10e6 Ts 1.0/Fs M 127 tstart 50e-6 tstop tstart N/Fs openResults( results/tr_fft/psf ) selectResult( tran ) sig v( out ?result tran ) ; 直接从指定窗口取FFT spec fft( sig N Ts Rectangular tstart ) loss 0.0 ; 根据实际窗函数修正 ; 基波幅度 fund_dB peakdb( spec tstart(M/N)/Fs ) ...Ocean脚本里没有现成的“自动找所有谐波并算THD”的万能函数很多团队是自己写一套循环代码遍历各次谐波位置读幅度再按公式累加。如果有同事已经写过类似脚本直接复用并验证一遍是最好的方式。跑完仿真后还可以在Ocean脚本里用printf把THD结果直接打印到日志文件或者写到CSV里供进一步处理。这样可以一次性把所有corner的结果汇总成一个表格非常利于后续比较。6.2 从THD到SINAD/ENOB一套指标吃透项目里通常不止看THD还会看SNR、SINAD、SFDR和ENOB。这几个指标在频域上一脉相承。SNR信号功率与所有非谐波噪声功率之比需要把频谱上除DC、基波和谐波之外的bin全部积分。SINAD信号功率与噪声加失真总功率之比也就是SNR和THD的合成。已知SNR和THD都用dBc表示时SINAD近似为SINAD -10 × log10( 10^(-SNR/10) 10^(-THD/10) )ENOB (SINAD - 1.76) / 6.02单位是bit。这个公式在ADC测试里几乎天天用。把这几个指标在Ocean脚本里一起算出来输出一张“corner 温度 THD SNR SINAD ENOB”的表无论是自己调试还是给团队汇报都会轻松很多。我个人在实际操作中的体会是Virtuoso的FFT和THD分析本身不复杂但九成以上的问题都出在相干采样这一步。只要把M/N算清楚仿真步长和等间隔输出设对后面的FFT参数和THD计算就是水到渠成的事。建议你拿到一个电路时先花五分钟把采样参数表算好再开仿真千万不要图省事随手填一个频率就往上怼。数据算得越靠前后面越不会翻车。
返回列表