我给大家讲一个有关功耗的bug。
那是我在前东家所参与的第一个重点的芯片设计项目。那个项目之初的设计目标就是低功耗,当时市面上竞争对手的最低休眠功耗在1.1V电压下可以做到1uA,但是他们用了较为旧的工艺,所以芯片面积大。而我们选择了更新的工艺,面积可以减小一半多,但是由于新工艺的漏电流较大,经过初期的估算,我们的目标是接近1uA。最后在前端设计完成后,用PTPX后仿真的结果就是1.5uA。老大觉得达到了预期,于是就送出去流片了。
芯片回来后bring up,在基本功能正常, 无线收发的指标都达到预期之后,组里的老板,director,甚至部门的VP就关心一个东西:休眠状态下的静态功耗。当我们满怀期待地接上电流表之后,电流表稳定在了6uA,是预期值的整整4倍,足足大了4.5uA!换了5块板子,都是这个数,换了socket 板子,再测了三四颗芯片,都没有比6uA低的。这可要了命了,我们的芯片主打就是面积小低功耗,现在这功耗简直被竞争对手吊打啊,director下了死命令,必须在下一次流片之前把问题找出来,而下一次流片就是量产流片了。
组里所有人开始行动起来开始找原因。我并不是always on模块的设计者,但是是我跑的PTPX仿真,我于是先又跑了一遍仿真,重新检查了各种设置,没有发现任何问题,仿真就是告诉我是1.5uA。同时跑其他非休眠状态的仿真,仿真功耗值和实测值可以对得上,证明设置是正确的,工艺库的值也是准确的。
接下来怀疑是板子上哪里有漏电或者是板子设计的问题,但是经过将近一周的重新排查,PCB板设计并没有问题,那么就是芯片内部的问题了。
always on模块的设计者也和大家重新review了design,各种猜想被提出,但是又各种被实测否定。比如说,猜测某个isolation cell没有插入对,于是我们和模拟团队坐在一起,把上千个信号又一起review了一遍,最后发现都是正确的。类似这样的头脑风暴几乎每天都在进行,每次大家满怀希望以为找到一个合理解释,但是最终都是失望而归。
这里要和大家讲述一下silicon debug的难度。 软件debug通常有日志,有调试器的帮助,单步运行足以找出绝大多数bug。但是小小的芯片就难了,封装好的芯片还没有小拇指甲盖大,上面的引脚比头发丝也粗不了多少,GPIO一共也就二三十个,每个IO后面能mux出来的信号也是有限的几个,要是动态的信号好歹可以利用示波器和逻辑分析仪看波形,但是这种静态功耗的debug,示波器和逻辑分析仪也只能抓瞎。我们测算过,4.5uA说大也大,说小也很小,一个transistor短路就足以引起这么大的short circuit current,可是小小芯片里面几千万上亿个transistor,找出这个无异于大海捞针。
大海捞针也得捞啊,在我们大家都想不出其他解释之后,老大批准了给芯片照热成像和FIB。给芯片照热成像是啥意思,因为芯片在运行的时候是有功耗,那么在有电流流过的地方就会有功耗,那么相应的温度就比周边稍稍高一点点,这个时候用专用的热成像仪照一个照片,只要看到哪一个地方比其他地方红一些,那么就大概可以定位出功耗大的区域,然后再在layout上找到那片区域对应的模块。
![](https://img.jasve.com/2024-4/9a09b2c68e061a0013dded820fd34834.webp)
但是照回来的结果是,热成像分布非常均匀,完全看不出有哪个地方过热。想想也是,4.5uA的电流,换算成功率也就是几uW,太难了。
然后又在几个怀疑的点做了FIB,简单说就是把封装打开,在die上面重新用仪器去把metal wire断开,这个因为难度高,做一次就要好几千美金,我们前后做了好几次,每次都是没有效果,上万美金就这样打了水漂。真是心疼啊,我们几个年终奖加起来也不到这个数。
这样大概折腾了2个月,下至工程师,上至director,我们都觉得要放弃了。只能猜测是厂家工艺的原因,随着量产芯片tape out日期的临近,我们只能寄希望于下一批次回来的芯片能够功耗第一些。
直到有一天,我和另一个项目的后端工程师一起开会,review placement 和 critical timing path时,他给我们看了当前的placement, 我发现standard cell之间还有一些空位,就像下面这个图, 所有的单元应该是按行摆放,但是中间会有空位。
![](https://img.jasve.com/2024-4/53f33140fc26c004ea4e462a6dfde655.webp)
于是问他们这些空位要怎么处理,他们说要放decap cell 和filler cell. 我之前知道filler cell是用来填满空隙的, 可以去平衡metal density,可是decap cell是个什么东东?这玩意有功耗吗?开完会立马打开lib文件一查,我擦,decap cell这玩意居然是有leakge power的!而且x2, x4, x8 (就是不同大小)的功耗也是不一样。 我隐约觉得自己发现金矿了!
于是检查后端给我们的netlist, 没有filler cell, 没有decap cell!难怪前端功耗仿真偏小,因为这些cell压根就不存在。在后端给前端返回netlist的时候,因为decap cell和filler cell属于没有任何功能,没有任何connection的cell, 他们通常的做法是在写出netlist的时候不包括这些cell。 于是我们重新让后端写出带这些cell的netlist, 再跑功耗仿真,非常准的6uA, 问题解决!
进一步分析表明,绝大多数的decap cell被放置在了always on的区域。这里面插一句,现代SoC低功耗设计的一个常用方法是将芯片划分成不同的power domain,有的power domain可以开可以关。在关闭的时候连power都关掉,这样连漏电流就都没有了,是最省功耗的做法。但是芯片睡眠后必须有一部分电路还是工作的,准备随时唤醒整个芯片,这一部分always on的电路因为power rail不同,在版图上通常是划定一个特定的区域。我们的芯片由于always on逻辑很少,这片区域function cell比较稀疏,而后端在放置decap cell的时候是全局铺放,当tool看见这部分空位比较多的时候,将大部分的decap cell都放在了always on区域里,这样引入了多余的4.5uA功耗。
这个bug坑的地方在于,前端拿到的netlist里没有decap cell,而我们前期也压根没有往这方面想,花了大量时间去检查看function上是不是有问题。