uvm-1.2 examples —— 2.10 objections

2.10 objections



前言

本文以uvm-1.2/examples/simple/objections为例,通过代码了解UVM中objections机制的一些用法。通过这个例子可以基本了解以下知识点:

  • 什么是objections机制
  • 如何使用objections机制
  • set_drain_time的使用

一、基本介绍

objection翻译过来就是反对、异议的意思,在UVM中,通过举手(raise_objection)和放手(drop_objection)的方式来控制仿真平台的运行。

在张强《UVM实战》5.2节中,对UVM的objections机制有一个比较详细的介绍。其中有个例子较为形象有趣:将UVM的树形结构的每个componet组件,比作一层房子的每个房间,每一层的房间布局一样,将每一层比作一种类型的phase,一棵叫UVM的植物负责依次检查每层(phase)的各个房间(componet)是否有僵尸(是否raise_objection),直到所有的僵尸消失(drop_objection)。这个类比的例子说明几点问题:首先,由于每层的布局都一样,竖着来看这个房子,可以发现每个房间(componet)的层数(phase)都一样,这说明每个UVM的组件都拥有相同的phase数量;其次,任意一层的任意一个房间都有可能存在僵尸,这说明任意一个组件的任意一个phase都可以raise_objection,最后,发现了僵尸就一定要将其消灭,这说明raise_objection和drop_objection要成对存在。

这个例子设置了drain time为10ns,之后通过fork同时启动了4个并行的进程,当最后一个进程在50ns结束时,drain time起效,整个仿真在60ns结束。同时,这个例子还设置了drop_objection的回调函数,每执行一次drop_objection结束一个进程,该回调函数就会被调用一次。

二、代码分析

这个简单的测试用例只有simple.sv一个文件。

2.1 simple.sv

`timescale 1ns/1ns

module test;

  // This simple example shows how the uvm_test_done objection is
  // used to coordinate end of test activity. For an example of
  // using end of test coordination in the context of a full
  // environment, refer to the xbus example.

  // In this example, a drain time of 10 is set on the component.
  // The component then forks 4 processes which consume different
  // amounts of time. When the last process is done (time 50),
  // the drain time takes effect. The test is completed at time
  // 60.

  // The example also shows usage of the component objection 
  // callbacks. In this case, the dropped callback is used, but
  // the raised and all_dropped work similarly (except the 
  // all dropped is a time-consuming task).

  import uvm_pkg::*;
  `include "uvm_macros.svh"

  class simple_test extends uvm_test;
    function new (string name, uvm_component parent);
      super.new(name, parent);
    endfunction : new

    // Register with the factory.
    `uvm_component_utils(simple_test)

    virtual task run_phase(uvm_phase phase);
      // Set a drain time on the objection if needed
      uvm_report_info("drain", "Setting drain time of 10", UVM_NONE);
      uvm_test_done.set_drain_time(this,10);

      // Run a bunch of processes in parallel
      fork
        doit(35);
        doit(25);
        doit(50);
        doit(15);
      join
    endtask

    // A simple task that consumes some time.
    task doit (time delay);
      static int s_inst = 0; int inst = s_inst++;

      //Raise an objection before starting the activity
      uvm_test_done.raise_objection(this);

      uvm_report_info("doit", $sformatf("Starting doit (%0d) with delay %0t", 
          inst, delay), UVM_NONE);
      #delay;
      uvm_report_info("doit", $sformatf("Ending doit (%0d)", inst), UVM_NONE);

      //Drop the objection when done
      uvm_test_done.drop_objection(this);
    endtask

    // Use an objection callback do something when objections are raised or
    // dropped (or all dropped). This example prints some information on each
    // drop.
    virtual function void dropped (uvm_objection objection, 
        uvm_object source_obj, string description, int count);
      uvm_report_info("dropped", 
        $sformatf("%d objection(s) dropped from %s, total count is now %0d", 
        count, source_obj.get_full_name, objection.get_objection_total(this)), 
        UVM_NONE);
    endfunction

  endclass : simple_test

  // Run the test
  initial
    run_test("simple_test");

endmodule

第1行指定了仿真的时间单位和时间精度,斜杠前面是时间单位,斜杠后面是时间精度。

第24到73行定义了一个simple_test的类。
25到27行是这个类的构造函数;
30行将这个类注册到UVM的factory机制中;
32到44行定义了run_phase,其中,35行设置了drain_time=10,38到43行利用fork,同时调用了doit这个task,启用了四个并行的进程,但传递的参数不一样。
47到60行定义了doit这个task,在这个task中,48行利用静态变量的唯一性,保存doit被调用的次数,51行和59行构成了一对“举手”和“放手”,这中间执行的是消耗时间的仿真,并打印了相关信息。
65到71行定义了drop_objection的回调函数dropped,也就是没执行一次drop_objection,这个dropped函数就自动执行一次。

77行启动并执行仿真。

2.2 仿真结果

UVM_INFO @ 0: reporter [RNTST] Running test simple_test...
UVM_INFO @ 0: uvm_test_top [drain] Setting drain time of 10
UVM_INFO @ 0: uvm_test_top [doit] Starting doit (0) with delay 35
UVM_INFO @ 0: uvm_test_top [doit] Starting doit (1) with delay 25
UVM_INFO @ 0: uvm_test_top [doit] Starting doit (2) with delay 50
UVM_INFO @ 0: uvm_test_top [doit] Starting doit (3) with delay 15
UVM_INFO @ 15: uvm_test_top [doit] Ending doit (3)
UVM_INFO @ 15: uvm_test_top [dropped]           1 objection(s) dropped from uvm_test_top, total count is now 3
UVM_INFO @ 25: uvm_test_top [doit] Ending doit (1)
UVM_INFO @ 25: uvm_test_top [dropped]           1 objection(s) dropped from uvm_test_top, total count is now 2
UVM_INFO @ 35: uvm_test_top [doit] Ending doit (0)
UVM_INFO @ 35: uvm_test_top [dropped]           1 objection(s) dropped from uvm_test_top, total count is now 1
UVM_INFO @ 50: uvm_test_top [doit] Ending doit (2)
UVM_INFO @ 50: uvm_test_top [dropped]           1 objection(s) dropped from uvm_test_top, total count is now 0
UVM_INFO ../../../src/base/uvm_objection.svh(1270) @ 60: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO ../../../src/base/uvm_report_server.svh(847) @ 60: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :   16
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[RNTST]     1
[TEST_DONE]     1
[UVM/RELNOTES]     1
[doit]     8
[drain]     1
[dropped]     4

$finish called from file "../../../src/base/uvm_root.svh", line 517.
$finish at simulation time                   60
           V C S   S i m u l a t i o n   R e p o r t 
Time: 60 ns
CPU Time:      2.940 seconds;       Data structure size:   0.3Mb

从仿真结果来看,在0ns时刻,利用fork同时调用了四个doit进程。由于进程3传递的delay=15,所以在15ns时刻,进程3首先结束,并调用drop_objection的回调函数dropped;其次分别在25ns、35ns和50ns处,进程1、0、2依次分别结束;最后由于drain_time=10ns,所以,仿真在60ns处结束。


总结

通过这个测试用例,可以进一步理解UVM中运行的objection机制,同时了解set_drain_time()方法的使用,该方法在实际验证环境中往往很有用,可以有效避免激励还没有完成,仿真就结束的问题。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值