天天看點

uvm-1.2 examples —— 2.10 objections2.10 objections前言一、基本介紹二、代碼分析總結

2.10 objections

文章目錄

  • 2.10 objections
  • 前言
  • 一、基本介紹
  • 二、代碼分析
    • 2.1 simple.sv
    • 2.2 仿真結果
  • 總結

前言

本文以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()方法的使用,該方法在實際驗證環境中往往很有用,可以有效避免激勵還沒有完成,仿真就結束的問題。