- build_phase负责测试用例结构的创建和配置,构建组件的层次结构。
- connect_phase用于连接类中的不同子组件。
- run_phase是主要阶段,在其中执行仿真。
- report_phase可用于显示仿真的结果
为了在类和变量中实现一些重要的方法,UVM提供了UVM宏。最常见的UVM宏如下:
- uvm_component_utils: 当类从uvm_component类派生时,注册一个新的类的类型。
- uvm_object_utils: 类似于uvm_component_utils,但类是从类uvm_object派生的类。
- uvm_field_int: 在UVM工厂注册一个变量。这个宏提供了像copy()、compare()和print()这样的函数.
- uvm_info:在环境中仿真期间打印消息。
- uvm_error:这个宏发送带有错误日志的消息。
- uvm_fatal: 仿真发生致命错误时,这个宏可以强制结束仿真并打印消息。
为了解释一个UVM环境的结构,在测试用例中,将使用一个简单的加法器作为测试设计(DUT)。UVM测试平台如图所示。DUT是与测试台交互以验证其功能的硬件实现。
为了实现DUT的仿真, sequencer产生一系列数据送入DUT。由于sequencer发送高抽象级别的数据包,并且DUT只接受来自接口的数据,所以,driver用来将来自sequencer的数据包,转换成信号送入DUT。
经过接口的数据需要被捕获,以便后续的仿真验证。由于driver只能实现数据包到信号的转换,所以,另外还需要一个模块实现与driver相反的功能,将信号转换成数据包。monitor就是这样的一个模块,收集driver与DUT之间通信的接口信号,并将其转换成数据包,最后送入参考模型中去进行比较。
一个agent通常包含三个组件:一个sequencer序列发生器,一个driver驱动,一个monitor监控。有两种类型的agent:Active Agent包含上述三个组件;Passive Agent只包含上述的monitor监控和driver驱动。agent包含build phase函数,用于去创建层次结果,以及connect phase用于连接模块。
参考模型(refmod)是在RTL实现之前,早期阶段构思的理想的模型。在抽象的高级别上模拟DUT。
comparator类主要用于比较参考模型和DUT之间的数据。参考模型和比较器组成了记分牌,用于检查DUT产生的传输是否正确。一个或者多个agent加上记分牌构成了env类。测试类负责执行测试,创建环境,并将序列连接到序列发生器上。最后,top中实现DUT和testbench的例化。
下面通过对一个加法器验证环境的搭建,来进一步理解UVM中的各个组件。加法器模块的功能验证平台分为以下的模块和类。
接口的构造是专门为封装块之间的通信信号而创建的,modport为模块端口提供方向信息,并控制特定模块内任务和功能的使用。
待测设计DUT(design under test)是需要被验证的设计代码。
传输数据包的构造是专门为封装块之间通信的数据而创建的,其中的field机制能够将数据包中的数据注册到UVM工厂中,为数据提供copy()、compare()、print()、colne()等函数。
UVM序列是一个对象,它用于生成仿真的行为。UVM序列不是组件层次结构的一部分。每个UVM序列最终被绑定到一个UVM序列器。多个UVM序列实例可以绑定到同一个UVM序列器。
UVM序列器作为仲裁器,用于控制来自多个仿真序列的事务流。更具体地说,UVM序列器控制,由一个或多个UVM序列生成的事务流。
驱动器(driver)从序列器(sequencer),接收序列(sequence)产生的传输数据包(transaction),并在DUT接口上应用(驱动)它。因此,驱动器driver将传输级别的数据包仿真,转换成管脚信号级别的仿真。它还有一个TLM接口,用于接收来自序列器sequencer的传输数据包transaction,去驱动DUT上的接口信号。
代理(agent)是一个分层组件,它将处理特定DUT接口的其他验证组件组合在一起。一个典型的代理包括:一个sequencer,用于管理仿真流的UVM序列器;一个driver,用于在DUT接口上驱动仿真的驱动器;一个monitor,用于监视DUT的接口。代理可能包括其他组件,如覆盖率收集器、协议检查器、TLM模型等。
记分板(scoreboard)的主要功能是检查DUT的行为是否正确。记分板接收的实际数据包,来自代理(agent)送入DUT的输入输出,接收的期望数据包,来自参考模型,最后在记分板中比较实际的数据包和期望的数据包。
测试用例是测试台中最顶层的组件。测试用例通常执行三个主要功能:实例化顶层环境、配置环境(通过工厂覆盖或配置数据库),以及通过在环境中调用序列来进行仿真。
通常,有一个带有UVM环境实例化和其他公共项的基本UVM测试。然后,其他单独的测试将扩展这个基本测试,并以不同的方式配置环境或选择不同的序列运行。
测试用例是在运行时动态实例化的,允许UVM测试台只编译一次,并与许多不同的测试一起运行。
顶层主要实例化DUT模块和测试类,并配置它们之间的连接。
SystemVerilog直接编程接口(DPI)是SystemVerilog调用外部语言(如C、c++等)函数的接口。DPI由两个层组成:SystemVerilog层和外语层,它们彼此隔离。下面给出了refmod的代码,以说明DPI的用法。sum()函数在文件external.cpp中定义,一旦在refmod中调用它,就应该在sum()函数的定义之前添加关键字“external C”
comp函数先通过g++编译C程序,再通过VCS进行编译,其中-debug_access+cbk选项对静态网络、寄存器和变量启用基于PLI的回调。-cm tgl+line+fsm+cond+branch选项开启代码翻转覆盖率、行覆盖率、状态机覆盖率、条件覆盖率、分支覆盖率。
sim函数执行VCS仿真。
dbg函数用于VCS和verdi联调,编译里边加入了-debug_access+all -kdb –lca选项,仿真里边加入了-gui=verdi选项。
verdi函数用于启动verdi查看波形。
urg_gui函数用于查看代码覆盖率。
上述完整代码下载链接如下:
https://github.com/AFEI1100/easyUVM-master.git
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/13238.html