uvm-1.2 examples —— 2.11 phase - basic

2.11 phase - basic



前言

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

  • phase的类型和分类
  • phase的运行机制

一、基本介绍

UVM中全部的phase如下图所示,按照图中的顺序自上而下自动执行,通过phase来控制仿真的执行顺序。黄色部分是function_phase,这类phase不消耗仿真时间;绿色部分是task_phase,这类phase消耗仿真时间。添加这么多的phase,是为了对仿真更精细化的控制,而且也让环境更加灵活。
UVM中的所有phase
build_phase的执行顺序是自上而下,即先执行UVM树状结构根节点的build_phase,再一层一层的往叶子端去执行build_phase。这是因为,在build_phase中主要执行的是实例化工作。例如:driver和monitor都是agent的成员,在agent的build_phase中实例化driver和monitor,但是如果在执行agent的build_phase之前去执行driver的build_phase,就会报错,因为此时driver都还没例化。

除了build_phase之外的其他不消耗仿真时间的function_phase,执行顺序都是自下而上。例如:先执行driver和monitor的connect_phase,再执行agent的connect_phase。

二、代码分析

这个测试用例比较简单,只有一个test.sv文件,创建的UVM树形结构如下所示。

  //                               top  
  //              __________________|_______________
  //             |                                   |
  //           a1(AA)                             a2(AA)
  //       |            |                      |            |
  //     u1(A)         u2(A)                 u1(A)         u2(A)
  //    |     |      |        |              |     |      |        |
  //   b1(B) d1(D)  b1(B)    d1(D)          b1(B) d1(D)  b1(B)    d1(D)

2.1 test.sv

module top;
  import uvm_pkg::*;

  //No run phase
  class D extends uvm_component;
    function new (string name, uvm_component parent);
      super.new(name,parent);
    endfunction
    function void build_phase(uvm_phase phase);
      $display("%0t: %0s:  build", $time, get_full_name());
    endfunction
    function void end_of_elaboration_phase(uvm_phase phase);
      $display("%0t: %0s:  end_of_elaboration", $time, get_full_name());
    endfunction
    function void start_of_simulation_phase(uvm_phase phase);
      $display("%0t: %0s:  start_of_simulation", $time, get_full_name());
    endfunction
    function void extract_phase(uvm_phase phase);
      $display("%0t: %0s:  extract", $time, get_full_name());
    endfunction
    function void check_phase(uvm_phase phase);
      $display("%0t: %0s:  check", $time, get_full_name());
    endfunction
    function void report_phase(uvm_phase phase);
      $display("%0t: %0s:  report", $time, get_full_name());
    endfunction
  endclass

  //Has run phase
  class B extends uvm_component;
    rand logic [7:0] delay;
    function new (string name, uvm_component parent);
      super.new(name,parent);
    endfunction
    function void build_phase(uvm_phase phase);
      $display("%0t: %0s:  build", $time, get_full_name());
    endfunction
    function void end_of_elaboration_phase(uvm_phase phase);
      $display("%0t: %0s:  end_of_elaboration", $time, get_full_name());
    endfunction
    function void start_of_simulation_phase(uvm_phase phase);
      $display("%0t: %0s:  start_of_simulation", $time, get_full_name());
    endfunction
    function void extract_phase(uvm_phase phase);
      $display("%0t: %0s:  extract", $time, get_full_name());
    endfunction
    function void check_phase(uvm_phase phase);
      $display("%0t: %0s:  check", $time, get_full_name());
    endfunction
    function void report_phase(uvm_phase phase);
      $display("%0t: %0s:  report", $time, get_full_name());
    endfunction
    task run_phase(uvm_phase phase);
      $display("%0t: %0s:  start run phase", $time, get_full_name());
      #delay;
      $display("%0t: %0s:  end run phase", $time, get_full_name());
    endtask
  endclass
  
  //Has run phase and contains subcomponents
  class A extends uvm_component;
    rand B b1;
    rand D d1;
    rand logic [7:0] delay;
    function new (string name, uvm_component parent);
      super.new(name,parent);
      b1 = new("b1", this);
      d1 = new("d1", this);
    endfunction
    function void build_phase(uvm_phase phase);
      $display("%0t: %0s:  build", $time, get_full_name());
    endfunction
    function void end_of_elaboration_phase(uvm_phase phase);
      $display("%0t: %0s:  end_of_elaboration", $time, get_full_name());
    endfunction
    function void start_of_simulation_phase(uvm_phase phase);
      $display("%0t: %0s:  start_of_simulation", $time, get_full_name());
    endfunction
    function void extract_phase(uvm_phase phase);
      $display("%0t: %0s:  extract", $time, get_full_name());
    endfunction
    function void check_phase(uvm_phase phase);
      $display("%0t: %0s:  check", $time, get_full_name());
    endfunction
    function void report_phase(uvm_phase phase);
      $display("%0t: %0s:  report", $time, get_full_name());
    endfunction
    task run_phase(uvm_phase phase);
      $display("%0t: %0s:  start run phase", $time, get_full_name());
      #delay;
      $display("%0t: %0s:  end run phase", $time, get_full_name());
    endtask
  endclass

  class AA extends uvm_component;
    rand A a;
    function new (string name, uvm_component parent);
      super.new(name,parent);
      a = new("a", this);
    endfunction
  endclass

  //Top level contains two A components
  class top extends uvm_env;
    rand AA a1;
    rand AA a2;
    function new (string name, uvm_component parent);
      super.new(name,parent);
      a1 = new("a1", this);
      a2 = new("a2", this);
    endfunction
    function void build_phase(uvm_phase phase);
      $display("%0t: %0s:  build", $time, get_full_name());
    endfunction
    function void end_of_elaboration_phase(uvm_phase phase);
      $display("%0t: %0s:  end_of_elaboration", $time, get_full_name());
    endfunction
    function void start_of_simulation_phase(uvm_phase phase);
      $display("%0t: %0s:  start_of_simulation", $time, get_full_name());
    endfunction
    function void extract_phase(uvm_phase phase);
      $display("%0t: %0s:  extract", $time, get_full_name());
    endfunction
    function void check_phase(uvm_phase phase);
      $display("%0t: %0s:  check", $time, get_full_name());
    endfunction
    function void report_phase(uvm_phase phase);
      $display("%0t: %0s:  report", $time, get_full_name());
    endfunction
    task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      $display("%0t: %0s:  start run phase", $time, get_full_name());
      #500;
      $display("%0t: %0s:  end run phase", $time, get_full_name());
      phase.drop_objection(this);
    endtask
  endclass


  top t = new("top", null);

  initial begin
    //Randomize all of the delays
    void'(t.randomize());

    run_test();
  end
