UVM入门进阶4

发布时间 2023-07-15 21:50:25作者: Fireworks、

UVM结构回顾

UVM结构

Alt text

UVM_TOP

UVM中真正的树根是uvm_top。uvm_top是一个全局变量,是uvm_root的唯一一个实例(设计模式中的singleton,单态模式),uvm_root派生于uvm_component,因此uvm_top本质是一个uvm_component。uvm_test_top的parent是uvm_top,而uvm_top的parent是null。uvm_root在仿真一开始就存在,在仿真时跑run 0以后可以发现,top层有了层次结构,可以看到所有的实例都是在0时刻创建的(因为顶层调用了run_test)。

(1) uvm_test_top实例化时的名字是uvm_test_top,这个名字是由UVM在run_test时自动指定的;
(2) uvm_top的名字是_top_,但是在显示路径时,并不会显示这个名字,而只显示从uvm_test_top开始的路径;

如果一个component在实例化时,其parent被设置为null,那么这个component的parent将会被系统设置为系统中唯一的uvm_root的实例uvm_top。
如下图所示:
Alt text
在验证平台中,有时候需要得到uvm_top,由于uvm_top是一个全局变量,可以直接使用uvm_top。除此之外,还可以使用如下方式得到它的指针:

uvm_root top;
top = uvm_root::get();

UVM_TEST

Alt text

  • "test"类是用户自定义类的顶层结构
  • 所有的test类都应该继承于uvm_test,否则,uvm_top将不识别——无法启动test
  • test的目标包括
    • 提供不同的配置,包括环境结构配置,测试模式配置等,然后再创建验证环境
    • 例化测试序列,并且挂载到目标sequencer,使其命令driver发送激励

构建环境的主要组件

uvm_component

  • 继承于uvm_report_object(进一步继承于uvm_object)
  • 所有的验证环境组件均继承于uvm_component
  • 管理验证环境的层次

uvm_env

  • 继承于uvm_component
  • 为验证环境结构提供一个容器

uvm_test

  • 继承于uvm_component
  • 提供对uvm_env的额外配置以及挂载激励

MCDF顶层验证方案

概述

MCDF主要功能:将输入端的三个通道数据通过数据整形和过滤,最终输出

MCDF的设计结构分为四个模块:

  • 上行数据的通道从端(channel slave)
  • 仲裁器(arbiter)
  • 整形器(formatter)
  • 控制寄存器(control register)

MCDF顶层验证方案

REG_ENV

Alt text
寄存器模块的验证环境组件包括:

  • reg_master_agent:配置寄存器,提供寄存器接口驱动信号,如:addr,cmd,data等
  • reg_slave_agent:提供寄存器接口反馈信号。如:chnl_slv的chnl_en信号,arbiter的priority信号,formatter的data_length信号,slv_fifo的available信号
  • scoreboard:分别从reg_master_agent和reg_slave_agent内的monitor获取监测数据,并且进行数据比对

chnl_en信号,arbiter的priority信号,formatter的data_length信号不需要驱动,因此使用reg_alv_agent中的monitor来监测即可。slv_fifo需要reg_slave_agent的driver进行驱动,配置。 reg_slave_agent将其配置为某一个数后,reg_master_agent进行读操作

对于寄存器的写操作:
通过reg_master_agent对寄存器进行配置从而达到对三个chnl的配置,然后reg_slv_agent通过slave_if将变化后的chnl_slv的chnl_en信号,arbiter的priority信号,formatter的data_length信号监测回来传到scoreboard中。reg_master_agent写的数据也送到scoreboard中,这部分数据通过数组存放在scoreboard中,然后在scoreboard中将这两部分数据进行比较。

