使用VMM和DPI技术验证复杂多媒体SOC芯片


祝丹, 高勇, 陈辉, 张亚静, 李树杰
中星微电子

zhudan@vimicro.com

摘要

现代高端的多媒体芯片通常是复杂的SOC。这类芯片的验证面临着许多挑战:第一,验证的工作量越来越大,迫切需要提高验证工作的效率,及验证平台的可重用性与可维护性。第二,设计复杂度的增加,提升了验证工作的复杂度,从而对验证激励的随机产生提出了很高的要求。第三,人工比对输出结果的工作非常繁琐并且容易遗漏问题,从而使自动比对成为验证系统的核心功能之一。

SystemVerilog和C/C++都是支持面对对象的编程语言,允许在更高抽象层进行建模,帮助提高验证工作的效率。其中SystemVerilog提供对覆盖率和断言的支持以及与DUT的无缝集成,而DPI技术提供了SystemVerilog和C/C++之间的高性能链接。

中星微电子一直致力于多媒体芯片的开发,在VC08XX项目的验证过程中,我们使用了Synopsys的VMM验证方法学以及SystemVerilog的DPI技术,显著的缩短了项目开发周期,提高了芯片验证的全面性,确保了芯片的功能正确性。

关键词:SoC,功能验证,VMM,DPI

1. 引言

在验证过程中,验证方法学扮演着十分重要的角色。尤其是对于高集成度和高复杂度的SOC的验证,好的验证方法学,首先可以显著的提高验证平台的可重用性,缩短功能验证的时间,节省验证资源,其次可以使验证平台具有输出结果自动比对等功能,同时还使各个验证组件结构清晰,任务划分和集成更加易于进行。

VMM是当前业内公认的验证方法标准,目前Synopsys已将其捐赠给EDA标准化组织Accellera,Accellera正在VMM及VMM applications的技术基础上制定验证互操作性的标准。VMM根据功能和抽象层次,将验证平台分成功能不同的模块,提高了验证平台的重用性和抽象层次。Synopsys根据VMM验证方法学,用SystemVerilog实现了一套可继承的基类库使用OOP技术,验证工程师可以更快建立起复杂的验证平台,并使其具有激励受约束随机产生(Constraint-Random),DUT输出结果自动比对(Self-Checking),功能覆盖率驱动(Coverage-Driven)等高级功能。

2. VMM验证方法学概述

VMM验证方法学将验证平台按照设计所处理数据的抽象级别划分为几个层次。

各层次之间的数据流关系如图1所示。

图1: VMM验证方法学分层结构

测试层(Test Layer):生成测试案例,由功能覆盖率控制,可能会包含一些随机激励的约束,也可能是一次直接测试激励。

场景层(Scenario Layer):生成事务级的随机激励,主要指事务发生器(Generator)等。包括Atomic Generator,生成单独约束的事务,以及Scenario Generator,生成有一定关系的随机事务序列。

功能层(Functional Layer):控制事务(Transaction)的传输与监测,实现自动比对的功能。包括记分板(Score Board)等部分。

指令层(Command Layer):完成对硬件的直接驱动,以及对硬件接口的监控。包括驱动器(Driver),监控器(Monitor)等部分。

信号层(Signal Layer):实现验证对象(DUT)与验证环境(ENV)的信号连接。

另外还有几个非常重要的模块,包括基于断言的检查器,功能覆盖率收集等。

3. VC08XX项目介绍

VC08XX是中星微电子一款针对PMP解决方案的产品。采用了ARM9和高性能的媒体引擎,具有高集成度和低功耗的特点。其结构如图2所示。

图2 : VC08XX系统架构图

4. 利用VMM搭建Memory Subsystem验证平台

图3: Memory Subsystem验证环境示意图

VC08XX的Memory Subsystem主要实现了总线仲裁,内存控制(SDRC)以及数据搬运(DMAC)等功能,其结构如图3所示。总线仲裁包括CPU子系统总线仲裁(CPUD SARB),存储子系统总线仲裁(STORAGE SARB)和整个系统的总线仲裁(MARB),这些模块与各个主设备(MASTER)由AHB或AXI标准总线接口相连。内存控制(SDRC)主要负责控制SDRAM的读写操作,SDRC与MARB的接口是AXI接口。系统总线上除了SDRAM,还挂有ROM和APB等从设备(SLAVE)。

