Virtuoso中主从式DFF设计:从原理图到仿真验证

发布时间:2026/10/6 1:36:13
Virtuoso中主从式DFF设计:从原理图到仿真验证
Virtuoso 里把 DFF 从电路图画到仿真通过说难不难说简单也真有不少坑。很多初学者一上来就照着教材抄波形结果原理图都存不过 DRC或者仿真出来 Q 端纹丝不动最后卡在“我以为我懂了”的阶段。这篇东西我按照自己在 Cadence Virtuoso 里完整做过一轮主从式 DFF 的流程来写从建库、画原理图、设仿真、看波形到建立时间、保持时间、CLK-to-Q 延迟这些指标怎么从波形里抠出来尽量一次讲透。1. 整体设计思路为什么要做 DFF以及主从式方案怎么选1.1 DFF 在数字 IC 设计里的位置D 触发器是几乎所有时序逻辑的“细胞”。寄存器、移位寄存器、计数器、状态机、分频器底层都是 DFF。在模拟和数模混合电路里DFF 也大量出现在分频器、相位检测器、可控振荡器分频链路这些位置所以我一直觉得DFF 是很多人从纯粹画放大器、画带隙基准转向开始碰“有一点数字味道”的电路时最合适的切入点。它最大的价值在于电路规模不大晶体管数量少但包含了完整的时序概念——建立时间、保持时间、传播延迟、时钟边沿采样。这些概念在后续做更大规模数字模块、做 PLL 分频器、做 SerDes 里的并串转换时全都是同一套底子。用 Virtuoso 画一轮 DFF等于把模拟设计流程和数字时序概念同时过了一遍。1.2 为什么选主从式传输门结构DFF 的 CMOS 实现方式有好几种真单相时钟TSPC触发器、动态触发器、C2MOS 结构、主从式传输门结构。我在 Virtuoso 里最推荐第一次做的是主从式传输门 DFF原因有三个结构直观主锁存器和从锁存器各司其职分析波形时容易定位问题到底是出在采样级还是输出级。静态逻辑不存在动态节点泄漏问题不需要额外考虑刷新周期功能测试时少一种出错可能。传输门用互补时钟控制导通电阻低信号完整度好对新手来说波形分析友好。TSPC 结构虽然晶体管更少但动态节点一旦电荷泄漏低功耗工艺下很容易出现逻辑错误调试难度对初学者偏高。C2MOS 结构则需要仔细处理时钟交叠问题第一次做的话我建议还是把主从式传输门结构吃透。1.3 Virtuoso 平台的优势有人会问直接拿 SPICE 网表跑仿真不行吗当然行但 Virtuoso 的价值在于它在同一个平台里把原理图编辑、符号生成、仿真配置、波形查看、版图编辑全部串起来了。画完原理图自动生成 symbol再在 testbench 里调用 symbol这种“所见即所得”的方式对理解电路连接关系特别有帮助。我自己的经验是如果你以后打算做模拟版图那 Virtuoso 几乎是必选项因为画完原理图、仿真通过之后可以直接进入 Layout Editor 做版图然后做 LVS版图与原理图一致性检查。DFF 正好是个规模合适的练习对象。而如果你只想做网表级验证那用任何 SPICE 工具都行但 Virtuoso 这套完整流程能帮你把“原理图→仿真→版图”的整个链路打通。2. Virtuoso 环境准备与 DFF 原理图搭建2.1 建库和选工艺先把“地基”打对打开 Virtuoso 之后第一步不是急着画管子而是在 Library Manager 里新建一个工作库。我用的是 Cadence 自带的教学工艺库 gpdk180180nm CMOS 工艺这个库里面包含了完整的 NMOS、PMOS、电阻、电容、电源地等各类器件同时还有对应的工艺文件可以直接跑 Spectre 仿真。注意几个细节新建库的时候Technology File 一定要选“Attach to an existing technology library”然后选 gpdk180。如果不 attach 工艺文件后面画版图或者跑某些仿真时会报 techfile 相关的错误。库名不要用中文也不要用空格Virtuoso 对路径里的特殊字符很敏感。我习惯用 dff_lib 这样的小写加下划线命名。Cell 名建议用 dff_master_slave 或者 dff_tg避免用 dff 这种太笼统的名字等以后库大了cellview 多了命名规范能省不少事。2.2 新建原理图 Cellview在库下面右键 → New CellviewCell 名字填 dff_tgType 选 schematic打开原理图编辑器。这一步有个容易被忽略的地方打开了原理图编辑器之后先检查右上角的“V”和“I”有没有亮出来这是实例instance和连线wire的快捷键。用快捷键 i 来放置器件用 w 来连线用 p 来打引脚。我个人的习惯是先把整个 DFF 的晶体管列表列出来再去画图。别小看这一步很多人一边画一边想管子够不够结果画到一半发现少画一个反馈反相器又得回头改线特别浪费时间。2.3 主从式 DFF 的晶体管级结构清单我设计的这个 DFF 是上升沿触发结构如下输入反相器D 信号进来先过一个反相器生成内部反相信号 DN方便后面用传输门做数据通道切换。有些设计不做这个反相器直接把 D 和 DN 同时提供给输入传输门但为了简洁我只画一个主输入。主锁存器由输入传输门、主级反馈反相器、反馈传输门组成。从锁存器由级间传输门、输出反相器、输出反馈反相器、反馈传输门组成。时钟反相器链CLK 进来过一个反相器生成 CLKB再过一个反相器生成 CLK 的延迟版本或者在标准设计里直接由外部提供互补时钟。在原理图里我更习惯用两个反相器把 CLK 变成 CLKB这样原理图自包含测试时只需要一个时钟源。具体晶体管清单输入驱动反相器PMOSNMOS 一对尺寸按后面说的比例来。输入传输门NMOSPMOS 一对。主级主反相器PMOSNMOS 一对。主级反馈反相器PMOSNMOS 一对。主级反馈传输门NMOSPMOS 一对。级间传输门NMOSPMOS 一对。从级输出反相器PMOSNMOS 一对。从级反馈反相器PMOSNMOS 一对。从级反馈传输门NMOSPMOS 一对。时钟反相器两个共四管。算下来大约 18 个晶体管规模不大但麻雀虽小五脏俱全。2.4 端子命名和连接规范在原理图里打引脚时我建议用这组端口CLK、D、Q、VDD、VSS。不要偷懒不打电源地引脚很多初学者画数字模块时把 VDD、VSS 隐掉觉得仿真时全局变量能搞定。但在 Virtuoso 里做 spectre 仿真时如果 cell 内部没有明确的电源地连接后续做 LVS 会非常痛苦。而且从信号完整性角度显式的电源地引脚能让你在仿真中直接观察电源电流。连线时注意几点传输门 NMOS 的源漏不要接反。虽然传输门本身是对称器件但在原理图里我习惯把输入方向放在左侧输出方向放在右侧这样阅读原理图时思路更清晰。交叉线不要直接相连Virtuoso 里如果是四线交叉系统会认为是不同网络需要显式打 Pin 或者用导线节点连接。导线命名用大写比如 CLK、D_NODE避免和器件名混淆。3. 核心电路细节传输门 DFF 的原理与尺寸选择3.1 主锁存器如何“采样”和“保持”理解主从式 DFF 的关键在于记住“采样”和“保持”由时钟电平交替控制。时钟为低电平时CLKB 为高输入传输门导通D 信号进入主锁存器内部节点 X此时主级处于“透明”状态。同时级间传输门截止从锁存器与主锁存器隔离输出 Q 保持上一次锁存的值。时钟上升沿到来时CLKB 变低输入传输门截止级间传输门导通。此时输入 D 在上升沿前一瞬间的值已经被主级“冻结”在节点 X 上现在这个被冻结的值通过级间传输门传给从锁存器从锁存器的输出反相器再驱动 Q 输出。时钟为高电平期间级间传输门保持导通但主动输入传输门已关闭所以 Q 不会再跟随 D 变化。直到下一个上升沿主级重新采样 D 的新值。这个逻辑关系写出来就是一句话输出 Q 在时钟上升沿锁存 D 的值其他时间保持不变。3.2 传输门的作用和尺寸选择传输门就是并行的 NMOS 和 PMOS一个用 CLK 控制一个用 CLKB 控制。它的作用是像开关一样在导通和断开之间切换。NMOS 传输高电平时会有阈值损失PMOS 传输低电平时也会有阈值损失但两者并联之后一个负责传强高、一个负责传强低所以输出摆幅可以做到满摆幅。尺寸上我用的基础是 180nm 工艺NMOS 栅长取最小尺寸 180nmPMOS 栅长也取 180nm。宽度方面传输门内部 NMOS 我取 400nmPMOS 取 800nm这样等效导通电阻在电源电压 1.8V 下大概在几千欧姆量级足够驱动下一级小尺寸反相器。反馈回路的传输门可以稍微做小一点比如 NMOS 300nm、PMOS 600nm因为它只需要维持节点电平不需要高速翻转。但如果做小太多反馈驱动能力不足在高频时钟下可能锁不住值。3.3 反相器的尺寸比例PMOS 和 NMOS 的 2:1 规则CMOS 反相器里 PMOS 和 NMOS 的宽长比我习惯取 2:1 到 3:1。原因很简单PMOS 的载流子迁移率大约是 NMOS 的一半为了让上升时间和下降时间对称PMOS 需要更大的宽度。在我的 DFF 内部反相器里NMOS 用 400nm 宽PMOS 用 800nm 宽。输出级反相器驱动 Q 的那个稍微加大一点NMOS 用 600nmPMOS 用 1.2um这样 Q 端能够驱动测试负载通常是几十飞法的负载电容而不至于翻转太慢。时钟反相器链的输出级也要注意因为时钟要驱动多个传输门的栅极负载电容不小。我用的时钟反相器输出级尺寸是 NMOS 800nm、PMOS 1.6um以保证时钟沿足够陡峭。3.4 使用 IDE 快捷键和检查连线画图的时候Virtuoso 有非常多的快捷键熟悉了之后效率翻倍。我常用的几个i放置实例器件w连线p打引脚c复制m移动s拉伸鼠标中键或者按 ESC退出当前操作画完大概就是下面这个连接顺序从左到右D → 反相器 → 输入传输门 → 节点 X → 主级反相器 → 节点 X 反馈传输门 → 反馈回节点 X节点 X → 级间传输门 → 节点 Y → 从级反相器 → 输出 QY 节点还有一个反馈反相器和反馈传输门反馈环回到 Y。画完之后用 Check and Save快捷键 X 或者快捷键 ShiftX检查一遍。如果报错说 floating nets多半是线没连到器件的 pin 上或者引脚名字打错了。我建议画完一个传输门就保存检查一次别等全部画完再检查那样报错位置一多人容易看花眼。4. 功能测试从 Testbench 搭建到波形验证4.1 新建 Testbench 原理图DFF 本体画好了接下来要验证功能。我的做法是再新建一个 Cell叫 dff_tb这里放被测 DFF 的 symbol 和激励源。在 dff_tb 原理图里按 i 放置实例在 Library 列表里找到 dff_lib选 dff_tg然后选择 View 为 symbol。如果之前原理图画完保存后系统没有自动生成 symbol可以在 Cellview 里选 Design → Create SymbolVirtuoso 会基于引脚自动生成一个方框符号引脚位置可以手动调。4.2 激励源的设置方法在 testbench 里需要放电源 VDDDC 值 1.8V。时钟源 CLK用 Pulse 类型周期设 20ns50MHz脉冲宽度 10ns上升和下降时间各设 100ps 到 200ps。数据源 D用 Pulse 或者自定义 PWL 波形。为了让验证更具完整性D 信号应该在时钟边沿附近故意变一次看看建立时间如果不够会发生什么。时钟源在 Virtuoso 模拟库里的名字通常是 vpulse数据源可以用 vpulse也可以用 vpwl。参数示例时钟 vpulseV10, V21.8, TD10n, TR0.1n, TF0.1n, PW10n, PER20n。 数据 vpulseV10, V21.8, TD15n, TR0.1n, TF0.1n, PW30n, PER60n。这样设置之后第一个上升沿在 10ns 处而 D 在 15ns 处才从 0 变 1。由于上升沿先于 D 变化所以第一个上升沿应该采到 D0Q 应该保持为 0。第二个上升沿在 30ns 处这时候 D 已经变成 1Q 应该被置 1。这样的波形能非常清晰地区分“时钟采样时刻”和“数据变化时刻”。4.3 ADE L 仿真环境配置Virtuoso 里现在的仿真环境叫 ADE LAssembler或者 ADE XL老版本界面是 ADE L。我习惯用 ADE L 做快速功能验证它的界面直观设置起来快。在 testbench 原理图界面打开 Launch → ADE L然后进行以下设置选择仿真器Simulator 选 spectre。在 Analyses 里选 tran瞬态分析Stop Time 设为 150ns这样能覆盖多个时钟周期。精度按 moderate 起步如果波形有问题再改 conservative。在 Outputs 里手动添加要查看的节点D、CLK、Q还有电源 VDD 上的电流用来看功耗。勾选保存所有信号方便后续查看内部节点。设置完了之后先点 Netlist and Run。第一次跑会生成网表如果原理图有问题会在 Netlisting 阶段报错。最常见的错误是某个器件的 model 名没对上gpdk180 里的 NMOS 模型名是 nchPMOS 是 pch如果从别的库复制器件过来一定要检查 model name。4.4 波形阅读怎么判断 DFF 功能正确仿真跑完打开 wavewindow或者直接按 ADE 里的波形按钮把 D、CLK、Q 三条曲线拉出来看。判断标准就一句话Q 的变化只发生在 CLK 的上升沿且变化后的值和那个时刻 D 的值一样。具体到我们的激励10ns 上升沿D0Q 应该为 0初始值也是 0所以这段看不出变化。15nsD 变 1但此时没有时钟上升沿Q 必须保持不变。如果这里 Q 跟着变了说明主锁存器或从锁存器隔离失效。30ns 上升沿D1Q 应该从 0 翻到 1。45nsD 变 0Q 继续保持为 1。50ns 上升沿D0Q 从 1 翻回 0。如果 Q 在非边沿时刻跟着 D 变最常见的原因是级间传输门时钟接反了。比如级间传输门本应 CLKB 控制的 PMOS 接成了 CLK导致低电平时从锁存器也透明直接把主级输出透传出去。4.5 内部节点检查用探针定位问题如果发现 Q 波形不对我通常不直接猜而是把内部节点也调出来看。具体做法回到 ADE L在 Outputs 里 Add Outputs 选择 Schematic然后在原理图上点几个关键节点。比如主级输出节点 X、从级输入节点 Y。如果 D 变化了但节点 X 在时钟低电平阶段没有跟着变说明输入传输门没导通或者主级反馈回路把节点牢牢锁住了。如果节点 X 跟着变但 Y 不变那就检查级间传输门。这种一级一级往下定位的方式比瞎猜快得多。4.6 功能测试用例设计多几种数据样式一次仿真只能证明“在这个激励下功能正确”不能证明 DFF 真的没问题。我建议至少跑三组激励低频随机数据验证基本采样功能。时钟 20ns 周期D 每隔几个周期翻转一次。最坏情况数据验证建立时间和保持时间。让 D 尽量靠近时钟上升沿翻转比如 D 在上升沿前 100ps 才变化看看 Q 能不能正确采样。时钟频率提高比如从 50MHz 提升到 200MHz周期 5ns看看高频下输出是否还能跟得上。第三组测试非常重要因为很多功能问题在低频下不暴露频率一高传输门的导通时间和锁存器的建立时间不够问题立马现形。5. 建立时间、保持时间和 CLK-to-Q 延迟的测量5.1 三个时间参数分别是什么功能正确只是第一步DFF 的性能要靠三个时间参数来衡量建立时间 ts数据 D 在时钟上升沿之前必须保持稳定的最短时间。保持时间 th数据 D 在时钟上升沿之后必须保持稳定的最短时间。CLK-to-Q 延迟 tcq从时钟上升沿到 Q 稳定输出新值的时间。直观理解建立时间不够相当于数据还没“到达门口”时钟就关门了保持时间不够相当于时钟刚关门数据就跑了锁存器没来得及把值锁牢。CLK-to-Q 则是“关门之后门后的灯多久亮起来”。5.2 扫描法测建立时间建立时间的测量思路是设计一个数据变化时刻相对于时钟上升沿可变的激励然后观察 Q 是否正确采样。在 ADE L 里我通常会用一个变量 data_delay 表示数据翻转时刻把 vpulse 的 TD 参数写成 {data_delay}然后用参数扫描假设时钟上升沿在 10ns设 data_delay 从 9.5ns 开始以 50ps 步进扫到 10.2ns。当 data_delay 越来越接近 10nsQ 开始出现采样错误的点这个临界点前后就是建立时间的边界。比如数据在 9.8ns 变也就是上升沿前 200ps 变Q 能正确输出 1数据在 9.9ns 变也就是上升沿前 100ps 变Q 采样失败那建立时间就是 150ps 左右介于 100ps 和 200ps 之间。更精细的做法是二分法逐步缩小区间。这样测出来的建立时间比直接看一条波形靠谱得多。5.3 测保持时间的技巧保持时间测量稍微麻烦一点因为要让数据在时钟沿之后立刻变。设置方法让 D 为高在时钟上升沿之后的某一时刻突然变为低观察 Q 是否还能保持刚才采到的 1。如果 D 在上升沿之后 200ps 就翻转而 Q 还能保持 1说明 200ps 大于保持时间。如果 D 在上升沿之后 50ps 翻转Q 没保持住说明 50ps 小于保持时间。通过扫描这个翻转时刻就能找到保持时间的边界值。5.4 CLK-to-Q 延迟和波形光标使用CLK-to-Q 延迟最容易测。在瞬态波形里把 CLK 和 Q 放在同一个图里放大上升沿附近用波形查看器的标尺Marker分别点时钟上升到 50% VDD 的位置和 Q 从旧值翻转到 50% VDD 的位置两个时间戳之差就是 tcq。这里我建议统一用 50% VDD 作为测量点因为 CMOS 逻辑的延迟定义都是基于 50% 摆幅点的这样论文、报告里的数据才能跟你的对比。5.5 功耗测量DFF 是时钟控制器件动态功耗主要来自时钟翻转时对各个传输门栅极电容和内部节点的充放电。我在 ADE L 里把 VDD 电源的直流电流加为输出仿真结束后用计算器Calculator的 average 函数求平均电流再乘以 1.8V就是平均功耗。功耗会随时钟频率线性上升所以记录功耗时一定要注明测试频率。50MHz 下也许只有几微瓦200MHz 下可能是几十微瓦这个趋势是正常的。6. 常见问题与排查技巧实录这一节把我自己遇到过、也看别人反复踩过的几个坑列一下每个都是真实场景。6.1 Q 端一直不翻转永远是高阻或固定电平出现这个现象先检查电源和地有没有连上。Virtuoso 原理图里电源地如果不打引脚只靠全局名称连接有时候 spectre 网表里不会自动连到 VDD 全局网络。另一个常见原因是输出级反相器接反了。PMOS 应该接 VDDNMOS 应该接 VSS如果不小心把两者的 drain 都接到了 VDD那输出端永远没有下拉通路Q 就只会是高或者高阻。6.2 Q 在非边沿时刻跟着 D 变化这个非常典型几乎可以肯定是时钟控制方向接反了。D 一变化Q 立刻跟着变说明主锁存器和从锁存器同时透明了。排查思路看主锁存器的输入传输门它应该在 CLK 低电平时导通如果你在原理图里接成了 CLK 高电平导通那就是反的。反过来级间传输门应该在高电平时导通如果接成低电平导通也会出现类似现象。我建议每次画完一个传输门就记住当前这根时钟线是 CLK 还是 CLKB在网线名称上直接标清楚不要只靠颜色区分。6.3 仿真报错“No DC path to ground / VDD”这种错误通常是某个节点没有任何低阻通路连到电源或者地。DFF 里如果反馈回路没画完整或者传输门全部处于关闭状态某个内部节点就会悬空。定位方法在 ADE 里点击 Simulation → Netlist → Display直接看生成的 spice 网表检查每个节点的连接情况。网表里如果出现某个节点只接了一个器件的某个端子那就一定是悬空节点。6.4 高频下功能退化波形变圆角如果低频功能正常频率一高输出波形就变得跟正弦似的那是驱动能力不足。时钟频率提高后每个时钟周期留给信号翻转的时间变短而内部节点的 RC 延迟是固定的翻转跟不上。解法就是把输出级反相器和时钟反相器的宽长比加大。我一般先把输出级翻倍如果还不够再把时钟树上的反相器尺寸加大。注意不要盲目把全部管子都加宽加宽会增大输入电容反而增加前级负担形成恶性循环。正确思路是从输出级逐级向前找到真正的瓶颈级。6.5 用 Corner 仿真验证鲁棒性功能测试通过之后做一次 Corner 仿真很值得。gpdk180 工艺库通常支持 ff、tt、ss 三种工艺角。不用跑太多跑 tt 和 ss 两个就行。SS 角下NMOS 和 PMOS 都偏慢建立时间和 CLK-to-Q 延迟都变差。如果 SS 角下 50MHz 都跑不过那你的 DFF 在真实芯片里大概率不可用因为真实芯片总有工艺偏差。7. 从原理图到版图的延伸准备7.1 为什么要提前想版图很多人觉得“我只画原理图不画版图”。但如果你是在 Virtuoso 环境里做设计版图是绕不开的。DFF 这种模块做版图其实比想象中简单而且能帮你真正理解器件的物理连接。我建议在原理图画完、仿真通过之后至少去 Layout Editor 里把 DFF 的版图画出来跑一次 LVS确认版图和原理图一致。7.2 版图布局的基本策略DFF 的版图核心是匹配和对齐。主锁存器和从锁存器的 PMOS 尽量放在同一个 N 阱区域NMOS 放在同一个 P 衬底区域。电源线 VDD 和地线 VSS 用金属线横贯整个模块器件的源端直接打接触孔连到电源轨上。时钟线要尽量短而且 CLAK 和 CLKB 的走线要平行靠近这样两者之间的寄生电容耦合是确定的不会出现一个快一个慢的偏斜问题。输出 Q 的走线适当加宽因为它要驱动外部负载。如果 DFF 之后还要接反相器缓冲器那缓冲器的位置应紧邻 DFF 的输出端减小寄生电容。7.3 LVS 检查注意什么在 Virtuoso 里跑 LVS通常会提示“Source/Drain 不对称导致匹配失败”这属于常规信息不用太紧张只要短路开路检查通过器件数目和类型一致LVS 基本就能通过。真正容易出问题的是电源和地引脚。原理图里如果 VDD 和 VSS 是引脚那版图里也需要有对应的 pin而且要保证 pin 的网络名和原理图一致。很多第一次画版图的人在这里卡住因为高压器件 PIN 打错一个字母LVS 就怎么都过不了。8. 我的一些实操体会做完一轮 DFF我对“设计闭环”的理解比单纯看教材深得多。很多书上写得一笔带过的细节比如传输门尺寸到底取多少反馈回路要不要单独加小尺寸管子时钟到底怎么分配这些只有自己在 Virtuoso 里跑过一遍才知道里面的取舍。我最大的一个体会是仿真器不会骗你但你的测试可能覆盖得不够。第一次功能仿真 Q 波形全对我心里还挺高兴结果把 D 翻转时刻往时钟沿附近挪了 100ps输出立刻出错这才意识到所谓“功能正确”其实是有条件限制的。设计 DFF不是为了跑通一个波形而是为了找到能让它在各种数据时序下都正确工作的那组设计参数。如果你正在学 Virtuoso我的建议是别急着去跑那些花里胡哨的射频电路先把 DFF 这种基础单元真正吃透。画一遍、仿一遍、量一遍建立保持时间、再画个版图跑一遍 LVS这一个完整循环下来你面对的就不再是零散的操作技巧而是一套带着物理直觉的设计方法论。而这套方法论才是 Virtuoso 真正值钱的地方。