>
首页 » 技术文章 » 模块级验证环境在顶层验证中的复用

模块级验证环境在顶层验证中的复用

作者:华为技术有限公司 俞波  时间:2006-05-31 14:07  来源:本站原创

摘要:模块级验证环境在顶层验证中的复用可以有效地提高生产率,利用Synopsys先进的NTB验证语言可以方便地实现验证环境复用。本文介绍了验证环境复用的方法,并通过一个实例说明了验证环境复用的实现细节。

引言

复杂芯片通常需要先划分成几个模块分别验证,在此基础上再进行整个芯片的顶层验证。验证环境的开发是一件费时的工作,如果顶层验证可以复用模块级验证的环境,就能大大提高生产效率。本文基于一个成功的案例,给出一种验证环境复用的方法。

案例采用Synopsys的NTB(Native TestBench)作为验证语言,它是Synopsys OpenVera验证语言的一个子集,支持并行、时序、 比特类型等硬件特性,也支持类等高级软件特性。NTB已经集成到VCS7.1以上版本中,无需额外的许可证。NTB可以被VCS本征编译,不再需要OpenVera的PLI/DKI接口,因此仿真速度更快。

验证环境复用原理

一般的验证流程是:首先根据规格书制订验证方案,然后构建验证环境、设计验证用例,待设计人员提交代码后开始仿真,直至通过所有用例并满足覆盖率指标。验证会占据整个芯片开发工作量的大部分,因此,验证环境的效率就显得非常重要。高效的验证环境通常是层次化的,不同芯片需要的具体层次可能不同,一个具有普遍意义的层次化验证环境如图1所示。


图1 层次化验证环境示意图

该验证环境既适用于模块级验证也适用于顶层验证。在模块级验证中,DUV(Design Under Verification)就是模块的设计代码,模块的输入被建模成一个驱动引擎,模块的输出被接收检查器采样和检查。测试用例的意图表征在配置文件中,由验证环境中的解析器解析成一些消息输送给驱动引擎。驱动引擎根据一定的算法处理消息,驱动芯片激励。同样的配置文件也输入参考模型,产生期望数据文件,用于和接收检查器的输出进行比对。某些芯片的输入输出有时间约束,因此应在验证环境中设计一个定时器,用于整个验证环境的同步定时。在顶层验证中,DUV就是整个芯片,包含多个模块。一个模块的输入可能是顶层输入,或另一个模块的输出;一个模块的输出可能是顶层输出,或另一个模块的输入。
  
验证环境复用的原理如图2所示,其中简化了图1的验证环境。基于A、B模块已有的验证环境,顶层验证环境需要保留模拟顶层输入的驱动A,关闭驱动B;同时保留顶层输出的检查B,检查A可关闭,也可开启作为内部信号的监视器。为达到良好的验证环境复用效果,需要验证语言的支持。使用NTB可以将验证环境中的驱动模块、检查模块等封装成一个类,以便验证环境复用。另外,验证环境复用时还要注意以下几点:

1) 在顶层验证环境中,用作监视器的检查器采样的已不是输出信号,而是内部信号,因此需要重新定义信号路径;
2) 对于模块级验证环境原有的监视器,需要重新定义在顶层验证环境中的信号路径;
3) 可能多个模块都需要顶层输入,这时需处理顶层验证环境中的输入冲突。

验证环境复用实例

芯片拓扑图

本文基于NTB完成了一个数百万门级芯片的验证环境复用,芯片的拓扑结构如图3所示。顶层设计中模块A和C共享了DSP的接口,因此需要处理激励冲突;其余模块的输入驱动均为芯片内部信号,需要关闭。对于顶层环境,只需检查模块D的输出,其余模块的输出均为芯片内部信号,其接收检查器可以关闭也可以保留作为监视器,作为监视器时需要在顶层验证环境中修改接口信号路径。


图2 验证环境复用示意图



通用NTB代码结构

模块A、B、C、D分别构造模块级验证环境,封装成一个类,其通用NTB代码结构如下:
// interface definition
// bind definition
class x_harness {
cnttimebase;
dsp_bfmdsp;
parseru_parser;
engineu_engine;
checkeru_checker;
tasknew ( cfg_fn );
}

x_harness中的x代表A~D模块,下同。其中的cnt、parser、engine、checker分别对应图1中的定时器、解析器、驱动引擎和接收检查器,并且均定义成类。engine主要用于模拟DSP发给DUV的激励,总线行为模型dsp_bfm将具体的激励时序封装成函数供engine调用。接收检查器中也包含一个封装DUV输出时序的总线行为模型。总线行为模型的参数是虚端口,虚端口是NTB提供的一种数据类型,用以屏蔽验证环境和DUV的连接。interface definition中定义了验证环境和DUV的接口,通过bind definition可以将虚端口绑定到接口上,修改绑定可以改变总线行为模型对应的实际DUV信号。