图4 : SDRC验证平台示意图

首先我们搭建了SDRC的模块级验证平台,其结构如图4所示,包括SDRC的自检查结构以及符合AXI协议的事务发生器,驱动器和监控器等验证组件。然后通过对这些模块的大量重用,我们迅速的搭建了Memory Subsystem的验证平台,其结构如图3所示。该平台从不同的接口监测数据,分别验证了CPUD SARB、STORAGE SARB、MARB和SDRC四个模块,其中SDRC的自检查结构在这里得到了重用。由于MARB与各个主设备由AXI标准总线相连,我们又重用了SDRC模块级验证平台的事务发生器(AXI Transaction Generator),驱动器(AXI Master)和监控器(AXI Monitor),用来模拟和监控与MARB相连的11个主设备的行为。

VMM方法学提供了一系列基类,使验证平台得以快速开发。例如验证环境通过继承vmm_env类来实现,它的主要作用是实例化各个验证组件并控制流程。事务(Transaction)通过继承vmm_data类来实现。驱动器、自检查结构通过继承vmm_xactor类来实现。各个xactor之间的通信通过vmm_channel实现。功能覆盖模块通过继承vmm_xactor_callbacks类来实现。后面的章节会详细介绍各个模块的实现细节。

4.1 激励的生成

4.1.1 随机激励

多媒体处理需要大量的访存操作,尤其是视频解码(VDEC),图像处理(IPP),LCD控制(LCDC)等模块,经常同时读写SDRAM,用直接测试(Direct Test)很难覆盖完全AXI总线上多种多样的情况,因此我们在搭建验证平台时采用了VMM方法学的Constraint-Random技术。

Memory Subsystem的验证平台中实例了11个事务发生器(Generator),随机产生符合AHB和AXI协议的事务(Transaction),并通过输出通道(Channel)传送给驱动器(Driver),驱动器解析接受到的事务(Transaction),并按照总线时序驱动DUT,如图5所示。在定义好事务(Transaction)后,事务发生器和输出通道不需手工编写,只需要调用对应的vmm宏,就可以在验证环境中重用了,如下面代码所示。

//###### axi_trans.sv ##############

class axi_trans extends vmm_data;

typedef enum {READ, WRITE} kinds_e;

typedef enum {BYTE, HWORD, WORD} size_e;

typedef enum {INCR, BURST, WRAP} burst_e;

kinds_e write;

size_e size;

burst_e burst;

bit [31:0] addr;

bit [ 3:0] len;

…………

endclass:axi_trans

`vmm_channel(axi_trans)//定义输出通道

`vmm_atomic_gen(axi_trans, “axi_trans”)

//定义事务发生器

//####### sdrc_env.sv ##############

…………

//实例事务发生器

axi_trans_atomic_gen dmac_trans_gen;

axi_trans_atomic_gen pdma_trans_gen;

axi_trans_atomic_gen stor_trans_gen;

…………

 

图5: 事务发生器和驱动器的关系

一笔随机事务首先会产生指令信息,包括地址,传输长度等,如以上代码所示。随后根据传输长度产生写数据,同时,还会产生该指令和上一个指令之间的延迟时间,以及该数据和上一笔数据之间的延迟时间,然后将这些信息统一打包放入输出通道。由于AXI总线协议定义了指令通道,写数据通道和读数据通道,因此驱动器也并行的启动了三个进程,在收到一笔事务后,先根据指令延迟发送指令,同时把数据放入一个队列,再在其他进程中拿出数据,并根据数据延迟发送数据。这样,即保证了指令和数据的一一对应,又使指令和数据发出的时间可以任意随机,比如可以连续发出几笔指令,再连续发出几笔数据。

4.1.2 通过文件操作实现定向激励

有的时候,Memory Subsystem验证环境需要重现具有特定操作的系统级仿真,这时候对于MARB或SDRC的随机激励应当被直接激励代替。

我们通过文件操作实现的这样的直接激励。具体来说,就是把系统级仿真中的AXI总线上每笔指令和数据以及延迟信息通过AXI监控器输出到一个指定的文件中,再建立一个事务发生器,从文件中读出这些信息,转换成一笔笔的事务,发送给驱动器。

