陈琳娜, 孟建熠, 林志涛
(1.浙江大学 电气工程学院,浙江 杭州 310027; 2.复旦大学 微电子学院,上海 201203)
提高芯片的验证效率至关重要[1],现有的验证平台大部分是基于通用验证方法学(universal verification methodology,UVM)环境开发的[2],然而验证组件的实现与被测器件(device under test,DUT)紧耦合,导致其可重用性需要通过更改或替换已有验证平台的部分代码来实现[3,4];另一方面,在一个含有上千个测试用例的大型项目里,仿真测试需要的时间变得很长。因此如何提高验证组件代码的可重用性和缩短测试用例仿真时间已成为验证平台开发的困难与挑战之一。标准化串行总线接口作为设备之间信息交流的主要通道,是片上系统(system on chip,SOC)芯片不可缺少的部分[5]。针对广泛应用的串行总线协议,以及现有的UVM验证组件代码可重用性差和仿真时间长等缺陷,本文提出了一种面向串行总线协议的层次化公用库设计,同时对UVM transaction定义进行改进,加快仿真速度,实现了快速验证。
UVM继承了 SystemVerilog验证语言面向对象的思想,实现了验证的重用性和清晰的层次结构。UVM常用类的层次结构如图1所示[6,7]。
公用库的设计是将环境模型和功能模块抽象出来,定义为可重用的通用库文件。串行总线协议通常具有共性:1)支持主从或对等模式;2)支持大端或小端;3)支持同步或异步模式。
层次化的公用库主要基于验证平台的重用层级来进行建模和管理,主要分为以下几个层级建模:1)事务级建模;2)组件级建模;3)功能级建模。图2为在原有的库基础上添加的层次化公用库。
图1 UVM常用类层次结构
图2 层次化公用库类
2.1.1 事务级建模
该层次的建模主要包括具体协议内容的transaction定义以及相关语义类型定义,一个标准串行总线协议的transaction通常是定义一些数据包类型,数据传送格式,数据传送长度等基础内容。
2.1.2 组件级建模
该层次的建模与协议内容无关,主要包括验证组件基本功能的实现。组件级的建模包括:
1)lib_driver:所有协议的driver设计都有一个共同功能:当检测到一个复位信号到来时,立刻退出所有的接口驱动。可以设计一个公用组件lib_driver派生自driver,并在该组件中加入该功能。
2)lib_monitor:该组件派生自monitor, 不同的协议对接口的monitor方式各不同,故在该组件中加入一个虚函数并通过无限循环来不断收集DUT 接口的输出。
3)lib_scoreboard:该组件派生自scoreboard,用于比较期望数据和实际数据。可在lib_scoreboard中声明2个imp端口,同时另设2个 Buffer 用于缓冲数据。在check_phase里检查Buffer是否为空。
4)lib_test:该组件派生自uvm_test,并包含基本功能:a.设置整个验证平台的超时退出时间;b.设置用例跑的次数;c.在report_phase中根据UVM_ERROR的数量来打印不同的信息。
2.1.3 功能级建模
该层次的建模主要包括协议通用的功能和任务函数。串行总线协议的通用函数包括:
1)传输起始与停止条件:主从模式下的串行协议,起始和停止条件由主机产生;对等模式则由发送模式产生。无论是何种模式,都需要实时监测起始与停止条件。这些过程可封装成公用函数。
2)时钟线驱动:同步传输模式下的串行协议,需要时钟信号确定同步传输的速度;异步传输通过配置波特率对时钟进行采样。该过程可封装成公用函数实现不同频率的时钟产生。
3)数据线驱动/监测:同步传输模式下,不同的时钟极性和相位决定了在时钟不同的跳变沿对数据线进行驱动或监测;异步传输数据的驱动与监测由采样时钟确定。数据传输有大端和小端模式。该过程可封装成公用函数。
UVM各个组件之间的信息传递基于transaction。transaction中数据变量通过Field-Automation宏机制注册,简化了transaction的处理过程[8]。
Field-Automation宏机制的实现过程如图3所示。′uvm_object_utils_begin()为宏开始定义,用于注册transaction类,该宏扩展为一个内部方法: __m_uvm_field_automation()。′uvm_filed_*系列宏体用于注册transaction内部定义的变量[9],每个宏体的声明都会扩展成一个case语句的实现。当用户调用print,copy,compare等函数对transaction进行处理时,如果该transaction使用了Field-Automation机制,那么这些函数就会自动调用内部方法,并把第二个参数what_设置成对应的函数处理字段。宏体的声明导致相应case语句分支操作的执行,而分支操作里的函数又通过调用其他方法实现。过长的调用路径导致过多的冗余代码执行,使得测试用例的运行时间和调试难度大大地提高。
图3 宏的实现
UVM库里提供另一种方法来实现函数print,copy,compare,pack,unpack,即do_
do_compare的重写只需添加下面几行代码即可实现compare的功能:
function bit do_compare(uvm_object rhs);
transaction rhs_;∥transaction为自定义的类
do_compare=(S|cast(rhs_,rhs)&&addr==rhs_.addr);∥添加要比较的变量
endfunction
相比原有的transaction定义,改进的transaction定义没有宏体的声明,避免了过长的路径调用;重写的do_
本文以通用串行接口(universal serial interface,USI)模块的快速验证为例,对文中提到的方法进行评估。USI 为自行开发,该模块包括了高级外围总线(advanced peripheral bus,APB)接口,寄存器TX FIFO和RX FIFO,功能模块(UART,I2CM,I2CS,SPIM,SPIS)和串行接口,通过配置控制寄存器,可使相应的功能模块工作,实现了UART, I2C, SPI 3种协议。
基于层次化公用库的思想和高效的transaction定义,设计了如图4所示的USI模块验证平台。该平台构建了APB UVC,INTR UVC,Reset UVC,DMA UVC(Reset UVC和DMA UVC图中未标出),包含SPI ,I2C,UART UVC的Peripheral。SPI ,I2C,UART UVC均有2个Monitor port,分别用于传递期望的数据和实际的数据。Reference model包含了TX,RX FIFO,APB,SPI,UART,I2C等模型,功能行为与DUT一致。 用户在case里通过寄存器模型操作APB_UVC配置控制寄存器选择相应的功能模块。写操作时,APB UVC向DUT TX FIFO写数据,写入当前数据同时也传给reference model的TX FIFO模型,根据配置选择相应的功能模型(SPI,I2C或UART)读出数据,发送给Scoreboard,作为期望的数据;实际的数据则是设备UVC监测DUT接口得到的数据。读操作时,通过case启动sequencer,将得到的transaction数据写入reference model RX FIFO, 并通过APB模型读出发送给Scoreboard,作为期望的数据;实际的数据由寄存器模型操作APB UVC读取DUT的RX FIFO数据。
USI验证以高效性为原则。原有的验证平台的代码量有一万行之多,基于公用库的验证平台将代码量减少到数千行之内,60 %以上的功能代码可通过调用公用库实现。由于使用了公用库,验证不同串行总线IP时,验证工程师只需在此基础上进行功能扩展,实现了验证组件可重用性。
图4 USI验证结构
与传统的transaction定义方法相比,改进的transaction定义缩短了仿真运行时间。表1列出在回归测试之前相同测试用例下,2种不同的transaction定义对仿真时间的影响。I2C,SPI模块对transaction的操作相对复杂,调用了copy,compare,print函数,与改进前的transaction定义相比,仿真速度提升了6 %~7 %左右;而UART模块相对简单,对transaction的处理次数少,仿真速度只提升了3 %。
表1 仿真时间对比
图5为同期开展的USI回归测试2种不同transaction定义,达到规定覆盖率要求所需验证时间的对比结果。可以看出,使用改进的transaction 的验证平台在50 h左右的测试时间内,完成USI模块100 %的功能覆盖率验证,96.6 %的代码覆盖率验证;使用Field-Automation机制的transaction 验证平台则在56 h左右达到相同的覆盖率。测试结果表明,改进的transaction定义使USI验证时间缩短10.7 %。对于在大型的验证项目中,对transaction处理的次数越多,仿真速度提升效果将会越明显。
图5 不同transaction定义达到96 %覆盖率所需验证时间
本文设计了一种面向串行总线的层次化UVM验证平台。相对于已有的UVM验证平台,引进了公用库的概念,使得验证平台能最大限度重用,同时对传统的transaction定义进行改进,缩短了仿真测试时间。实验表明:基于公用库的多标准串行总线协议验证平台和改进的transaction定义使验证效率得到了提升。下一步将根据配置文件,用脚本自动生成公用库,实现验证组件的自动化生成。