ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ISO输入端为何不能插buffer?dont_touch坑掉的功耗优化

2026/10/5 1:36:01 拓冰建站 浏览量
ISO输入端为何不能插buffer?dont_touch坑掉的功耗优化 做低功耗数字后端的人基本都跟 power domain 的 check 报表打过交道。今天聊一个看着特别基础、但真实项目里反复踩坑的问题ISO 的 input 端为什么不能插 buffer更麻烦的是有人图省事在这条路径上设了一条 dont_touch结果 standby 功耗直接失控一条漏电路径藏在了几百条标准单元里。把这条“隔离边界上的多余 buffer”拆开讲透顺便聊聊那次被一条 dont_touch 坑掉的功耗优化。1. 先从电源域隔离说起ISO 到底在防什么1.1 为什么要做 power gating 和 isolation低功耗 SoC 现在普遍采用多电压域设计最常见的就是 AONalways-on域和可关断域共存。某个功能模块在休眠时通过电源开关把内部 VDD 直接切掉从而把该模块的静态功耗降为接近零。这个思路很直接但会带来一个连锁问题如果关断域模块有条输出信号要送到仍然上电的模块关断之后这个输出节点就变成浮空节点电平不定。浮空节点对于后面还在工作的电路来说等于一颗定时炸弹。它可能停在中间电平让接收端反相器里的 PMOS 和 NMOS 同时导通形成从 VDD 到 VSS 的低阻通路产生持续漏电还有可能在电压波动时来回翻转导致下游逻辑出现不可预期的跳变甚至把状态机带飞。所以设计规范里强制要求所有从可关断域到常开域的跨域信号必须经过 isolation cellISO做钳位在关断期间把输出强制固定到安全电平通常是 0也可能是 1由协议决定。所谓 ISO本质上就是一个带使能控制的逻辑门。库里的 isolation cell 一般长这样输入是来自关断域的数据输出连到常开域另外还有一个 isolation_enable 控制信号。正常工作时enable 无效ISO 跟着输入走当关断域要断电时先拉有效 enableISO 输出被钳到约定电平然后再关断电源。这个顺序在 UPF 里通过 power state 和 isolation strategy 保证后端工具会据此自动插入 ISO或者把综合阶段插入的 ISO 映射到物理库。1.2 ISO 单元的基本结构与 UPF 表达从实现角度讲一个最常见的 ISO 单元就是把数据信号和一个反相的 enable 做 AND输出钳到 0要钳到 1 就用 OR 结构。还有一些库提供 clamp 到指定值的专用 cell内部可能用传输门和反馈保持结构。电路上看ISO 和普通组合逻辑没有本质区别但它在低功耗流程里的身份很特殊它是电源域边界上的“关卡”UPF 对它的位置和连接关系有明确约束。UPF 里的约束一般长这样set_isolation iso_out_ctrl \ -domain PD_OFF \ -isolation_power_net VDD_ON \ -isolation_ground_net VSS \ -clamp_value 0 \ -applies_to inputsapplies_to inputs 表示对 PD_OFF 的输出边界信号做输入隔离也就是说 ISO 必须放在这个关断域和常开域之间的交叉口数据从关断域输出之后先经过 ISO再进入常开域。这里的关键点是ISO 的输入侧连接的应该是关断域逻辑锥的末端ISO 本身由常开电源供电。工具读进 UPF 后在综合和布局布线阶段会按要求插入并优化 ISO 网络但前提是这条边界网络保持“干净”没有被其他普通逻辑单元横插一脚。2. 输入端接 buffer 为什么不行浮空与漏电的根本原因2.1 从工具视角看 ISO 的输入侧约束很多刚从后端流程入门的朋友会问ISO 输入端加一个 buffer 有什么不行不就是多一个反相器或者缓冲器驱动一下吗还能修 max transition、修 fanout看起来都是正向收益。问题出在电源域的划分上。ISO 输入端前面这个 buffer从逻辑归属来看是跟着关断域走的布局时会被放在可关断域区域电源接的是可关断域的 VDD。也就是说模块一关断这个 buffer 的电源也没了。电源都断了它自然无法正常输出一个确定电平于是 ISO 输入端变成悬空节点。更麻烦的是ISO 本身接在常开电源上。它的输入级为了读入前级信号必须保留正常的 CMOS 输入结构。输入悬空时输入级反相器的栅极电平不定可能停在中间阈值附近于是内部上下管同时打开形成从 VDD_ON 到 VSS 的直流通路。这个电流不经过任何逻辑切换是典型的静态漏电而且比库模型里给出的标准泄漏电流高一个数量级以上。一条路径可能只是几十纳安上百条边界路径累加起来待机电流的预算就彻底废了。工具层面同样不认可这种结构。低功耗规则检查会要求隔离单元的输入和关断域驱动逻辑之间不能插入普通 buffer。原因很直白isolation 的设计语义是“把最后一级钳住”如果中间有一个不属于隔离单元的 buffer它钳不住也无法保证隔离信号的电平在关断后还能维持。很多工具无法知道你加这个 buffer 的目的是什么只会在检查报告里甩给你一条不可自动修复的 violation。2.2 输入悬空后的漏电路径逐级拆解把漏电路径拆细一点。假设关断域里有这样一个结构PD_OFF_logic_reg_reg - buffer_before_iso - ISO_in其中 buffer_before_iso 是后来手工插入的、并且被 set_dont_touch 保护的 buffer。模块正常工作时这条路径没有任何问题buffer 如实放大信号ISO 如实跟随输出。模块进入休眠时控制器先让 ISO 的 enable 生效把 ISO 输出钳到约定电平然后切开关断域电源。此时会发生几件事第一PD_OFF_logic_reg_reg 的输出因为寄存器掉电而浮空buffer 的输入端浮空buffer 的输出节点随之变成中间电平或者彻底悬空。这个悬空节点一直连到 ISO 的输入管脚。ISO 输出确实被钳位了但钳位功能只能保证输出侧安全并不能避免输入级漏电。第二ISO 输入级反相器栅极悬浮在中间电平附近输入级 P/N 管同时导通电流路径从常开电源 VDD_ON 流经 ISO 输入级上管、下管到 VSS。这条路径和后面的钳位输出逻辑没关系是独立发生的静态漏电。第三buffer 本身虽然掉电但它的衬底和阱还连着固定的电位源漏两端由于浮空节点的作用也可能出现漏电通路。常规 leakage 分析工具默认所有输入都有确定的状态这样浮空栅极导致的漏电根本算不准只有做精细的 SPICE 仿真或者专门加 probing 才能发现。所以结论非常明确ISO 的 input 端不是不能插 buffer而是插入的 buffer 如果属于可关断域就会在关断后成为悬空节点悬空节点直接造成隔离单元输入级穿通漏电。规范做法是确保 ISO 之前的路径上不出现任何可能被断电的逻辑单元ISO 输入 net 直接由关断域逻辑驱动中间只允许物理走线不允许再插有源器件。2.3 一个很容易混淆的点ISO 输出侧加 buffer 为什么没问题很多人在讨论这个问题时会把单位搞混。ISO 输出侧是完全不同的情况。ISO 输出是经过钳位之后的确定电平它接入的是常开域逻辑所以在 ISO 输出后面加 buffer、加 delay cell、加 fanout buffer 都没有问题这些 buffer 本身在常开域供电下工作不会因为关断而失去输入信号。有些后端工程师为了修 hold、修 transition 会把 buffer 加在边界路径上那么选择加在 ISO 输出侧通常可以规避漏电问题同时也满足时序要求。如果你发现一条边界路径的 transition 很差第一反应不应该是“在 ISO 前面塞个 buffer”而是先看 ISO 驱动端的 cell 尺寸够不够再看这条 net 的物理距离是否太长。真到了必须加 buffer 的时候加在 ISO 的输出端逻辑上等价于增强隔离后的信号驱动能力代价是要评估常开域那边的负载和功耗但至少不会产生浮空漏电。3. 一条 dont_touch 惹出的漏电事故3.1 dont_touch 为什么会出现在 ISO 输入端我那次印象很深的问题追根溯源就是一条 dont_touch。模块里有一条从关断域到常开域的边界信号原本已经按照 UPF 插好了 ISO cell。后来前端工程师在验证时发现这条信号经过 ISO 之后 delay 偏大影响了对面的握手时序于是没改 RTL直接在后端网表里加了一颗 buffer。为了不让后续优化把这颗 buffer 当成冗余单元吞掉又顺手对 buffer 的 pin 和 net 都加了 set_dont_touch。这颗 buffer 恰好被加在 ISO 的 input 侧性质就成了“关断域逻辑输出 - 手工 buffer - ISO 输入”。dc_shell 或者 genus 跑优化时dont_touch 会阻止工具重新归类、复制或删除这颗 buffer。综合工具其实想动这颗 buffer因为它知道 ISO 输入侧不应该有多余逻辑但优化器看到硬约束只能收手。工具不一定报错也可能只是报个低优先级的 warning大家扫一眼就放过去了。功耗分析阶段也没有显眼的 fail因为标准 leakage 分析把 buffer 当成普通掉电 cell 算静态漏电把 ISO 输入当成有确定输入条件整体漏电数字看起来人畜无害。问题真正爆发是在做芯片级 standby 电流测试时。整个模块关断后实测待机电流比功耗仿真结果大了不少。逐条 check 边界路径时才把目光放到这颗手工加的 buffer 上用 SPICE 提取局部电路浮空栅极导致的穿通电流立刻现形。3.2 事故现场复盘从 DRC 到 leakage 报告把复盘过程按现场视角排一遍方便你对着自己的 flow 自查。第一轮嫌疑是隔离单元本身。check_mv_design 或者同等功能的多电压规则检查跑出来的结果里其实已经有一类关于 isolation cell input 的提示。正常情况下这类提示会写出类似“isolation cell input is driven through non-isolation cell”的描述但很多团队会把它当成普通建议性 warning 或者直接过滤掉没追下去。第二轮嫌疑是 dont_touch 的来源。看网表里那颗 buffer 的 origin可以直接从命令打出来比如 report_dont_touch 和 get_cells 交叉验证它会显示这颗 buffer 被设置了 dont_touch。问一下当初是谁加的回答往往都是“为了修 timing”但 timing 修复完全可以通过调整驱动 cell 或者布线约束来做根本不需要在隔离边界上加 buffer 再锁死。第三轮才是功耗现场。leakage 分析报告里常规项一切正常因为库里的 leakage 表假设输入 pin 是某个固定电平浮空栅极这种状态根本不在表里。只有用 SPICE 仿真把这段电路拉出来给浮空节点一个初值看它骑在中间电平上时 ISO 输入级的电流才能看到几十倍于标准漏电的值。这块问题我没有给出具体数值因为不同工艺节点差异非常大。7nm 以下的标准单元泄漏本来就比成熟工艺大不少悬空引入的额外漏电在低功耗产品里属于完全不能接受的量级。如果模块里挂了上千条隔离信号每条都路过一个不该出现的 buffer那待机功耗翻倍不是夸张。3.3 工具为什么不会自动帮你修工具不碰这颗 buffer根本原因就是 dont_touch 给了它“不许动”的指令。这里其实有一个反直觉的点后端工具的优化器默认会做逻辑重写、单元重定时、网表整理它有能力把 ISO 输入端的多余 buffer 吸收掉也有能力把 buffer 搬到 ISO 输出侧但前提是这些 pin 没有被保护。一旦设了 dont_touch等于告诉工具“就算这里有问题你也不许碰”。工具在流程上还没有强大到反过来质疑你的 dont_touch。你说的每一条约束工具都当成设计意图来执行。所以类似问题必须靠人肉 review 和规则检查的硬约束来堵住。还有一个关键原因许多低功耗约束检查的默认过滤级别很高。对于 “ISO input net has additional cell”这类边界问题在很多工具里只作为 warning 出来不会让 flow 直接中断。后端flow普遍重视 timing signoff对功耗约束检查这类相对低频的报告没有真正卡死于是这些 warning 就一路存活到了流片前。4. 正确做法与排查清单几十万门设计中怎么防止踩坑4.1 UPF 和网表层面的正确约束姿势先明确标准的 UPF 约束方向。isolation cell 通常由常开电源供电enable 信号来自常开控制逻辑隔离单元的输入 pin 直接接关断域逻辑输出端口。如果电源域边界本身设置了 level shifter那 level shifter 的处理要单论不同工具对 level shifter 和 isolation 的先后顺序有不同要求ISO 输入前也不能出现普通 buffer但 level shifter 是边界单元的一部分不在此列。推荐的做法是在综合之前就把边界路径的逻辑结构定清楚每个可关断域输出的信号在 RTL 顶层 net 上只允许经过 ISO再进入其他域。如果驱动能力不足在关断域内部靠近源端的位置加大驱动 cell不要贴着 ISO 输入端补 buffer。如果必须额外增强信号把 buffer 放在 ISO 输出侧让它工作在常开域。不要在 isolation cell 的输入 net 上使用 set_dont_touch。如果一定要保护边界路径不被优化破坏优先用 set_dont_touch 作用于模块内部逻辑而不是边界网络上的中间 buffer。一颗 buffer 加错位置带来的不只是泄电流还会让后续 ECO 和 formality 都变得痛苦。网络上的多余 buffer 会改变 RO 逻辑锥的边界形式验证时需要用额外的 examine 来排除不然很容易出现奇怪的 LEC failure。我见过好几个项目把这些时间耗在“为什么 LEC 报 fail”上最后发现就是 ISO 前那颗 buffer 的 inverting 属性导致工具无法自动匹配。4.2 后端流程中的检查与兜底手段在不同工具链里低功耗规则检查命令名称不一样但核心思路一致。Synopsys 流程里的 check_mv_designCadence 流程里的 verifyPowerDomain都提供针对 isolation 单元位置的规则检查。重点看以下几类问题问题类型典型报告内容处理方式ISO input 有多余逻辑单元isolation cell input driven by non-isolation cell删除/移动 buffer重新综合dont_touch 导致边界不可优化dont_touch prevents optimization at isolation input去除 dont_touch重新 optISO 单元电源域错误isolation cell powered by off-domain supply修正 UPF换到常开域隔离 enable 时序错误isolation enable path from off-domain修改使能信号的电源域归属除了工具自带的 low power 检查我这里强烈建议在 RTL2GDS 流程里加一道自定义脚本检查。遍历所有 isolation cell核对每个 cell 的 input pin 驱动的网络是否只有一个驱动端并且这个驱动端必须是关断域逻辑 cell 的输出 pin或者直接连到关断域的端口。脚本本身不复杂几十行 Tcl 就能跑完但可以在后端优化后的每个阶段快速扫出“ISO 前出现普通 buffer”这类问题不用等到功耗 signoff。# 伪代码思路 foreach iso_cell [get_cells -filter is_isolation_cell] { set in_pin [get_pins $iso_cell/ISO_IN] set driver [get_drivers $in_pin] if {[llength $driver] ! 1} { report_issue multiple driver } if {[get_attribute $driver base_cell_type] ! isolation} { report_issue unexpected driver at ISO input } }注意脚本里要排除 ISO cell 本身、电源域端口驱动、以及合法的 level shifter。每个工艺库的 isolation cell 命名规范不同用is_isolation_cell或者base_class isolation这类属性来识别比硬编码 cell 名靠谱得多。另外在功耗分析阶段不要只盯平均功耗。如果有 SPICE 仿真条件建议挑几条典型隔离边界路径做浮空态仿真观察关断后 ISO 输入级的穿通电流。没有 SPICE 条件的话至少在做 leakage 分析时用最悲观的状态建模把悬空节点设成中间电压对比正常状态的漏电量级可以快速暴露异常路径。4.3 常见误区和避坑清单把实际项目中反复出现的误区整理一份清单第一不要为了修 max transition 在 ISO 输入端加 buffer。修 transition 的正确手段是加大源端驱动、优化布线长度、在源端附近加 buffer而不是在边界关卡前面塞一个注定掉电的单元。ISO 输入悬空造成的问题比 transition 违例本身严重得多。第二不要盲目相信综合工具有能力把额外 buffer 优化掉。如果综合阶段这些 buffer 还不是 dont_touch工具可能会吸收一旦进入后端物理优化阶段碰到 dont_touch工具动不了问题就僵住了。所以从源头就要保证边界 net 是干净的。第三不要用 dont_touch 掩盖问题。我看到过不少工程师为了快速通过一轮 timing把一条路径上的 buffer 全设成 dont_touch这种操作会冻结整个逻辑锥的优化空间让后续所有工具迭代都失效。合理的做法是定位具体违例的物理原因再针对有限的单元做调整。第四要区分 ISO 输入侧的不能插 buffer 和 ISO 输出侧的可以插 buffer。如果把这条规则记成“ISO 附近不能有 buffer”那你会在 ECO 时错过一个可行的修复选项。输出侧 buffer 属于常开域不会浮空是可以正常使用的。第五UPF 和网表的对应关系要严格一致。库里的 isolation cell 有时同时提供输入隔离和输出隔离两种模式工具根据 UPF 的 applies_to 属性选择对应结构。如果你自己手工插入了普通 buffer很容易让工具误判这条路径的电源域边界导致后续 cluster 和布局出现问题。第六注意多电压域边界上的 level shifter。level shifter 本质上也属于边界单元但它和 ISO 不同它的输入输出分别属于两个电压域工具会自动识别。问题在于有些库里的 level shifter 带 enable 或者带隔离功能命名方式和普通 ISO 很像检查脚本如果不去重容易在统计时误报。最后说一个投入产出比非常高的习惯。每次 ECO 或者 RTL freeze 之后花十分钟跑一遍隔离单元输入侧的结构检查再花十分钟人工 review 两条典型边界路径的网表结构。低功耗设计里很多问题都不是从大流程能看出来的恰恰就在这种“看起来没啥问题”的边界 signal 上。半年以后再回头查漏电路径你会感谢当时多做的这次检查。