1. 从一次LVS报错说起:那些让人头疼的端口不匹配
最近在跑一个28nm工艺的项目,LVS验证的时候,报出来一大堆让人头皮发麻的端口不匹配错误。错误信息密密麻麻,核心问题都指向标准单元库里的那些小管子——它们的bulk端口,也就是我们常说的“体”或者“衬底”连接,在网表里要么是没声明,要么是连错了。这可不是个小问题,LVS卡在这里,后仿、时序签核全都进行不下去,项目进度一下子就亮起了红灯。
我一开始也纳闷,这版图明明是按照设计规则来的,自动布局布线工具也没报错,怎么到了物理验证这一步就出幺蛾子了呢?后来把source netlist和layout提取的网表拉出来一对比,真相大白。问题就出在标准单元的抽象视图和实际物理视图的“信息差”上。我们做数字设计用的标准单元库,为了追求面积最小化和工具处理效率,在给APR工具用的LEF文件里,往往只声明了电源、地、输入、输出这些功能性的端口。那个对数字功能“看似没用”的bulk端口,经常就被省略了。但是,LVS工具可不管这些,它眼里CMOS晶体管就是个标准的四端器件:栅极、源极、漏极,还有这个bulk端,一个都不能少。两边信息对不上,端口数量都不一致,这验证自然就失败了。
这其实就是我们今天要深入聊的核心矛盾:前端设计流程的抽象化、高效化需求,与后端物理验证的精确化、完整化要求之间的冲突。bulk连接,这个在数字设计里常常被“隐藏”起来的端口,恰恰是保证芯片物理上正确工作的关键。它就像房子的地基,平时看不见,但地基要是没打好,整个房子都不稳。
2. 追根溯源:为什么std-cell的bulk连接会“消失”?
要彻底弄明白这个问题,我们得从标准单元库的物理实现说起。现在主流的CMOS工艺,基本上都是在P型衬底上做的。你可以把整个芯片的硅片想象成一大块P型的“蛋糕胚”。在这块胚子上,我们要制作两种晶体管:NMOS和PMOS。
NMOS是直接做在这个P型衬底上的。所以,每一个NMOS晶体管的bulk端,本质上就是它所在的那一小块P型衬底。由于整个芯片的P型衬底在物理上是连成一片的,那么所有NMOS的bulk端,在物理上也是天然连在一起的。为了给这个庞大的P型衬底网络提供一个稳定的电位,我们通常会把它接到芯片的全局地线VSS上。怎么接呢?就是通过一种特殊的单元——TAP Cell。TAP Cell就像一根“探针”,垂直地插入到标准单元行里,把P型衬底和金属层的VSS线连接起来。
PMOS的情况稍微复杂一点。它不能直接做在P型衬底上,需要先做一个“N型阱”。你可以把这个N阱想象成在P型蛋糕胚上挖个坑,然后倒进去N型材料。PMOS就做在这个N阱里面。因此,PMOS的bulk端,就是这个N阱。同样,为了给N阱提供电位,需要把它接到电源VDD上,这个连接也是通过TAP Cell来完成的,只不过连接的是VDD。
理解了物理结构,我们再来看设计流程。为了最大化利用面积,现在的标准单元库普遍采用 “tapless” 设计。意思是,标准单元本身内部不包含TAP结构,它只提供有源区和晶体管。TAP Cell被设计成独立的单元,由布局布线工具按照工艺规定的间距(比如每隔10个或20个标准单元)插入一行。这样做的好处是,标准单元的面积可以做得更小,因为省去了TAP的区域;同时,TAP的分布可以由工具更智能地优化。
矛盾就在这里产生了。对于布局布线工具来说,它从LEF文件里看到的标准单元,就是一个没有bulk端口的“黑盒子”。工具只关心如何连接它的电源、地和信号线。至于bulk,工具认为那是通过物理上插入的TAP Cell,在版图层次自动连接好的,不需要在逻辑网表里体现。因此,APR工具导出的网表,无论是Verilog还是VHDL,里面标准单元的实例,都只有两三个端口(输入、输出、可能有的使能端),加上VDD和VSS。bulk端口,彻底“消失”了。
但是,当我们进行LVS验证时,工具会从GDS版图中提取出实际的晶体管及其连接关系。在提取出的网表里,每一个晶体管(无论是NMOS还是PMOS)都会老老实实地带着它的四个端口,包括bulk。这时,LVS工具左手拿着“残缺的”前端网表(没有bulk),右手拿着“完整的”版图提取网表(有bulk),一比对,端口数量根本对不上,立刻就会抛出大量的端口不匹配错误。
3. 手动补丁时代:那些年我们用Perl脚本踩过的坑
遇到这个问题,早期的工程师们是怎么解决的呢?最直接、最“暴力”的方法就是:手动修改网表。既然前端网表缺了bulk声明,那我们就给它补上。具体操作起来,大概分这么几步:
