最近和做无线基带芯片验证的一个朋友讨论比较多,他提的一些问题让我有点头疼,虽然很多我曾经遇到过,并且自认为已经解决的。我现在不得不重新思考,而且要思考得更深入一些,因为现在不止是要自己理解,还要让他,以及他的team里的算法工程师、设计工程师认可。确实是个很好的锻炼。
朋友的设计简单说就是无线基带常见的操作,包括相关、累加、峰值搜索等,我曾经建议他多使用随机数作为激励,再辅以特殊的testcase,对相关器饱和、截位等操作进行验证。在芯片输入端用随机数作为激励的好处是,覆盖比较全面,数据的产生也比较容易(即便没有specman和vera,只用HDL语言也是如此)。在自检查testbench(self-checking testbench)中,激励通过施加在DUT(待测芯片)和RM(reference model,参考模型)上,通过编写自动比较代码,可以验证各种数据激励下,DUT的行为是否正确。另外再加上特殊的testcase对饱和、截位等情况进行验证的原因在于,完全随机的验证可能很难击中(hit)某些情况,例如对于相关器,只有相关上了,才会输出一个较大的数值,如果后面有截位电路,此时截位电路才会动作,而完全随机的验证,相关上的可能性几乎为0,因此需要针对性的验证。其实,两者之和相当于约束随机验证(constaints driven verification),这是用specman和VERA的工程师必定会使用的方法。
朋友提到,系统工程师说用完全随机的12位有符号数作为激励,因为这样的激励不满足特定的相位和幅值关系,那么不就成了完全的噪声信号么?这么做有什么实际意义呢? 当时我不知道怎么解释才有说服力,不知道怎么回答。
我也曾经被别人问过这个问题,要对方理解确实不容易。如果那位系统工程师把我们的验证策略理解为“只用随机数进行验证,不能完全说明问题”,我是赞成的。但是如果他的意思是“所有testcase都应该是有实际意义的”,我就不完全同意了。
验证的对象常常可以分为控制流为主的设计,和数据流为主的设计,前者包括UART/I2C/PCI/DMA Controller等,后者主要是无线基带、图像、语音处理等,两者的验证思路有较大的不同。控制流为主的设计要实现全面的随机验证是比较困难的,因为涉及很多的控制信号,时序上需要协调的事情也很多,因此可能需要结合芯片真实工作情况,加以分类,然后对各子类进行模拟和随机验证。数据流的验证相对容易一些,主要是输入数据的不同,工作状态是基本一样的,验证时,在不同工作模式下,输入尽可能多的随机数就可以实现数据通道的验证。举个极端的例子,假设我们要验证一个乘法器,那么最简单的做法就是输入随机数,然后检查输出结果是否正确,跑上足够多的数据之后,再加上边界情况的测试(例如0×0等),就可以判断设计是否正确,也不需要过多的关注输入数据的实际意义。
假设我们要验证一个FIR低通滤波器,大家都知道FIR滤波器内部主要是乘法和加法电路,假设这个电路是RTL工程师根据算法工程师给出的定点算法“翻译”后设计出来的,那么我们怎样验证这个电路呢?简单来说,第一个方法是输入带噪声的数据,然后对输出结果做频谱分析,看看噪声是否被滤除了;第二个方法是输入随机数到DUT和参考模型RM(当然RM要通过某种方式和定点算法链路进行校准,保证两者的一致性),然后比较两者输出的每个bit是否一致,重复足够多次。如果二选一,我会选后者。前者固然有直观性,但是如果其中有几个数据错了,从频谱上是看不出来的。因此,很多时候有实际意义的数据对于提高了判断正确性的难度。
对于图像处理,用一幅带有噪声点的图像作为输入,然后观察处理结果,或者对无线基带芯片,用在某具体位置有径,然后看看芯片能否找出该位置的径,这种验证方法可以作为辅助手段,用于增加信心,但是不能说明设计的正确性,除非构建足够多的这种有实际意义的数据,这个工作量往往大得惊人。而且,这样大的工作应该在算法仿真平台已经做过,功能验证平台来做这个事情,一个是速度慢,第二是重复劳动。数据通道为主的设计,我觉得要以随机验证为主,思路是,定点算法保证性能,功能验证保证RTL代码功能和定点算法链路一致,最后通过FPGA测试或样片测试检验性能。