学术流片复盘(一):第一次流片复盘
在四月的尾巴终于把第一次流片交出去了。许多前辈曾告诫我流片如何困难,而想要请教却很难得到统一的回答。经过这一轮流片切身怯魅,积攒了一些浅薄的流片 know how 经验分享。
流片要见实物,而想要让数百万千万至数亿晶体管老老实实守本分工作并不是那么轻松。从算法到编译器到RTL到网表到GDS到电路板,庞大的工作量必须要分工合作;并且流片一批白银万两,创新点差了点顶多是降低一下文章档次,而流片失败则是彻彻底底打了几百万水漂了。
学术流片还有独特的困难之处:首先,主力军大多是学生,流片经验相对不足;其次,学生的核心诉求是发文章毕业,而流片对大多数同学在成本角度往往站不住,流片周期劳动力付出大于创新探索,不符合“小而美”“快而深”的实验室产出,文章挂名也是僧多粥少,导致学术流片往往集中在一俩个核心成员 cover 大部分流程,而流片又涉及多个环节的专业知识,极为考验核心成员的综合素质。
流片工程流程

完整的一次数字流片需要经过以上环节,其中大致根据随着时间项目进展顺序排序位置,蓝色表示更偏向软件设计、绿色表示硬件设计、黄色则是大量的验证检查。
这次流片后对流片特点总结如下:
- 流片难以进行持续开发
- 流片极其吃经验
- 流片磨片更磨人
流片开工前问问这三个问题评估流片可行性:“是否有清晰明确的设计方案?是否有至少一位具备完整流片经验的成员参与或指导?流片团队是否具有战斗力?”
流片难以进行持续开发
在前文博客中已论证架构工程的划分是一个 NP 问题,即使实现同一个功能,不同的模块划分方式会导致工程量差距极大,因此对模块接口的划分极其重要[1]。流片中最忌惮频繁变动,写代码容易维护代码难,并且对于多环节多人员参与的项目,变动带来的后果不仅是上下游全部迭代更新,并且版本混乱带来额外的管理困难。
最理想当然是前一个阶段彻底固定再进行下一个阶段,但时间成本有限,为了充分发挥人员效率往往需要并行开发。怎么能够在最短的时间内,付出最少的必要努力,将系统大部分固定下来?
RTL 是设计的最终手段
迭代会出现在于流程中存在难以预测的事件——必须要走到那一步才能获得相应反馈。但获取相同信息反馈的方法不止一种,比如要预测系统性能,既可以完成 RTL 设计得到网表过能耗仿真;也可以基于假设提取主要能耗,在 simulator 甚至 excel 中计算能耗。做出判断需要的信息精度需求可能没那么高,而获取信息反馈方法之间的实现成本天壤之别,尽可能让问题在项目早期暴露。其中以 RTL 开发最为关键,RTL 迭代维护成本极大,并且一旦 RTL 变动,后续所有综合后端都要相应变化,RTL freeze 是最为关键的节点之一。应当把 RTL 当作设计的最终阶段,而非设计的开始;应当寻求一切更加轻量的方法迭代验证系统设计,而非先写一版本 RTL 再迭代代码。
进一步将 RTL 开发分为架构设计和代码实现,前者回答怎样的芯片有学术创新价值,后者回答怎样具体实现这样的系统,甚至评估实现的复杂度。
- 架构迭代可以通过 simulator 探索,比如 AI 芯片主要性能开销集中在数据流上,即使不考虑相对复杂的控制流,分析精度也足够精准,如果系统 software-hardware codesign 创新点很重要,且必须要借助更具体细节才能评估,尽量在早期完成虚拟原型和软件栈编译器,不然到写测试环节也要吃亏;
- 实现迭代要重视写 SPEC 文档的环节,特别是接口的信号定义和时序逻辑,写 SPEC 的时间应当和 RTL 设计在一个数量级甚至更多;
- 此外遵循 top-to-bottom 的方式设计,迭代中增添模块可能都会引发蝴蝶效应导致整体接口逻辑变动。
行动前评估实现复杂度
即使确认系统功能准确可实现,也要控制保证实现复杂度在时间-人力的限制范围之内。不然 RTL coding 中经常出现:“脑中明明已经有这个电路了,但为何迟迟工程推进不出来?”的奇怪现象。在文档阶段无法预料到的实现困难主要集中在复杂的控制流,这里分享一套根据接口时序半定性评估实现复杂度的方法。
硬件开发难处在于同时可能存在交互关系的变量太多,举几种编程模式对比。(1)理解难度最低是单线程编程。序列性的单线程编程满足人脑对文本的处理逻辑,过去创建的变量对程序员不需要考虑,而在执行上靠内存回收机制“遗忘”。程序员仅需要考虑比较短上下文内部的变量交互逻辑;(2)再难一点是并行程序开发,程序员不仅需要考虑单线程上下文窗口内的逻辑交互,也需要考虑线程之间同步交互,当然较远历史变量大部分同样可以利用回收机制;(3)而最难的是硬件开发,硬件开发一个信号就是实打实的一个变量,生存周期贯穿整个功能,并且包含各类模块之间并行的交互。[2]
| 编程模式 | 空间:并行变量交互 | 时间:上下文长度 | 
|---|---|---|
| 单线程编程 | × | 短,历史变量靠内存回收机制 | 
| 并行编程 | √ | 短,历史变量靠内存回收机制 | 
| 硬件开发 | √ | 长,贯穿功能 | 
因此硬件开发可以粗糙通过信号数量大致衡量系统实现复杂度,需要考虑的信号数量和实现复杂度并不是线性关系,一个 100 接口的系统实现难度要大于 10 个 10 接口系统实现难度。并且显然同构的设计并不增加系统复杂度,实现 100 个加法器和实现 1 个加法器没有什么不同。具体来说要衡量信号对设计复杂度,也就是其涵盖的信息量的多少。如果两个信号有同步关系,应该认为是一种信号,比如信号A工作时信号B一定工作,信号A不用时信号B一定不用;同步的一组信号,如果存在不同延时也要考虑相应的复杂度,比如 SRAM macro 读时序,地址和使能在同一个周期给出,而数据在下一个周期读出,这要分作两种信号来考虑。
在本次流片中,早期系统控制流花费两周仍然没能实现跑通,后评估实现复杂度过高,牺牲硬件资源重构架构后,仅仅在一个周末内实现了系统控制流。
流片极其吃经验
流片中存在着大大小小的坑,而半导体行业又极其封闭,发展这么多年了甚至很难找到一篇完整介绍流片的教程或者书籍。很多困难并非能力而仅仅是单纯经验的差距。又因为流片中经常出现各种奇奇怪怪难以追踪的问题,使得半导体颇有“老中医”或“规则怪谈”的味道,过往的经历具象为了一条条操作规范,只能说遵循这样做比较保险,但究竟这样做会出什么问题难以说清。这也是流片不得不品的一环。
将本次流片遇到的问题总结如下,其中特别要谨慎出现问题源头和发现问题环节间隔过长的问题,这些问题早期隐蔽,极大可能导致项目在晚期被迫重新迭代更新:
| 规范 | 出现源头 | 不会发现问题环节 | 发现环节 | 
|---|---|---|---|
| 代码不可综合 | RTL 编程 | RTL 逻辑验证 | 综合、Spyglass RTL Sign-off | 
| 浮点方案 | RTL 编程 | RTL 逻辑验证 | |
| 寄存器使用异步复位+复位值 | RTL 编程 | RTL 逻辑验证、综合、Formal Check | 门级网表验证、物理网表验证 | 
| 常量限定位宽 | RTL 编程 | RTL 逻辑验证 | 综合(具有隐蔽性) | 
| 激励数据信号边沿和伴随时钟边沿错开 | 建立测试环境 | RTL 逻辑综合、无延时网表验证、STA | 物理网表验证 | 
说明:
- 代码不可综合: 大部分同学第一版代码都会存在这个问题,在培训的时候要特别强调,或者采用分而治之分模块综合;
- 浮点方案: 浮点计算不满足交换律,涉及浮点计算要特意留意虚拟原型的浮点计算方案,比如 torch 默认 bf16 累加在 fp32 中完成。此类差异会导致虚拟原型和硬件设计无法对齐;
- 寄存器使用异步复位+复位值: 如果一个寄存器下一个周期的值和自身上一个周期有关,比如 counter <= counter + 1'b1;,此时某 fab 标准单元库 verilog 建模 + VCS 环境下无法正确仿真未定态传播,导致仿真出错。若同步复位复位端会从 Dff 的 D 端传入无法正确复位,导致无法进行后仿环节。这种寄存器必须使用异步复位生成带复位的 Dff 单元才能仿真通过;或者在激励中手动给寄存器赋予初始值,但这极大增加了工程量和复杂度;
- 常量限定位宽:Verilog 标准中规定未注明位宽的常量为 32bit,a = -1 * a使用 DCcompile综合时生成了一个 32 bit 比特的乘法器导致时序违例,使用compile_ultra可能可以避免,但无法说清 DC 综合过程中是否受此影响,应该从源头上避免这种坏习惯;
- 激励数据信号边沿和伴随时钟边沿错开: 伴随时钟即时钟信号和数据信号一起通过 IO 打入, 很多标准单元对上升沿和下降沿的延时不一致,如果数据变化边沿对齐时钟采样沿,会导致某种电平信号脉冲少于一个周期进而无法正确被同步电路采样,需要在激励中将信号边沿错开时钟采样边沿,最极端是错开半个周期,当然这样可能会引发 setup 违例
此外还有 IO 太密导致封装 DRC 违例,需要提前和封装厂商量是否能做;控制流设计对打拍参数化方便 STA 违例修时序等等。但可以写成规则的坑踩过一次就可以避免,更多的坑是要决策者在项目远远不如预期的条件下,评估现状,果断大胆抉择调整方向。
流片磨片更磨人
流片逃离不开多人合作,既然学术流片存在流片工程难度和人员吃紧的核心矛盾,流片遇到各种乱七八糟的困难基本是百分百发生,并且流片是工程机械化的劳动成份占据主流,很容易让人感到乏趣枯燥,此时便更加考验团队的战斗力。学术小规模团队合作经验如下:
- 小规模团队建议按模块分工而非按环节分工,将设计和验证耦合,每个人负责一个模块的完整流程;
- 流片需要保证人员 full-time 参与,流片周期长,困难杂,在各个阶段都需要高度交流合作,人员变动十分影响项目推进;
- 核心成员保持战斗力和信心。
总结
这次流片挑战对我来说主要是工程和管理的挑战。工程的问题经过一次流片已能鼓起信心面对下次流片,可管理上却没有信心下次能够做得更好。以往学习研究,大多都是单打独斗,单打独斗也足够了,多人合作也大都是些无关痛痒的比赛,试错成本较低,这是第一次项目管理如此重要。
一方面挑战是工作方式的变化,和供应商外包商对接、内部流程汇报、对接各个成员进度,还有自己负责的部分,思绪很容易就在各种微信消息和邮件中迷失了,回复各种消息往往一天就过了大半,算是切身体会了异步系统的复杂性;
另一方面是流片的心理压力,几乎每一个节点都落后于预期,作为领导者看到的信息最多,也最了解问题的困难,常常感受“项目要做不完了,想放弃”,可一旦自己表现出泄气,必然影响整个团队的斗志,进而导致担心的事情真就发生了。半夜经常失眠,十分考验磨练心性。

好在虽然有不少遗憾,也算是完完整整走完这一次流程。特别感谢整个团队的支持以及关键时刻给予指点帮助的前辈们。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号