endmodule

2.2 仿真结果

UVM_INFO @ 0: reporter [RNTST] Running test ...
0: top:  build
0: top.a1.a:  build
0: top.a1.a.b1:  build
0: top.a1.a.d1:  build
0: top.a2.a:  build
0: top.a2.a.b1:  build
0: top.a2.a.d1:  build
0: top.a1.a.b1:  end_of_elaboration
0: top.a1.a.d1:  end_of_elaboration
0: top.a1.a:  end_of_elaboration
0: top.a2.a.b1:  end_of_elaboration
0: top.a2.a.d1:  end_of_elaboration
0: top.a2.a:  end_of_elaboration
0: top:  end_of_elaboration
0: top.a1.a.b1:  start_of_simulation
0: top.a1.a.d1:  start_of_simulation
0: top.a1.a:  start_of_simulation
0: top.a2.a.b1:  start_of_simulation
0: top.a2.a.d1:  start_of_simulation
0: top.a2.a:  start_of_simulation
0: top:  start_of_simulation
0: top.a1.a.b1:  start run phase
0: top.a1.a:  start run phase
0: top.a2.a.b1:  start run phase
0: top.a2.a:  start run phase
0: top:  start run phase
83: top.a2.a:  end run phase
124: top.a2.a.b1:  end run phase
155: top.a1.a:  end run phase
242: top.a1.a.b1:  end run phase
500: top:  end run phase
UVM_INFO ../../../../src/base/uvm_objection.svh(1270) @ 500: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
500: top.a1.a.b1:  extract
500: top.a1.a.d1:  extract
500: top.a1.a:  extract
500: top.a2.a.b1:  extract
500: top.a2.a.d1:  extract
500: top.a2.a:  extract
500: top:  extract
500: top.a1.a.b1:  check
500: top.a1.a.d1:  check
500: top.a1.a:  check
500: top.a2.a.b1:  check
500: top.a2.a.d1:  check
500: top.a2.a:  check
500: top:  check
500: top.a1.a.b1:  report
500: top.a1.a.d1:  report
500: top.a1.a:  report
500: top.a2.a.b1:  report
500: top.a2.a.d1:  report
500: top.a2.a:  report
500: top:  report
UVM_INFO ../../../../src/base/uvm_report_server.svh(847) @ 500: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :    3
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[RNTST]     1
[TEST_DONE]     1
[UVM/RELNOTES]     1

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

通过仿真结果可以看到:
首先,打印了top的build_phase,build_phase的执行顺序是自顶向下,当所有的build_phase执行完了,才进入下一个phase。
其次,除开build_phase之外,其他的phase的执行顺序都是自底向上,最后打印top的phase。
最后,可以发现,除去run_phase消耗了时间外,其他的phase都不消耗仿真执行的时间。


总结

总的来说,这个例子比较简单,但是通过这个例子,可以比较直观的看到UVM中,phase的类型和执行顺序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值