从定义阶段到设计阶段再到后端部分,我们整个硅前的流程都是将芯片按照层次划分的,一般我们称之为芯片系统级(chip level/system level)、子系统级(sub-system level)和模块级(module level/unit level),这种层次划分的方式对于芯片的好处有哪些呢?
1.便于拆解功能模块,实现人员的并行工作协同,这一点是从项目执行效率出发的。
2.对于系统定义而言,这是从主要的功能、性能要求量化为系统不同模块定义的方法。
3.从设计和验证角度出发,合适的复杂度模块也有助于估计合适的工作量和人员分配。设计最终是通过模块化来集成的,而验证的环境在模块化以后,也可以方便在更高级的验证环境中复用。
4.对于后端,在进行了合理的区域划分后,模块和SoC可以并行进行后续的物理设计流程,在每个设计阶段再合成进行相关电源设计、时序分析等设计项检查。基于模块化的设计最终再进行SoC级别的设计检查并通过流片要求。
如果我们是在为一款手机设计通讯芯片,那么如图显示,一开始系统定义阶段可能要规划出来这么多的功能模块,而且还需要考虑模块的性能因素。每一款芯片都会包括多个子系统,而每个系统也会包含多个功能模块,从举的这款手机通讯芯片来看,他包括的功能子系统有:
l 处理器子系统对于核心模块调制解调子系统来看,其中的2G/3G/4G又因为自身的复杂性依次提高,可以进一步作为独立的子系统来对待,进而细分下去。所以,如何划分层次,我们一般会从如下几个角度考虑:
l 协处理器系统
l 本地存储系统
l 外部存储控制器系统
l 数据接口系统
l 系统模块外设
l 多媒体子系统
l 调制解调子系统
l 系统的复杂性:如果该系统相对独立,那么它自身有作为子系统的条件。如果它本身任然过于复杂,可以进一步细分。在这里,我们将主要从验证的角度来考虑,如何选择合适的验证层次到下面不同的验证环境中:
l 芯片集成的便利性:对于顶层芯片继承而言,应该一个合适子系统应该与外界应该有清晰的功能边界,例如系统信号边界、标准总线边界、与其它子系统交互的边界,同时这些信号边界也尽可能保持稳定和精简,这是从顶层集成的工作量和后端布局布线的角度出发的。
l 验证的阶段:验证人员需要清楚哪些功能点在模块级验证、哪些属于子系统和芯片系统、是否有必要在不同级别重复验证、最终各个层次是否会保证验证完备性。
l 后端的流程:如果一个子系统占到了芯片整体面积的10%以上,那么后端就没有理由不考虑将其单独做综合,因为这样子系统综合有助于后期整个芯片综合的收敛速度。
1.模块级(block level/unit level)模块级
2.子系统级(sub-system level)
3.芯片系统级(chip level)
4.硅后系统级(post-silicon system level)
如果是图中的处理器子系统,我们会考虑先将DMA(direct memory access)、cache缓存、和core0/core1分别展开模块验证。每个模块验证首先要考虑的是哪些功能点是可以在模块一级完全验证的,这基于如下考虑:
l 内部功能如状态机验证同时我们也需要考虑哪些功能无法在模块一级被验证到:
l 内部数据存储验证
l 数据打包功能、编解码功能
l 指令执行
l 寄存器配置
l 与其它相邻模块的互动信号这些部分我们需要考虑在更高的层次来验证他们。
l 与其它子系统的互动信号
l 与芯片外部的互动信号
l 与电源开关的验证
子系统级
对于一个成熟的子系统而言,它既拥有完备的功能可以执行专门的任务,也有足够稳定的接口用来在更高级做集成。与模块相比,子系统更稳定也更封闭,这对顶层集成是有好处的。也正是这种便于集成相对封闭的特征,我们可以从公司外部或者内部得到不同的子系统。合格的子系统交付不单单包含着它的设计部分,也应该包括如下:
l 设计包完备的交付才会增强顶层集成的信任,同时减少在集成过程中发生的一些接口理解分歧和参数化配置问题。
l 验证包
l 递归测试表
l 覆盖率收集脚本和数据
l 完整的文档(设计、验证、集成、后端)
那么单就验证而言,除了充分验证内部功能以外,对于子系统的外部接口如果存在参数或者编译预处理(compiler directive)时,验证人员需要就这些参数和不同的编译选项(可能因此产生不同的硬件结构功能)给出完备验证。因为从子系统的封闭性和复用性来看,它们会在多个芯片项目中被使用,这对于设计复用来讲是一件好事,而验证也需要将验证环境参数化来适应硬件的参数化配置。只有充分验证了参数化的子系统,才可能让它在不同的芯片项目中都能够按照预期实现它的功能。
对于验证管理而言,子系统验证也是一个理想的可以切分的单元,因为这一层下面的模块之间互动很多,而这一层本身又趋于封闭,也即是与外围的接口有限,所以便于在子系统层建立验证小组——包产到组。
芯片系统级
在芯片系统级,我们的验证平台的复用性较高,这主要是因为:
l 外围的验证组件不需要像模块级、子系统级的组件数量多且经常需要更新,它们主要侧重于验证芯片的输入输出在芯片系统级的验证侧重于不同子系统之间的信号交互问题,以及实现更贴近实际使用的用例。这里的实际用例并非是在系统软件层面的,而是将系统软件层面的场景进一步拆分为多个模块互动情景,再分类测试的。
l 芯片内部的子系统之间的交互、协作检查主要交给了处理器和子系统,从寄存器检查和数据检查入手,写直接测试(directed test)用例
硅后系统级
尽管我们硅前验证部分与硅后系统软件开发联系较少,但是如果可以尽早将硅后软件开发的实际用例在硅前测试,也能够可以发现一些实际使用中的问题。实际上,系统软件用例和硅前的随机测试有着互补的特性,对于功能验证上面缺陷的理解是,如果没有被硅后测试、软件开发、用户使用的过程中发现,那么隐藏的缺陷也会永远静静躺在那里,也许永远也不会被发现(没有零缺陷的芯片,却有用户没有发现缺陷的芯片)。所以,如果可以将硅后的驱动、固件和系统软件尽早在硅前就引入验证过程的话,这可以跟硅前的验证方法形成互补,使得验证更加完善。
我们上面介绍了验证的四个阶段,也给出了他们各自使用的测试场景。这里我们再给出几点可以遵循的原则帮助大家选择适合的级别来进行验证:
1.如果更低的级别可以完成某一项功能验证,那么就不要在更层去验证它。因为更小的验证环境更有利于控制激励场景的产生,更加全面的覆盖功能点。
2.如果低层次已经充分验证过某一项功能,那么高层次不需要重复验证。而对于低层次无法完全覆盖功能点验证的时候,应该在高层次完全覆盖。
3.如果是低层次的验证阶段,应该适当地考虑高层次的测试用例,而在低层次创造一些条件来进行模拟发生。
4.如果是高层次的验证阶段,验证环境中的参考模型、数据比对、监视器等模块首先考虑从低层次环境复用,在无法满足的情况下再考虑重新构建。
5.如果是新的模块或者新的功能,应该投入更多的精力和优先级在不同层次充分验证。
最后,我们通过一张列表来更好的理解,不同的验证层次的验证侧重、性能、使用方法:
懂得选择一个合适的验证层次,并且通过在不同层次分配不同的功能验证点,是最终迈向验证完备性的一项必备技能。
来源:Robei