验证环境的通用主函数定义如下:
function string get_args();
extern task testbench ( x_harness th );
program main {
x_harnessth;
stringcfg_fn;
cfg_fn = get_args();
th = new(cfg_fn, cfg_fn);
testbench (th);
}
get_args()用于获取仿真脚本中指定的配置文件名称和路径,与主函数定义在同一文件中。外部任务testbench()控制x_harness的启动和结束,定义在一个独立文件testbench.vr中,其NTB代码结构如下:
task testbench(x_harness th, string cfg_fn)
{
// put reset here
// start timebase here
// start x_harness here
// wait for x_harness end here;
}

NTB代码可以和VCS一起编译运行,编译时需要输入NTB文件列表,替换列表中的文件名可以编译成不同的验证环境,比如替换testbench.vr可以实现不同的用例控制。需要注意,仅是替换文件路径和名称,但文件中的任务名“testbench”保持不变,由于主函数中声明的任务名就是“testbench”,因此可以不用改变主函数。


图3 芯片实例拓扑图

验证环境复用方法

首先定义顶层验证环境的harness,其中实例化各模块验证环境harness,如下:
// interface definition
// bind definition
class harness {
cnt timebase;
dsp_bfmdsp;
A_harnessu_A;
B_harnessu_B;
C_harnessu_C;
D_harnessu_D;
task new(string cfg_fn);
}

由于各模块级验证环境中都实例化了cnt对象,因此在顶层验证中必须统一,以确保所有验证环境组件工作在同一时间基准上。NTB提供了一种方法:直接将一个已经初始化的对象A赋值给对象B(没有初始化),则对象A、B实际指向同一对象。因此顶层harness中初始化的timebase成员将直接传入各模块的x_harness,x_harness 初始化时将传入的顶层timebase成员直接赋值给自己的timebase成员即可。需要注意,在模块验证时,x_harness还是需要初始化自己的timebase成员,模块验证和顶层验证时初始化操作的不同行为可以通过编译宏INTEGRETED区分。
|
INTEGRETED宏的另一作用是顶层验证时关闭非顶层输入的驱动引擎,顶层验证时驱动引擎将不被编译,因此不产生激励。

模块A、C的模块级验证环境中均模拟了DSP接口激励,集成时必须指向同一个DSP接口,方法和共享timebase相同,即在顶层环境中初始化一个dsp_bfm对象,将它传入x_harness并直接赋值给其中的dsp_bfm。由于A_harness和B_harness中的驱动引擎可能同时申请占用DSP接口,因此需要在dsp_bfm类中定义旗语避免冲突。

顶层的接口信号需要重新定义,如果模块的端口不在顶层,则需要特别定义。NTB提供语法将芯片内部信号也映射成一个接口信号,重新将其绑定到虚端口上,无需修改相应的验证环境代码。

顶层的testbench.vr需要另写,其中将分别控制模块A~D的启动和结束,程序结构如下:
task testbench(harness th, string cfg_fn)
{
// put reset here
// start timebase here
fork
{ // start A_harness here
// wait for A_harness end here };
{ // start B_harness here
// wait for B_harness end here };
{ // start C_harness here
// wait for C_harness end here };
{ // start D_harness here
// wait for D_harness end here };
join all
}

fork-join是NTB的并行控制语法,fork-join段中用{ }分割的程序段将并行运行,参数“all”表示将等待所有并行程序段结束后才执行fork-join段后面的语句,因此顶层验证环境将等待各模块harness中的操作都结束后才结束。

以上介绍了验证环境复用时所有的新增代码,合并各模块验证环境的NTB文件列表,相同文件只保留一份,用顶层testbench.vr文件路径替换模块级验证的testbench.vr,再加入顶层harness文件,就完成了模块级验证环境在顶层验证环境中的复用。

结语

利用NTB语言构造了层次化、统一架构、封装良好的模块级验证环境后,可以方便地复用以生成顶层验证环境,几乎无需开发新代码,大大减少了顶层验证环境的开发工作量。并且,模块级验证环境在模块级验证时已经稳定,也缩短了顶层验证环境稳定的时间。采用这种方法,笔者在非常紧张的项目计划下,成功完成了一款数百万门级芯片的流片。■

相关推荐

模块级验证环境在顶层验证中的复用

在线研讨会
焦点