soc基本仿真环境介绍
我在论坛上写过一个。《如何搭建soc项目的基本testbench(我的流程)》,这里挑重要的和有改变的地方说一下。
假设这个soc有cpu系统、内存控制器、总线拓扑、pad、clockreset和一些逻辑功能模块。
1. 仿真环境中有嵌入式软件(firmware)
这里包括两部分,一是初始化的bootloader(一般是固化在rom或者存放在外部的flash里),一是boot起来以后放在外部易失性存储介质上的应用层面的程序。
2. 使用指令集模拟器(iss)来代替cpu-ip.
有开源的也有不开源免费的arm多款处理器ip的iss.考虑到iss本身并不真实,如果不是为了验证bootrom代码的话,个人建议找一个开源的就可以了。iss可以编译成.so的库文件,这样在仿真的时候就不用编译整套iss的c代码了(需要设置ld_library_path,告诉仿真器仿真的时候去哪里找;编译过程中需要告诉链接库地址和库名称)。
iss需要一个配置文件来告诉它cpu的地址访问空间,像程序区、堆栈区是iss管理的空间(假设叫memory空间),像dut的内存地址以及dut的寄存器空间就是dut管理的空间(假设叫io空间),iss要能看到所有的地址空间,并且根据地址来判断是memory空间还是io空间来做不同的操作。
3. 共享空间cpu(iss)和testbench交互的时候可以指定一块地址空间(比如0x3000_0000 ~ 0x3100_0000),这块空间就是testbench中的一个数组。比如要实现对寄存器的随机配置,由于iss的c程序不方便做约束随机,可以在testbench组件中把约束随机产生好的数值写入到这块共享空间中,然后让iss的c读出共享空间的数值再配到寄存器中。
4. define文件的维护
soc项目中testbench的一个define可能同时在汇编程序、嵌入式c程序、cmodel的c程序、testbench的sv代码都要使用。同时维护多个类似的define文件肯定容易出错,所以只维护一个,其他的由脚本程序自动产生。
5. 内存控制器模块(ddrc)的替换
ddrc是系统中最主要bus-slaver,通常需要初始化过程(也有的ddrc不需要),还通常需要ddr-phy的模型,这些都比较影响仿真速度。而且在验证功能模块的时候,使用ddrc也不容易模拟带宽不同变化的场景。因此验证的时候可以考虑用一个bus-slaver的bfm来代替ddrc.
6. 打印的实现在soc环境的testcase的嵌入式c语言程序中没有标准的stdio,所以要实现printf. printf是“不定参数个数的函数”,利用“参数从右向左压栈,最开始的参数在最接近栈顶的位置,字符串最后一个字符是\0”来实现printf.在c端只需要把第一个参数的地址(肯定不是0)传到共享空间指定位置,在svtb中获取到地址以后按照%和参数地址来实现(sv端的实现和c语言里printf的实现很类似),需要注意的是1)c端程序要保证参数地址及时写入到共享空间中,不要停在cache或者传输太长;2)使用iss要打印的信息存在memory空间里,要能让sv端看到memory空间。当使用多核cpu-rtl的时候,注意不同core的打印控制(可以为每个core分配一个共享的空间,在print函数中根据不同的core-id来执行不同的操作)。
malloc等函数的实现也可以利用共享空间来实现。
7. 多个模块的协同验证在系统级下经常要跑系统级case来模拟整个系统一起工作起来的场景(一般该case也适用于power分析)。这种case可能要花比较大的精力在testcase的构造上,如果有硬件仿真加速器还好,如果只能在纯粹的仿真环境下做的话,尽量做简化处理。
8. 单一case流程编译dut和testbenchà编译firmwareà开始仿真(在合适的时机loadfirmware和产生随机控制数据写入到共享空间。如果要把firmware load到ddr model中,并且ddrc初始化流程会做data-training这种写数据的操作,那要保证初始化的数据不要被冲掉)
模块级验证相对于系统(子系统)级仿真环境的优势:
1)仿真速度快
2)随机可控性好
3)更容易做error-injection
4)更容易做开关切换和模式切换
仿真工具(2010年以后的版本)都支持模块级和系统级的覆盖率合并,可以加速收敛。
需要注意的是:虽然模块级环境理论上可以覆盖所有的系统级环境里的情况,但是在有限的人力和时间资源的情况下,很可能达不到100%的覆盖。举个例子:视频外同步的dataenable信号变化情况过多,以至于random不到实际系统中可能出现的情况。总之:关键是模块级环境有可能没有覆盖到实际中可能出现的情况。
模块级环境基础结构
模块级基础环境中除了有验证组件(monitor driver scoreboard等),还有一条总线连接master和slave、cpu-model控制dut.注意:这里所说的模块级环境里的dut是一个完整的模块,不考虑一个模块内部的子模块.
假定dut是一个总线的master设备,会发起访存操作。cpu-model负责配置寄存器和一些访存,模块级环境为了简化,让cpu-model不用通过总线而是直接访问bus-slaver的空间。
模块级环境testcase在系统级上的重用
在人员和时间资源有限的情况,要保证模块级代码在系统级上的重用。一般来说testbench组件(driver monitor model scoreboard等)重用比较简单,比较麻烦的是testcase在soc系统级(cpu上的c程序)环境下的重用比较麻烦。testcase构建是由tb架构中cpu-model的实现方法决定的。下面两种我主要用的方案testcase都是c的.
方案一:
使用iss实现。与soc基本仿真环境比较一致。
方案二:
使用dpi实现。cpu-model是一个sv的model,实现寄存器访问和内存地址空间访问的task,比较复杂的是对中断的模拟。可以使用sv的fine-grain-process(process::self())来实现main-task和irq-task,模拟“cpu进入中断以后挂起主程序,执行完中断以后返回主程序”(main_task.suspend(); ….; main_task.resume();)的行为。使用dpi来把底层硬件接口的sv-task传递给c程序。
dpi实现的方案中要注意底层硬件接口的代码,以及c代码中直接访问的代码(例如指向dut内存的指针的操作),尤其是ip-vendor提供的参考代码里很可能有类似代码。比如,usb ethernet的软硬件交互的协议栈放在内存中,软件代码中一般会维护一个数据结构,然后指针指向数据结构地址操作。dpi环境下这样的代码就没法直接用了(指针的操作就不行了,得换成硬件底层代码实现)。这样模块的firmware代码可能是现成的,仿真应该尽量复用。简单的方案就直接放弃模块级环境,上系统级环境里验证,或者用iss。iss环境下,firmware代码可能也要修改,比如上述的数据结构地址就要注意分配到dut内存地址上去(比如一个大的struct的赋值操作,先malloc出一块空间,然后向这个空间填数。只要malloc到dut内存地址上就可以了)。
其他方案:
testcase不用c直接使用sv实现;或者把cpu-model换成真实的cpu-ip,带上boot-rom和boot-ram。
架构评估
个人首推还是硬件加速器,需要注意的是架构评估最好保证频率的比例关系(访存模块的总线访问频率、总线拓扑中各组件频率、内存控制器和内存工作频率),个人感觉可能palladium和veloce这种方案的硬件加速器更加适合。
如果采用仿真的方法做评估的话,需要注意:
1)pattern的真实性。现成的模块rtl虽然可以反映真实的访存行为和latency的容忍度,但是构建环境偏复杂,仿真速度偏慢,通常还需要有初始化流程才能工作。个人建议构造bfm模拟访存行为:bfm可以吃配置文件,从而模拟比较真实的场景。
2)基础架构的自动集成。稍微复杂一点的soc架构中,总线拓扑的集成可能就很复杂了(统一的组件不太方便用emacs自动集成的功能来做,而且一些特殊信号位宽的匹配手动做起来很容易出错)。多年前就有自动化的工具来实现这个集成。但是商业化的工具虽然提供了很多的功能,但是未必能直接满足个体项目的需求,建议考虑开发自动集成的工具。目前的low-powerflow里已经不用在架构集成的rtl中写入多少额外的代码了,简化了自动集成的难度。
架构评估环境里还需要有内存控制器和总线架构模块的performance-monitor,来统计吞吐量、内存控制器效率、功能模块访存行为的latency等,根据吞吐量来看架构评估环境是否和期望的访存数据量比较一致,在这个前提下看内存控制器的效率达到了多少,以及系统中哪个模块会出现不合理的比较大的latency(导致该模块可能设计的时候需要加大fifo深度)。通过调整内存控制器和总线拓扑模块的优先级策略、时钟频率或者增减总线拓扑组件以及master/slave口的数量来做不同的仿真。
vip的使用
通常我们对复杂的标准接口协议的数通模块采用vip做bfm来验证。
vip的好处是不用特别开发bfm,有完整的tb组件,有的文档中有比较完善的测试计划和实例,随机性和error-injection完备。坏处是代码不可见,遇到问题容易抓瞎;vip作为工具安装使用可能挑os和仿真器;eda vendor本地support人员不足等问题,通常vip跑的速度比较慢。
能力和资源允许的情况下可以自己开发bfm.一种比较快的方案是reuse靠谱的rtl ip。比如我们要验证usbhost,那就找一个usb device或者uotg的rtl ip做bfm.这种方法的优势:bfm代码质量比较高,debug可见性高,将来在硬件加速器上可以更好的移植(有的可以不用phy,数字接口直接连)。劣势:开发代码量也不小,有的phy模型可能是个问题(比如一些单向数据传输的,master端是并行数据转lvds,slave端是lvds转并行数据,这样的phy model可能需要另外开发),rtl通常需要初始化过程,随机性和error-injection不够友好。
我觉得如果dut是内部开发的话,因为代码质量可能不够,用商用的vip更合适。如果dut是买的已经silicon-verification的ip的话,我觉得自己开发的bfm就够了。
coverage-driven和assertion-based
个人认为代码覆盖率是最重要的,是一定要统计和仔细的检查的。
功能覆盖率(包括assertion的覆盖率)应该是testplan的反映,我觉得只是提供对testplan覆盖的数据统计,testplan本身可能是不完备的,所以功能覆盖率的100%并不能代表验证充分了。
assertion对于一些不太复杂的协议时序验证还是比较适合的,但是感觉最近几年eda公司都不太在assertion上投入资源了。我觉得对于一个大模块内部的子模块,assertion是非常适合的,可以针对子模块的接口具体的做assertion的描述和验证。
仿真层面的加速
最快的加速技术肯定是硬件仿真加速器。
在“soc基本仿真环境介绍”中的cpu和ddrc的替换都有加速仿真的功能。除此之外还有一些我在用的加速方法:
1)系统级仿真环境中把不需要的模块dummy掉。-----需要两个脚本程序,一个是自动产生dummy文件,一个是自动把dummy文件替换掉原有的rtl.
2)缩短soc上电启动仿真时间。----通常是一个状态机根据若干个counter的技术来实现状态跳转。方法是更改counter的初始值或者跳转需要的数值,rtl级比较容易实现,门级仿真找信号比较麻烦,最好提前和flow的同事沟通好,把信号名保持住。
3)有些dut里的ip比较耗仿真资源,可以考虑用简化的model代替。比如pll、dcm以及某些phy-model.
4)某些rtl代码的写法可能很耗仿真资源。比如在clock的每个上升沿当reset有效的时候把一个比较大的二维数组附初始值。这种代码最好加ifdefelse endif来改写成initial-block.
5)减少dpi过于频繁的交互
6)谨慎使用separate-compilepartition-compile等技术,也许带来负面效果。
门级仿真
功能仿真中一般有如下几类门级仿真:
1)综合后网表仿真
2)dft后网表仿真
3)pr后反标sdf的网表仿真
4)fpga综合后网表仿真
5)gtech网表的仿真
综合后和dft后的网表比较类似,一般跑dft以后的就可以了。除pr后的网表要反标sdf以外,其他的都是跑0delay的门级仿真。一般额外做几个处理:
1)给std-lib cell库文件中给时序逻辑(dff等)加上clk2q的delay
2)保证sram model的输出端在不工作的时候不要输出x.
3)门级网表中如果有不带reset端的dff,一般要找出来做$deposit处理(找的方法可以请flow的同事拿对应的网表出一版sdf,然后parser sdf文件就可以得到对应instance里的dff)。
4)反标sdf的门级仿真如果checktiming的话,要注意把2dff等跨时钟域的逻辑的timingcheck去掉。
fpga综合后的网表仿真一般不用做,但是当fpga timing报告、fpga功能仿真、cdc和lint-check都没有问题,怀疑fpga综合有问题的时候值得做一下。我在做fpga综合后网表仿真中发现过几个问题:1)xilinx-v7默认把rtl中复杂的case语句用blockram实现,结果实现的时候时序差了一拍2)fpga把rtl里的一些运算直接用内部的dsp来实现,结果dsp的功能综合错误。fpga综合网表的信号名太乱,testbench如果拉了一些内部信号进行观测或者force的话,很难编译通过。
gtech网表的仿真很少需要做,如果fpga上跑gtech网表来代替rtl的话,需要注意fpga版本gtech单元的行为描述要保证和asic的一致,否则容易有“坑”.
pr后门级仿真重点是出比较准确的ir-drop和power数据,以及保证时序约束的完整和正确性,建议只跑典型的case就可以了。
仿真验证自动化
举例一些testbench的自动检查机制以外的自动化技术(很多是用crontab自动执行)。
1)每天自动checkout出一份代码做mini-regression,并且把结果自动发email通知给项目组。
2)每隔几个小时一旦检查到有新tag就自动update到新tag上做mini-regression并自动发email
3)每天自动把所有checkin的代码列出来并自动发email
4)每天自动把未解决的问题总结并发邮件(bug-zilla、issue-tracker、jira等bug-tracking系统有的自带这个功能,有的可能没有需要自己实现)
5)自动代码备份(有的代码可能还在开发过程中,所以不想checkin到代码库里去,如果mis没有针对这类代码做自动备份,可能需要一个自动备份的程序,)
6)除了自动比对环境以外,还要有一个parse编译和仿真log的程序在regression的时候调用。
如果某个功能上没有自动检查机制,也要尽量想办法减少人工比对的工作量。例如,有一个图像算法模块的c-code找不到了,但是rtl是golden的,跑实际图形pattern一幅图一幅图看会比较耗时间,可以把regression中产生的图像打包到一个网页中,然后用浏览器去看。
脚本语言是仿真工作中非常重要的一环。我们一般会用到shell\perl\tcl\python等脚本语言,建议在学习脚本语言期间,强迫自己遇到问题使用正在学的语言来实现。
验证项目管理
http://bbs.eetop.cn/thread-581216-1-1.html《多媒体类soc项目verification project leader工作内容介绍(讨论)》我在这个帖子里列的比较详细了,verificationengineer的工作基本上是verification project leader的子集。
帖子里是按照项目开始前的准备à项目启动但未提供第一版integration代码à0.5版本à0.75版本à0.9版本à1.0版本àto前到to后的项目开发时间来写的。我在这里列一下帖子里几个没有提到的内容。
leader要注意把握验证流程,上fpga验证前除了仿真和检查fpga时序以外,还要做cdc和lint等静态验证检查。
leader及时给项目组内新同事培训工作环境基本技能,避免组内同事出现因为工作环境影响工作效率(比如不同的工具对机器的要求侧重点不同,有的要求cache大,有的要求memory大,可能要综合考虑cache\memory\cpu-core-num\cpu-frequency等因素。如果mis没有按照机器性能来进行lsf计算资源划分的话,使用lsf预先配置的分配策略可能会把任务提交到不合适的机器上.)
注意避免验证工程师过度依赖模块级环境。比如fpga上报了问题,模块级上复现不出来就认为没有功能问题了。
leader一定要及时总结所有仿真遗漏的bug,开发阶段通常是设计工程师项目后期模块级环境跑仿真暴露以及fpga上发现的bug.有的bug可能是由于fpga在仿真验证过之前就开始导致遗漏的,对于的确是验证工程师遗漏的bug要特别关注。
一般power数据是来源于门级仿真的vcd或者saif文件,随着设计越来越大,有可能导致vcd文件过大,这种情况下及时与跑power分析的同事沟通,看有没有合适的手段解决。有的硬件加速器可以内部分析哪段时间翻转剧烈,可以根据这个信息来dump vcd.注意一点:当要dump的信号特别多的时候,其实dump vcd和dump fsdb这种压缩格式的文件大小是差不多的(大量的存储用来构建信号名的表了),这种情况下直接dump vcd就可以了,还可以避免引入dump波形的pli和后面的格式转换工作。
理论上说验证是做不完的,有所为有所不为。leader不能把事情大包大揽,有些事情在资源有限的情况下要推出去。
及时总结记录和分析
重用程度高的项目很容易犯经验错误,千万谨慎。改动的地方加强review.
介质波导双模滤波器设计方法与过程分析
WT2003H语音芯片在新能源汽车的应用
三元混合物主要功能是什么?
小米新品:小米6、小米meri、红米Note4X传言总汇
嵌入式处理器的结构是怎样的
如何搭建SoC项目的基本流程
RFID技术面临着哪一些挑战
iPhone8物超所值,仅售8888元!历代最贵不是没理由
python中的set类型
一批出口匈牙利中国产灯串被欧盟召回 原因或是绝缘部分缺少合适的电阻
多光子显微镜成像技术:多光子显微镜的焦点深度扩展方法
2018上半年智能手机AMOLED面板出货约2亿片,SDC遥遥领先占94.7%
三菱Q06UDV CPU与安川MP2300S CPU简易通信设置
Socket采用C/S模型进行设计的服务器模型
华为MateBook D怎么样值得买吗?华为MateBook D商务本评测
视频监控在零售中的主要应用可以分为三个环节
英创信息技术WinCE主板CAN接口数据接收性能测试介绍
神奇Li-Fi市场坐拥千亿美元“前景” 如今它有何最新成果?
千方科技宣布新的AI子公司博观智能正式落处济南
供应罗德与施瓦茨DVSG数字视频信号源