陈富强
摘要 分析了UVM(UniversalVerification Methodology)验证平台和使用UVM中寄存器模型的验证过程,通过研究流水线工作方式和验证过程中read()、write()任务工作的流程,证明UVM中寄存器模型在解决流水线方面的问题时存在固有的问题。然后结合寄存器验证中常见的复位验证、交叉位验证等给出合适的解决方案。
【关键词】UVM验证平台 寄存器模型 流水线固有问题 解决办法
1 引言
随着集成电路设计向超大规模发展,芯片验证工作的难度在不断增大,验证的工作量已经占到整个SOC研发的70%左右,因此提高芯片验证的效率己变得至关重要。UVM继承了VMM和OVM的优点,克服了各自的缺点,代表了验证方法学的发展方向。UVM实现了测试随机产生、自测试平台和随机化约束;采用最佳的验证框架去实现覆盖率驱动验证,能大大缩短验证时间。
寄存器模型跟参考模型类似,就是为工程里的寄存器提供一个参考模型这个模型里,包括各个寄存器字段描述、寄存器、寄存器组、寄存器地址映射等信息。
2 UVM验证平台
图1为典型UVM验证平台,包括一个基本的验证平台的所有组件。验证平台要模拟DUT的各種真实使用情况,这需要给DUT施加各种激励,有正常的激励,也有异常的激励。验证平台需要记分板( scoreboard)来根据DUT的输出判断DUT的行为是否与预期相符合;既然是判断,那么牵扯到两个方面:
(1)判断的内容即DUT的输出;
(2)判断的标准。
验证平台通过监控器(monitor)收集DUT的输出并把他们传递给scoreboard;而进行判断的判断标准是预期结果,产生预期结果的结构就是参考模型( reference model)。
3 通过UVM寄存器模型完成寄存器3证
通常来说,DUT中会有一组控制端口,通过控制端口,可以配置DUT中的寄存器,DUT可以根据寄存器的值来改变其行为。这组控制端口就是寄存器配置总线。如图2所示,为带有配置总线验证模块的验证平台。
在没有寄存器模型之前,只能启动sequence通过前门(FRONTDOOR)访问的方式来读取寄存器,局限较大,在scoreboard(或者其他component)中难以控制。而有了寄存器模型之后,scoreboard只与寄存器模型打交道,无论是发送读的指令还是获取读操作的返回值,都可以由寄存器模型完成。有了寄存器模型后,可以在任何耗费时间的phase中使用寄存器模型以前门访问或后门( BACKDOOR)访问的方式来读取寄存器的值,同时还能在某些不耗费时间的phase(如check_phase)中使用后门访问的方式来读取寄存器的值。
在寄存器模型的使用过程中,我们通常使用前门访问的方式,这样更接近DUT的实际工作状态。对一块实际焊接在电路板上正常工作的芯片来说,如果要访问其中的某些寄存器,前门访问操作是唯一的方法。
寄存器模型的前门访问操作最终都将由uvm_reg_map完成。uvm_reg_map调用read()任务的完整流程为:
(1)调用寄存器模型的读任务read()。
(2)寄存器模型产生sequence,并产生uvm_regjtem: rW。
(3)产生driver能够接受的transaction:bus_req= adapter.reg2bus(rW).
(4)把bus_reg交给bus_sequencer。
(5) driver得到bus_req后驱动它,得到读取的值,并将读取值放入bus_req中,调用item done。
寄存器模型调用adapter.bus2reg(bus_reg,rw)将bus_req中的读取值传递给rw。
(6)从rw中就可以得到需要读取的寄存器的值。
从上面过程中得到的DUT中寄存器的值,我们通常用来验证DUT中寄存器的行为是否正确。首先我们保留一份read()任务执行前的寄存器模型中的值,然后执行read()任务得到DUT中寄存器的值;然后将二者进行比较,从而判断DUT中寄存器的行为是否正确。代码如下:
m_val= reg.get();
n_val= reg.read();
if(m_val==n_val)
、uvmjnfo(“right”)
else
、uvmjnfo(“wrong")
4 寄存器模型在遇到流水线配置总线时的固有问题及解决办法
当我们需要更高的执行速度的时候,就需要通过流水线的方式配置寄存器;即在每一个时钟周期都会发送一次寄存器的值。在SystemVerilog中可以通过fork..j oin_none轻松实现流水线模型,从而完成driver驱动transaction到DUT内部。
假设每一个完整的指令由三个分解的操作步骤完成,顺序依次为操作1、操作2、操作3每一个操作的时间为T。那么流水线过程可以表示为如图3所示。
此时验证寄存器功能的读任务(read())的前门访问过程依然和前面是一样的,数据将通过3个周期后到达DUT中的寄存器,并将数据返回到bus总线上,从而得到DUT内部的寄存器数据。
但是在这个过程中,read()任务并没有如我们所希望的那样得到DUT中寄存器的值,read()任务在driver发送item done之后,就从bus总线上读取所需要的值,然后执行bus2reg将数据从DUT中取回到寄存器模型中,但是item done是在driver接收到sequencer发送来的transaction后就发送的,如果driver本身有多个周期,这就导致read()任务无法从DUT中读取正确的数据。这个问题是由UVM的寄存器模型先天不支持pipeline配置总线导致的。
解决这个问题由两种办法,第一种是修改UVM寄存器模型中的一些任务或者函数的源代码;第二种是采用通用的验证流程,设计reference model和scoreboard。将整个比较的过程放在scoreboard中,而不是放在sequence当中。
采用通用的验证过程来验证的过程如图4所示。在整个过程中,通过reg_ref_model将UVM寄存器模型read()之前的值,发送到scoreboard(即图4中的A过程)。然后通过monitor获得DUT中当前寄存器的值(即图4中的B过程)。
在上面的过程中,可以通过打印数据和波形图观察整个验证过程。
5 实验及结果
这种解决方案通过了实际应用的验证,在VIC(中断管理器)验证项目中的寄存器验证过程中,通过这种结构完成了含有流水线配置总线的DUT中寄存器的复位、置位、交叉位、隨机读写等功能的验证。
验证结果如表1所示。
其中,RW为读写寄存器,RO为只读寄存器,w0为只写寄存器,ws为写入时置位寄存器;success表示正常通过所有的寄存器验证,pass为忽略掉的寄存器,需要其他方法来验证。
6 结束语
在验证领域,验证语言整齐划一、仿真平台的统一、发展正规高效的验证方法学,一直是IC验证的发展趋势。本文分析了UVM中寄存器模型的使用方法和在解决流水线方面的问题中固有的不足,最后给出了具体的解决方案。
由于项目中的read()任务需要通过前门访问实现,所以对于那些只写的(write only)寄存器、随着其他状态变化的寄存器、瞬间变化的寄存器等的验证只能通过观察DUT的状态来实现。对于这些特殊的寄存器没有固定的验证方法,必须凭经验和深入分析寄存器的功能来制定合适的验证方案。
参考文献
[1]李磊,罗胜钦,基于VMM方法的sOc集成验证[J],电子测量技术,2011,1 (01):3—7.
[2]张强.UVM实战[M].北京:机械工业出版社,2016,7 -120.
[3]张强.UVMl.1应用指南及源代码分析[M].北京:机械工业出版社,2 011,400-631.
[4]Chris, Spear. System Verilog forVeriFication[M].US:SynopsysInc.2008, 5-10.