对于寄存器(状态寄存器)的读操作:
状态寄存器表示的是slv_fifo的余量。通过reg_slv_agent的driver对register的slv_available进行配置,然后更新(不明白slv_fifo的余量为什么需要配置呢然后reg_master_agent将这些值读回来,在scoreboard中进行比较

CHNL_ENV

Alt text
数据通道从端的验证环境chnl_env的组件包括

  • chnl_master_agent:提供上行的激励数据,data,valid,ready等
  • chnl_slv_agent:提供用来模拟arbiter仲裁信号(在chnl发送req命令后,chnl_slv_agent返回ack命令),并且接受流出数据。后续在MCDF时,chnl_slave_agent不再需要driver,sequencer了,因为真正和slv相连的信号是arbiter
  • reg_cfg_agent:提供用来模拟寄存器的配置信号,并且接收内置fifo的余量信号
  • scoreboard:分别从chnl_master_agent、chnl_slv_agent和reg_cfg_agent的monitor接收监测数据,并且对channel的流入流出数据进行比对.register和chnl连接的信号只有一个ch_en,reg_cfg_agent做的事就是什么driver什么时候enable,什么时候disable。monitor监测什么时候打开,什么时候关掉

ARB_ENV

Alt text
arbiter_master_agent:给arbiter提供并行数据,并且对来自arbiter的仲裁信号进行响应
arbiter_slave_agent:模拟formatter的功能,接收来自arbiter的输出数据,对arbiter的输出信号做出响应
reg_cfg_agent:对三个chnl的优先级进行配置
scoreboard:从三个agent的monitor中获取监测数据,对arbiter的仲裁机制做出预测,并且将输入输出数据按照预测的优先级做出比对

FMT_ENV

Alt text
fmt_master_agent:模拟接收从arbiter输出的数据
fmt_slv_agent:模拟formatter的下行端,输出整形后的数据,并且在formatter发送req信号后,给grant信号
reg_cfg_agent:模拟寄存器的配置信号,用来指定输出数据包的长度

环境集成方案一

Alt text

和sv时的验证框架基本一致,该方案中最大的投入在于需要新建一个scoreboard用来检查MCDF的整体功能。如果顶层设计复杂的话,构建一个新的scoreboard就很困难了,有可能难以实现

环境集成方案二

Alt text

  • 方案一与方案二都需要新建virtual sequencer和virtual sequence,用来生成顶层的测试序列。virtual sequencer和virtual sequence也是利用原有模块环境的序列库进行有机组合后生成的新的测试序列
  • mcdf的子组件不再是uvm_agent类,而是各个模块的验证环境uvm_env类
  • 通过直接复用子环境,也间接复用了子环境内部的scoreboard,在build阶段,需要通过config_db将不需要再产生激励的agent配置为passive模式,默认情况下agent为active模式
  • 使用方案二在新建MCDF顶层scoreboard时复杂度较方案一会低很多(也可以不用构建)
  • 复用了模块一级的scoreboard,因此方案二便于调试

构建验证环境的内经

环境构建的四要素

  • 单元组件的自闭性
  • 回归创建
  • 通信端口连接
  • 顶层配置

顶层配置

Alt text

环境元素分类

将uvm_test层作为比uvm_env更高的层次绘制出来,这是因为uvm_test层会有一些配置的部分传递给子环境。环境元素分为以下部分:

  • 成员变量
    • 一般变量
      • 一般变量用于对象内部的操作,或者为外部访问提供状态值
    • 结构变量
      • 用来决定内部子组件是否需要创建和连接(is_active)
    • 模式变量
      • 用来控制组件的行为

对于结构变量和模式变量,一般由int或enum类型定义,用户可以在uvm_test层通过uvm_config_db的配置方法直接设置,也可以通过结构化的配置对象进行系统设置

  • 子组件
    • 固定组件
      • 环境必须创建的组件,agent中的monitor,顶层的scoreboard
    • 条件组件
      • 通过结构变量的配置来决定是否需要创建,sequencer和driver
    • 引用组件
      • 内部声明一个类型句柄,经过自顶向下的传递后,使得该句柄可以指向外部的一个对象,此时传递后的外部的句柄为引用组件
  • 子对象
    • 自生对象
      • 某一层次中创建的一个对象成为自生对象
    • 克隆对象
      • 对象传递过程中,该对象经过克隆生成了一个成员数值相同的对象,此为克隆对象
    • 引用对象
      • 对象经过端口传递,到达另一个组件,该组件未经过克隆而进行操作,称为对引用对象的操作

对克隆对象的操作,不会影响自生对象的数值;对引用对象的操作,会影响自生对象的数值