4.2 对随机激励的控制

对于不同的随机激励,有些需要一定的约束来确保其有效性,有些则需要辅助性或修正性的约束,以便命中特定的边角情况。

4.2.1 通过开启或关闭某个属性的随机模式定义不同的测 试案例

我们有时会需要令某一个寄存器的配置保持常量,比如将AUTO_REFRESH的开关固定为关闭状态。因此,我们定义出固定配置的约束块,再在测试案例中开启或关闭其随机模式,从而控制不同的测试案例,如右图所示。

4.2.2 通过提供外部约束块或带有附加约束的派生类定义 不同的测试案例

在对总线操作的随机化过程中,我们可能会更加关注一些边角的情况,如对SDRAM进行跨行的读写操作,又如ARM发出的WRAP8操作。

可以在测试案例中定义一些外部的约束块,也可以使用带有附加约束的派生类替代原有的随机数据类,如右图所示。

//##########sdrc_config.sv#######

constraint auto_slfrfsh_c{

auto_slfrfsh_entry inside {0};

}

————————————————

sdrc_config.auto_slfrfsh_c.constraint_mode(0);

//##########test.sv###############

constraint axi_trans::cmd_delay_c {

cmd_delay inside {10,20};

}

————————————————

class axi_trans_arm extends axi_trans;

constraint wrap8_c {

burst_length inside {8};

wrap8_enable inside {1};

}

endclass

class sdrc_pre_monitor extends vmm_xactor;

……

