SystemVerilog中的随机化激励神州龙芯集成电路设计公司杨鑫 徐伟俊 陈先勇 夏宇闻[摘要]:随着集成电路的验证工作日渐复杂,对验证的可靠性提出了越来越高的要求。
传统的验证工作中也使用随机化激励以便减轻测试代码编写的工作量,以提升验证的可靠性。
在SystemVerilog更强调了利用随机化激励函数以提高验证代码的效率和验证可靠性的重要性。
本文以VMM库为例,阐述了如何在SystemVerilog中使用随机化函数来编写高效率的测试代码,重点介绍了可重用验证函数库的使用方法,以帮助读者理解如何使用SystemVerilog高效率地完成复杂的设计验证。
关键字:VMM SystemVerilog 激励随机化1. 前言随着电路工艺设计技术的不断发展,集成电路的逻辑设计变得越来越复杂,随之对验证工作提出了更高的要求。
由于投片(tip-out)的费用较高,很有必要在投片前对芯片设计进行全面、可信的验证,以尽量减少“设计——测试——投片——调试——发现Bug修改设计”这一流程的迭代次数。
因此在集成电路芯片的设计中,尤其是复杂逻辑设计中,对测试工作的效率和可靠性提出了更高的要求。
在传统的验证方法中,也有将激励随机化的方法,这样可以用较少的测试代码生成较多、较全面的测试激励。
这些方法减少了人为因素的干扰,能有效地提高验证的工作效率和可靠性。
在SystemVerilog中,强调在验证中使用可重用的验证IP,包括如何生成随机化激励。
对于如何尽可能地使用已有的验证IP,以及编写符合标准的可重用验证组件,SystemVerilog提供了一整套的工作机制,这使得符合规范的随机化激励组件能够很好地在多个设计间复用,这更进一步地提高了验证工作的效率和可靠性。
2. 在验证中使用随机化激励在验证中,可以依照DUT(Design Under Test,被测设计,以下简称DUT)的验证要求来设计定向的激励,并对照DUT的预期响应,用人工的方法来判断设计是否正确。
但也可以使用随机化激励来驱动DUT,并使用特定的机制来完成响应的自检测。
利用随机化来产生激励可以看作一种近似的自动化激励产生,因为随机化足够长的时间后,所生成的激励可以覆盖绝大部分的待验证特性。
但是纯粹的随机化激励效率并不高,因为其中正确的,或是有意义的激励只占很少一部分。
必须使用一定的约束条件限制随机化的范围,从而产生大量随机而有意义的激励。
3 在SystemVerilog中使用随机化激励SystemVerilog极大地扩展了验证的编写方式,SystemVerilog引入了面向对象的概念,强调基于已有验证库或验证IP,按照面向对象的方法编写可重用的验证组件。
VMM(Verification Methodology Maunul for SystemVerilog,以下简称VMM)是由Synopsys 公司推介的一套SystemVerilog验证解决方案,其中提供了VMM库以供用户在VCS环境下使用。
下文将结合VMM的使用,阐述在SystemVerilog中如何使用随机化激励。
3.1 VMM的验证结构层次VMM使用了一套层次化的验证结构,它将整个验证分为测试、验证平台和DUT三个主要部分,各个分立的测试(Test)通过一个相对稳定的验证平台(Test-Bench)来完成对DUT 的测试,其总体结构如下图所示:在整个结构中,测试平台是最为关键的部分,它负责响应测试的控制,对DUT施加激励,收集DUT的响应,并根据预期值判断、统计和报告测试情况。
其内部也分为若干层次,其中在激励的施加路径上,包括用于产生事务级激励的激励发生器(Generator),用于接收和处理、解析事务的事务处理器(Transactor),以及为事务处理器提供DUT驱动的驱动(Driver)等。
事务处理器和相关驱动是与DUT相关的,提供了测试平台对DUT的抽象和底层信号连接。
激励生成器则是测试平台中的激励源,编写适当的激励发生器,就能够方便灵活地产生各种所需的激励。
3.2数据与事务传统的测试中,数据(data)和激励事务(transaction)一般是一一对应的简单映射关系,这样使得数据(data)不仅难于使用,而且不易维护和更改。
在SystemVerilog中,事务(transaction)被看作是一个对象,使用面向对象的思想来封装数据,这既增强了数据的稳定性和可靠性,而且使事务的相关数据可以灵活地扩展或更改。
在VMM中,提供了基类VMM_DATA作为所有数据型类的基础,利用它我们可以方便地封装所需的数据,例如我们可以声明一个简单的事务bus_trans,用来表示一次总线传输:enum _trans =READ, WRITE;class bus_trans extends vmm_data;rand _trans Trans;rand bit [7:0] ChipSel;rand bit[19:0] Addr;[31:0] Data;rand bitendclass在该例子中,所有属性都被标识为可以随机化——即标明了类型:rand。
实际上如果没有特殊需求,应当将事务的所有属性都应将其标识为可随机化,这是为了能够让激励生成器能够最大限度地生成各种类型的事务。
同时所有的事务属性都应当是共有属性(Public),这样才能通过外部来引用或改变事务的各个属性。
在事务的类声明中,可以根据需要添加一些约束,以便保证所生成的事务是所需要的。
例如可以在上述例子的事务中加入一个约束,以要求片选信号ChipSel只能取1、8、16三个值:class bus_trans extends vmm_data;…{ChipSel inside {1, 8, 16};}constraint chip_selectendclass事务的约束中有些是必须遵守(must-obay)的,例如要求某些属性必须为非零等,这些约束是不能被关闭(turn-off)的,而其他的约束则是应当遵守(should-obay)的,在必要时,可以通过一些操作将其关闭,这些需要根据具体需要来指定。
在测试平台的编写中,事务的定义很重要,只有恰当地定义各种事务,才能有效地完成测试。
在编写事务类时,可以利用其各种面向对象的特性,例如可以使用继承和派生的方式衍生出新的事务类,在需要时重载或重写约束以达到新的边界情况等。
3.3使用工厂模式的激励发生器事务的实例化和随机化都是在激励发生器中完成的,在编写激励发生器时,需要控制激励事务的产生和约束控制等,以便在适当的情况下产生适当的事务。
激励发生器的编写也应该使用面向对象的思想,将事务和相关的操作封装到一个类中。
以便于管理和使用。
在VMM中,提供了基类VMM_XACTOR,用来封装所有与事务处理相关的对象。
激励发生器应当从VMM_XACTOR派生得到,而与此相关的事务处理器等也应从VMM_XACTOR 派生而来。
例如,可以声明如下一个最简单的激励发生器:class bus_master extends vmm_xactor;…main();tastforever beginnew();=bus_trans transtrans.randomize();=voidthis.chan.put_t(trans);endendtaskendclass这样就可以产生并随机化事务,然后将其通过通道传输到下游的事务处理器。
但是,使用这种简单的实例化方的激励发生器仍然不够灵活,其中一个主要问题是:如何通过激励发生器为事务添加新的约束块。
通过添加新的约束块来产生必须的激励事务是非常有效的控制方式,但采用上述控制方式的激励发生器要做到这一点却并不容易。
因为对于这种激励发生器,如果需要添加新的约束,就必须改写激励发生器的源代码。
这将极大地影响其使用的灵活性。
因此这里需要使用面向对象思想的又一思想:工厂模式(factory Pattern)。
使用工厂模式的思想来建立激励发生器,使之成为一个生产“事务”的“工厂”,而生产所需的“原料”则由更高层次的测试来控制和提供。
例如,编写形如下面所示的激励发生器:class bus_master_factory extends vmm_xactor;bus_trans trans = new();run();tastbeginwhile(run)bus_trans tr;trans.randomize();void=trans.copy());$cast(tr,process(tr);endendtaskendclass该激励发生器在运行时将会不断地将其属性trans随机化,然后将随机化的结果复制成一个新的实例,最后将这个新复制的实例经过处理发送到下游。
在整个流程中,其起点是类属性trans,该属性在该激励发生器实例化时会自动实例化,但是,在启动任务run()之前,外界,也就是更高层次的测试是可以将其替换成其他新实例的,只要新实例是属性trans所属类bus_trans的同类实例或派生类实例即可。
这样的话,如果需要加入新的约束,只需派生出相关的新类,在新类中加入所需约束,并用新类的实例替换工厂实例即可得到所需的效果。
例如,在下面所示的例子中,根据原有的事务类派生出了新类,并在新类中增加了约束,最后在测试中替换了原工厂实例:class my_bus_trans extends bus_trans;=0;}constraint new_constraint{addr[19:18]endclassprogram testverif_envenv;initial beginenv = new();env.build();beginnew();my_bus_trans my_trans =my_trans;=env.src[0].transendenv.run();endendprogram在该例中,在验证环境完成初始化之后,整个验证环境运行前,使用my_bus_trans类的实例my_trans替换了验证环境env中的激励发生器src[0]的工厂实例trans。
使用工厂模式的激励发生器大大提高了激励发生器使用时的灵活性,激励发生器应尽量使用工厂模式。
5 受控随机化激励生成依照所需激励的不同,可以编写出各种不同的激励发生器,其具体形态和复杂度也相差很大。
在VMM中,根据激励发生器的特性,可以将激励发生器大致分为:基元发生器(Atomic Generator),场景发生器(Scenario Generator),多流发生器(Mutil-Stream Generator)以及基于状态的发生器(State-Dependent Generator)。
下面就简要介绍一下各种发生器的特点和基本用途。