我对验证的一些理解
下面这些问题和回答是基于我个人对验证(主要是动态仿真验证)的理解,可能有理解的不到位、理解有偏差的地方,欢迎大家指正。
我是synopsys的用户,所以下面描述的大多是针对synopsys的工具。
欢迎发邮件到lshj98115@sohu.com和我讨论验证的问题。
Q:验证的目的?
A:发现Bug,发现所有的Bug,或者证明没有Bug(转自夏晶的帖子)
Q:对验证工程师的要求?
Hacker mentality ,Organized testing ,Tool automation。
如何做更多的testcase、如何覆盖更多的测试点、如何充分的利用服务器、如何尽可能最大化的自动比对
强调一下:“注重细节”是验证工程师一个非常非常好的工作习惯。
Q:语言、方法学有多重要?
A:我的观点是:这两个都不重要。做事情的是验证工程师,来源是Spec,所以Testplan(全覆盖testplan)最重要。重要的是验证的意识,愿不愿意去实现H-O-T,即使一开始做的“土”一些也没关系。比如tb里经常要做的“自动比对功能”:1)维护queue,然后foreach的比较2)利用file-operation(fopen fread fwrite fscanf)来做文件比对3)直接$system(diff a b > c)以后看c文件大小。上述三种方法都可以(虽然2)会导致比较多的文件IO,硬盘读写会影响仿真速度,3)不能做实时的比对。不必拘泥于方法,关键是有这个意识。
Q:EDA行业对验证的支持?
A:个人感觉虽然(动态)验证这些年在理论方面的突破不大(静态验证一直是热点),但是EDA行业一直都很重视,实现类的工具主要是在做算法优化,这些年突破不大。但是验证方向上的点工具一直在不停的出(虽然最终可能也没有几个好使的工具),但是说明EDA行业一直在致力于寻求在验证上的突破。而且由于现在做SoC的太多,IP又太多,大家都是越来越重视验证,很多上规模的公司里验证人员较设计人员多不少。个人觉得这可能也是EDA重视验证的一个原因(用牛工具替代掉一些人LL)。
Q:如何跟踪缺陷?
A:可以考虑bug-zillar这类的工具---- 自动跟踪问题。
Q:作业提交系统(lsf或grid-engine)
A:充分和合理的利用计算资源。
Q:环境变量的管理?
A:个人推荐使用Module 工具。很多公司都是用这个免费的工具
Q:Testbench用到的编程语言?
A:我觉得tb里systemverilog和verilog是可以互相替换(当然了,systemverilog特有的内容用verilog来实现会很复杂),所以推荐tb基于systemverilog来搭建,一些仿真模型可以用verilog。C除了Cmodel以外,firmware也会用C和汇编写。
基本上我做过的项目里用到的语言:
脚本:perl、makefile、shell(perl用的很多,其他用的很少)
Tb(包括vmm的组件):基本是systemverilog
仿真模型:systemverilog和verilog混着用
Cmodel :C或C++
Firmware :汇编和C
Q:验证工程师需要掌握的基本技术?
A:分享一份我做的基本培训内容安排,供参考
Perl,Makefile,AMBA介绍,SVTB.pdf ,sva,几种用到的编程语言的File operation ,Low-power, C-pointer,Cshell-AWK+SED,体系结构相关的一些内容,SV-1Day training ,VMM_source_code ,Arm的嵌入式编程的基本概念
Q:自动化必须吗?
A:不是必须的,但是应该尽量去实现自动化。总之是多让机器跑。如果人均License太少的话,要尽量做到白天debug、晚上让机器跑。“比对”这种事情太机械了,所以尽量让机器做,做这种事情机器的效率比人高太多。把精力放在构造testcase、testbench、coverage以及debug和分析上。
Q:Testplan如何做?
A:形式不重要,xls可以、word也可以、txt的也可以。但是来源于Spec!testplan里除了要罗列function-test-piont,还应该有error-injection 和 random-test-point以及cover-point和assertion。
需要和各个team仔细逐条review testplan,有些针对具体实现的coverpoint可能只有designer能提出来,需要尽早提出。Tb搭建之前,要充分的review testplan,因为Testplan的较大修改有可能会导致整个testbench的架构调整,effort较大。Testplan是一个需要不停增加,不停迭代、不停review的东西。
Error injection要和RTL-designer逐条review,一个是看看RTL-designer是不是没有想到,一个是设计是不是本身就不允许、或者架构上本身不可能出现。Error-injection应该往深里去好好挖掘。例如:内存控制器长时间不回数据(这里本身是一个随机点)à由于长时间不回数据是否产生错误中断à产生错误中断以后如何响应à响应不过来如何恢复à必须用software reset做恢复的话,对software的时机是否有要求àsoftware前需要遵守什么要求和步骤
虽然现在有一些工具可以根据规范化描述的testplan自动生成cover-point和assertion,不过我觉得自然语言描述的testplan应该是最“自然”的。
Q:哪些地方做随机?
A:1)随机配置(一般都想得到的),但是对于一个封闭的系统常常是最不重要的,因为firmware可以自己开发,从而控制配置的流程和数值
2)随机激励数据(很重要)
3)随机时序(通常容易被忘记)
但是有一点要明确:随机不是全随机,是约束随机,是在合理的范围内尽量充分的随机。
Q:写约束随机哪些地方要注意?
A:推荐看snug paper。(over-constraint导致测试不完全,欠约束导致不必要的debug和资源的浪费)约束的效率:写的不好会导致随机失败
Q:Coverage如何做?
A:code-coverage和function-coverage(covergroup, assertion coverage)。对于constraint-random的地方用covergroup做,对于一些时序的coverage可以用assertion-coverage。
Q:核心脚本?
A:单个仿真的脚本 ---- 建立所使用的不同的目录、不同的seed(目录可以叫case_$seed这样的格式;当然对于直接的testcase,可以是case_$casename);环境变量和license的管理;如果需要做离线比对也可以让脚本来自动调用比对脚本或命令(也可以在tb的代码里使用$system或者$systemf)。
批量仿真的脚本----自动批量提交到lsf上。自动收集log信息以判断哪些case失败,对于失败的case能自动重新提交,并且自动dump波形。以及产生批量仿真结束以后的汇总信息。
Q:SV中重要的点?
A:特殊的数据类型,比如新增的三种array(动态、associate、queue)、string(match函数、backref函数,参考vcs的svtb.pdf);面向对象编程思想(handle);coverage;constraint-random。
熟练掌握这些语言点的用法很有必要。
Q:VMM 1.0够不够?
A:刚开始用1.0来建立起vmm的概念,然后转到1.1或者1.2上。个人觉得不是必须一下子就转到1.1或1.2上(当然,1.1的一些扩展宏的确很好用)。个人建议vmm1.0+1.1的扩展宏+subenv
Q:是否要使用VIP?
A:VIP的使用 --- 复杂仿真模型推荐用VIP,简单的建议自己做。如果自己开发仿真模型的话,也推荐看看VIP的文档,经常可以看到一些有价值的error-injection和random-test-points来完善你自己的testplan。
Q:要不要做门级仿真?
A:如果是走design-service,不知道最终带sdf的netlist仿真是否需要做,如果做的话,最好在release 综合后netlist的时候也做一下(插完scan-chain和做完CTS以后有条件也做一下),如果需要VCD文件做power分析和指导PR工具的话,那么门仿是必须做的。如果design-service公司不负责调量产pattern的话,那么ATPG等的门仿是需要自己做的。
门仿并不是sign-off标准,但是推荐还是做一下,经常还是能跑出问题来的。如果做sdf反标的门仿的话,对于async的多级dff要剔除掉(VCS和NC都有option,vcs可以查手册里“+optconfigfile”,NC查”+nctfile”)。反标Sdf仿真的时候推荐notimingcheckàno_notifyàchecking_timing with optconfigfile的三步走。
前期在评估IP的时候,有可能个别模块可能需要单独搭门级环境,比如CPU-IP有RTL,要自己做flow,那么通常是需要做门仿的(有可能主要是为了跑vcd或saif做power分析)。
Tb的修改:由于CTS和综合的原因,导致时钟名字和信号名字有变化,所以tb有可能要修改。另外,tb里的probe文件建议使用反沿采样,也是为了避免带sdf反标以后clk踩不到整个data-vector。除此之外,个人不太建议在门仿的时候依然使用自动化的tb。因为你的tb里抓的很多内部信号可能名字变了(或者被优化掉了),这样导致tb在门级跑的时候维护起来有些麻烦。有些信号即便名字不变,可能会反向,这样会导致你的checker误报错。毕竟在门仿的时候不用跑太多的testcase,可以靠几条和rtl仿真一一对应的仿真来覆盖。门仿毕竟不是为了function,而是为了检查timing。
如果你的设计里用了不带reset的dff的描述,由于开始不定态的传播,可能导致你门仿失败。个人推荐的方法是:如果特别多的话,用脚本找到对应模块里所有dff,产生一个force-release文件(注意:很影响编译时间,所以能不用就不用)
Q:FPGA和仿真如何安排顺序?
A:首先是schedule优先,其次是力所能及。但是原则上是先仿真然后再上FPGA,仿真可以很快的扫清一些基本的bug。给仿真的时间充裕的话,那就仿真尽量往前赶,尽量在上FPGA之前多测一些(不是太多case的情况下,FPGA的测试速度毕竟要快一些)。即便FPGA很着急上,起码也让仿真先用几条直接testcase调试通过最基本的功能。第一版FPGA可能因为接死、悬空和信号反向导致逻辑被优化掉,这些问题有时候用仿真也不能全发现,就要结合leda等lint工具。
Q:仿真如何复现FPGA发现的bug?
A:首先保证配置的一致性,可以考虑做一些内部的工具。仿真上要probe寄存器操作端口,FPGA上要能把firmware里的配置流程转成文本。
如果配置一样还是不能发现的话,再去逻辑分析仪上debug时序。当然,CDC的问题在仿真上是看不到的。
个人不建议做FPGA网表的门仿,有点得不偿失。
Q:FPGA不能cover的部分的验证?
A:PAD_Mux(Test_mux)、Clkrst、Power-management-unit 以及FPGA跑不到的高频所对应的功能。Clkrst这部分主要就是pll config、clock-gate、divider、soft-and-hard reset,从测试点的角度还是很明确的,RTL代码修改的少的话,可以考虑不用做太复杂的验证(但是clkrst模块里可能会有一些控制逻辑或者状态机,比如:sdram的切频,这里一般是需要一个状态机控制的,这个需要仔细和小心的验证。)
PAD_mux个人比较推荐使用自动化的流程,因为代码风格非常固定,所以可以用脚本生成RTL和用脚本生成testcase(一般这样的testcase是一堆的force)
PMU建议看看VCS的MVsim的文档,里面介绍的很清晰了。(还是要配合静态验证工具MVRC一起来做)没有MVSim的话,可以考虑用VCS的$power $isolate。
Q:固化的firmware如何验证?
A:个人不建议让仿真去覆盖firmware,但是对于FPGA和ASIC不一样的地方要重点覆盖到。大的流程要覆盖到,其他细节由FPGA保证。
Q:架构评估?
A:我经验也不多,举几个例子。比如你的总线拓扑合理不合理?内存控制器的效率(机制)是否满足你的应用?使用哪类Cache?Cache的大小?模块的FIFO深度够不够(error-injection可以测到)?算法需要多少mips(rvds等工具带的模拟器可以给出结论,但是要让模拟器能考虑到内存access的latency)?软件里如果有不少memcpy的话,要模拟系统运行起来以后memcpy的效率。
如果没有人手专门用ESL(如Carbon的CMS)工具的话,建议在验证平台上做(当然一旦有大问题,要推翻架构会很麻烦)。
Q:哪些资源要节省?
A:当然首先是人(数)要节省,人的成本比起计算资源成本和存储资源成本要大多了。提高技术、提高自动化程度才能节省人的成本。(低Package这种方法属于伤天害理的手段,不是正当途径)
减少硬盘需求(如果有必要) 共享simv/simv.daidir csrc(包括regression过程中自动清理磁盘空间);激励数据是否可以不一下子全产生出来(对于通讯类的比较有意义,由于是floating的激励数据,所以经常很短时间就需要GB的空间)。注意对每个人每个项目设置硬盘quota,避免被个别人撑爆存储。
减少编译次数(soc项目里比较有必要,testcase基于firmware),parallel-compile or separate-compile ,vmm-test,在一个testcase里做多个功能点的覆盖,fsdb/vpd的dump层次的改变不要重新编译(fsdb有command,vpd可能得用ucli)。
Q:设计规模大了编译很慢怎么办?
A:有时候设计规模太大导致编译很慢,但是SoC项目很多情况下,功能模块彼此之间是用总线隔开的(即便在功能模块之间有硬件连线也可以考虑用仿真模型来做替代)。在仿真某一个功能模块的时候,可以考虑dummy掉不相关的模块。
但是这就引入了一个新问题“文件列表的维护”。基于这种dummy的思想,文件列表的维护就成了tb里的一个很关键的地方,要尽量避免维护太多的文件列表。我个人比较推荐利用脚本来自动产生所需要文件列表。除此之外,仿真用的文件列表里我个人比较推荐用绝对路径(避免别人debug的时候出现调错文件的问题,另外可以指定不同的工作目录)。CVS里用相对路径,相对路径转绝对路径的工作由脚本自动完成。
Q:编译还是运行option?
A:为了减少编译的次数,能使用运行的option就使用运行的option。比如使用$value$plusargs $test$plusargs
Q:Assertion谁来写?
A:建议RTL designer和IC验证工程师都写。内部实现细节的描述由RTL-designer自己写,模块之间的时序由IC验证工程师来写。
Assertion的抽象层次有些高,写复杂了有时候极容易出现和你想象不一致的地方。而且如果spec上描述的不清楚,误报assertion-fail也会引入不必要的debug时间。
Q:IC验证工程师要不要看RTL?
A:不是很必要,但是有些设计背景比较强的验证工程师看代码通常能看到一些问题。个人建议还是拿出点时间来review一下RTL code。
Q:自动化的tb搭好了,波形对验证工程师来说还那么重要吗?
A:非常非常的重要。毋庸置疑!波形是最直接的,checker可能写错,有问题没有报出来。但是没有激励就没有所要的波形信息。
Q:如何重用?
A:reuse可以分为横向和纵向。
横向是指项目之间。这个reuse主要包括:文档和tb、script。
纵向是指同一个项目内,一般是模块级和系统级(包括子系统级)。一般是tb和script。
比如在一个项目中,所有的tb都是用run_sim和regress脚本的,只是带的filelist不同。对于tb来说,driver和generator可能不能reuse,但是一般monitor和scoreboard这类被动接收的一般都可以reuse。而且testcase通常是可以reuse的。
对于SoC类项目,为了保持testcase的一致性,我个人比较倾向于都使用firmware做testcase,这就要求
1)模块的验证也要基于一个(类)soc的tb下验证。
2)cpu-ip要尽量简单,否则cpu会占用太多的仿真资源。个人推荐用iss做cpu-ip,负责配置寄存器。
Q:regression什么时候做?做多少次?
A:tb好了以后,任何时候都可以做。下班后尽量提交regression到lsf里,让机器充分的跑。如果你的环境是random的,那么随机空间实际是很大的(随着random-test-point的增长指数级增长),所以只要seed不同,其实是可以跑到各种各样的情况。
Q:DPI要不要用?
A:有的人很喜欢用DPI,不过我个人不喜欢用。我尽量是把C封装好(自己写wrapper),产生可执行文件,然后在tb里用$systemf来调。不喜欢用DPI的原因主要是因为如果代码里有不太安全的地方(比如C代码里你不是在堆上而是在栈上开了一个大数组,或者C和SV之间的参数传递写法不合理),很容易造成coredump。而且你也不确定到底是SV写的不安全还是C写的不安全。另外,有些大公司的算法源代码是不提供的,只给你一个.o文件,这样coredump了你debug起来会让你有砍人的冲动。
但是不用DPI也带来一些坏处:
1)
要自己写一些wrapper之类的代码
2)
静态变量处理要小心。举个例子:我是每帧调一次systemf来做比对,某个函数每次比对会被调用一次。函数里的静态变量就没什么静态的意义了。如果不做修改的话,肯定会出错。一般是要求算法组尽量少用静态变量,非用不可的话,我们会把静态变量改成全局变量,然后让systemf多一个参数。
要说明的是:DPI“天然”的就是tb的一部分。但是我觉得把时间浪费在debug 算法C代码的优劣上是一件很不值得的事情(无论什么时候都是schedule优先),当然我也很佩服有些人对任何事情都“精益求精”的态度。
无论用不用DPI,你都可以使用DDD这类debug工具。DDD这种工具在非DPI情况下用起来会更加的得心应手。
Q:Force要不要用?
A:有的人比较抵触用Force-release,觉得如果写的不注意的话,可能会浪费时间(debug或者re-compile)。个人觉得“规定所有人把各自模块的force语句写在一个文件里,然后再被一个统一的force_prj.sv include进去,并且include前要有`ifdef保护起来”应该可以规避掉一些风险。
Q:人手少的情况下怎么做验证?
A:我个人觉得验证不能大包大揽,人手少的话就要更多的靠RTL-designer自己做验证。对于某些模块验证工程师就不要做了,否则陷进去出不来,反而影响了核心模块的验证力度。可以适当的更多依赖FPGA。但是对于核心模块一定要做好验证(比如内存控制器以及FPGA覆盖不到的模块等)
Q:IP要不要验证?
A:首先是去找业界口碑好的IP(个人觉得对数字IP来说silicon-validition一样重要)。人手不够的时候,可以考虑让FPGA多承担一些IP的验证,对于IP里一些FPGA无法cover到的测试功能点,可以考虑用直接testcase的方法覆盖。
Q: Debug到什么程度请designer来debug?
A:首先schedule优先,然后本着“力所能及”的原则,有时间有精力就debug的深入一些,否则checker报错以后,确认一下不是checker误报,就可以先提交给RTL-designer。
Q:遗漏bug怎么办
A:开发过程(FPGA)乃至最终silicon-validition甚至已经产品化后都可能发现遗漏的bug,要重视这些被仿真遗漏掉的bug。要一个一个的做case-analysis,仔细的分析为什么testbench没有抓到这样的问题。而且对于TO以后发现的Bug,要在下一版里重点review,以保证不犯同样的错误。另外,对于每个bug都应该尽量加一条对应的assertion。
Q:验证工程师要不要深入了解自己负责验证的模块?
A:虽然不深入了解,也不影响刚开始的工作,但是要把自己负责的模块吃透的话我觉得是很有必要的,我希望验证工程师能从系统(架构)一直到应用这些层面上都能深入的了解自己负责的模块。
Q:分享的氛围。
A:我个人觉得验证的范围很广,一个人很难把各个方面都搞的很精通。经常的技术讨论和培训是非常有必要的。Team-leader应该营造一个很好的技术分享的氛围。
-----------------------------------------------------------
推荐的学习材料(For VMM User)
1)
svtb.Pdf
2)
vmm源代码
3)
systemverilog for Verification
4)
VCS目录下的文档(包含vmm文档)
5)
例子(先把VCS目录下的例子看懂)
6)
Snug paper
7)
转夏晶帖:总结我的思路,如何在验证中发现和定位Bug(里面有些观点太偏激)
8)
一些资源网站 比如verification-guild EEtimes EETOP等等
总结的非常好。很多都是书中看不到的。
希望能够多多交流!
写的很好,功力不浅啊。拜模
学习了,谢谢
的确很不错,学习了
客气 客气 共同提高
本来是同学实验室里建验证组让我去给他们讲一下仿真验证,所以写的比较琐碎,也不见的都对,主要是让人家少走一些弯路。
抱歉,Word里排版还不错,结果发出来就变这样了。
膜拜,漫漫长路。
不错
这个必须顶。
大牛的切身经验,需要好好学习
本帖总结了SoC验证工程师必须掌握的一些验证技巧,值得有工程经验的工程师好好扩充和总结,服务于以后的工程项目。对于初学SoC验证的同学,个人推荐两本书《writing testbench with system verilog》和《system verilog for verification》,在深入一些可以参考synopsys的两个workshop 《SVTB》和《VMM》。
总结的非常好
大牛的切身经验,需要好好学习
总结得相当的不错啊
很不错的经验分享,许多东西现在看了都感同身受
好冷清!
谢谢小编的总结。
小编写的还是不错的!
写的真不错支持支持!
牛人 总结的很全面
拜读,真亲切啊
很好,学习了~
谢谢分享!
膜拜
很细致,内容也很丰富,多些这样的帖子才好
文章写的不错,标记一下
收藏了
很实际!senior级别的。佩服!
好好向小编学习~
为什么我早就有这个了呢,而且是很早之前
好东西,认真学习下
虽然看不太懂,还是mark一记!