pre_wdata_channel[`SIGS.marb_sdrc_wid].sneak(pre_wdata);

……

endclass

4.3 自检查结构

4.3.1 记分板(Score Board) 和参考模型(Reference Module)

记分板用来动态的预测DUT的响应,它将施加给DUT的激励转换为预测响应的形式,然后跟DUT输出的真实响应进行对比。

转换功能的实现有很多方式。对于总线仲裁器(MARB)来说,它的主要功能是从多路访问同一个从设备的主设备中选出一路进行传输,因此可以对MARB输入的激励和输出的响应根据相应的主设备ID进行对比;对于内存控制器(SDRC)来说,它的主要功能是将AXI总线上的读写操作转换成符合SDRAM接口时序的指令和数据,因此需要建立SDRAM的参考模型,得到预期的数据,同时直接从SDRAM中取得真实的数据,再与输入激励的数据进行三方面的对比;而对于视频解码模块的验证,参考模型可以通过C语言实现,用直接编程接口(Direct Programming Interface)集成到VMM验证环境中,后面的章节会给出详细的介绍。

SDRAM的参考模型是一个可配的存储矩阵,它与真实的SDRAM模型有着相同的配置,包括传输长度(Burst Length),存储矩阵的深度,宽度等,并以同样的顺序读写数据,但并不需要产生精确的延迟和周期输出,也不需要有相同的外部引脚。

4.3.2 使用索引表和多个独立的按序队列定位匹配的预期 响应

为了获得更高的SDRAM带宽利用率和更快的高优先级指令响应速度,内存控制器(SDRC)将输入的指令按照一定的规则重新排序并输出给SDRAM,也就是说,输入激励与响应的顺序是不一致的。对这种乱序响应的验证,常常通过建立联合数组(Associative Array)和多个独立的按序队列(Queue)来定位所匹配的预期响应。

以对写数据的检查举例,将AXI总线上的写数据按照不同的主设备ID分别放入不同的队列里。记分板根据输出写数据的主设备ID选择相应的队列进行比较,这样即保证相同主设备ID的写数据顺序不会被改变,又保证了写数据的正确性。如下所示。

class sdrc_score_board extends vmm_xactor;

……

post_cmd_channel.get(tr);//取得指令信息

pre_wdata_channel[tr.mst_id].get(pre_wdata);//取得输入激励的写数据

write_ref_mem(tr);//把数据写入参考模型

read_real_mem(tr,post_wdata);//从SDRAM中读取真实的写数据

if(pre_wdata.data != post_wdata.data)//进行数据比较

……

endclass

4.3.3 系统级重用

为了使自检查结构可以方便的在系统级重用,自检查结构不应包含对模块级仿真环境的类引用,也就是说,监控器(Monitor)和驱动器(Driver)应当完全分离,同时,对功能覆盖率的采集工作也应在监控器中进行。这样,在系统级仿真中重用自检查结构和功能覆盖率验证模块,只需要在系统级环境中实例监控器和记分板,同时更改Interface文件。

在Memory Subsystem的验证平台中,CPUD SARB、STORAGE SARB、MARB和SDRC四个模块的自检查结构都可以方便的在整个芯片的系统级验证平台中得到重用。

4.4 回调(Callback)在验证平台中的应用

4.4.1 利用回调(Callback)插入异常(Error Injection)

完善的验证过程应尽可能去试探,甚至打破协议的极限,比如地址出界,零延迟的发出两笔指令或两笔数据等情况。这些异常情况可以通过回调(Callback)的方式插入到正常的事务执行过程中,并在自检查结构中判断DUT是否输出正确的响应。

回调方法使单个的测试案例需求不需要修改事务处理器本身,就可以对事务加以控制。在收到一笔事务之后,驱动器会先调用回调方法(Callback Method),对事务进行修改,以插入错误,再发出给DUT,这些回调方法在具体的测试案例中被实现,并通过信号或时间控制其出现的频率。

下面代码示意了如何利用回调插入零延迟的事务。

//########### axi_mst.sv ################

virtual class axi_mst_callbacks extends vmm_xactor_callbacks;

virtual task pre_trans(ref axi_trans tr);

endtask

endclass

class axi_mst extends vmm_xactor;

……

pre_tr_chan.get(tr);//接收事务

`vmm_callback (axi_mst_callbacks,pre_trans(tr));//插入错误

do_cmd(tr);//驱动总线

……

endclass

//########### sdrc_test.sv ################

class zero_delay_injection extends axi_mst_callbacks

……

virtual task pre_trans(ref axi_trans tr);//实现回调方法

if(……) begin//通过信号控制出现频率

tr.cmd_delay = 0;

tr.data_delay = 0;

end

endtask

……

endclass

4.4.2 利用回调(Callback)进行针对覆盖率的验证

覆盖率度量指标是验证设计可信度的重要指标。VMM验证方法学采用覆盖率组(Cover Group)来定义验证的需求,并可以自动的生成覆盖率度量指标,具有建模快捷,便于采样和易于分析等特点。

在Memory Subsystem的验证中,我们主要关心来自于寄存器配置和总线激励的功能覆盖率。因此,我们分别在负责寄存器配置驱动和负责总线监控的模型(Monitor)中调用覆盖率组的采样函数。

在验证的整个执行过程中,覆盖率目标通常不是一成不变的,而是从初始的状态渐渐深入,随着新的coner情况的出现而不断更新,因此,我们采用了回调(Callback)的机制,这样不需要修改监视器或驱动器本身,就可以对覆盖率的采集操作进行控制,同时对覆盖率组(Cover Group)进行修改。

具体实现的时候,使用覆盖点(Cover Points)和交叉覆盖点(Cross-points)记录相应的验证需求,采用覆盖率权重(weight)来区分功能验证的优先级,覆盖率组被封装在覆盖率对象中,这个类是vmm_xactor_callbacks基类的继承。

5. 利用VMM-DPI搭建system验证平台

VMM验证方法学对验证环境抽象层次的提高,使验证工程师可以在完成RTL设计前就搭建出行为级的验证平台,比如测试层,场景层和功能层的验证组件。当设计完成后,再实现涉及到指令层和信号层的功能,同时复用算法部门使用C/C++或System C开发的行为级模型作为参考设计从而实现自动比对的功能。

SystemVerilog(SV)的直接编程接口(Direct Programming Interface,DPI)技术提供了在SV验证环境中使用C/C++程序的接口。它允许Verilog/SystemVerilog代码通过使用简单的import声明导入C函数从而直接加以调用,或使用export声明导出Verilog/SystemVerilog的函数并在C/C++程序中加以调用,从而实现了参考模型和仿真环境的数据交互,可以帮助快速的搭建视频解码等算法单元的自检查结构。

在VC08XX项目系统级验证平台的搭建过程中,我们使用了VMM验证方法学以及DPI技术,显著的缩短了项目开发周期。

5.1 DPI与PLI的比较

Verilog PLI提供一个使用户自带的C函数能够在运行时间读取和修改仿真数据结构的接口,而DPI提供了一条新的集成SV和C/C++的途径。

对比于PLI,DPI有以下两点优势。首先,DPI消除了PLI使用的复杂性。PLI必须定义系统任务/函数名称,并把calltf C函数和该系统任务/函数的名称关联起来,而DPI可以直接在Verilog代码里调用C函数。使用DPI导入C函数后,SV的逻辑数值可以作为输入直接传递给C函数,C函数的返回值和输出参数也可以直接传递回SV,无需像PLI需要通过复杂的PLI库间接传递数值。其次,DPI允许SV的函数或任务导出给C函数调用,而PLI没有对应的功能。这使得复杂的设计可以从一个很高抽象层次的C模型开始,然后随着设计流程的推进,这些C模型的一部分使用SV替换,两种语言通过DPI交互,最终实现整个设计。这些导出的SV任务或函数可以通过非阻塞赋值,延时等方法使基于DPI的C函数与仿真时间同步。

然而,DPI并不能直接访问内部仿真数据结构,这限制了DPI的应用。然而,对于大多数的验证工作而言,DPI提供了一种更加简单高效的途径来进行SV与C/C++代码的集成。

5.2 VDEC模块级验证平台

使用C模型建立算法单元的参考模型,可以重用前期算法开发时建立的C模型。而在仿真过程中,用SV动态调用C模型进行自动比对可以避免了人工比对带来的问题遗漏,并且实时的发现错误响应,尽早中断仿真,减少仿真时间损失。

以视频解码算法模块VDEC为例,RTL的配置、激励和参考响应都是从C程序中得到的,因此我们使用VMM方法学结合DPI技术搭建模块级验证平台,图6示意了VDEC模块级验证平台的基本结构。其中Driver负责把从C模型中得到的数据,转化为DUT所需要的配置和激励;而Monitor则负责采集DUT的响应结果,传递给记分板进行数据比对。

图6同时举例示意了C程序是如何利用DPI调用Task与VMM ENV在仿真过程中进行数据交互,从而实现自动比对功能的。这些Task由System Verilog实现,在C的主函数中被调用。仿真开始时,VMM ENV和C的主函数被同时启动,当C程序的算法单元执行完毕后,Task C_result( )把所得到的配置和参考数据传到VMM ENV中。Task C_over( )用于C程序告知VMM ENV,C 模型已经运行完毕,RTL可以开始运行。随后,C程序通过一个While循环反复查询函数Rtl_over( )的返回值,这个Task将RTL是否运行完毕的信息从VMM ENV传递给C程序,当返回值为1时,C程序得以继续运行。Rtl_result( )用于返回RTL解码后的结果,该结果用于取代C中相应的解码数据。与此同时,VMM ENV将参考数据与真实响应进行比较,实时的报告比较结果,控制仿真是否结束。

 

图 6: VDEC模块级验证平台示意图

5.3 系统级验证平台

在系统级验证平台中,我们重用了模块级验证平台中Monitor和Score Board,并利用DPI技术调用C模型产生参考结果,从而实现了系统级仿真中算法模块的自检查功能。

图7举例示意了VDEC的系统级验证平台。其中监控器负责采集VDEC内部每一级流水的输出结果以及输出到总线上的最终结果。记分板则通过DPI调用VDEC的C模型得到参考数据,并实时的与真实结果进行比对。由于可以在出现错误的时候提前中断仿真,实时比对结果对于仿真时间较长的系统级验证尤为重要。

图 7: VDEC系统级验证平台示意图

6. 总结

在VC08XX项目的验证过程中,在SYNOPSYS的VMM验证方法学的指引下,我们结合DPI技术,在很短的时间内建立起功能强大的验证平台,显著提高了验证的效率,缩短了芯片的开发周期,确保了芯片的一次性流片成功。目前,我们已经在后续的项目中多次成功重用已开发的验证平台。

7. 参考文献

[1] Synopsys Inc. Reference Verification Methodology User Guild

[2] Chris Spear,System Verilog for Verification

[3] Janick Bergeron,Verification Methodology Manual for System Verilog

[4] Janick Bergeron,Writing Testbenches using System Verilog

[5] “SystemVerilog 3.1a,draft 4: Accellera’s Extensions to Verilog”,Accellera,Napa,California,2004