绪论
经过了前面的文档、编码、验证阶段,我们手头已经有了没有错误的RTL代码。这一章我们把这些RTL代码转化成后端的输入:网表(Netlist,综合工具自动将RTL翻译成与或非门,用于实现)。这个步骤主要是有工具来完成的,我们知道流程就行。
说是实现,其实包含了DFT (Design For Test)三板斧的插入、DC综合以及形式验证。算是芯片设计里承上启下的一个流程。我此处把它归到前端里了,也有归到后端的,或者单拎出来让DFT工程师专门做的。插句额外的话,此处只是简单列了DFT的基本原理,实际上DFT也和验证一样是个有自己神奇而独特技术栈的活,有专门的工程师工种叫DFT工程师。
一 DFT-F1: 插入BIST
BIST(Build-in-self test)是内建自测试的意思。又分为MBIST和LBIST。
MBIST (Memory build-in-self test), 指的是存储内建自测试。这个原理上讲起来比较容易,就是在SRAM周边加上一些测试逻辑。Memory通常来讲在芯片中占据的面积比较大,也容易出错,所以加上专门的测试逻辑。这个地方需要区分MBIST和ATE (Auto-Test-Equipment, 我们后面讲芯片封装测试的时候讲)的区别,ATE的激励是外部给的,MBIST激励是自己生成的。而且MBIST可以每次芯片上电都测试一遍,防止芯片出错。
这个东西的工作原理如上图,在Memory周围加上激励,至于怎么加激励有人专门研究这个(MBIST Algorithm),感兴趣的可以学习一下。此外,还有一种Memory Built-in Self Repair (BISR)的办法,MBIST检测到Memory有问题后将有问题的cell映射到冗余的好的cell上去。
LBIST (Logic build-in-self test), 逻辑内建自测试。和MBIST同理,在关键逻辑上加上自测试电路,看看逻辑cell有没有工作正常。BIST总归会在芯片里加入自测试逻辑,都是成本。个人理解如果不要求稳定性非常好的芯片,LBIST可以不要。但是一些芯片,比如自动驾驶可能LBIST还是需要的。
一般来讲BIST用工具直接插到RTL代码里去,其实算是正常的交付功能。
二 DFT-F2: 插入Boundary Scan
这个boundary scan主要用来对芯片的输入输出(也可以是关键逻辑块,比如RISC-V核心)检测和测试,其实就是我们常听过的JTAG接口(JTAG有个很奇葩的名字,Joint Test AcTIon Group, 联合测试工作组 Orz)。
基本原理也简单,像上面这张图一样,把芯片的IO用寄存器链穿起来。JTAG端口虽然只有4个信号,但是能实现的测试功能非常多,可不是简单把IO串行拿出来看看这么简单。
上面一个小方块scan cell包含了下面内容。
里面包含了几个capture cell寄存器,用来把IO上的值给采下来。还有一个update hold cell, 可以把想要的值传给IO。
用法1:左上,直接bypass, 可以方便的把不同的JTAG CHAIN给穿起来。
用法2:右上,把IO穿起来,可以看IO的值,也可以外部给所有IO输入值
用法3:左下,可以当做串口,给上面讲的BIST输入控制信号
用法4:右下,Clamp模式,bypass和chain同时开了, 可以给IO置为,但是值从bypass输出。
JTAG也是直接加到RTL代码,当做一个功能来用。
三 DC综合
经过了DFT的两把斧,我们接下来要跑综合。综合的主要目的是把Verilog代码转换成门级网表。
DC是design compiler的意思,Synopsys的软件,当然也可以用其他厂商的RTL Compiler,不过我没用过不熟悉。DC内部主要实现了3个步骤:
·TranslaTIon, 单纯的把RTL转化成DC内部的数据库,这个库和工艺无关,就是标准的与或非等等。
·OpTImizaTIon, 这个阶段根据工作频率、面积、功耗来优化电路,然后生成满足设计标准的门级网表。
·Mapping, 这个步骤与工艺相关,将门级网表映射到代工厂给的门级网表上。
这个过程其实大部分都是工具来完成的,我们只用设置一些配置。
一共九个步骤。
step0 Develop HDL files. 这个步骤就是前面介绍了一大堆设计的Verilog文件
step1 Specify libraries. 这个步骤主要是指定一下需要的库文件。几个库文件都是干嘛的我们简单讲讲。link library指的链接的库,比如RAM, ROM core的库,一般放在link library. target library是代工厂给得工艺库,最后会把网表映射到这个库的单元上。symbol library可以不用,GUI用到的,synopsys library. synopsys的标准lib. 中间过程要用到。
step2 Read Design. 比较简单,把你的设计读到DC里面去。
step3&4 Design Constraint. 这两个步骤其实可以一起讲。给综合设置一些约束,比如时钟频率,允许的时钟不确定性等等。
step5 Compiler Strategy. 这个步骤主要是选综合策略。综合策略一般有两种,top-down, bottom up。top-down用来综合小模块,设计约束在顶层,当做一个整体一把综合了。bottom up一般用来综合大型的设计。先约束并综合底层,然后设置一个dont touch, 一层一层向上综合。
step6 Synthesis. 综合优化,主要占用时间的就是这一步骤。一般会在机器上跑几个小时到几天甚至几周时间。
step7 Report design. 这个步骤主要是报出综合的面积,时序,看看面积有没有超标,时序有没有违例,如果时序或者面积有问题,返回step0修改设计,重新来综合。
基本上的综合流程就这些。
四 形式验证:RTL vs SYN Netlist
做完了综合,我们还有做个步骤,到底综合对了没,等不等价,需要验证一下。这种验证叫形式验证 Formal Verification。有个工具叫formality的可以干这个活。简单理解这个步骤就是做等价性验证的。这个步骤比综合会快很多。这也可以理解,一个是从无到有的生成,另一个只是对比一下功能是不是等价的。原理大概是在RTL代码和netlist中抽取一些点(一般是寄存器的输入或者输出),验证组合逻辑的等价性。
如上面两个设计,使用的单元是不一样的,但其实功能是等价的。formality只能保证功能是等价的,但是保证不了STA不出问题。所以只能说STA没问题的情况下,formality能保证SYN功能正确。
五 DFT-F3:SCAN CHAIN
emmm 形式验证完后,还有一个DFT步骤。DFT的第三把斧: 加入scan chain. 这个步骤一般不加在RTL而是直接加在DFT网表。原理也很简单,把设计中的所有寄存器连接成一条或者几条链。
向上面这样。正常的功能数据走functional path, 在测试模式下所有FF都是移位寄存器,可以把值读出来看看。
当然,也可以把值插进去,看看某段组合逻辑有没有问题。
比如这样,先拉高scan enable, 用若干拍把数据load到寄存器里,然后拉低scan一拍,让组合逻辑算出结果,然后继续拉高scan enable, 把计算结果shfit out出来。
其实这里有个搞笑的事儿,研究生第一次流片的时候看到DFT scan chain,觉得这个东西贼有用,毕竟没有专业测试,一旦逻辑什么写错了,我岂不是可以自己写一段数据,直接shift到芯片里,看看哪里有了BUG,针对性的解决。那一瞬间,感觉自己像个小天才Orz…
后来知道一般设计中寄存器何止成千上万,即使拆成多条链,每条也很长。指望手动造一个scan数据来debug是不现实的。一般都是自动生成若干组pattern, 自动测试,如果输出和预期不一致,丫直接当做废片处理了Orz。所以不量产的芯片不用加DFT,加了也没啥实质性的用处。
DFT三板斧就讲完了。
六 形式验证:DFT vs SYN
最后再来一次形式验证。对比一下加入DFT的网表和综合出来的网表是不是功能一致的。原理和上面一样,无须赘述。
七 总结
经过这篇文章,我们终于得到了芯片设计的网表。行文至此,我们前端设计的所有流程就都讲完了。