在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: asic_wang

[原创] UVM phase的用法研究------个人总结

[复制链接]
 楼主| 发表于 2013-4-23 16:37:22 | 显示全部楼层
回复 30# usb_geek


    既然有朋友多次要求先用一个例子来看看效果,那我就先用个例子来说明吧。
    我这个例子的背景如下:
  (1)env里包含两个component, U和A, 且我们假设UVM的task phase
         里只有reset、main和shutdown(主要是为了方便说明,没其他意思)
  (2)U里的phase组织结构都是UVM默认的,我只在connect phase
         后面增加一个phase叫做check_connect_phase,它是一个function。
  (3)component A里面的phase结构是我们自定义的,当时是我随便想的一个,
         没有什么实际的意思。
  (4)我想呈现出来的U和A的phase的关系是如下的:
          前面的那些从build phase到start simulation phase的关系我就不画了,
          都是function,好理解。
          关键看看task性质的那些phase吧。
U  comp |-----------------------|---------------|----------------- |---------|                                                   
                     reset                       main            shutdown       extract
A  comp |----------|------------|---------------------------|
              p1_reset    p2_reset                     work        
             |---------------------------------------|
                               reset_and_main
                           |-----------------------------------------------|
                                                          wired

          从上面的图就可以一目了然,我想达到如下效果:
          1)A的p1_reset phase的起点和U的reset phase的起点是同时启动的;   
          2)A的p2_reset phase接着p1_reset phase;
          3)A的work phase的起点和U的main phase 的起点是同时启动的;
          4)A的work phase的跨度可长可短,但最长到U的shutdown phase的结束
          5)A的wired phase的起点和A自己的p2_reset phase相同
          6)A的wired phase的跨度可长可短,但最长到U的shutdown phase的结束

          我子所以想举这个例子主要是想说明一些phase 的基本结构:
          有并行的,如wired和work,reset_and_main和reset/main等;
          有串行的,如p1_reset,p2_reset和work;
          有合并的,如把原uvm参照中的reset和main合并成reset_and_main;
          有分解的,如把原uvm参照中的reset分解成p1_reset和p2_reset;
          我想实际使用中无外乎是这些关系。

          代码如下:
 楼主| 发表于 2013-4-23 16:38:18 | 显示全部楼层
本帖最后由 asic_wang 于 2013-4-23 16:42 编辑

module phase_test ;

typedef class A ;

class A_reset_p1_phase extends uvm_task_phase;

   virtual task exec_task(uvm_component comp, uvm_phase phase);
      A  Acp ;
      if($cast(Acp,comp))
        Acp.reset_p1_phase(phase);
   endtask

   local static A_reset_p1_phase m_inst;
   static const string type_name = "A_reset_p1_phase";
   static function A_reset_p1_phase get();
      if(m_inst == null)
         m_inst = new();
      return m_inst;
   endfunction
   protected function new(string name="A_reset_p1_phase");
      super.new(name);
   endfunction
   virtual function string get_type_name();
      return type_name;
   endfunction
endclass

class A_reset_p2_phase extends uvm_task_phase;

   virtual task exec_task(uvm_component comp, uvm_phase phase);
      A  Acp ;
      if($cast(Acp,comp))
        Acp.reset_p2_phase(phase);
    endtask

   local static A_reset_p2_phase m_inst;
   static const string type_name = "A_reset_p2_phase";
   static function A_reset_p2_phase get();
      if(m_inst == null)
         m_inst = new();
      return m_inst;
   endfunction
   protected function new(string name="A_reset_p2_phase");
      super.new(name);
   endfunction
   virtual function string get_type_name();
      return type_name;
   endfunction
endclass

class A_work_phase extends uvm_task_phase;

   virtual task exec_task(uvm_component comp, uvm_phase phase);
      A  Acp ;
      if($cast(Acp,comp))
        Acp.work_phase(phase);
    endtask

   local static A_work_phase m_inst;
   static const string type_name = "A_work_phase";
   static function A_work_phase get();
      if(m_inst == null)
         m_inst = new();
      return m_inst;
   endfunction
   protected function new(string name="A_work_phase");
      super.new(name);
   endfunction
   virtual function string get_type_name();
      return type_name;
   endfunction
endclass

class A_reset_main_phase extends uvm_task_phase;

   virtual task exec_task(uvm_component comp, uvm_phase phase);
      A  Acp ;
      if($cast(Acp,comp))
        Acp.reset_main_phase(phase);
    endtask

   local static A_reset_main_phase m_inst;
   static const string type_name = "A_reset_main_phase";
   static function A_reset_main_phase get();
      if(m_inst == null)
         m_inst = new();
      return m_inst;
   endfunction
   protected function new(string name="A_reset_main_phase");
      super.new(name);
   endfunction
   virtual function string get_type_name();
      return type_name;
   endfunction
endclass

class A_wired_phase extends uvm_task_phase;

   virtual task exec_task(uvm_component comp, uvm_phase phase);
      A  Acp ;
      if($cast(Acp,comp))
        Acp.wired_phase(phase);
   endtask

   local static A_wired_phase m_inst;
   static const string type_name = "A_wired_phase";
   static function A_wired_phase get();
      if(m_inst == null)
         m_inst = new();
      return m_inst;
   endfunction
   protected function new(string name="A_wired_phase");
      super.new(name);
   endfunction
   virtual function string get_type_name();
      return type_name;
   endfunction
endclass

class A extends uvm_component ;

    A_reset_p1_phase  rst_p1 ;
    A_reset_p2_phase  rst_p2 ;
    A_work_phase      wrk ;
    A_reset_main_phase rst_main ;
    A_wired_phase     wired ;

    uvm_domain        A_domain ;

    `uvm_component_utils(A)

    function new(string name = "A", uvm_component parent = null);
        super.new(name,parent);
    endfunction

    function void build_phase(uvm_phase phase);
        uvm_domain common_domain ;
        uvm_domain uvm_dom ;
        uvm_phase  L_sched,M_sched,R_sched ;

        super.build_phase(phase);
        `uvm_info(get_name(),"build_phase",UVM_NONE)

        common_domain = uvm_domain::get_common_domain();
        uvm_dom = uvm_domain::get_uvm_domain();
        A_domain = new("A_domain");

        L_sched = new("L_sched",UVM_PHASE_SCHEDULE);
        rst_p1 = A_reset_p1_phase::get();
        rst_p2 = A_reset_p2_phase::get();
        wrk = A_work_phase::get();
        L_sched.add(wrk);
        L_sched.add(rst_p2,.before_phase(wrk));
        L_sched.add(rst_p1,.before_phase(rst_p2));

        M_sched = new("M_sched",UVM_PHASE_SCHEDULE);
        rst_main = A_reset_main_phase::get();
        M_sched.add(rst_main);

        R_sched = new("R_sched",UVM_PHASE_SCHEDULE);
        wired = A_wired_phase::get();
        R_sched.add(wired);
      
        A_domain.add(L_sched);
        common_domain.add(M_sched,.with_phase(common_domain.find_by_name("run")));
        common_domain.add(R_sched,.with_phase(common_domain.find_by_name("run")));

        common_domain.add(A_domain,.with_phase(common_domain.find_by_name("run")));

        A_domain.sync(uvm_dom,A_domain.find_by_name("A_reset_p1_phase"),uvm_dom.find_by_name("reset"));
        A_domain.sync(uvm_dom,A_domain.find_by_name("A_work_phase"),uvm_dom.find_by_name("main"));
        common_domain.sync(uvm_dom,common_domain.find_by_name("A_reset_main_phase"),uvm_dom.find_by_name("reset"));
        common_domain.sync(A_domain,common_domain.find_by_name("A_wired_phase"),A_domain.find_by_name("A_reset_p2_phase"));
        
        set_domain(A_domain);
    endfunction

    task reset_p1_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"reset_p1_phase start",UVM_NONE)
        #6ps ;
        `uvm_info(get_name(),"reset_p1_phase end",UVM_NONE)
        phase.drop_objection(this);
    endtask

    task reset_p2_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"reset_p2_phase start",UVM_NONE)
        #5ps ;
        `uvm_info(get_name(),"reset_p2_phase end",UVM_NONE)
        phase.drop_objection(this);
    endtask

    task work_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"work_phase start;",UVM_NONE)
        #26ps ;
        `uvm_info(get_name,"work_phase end;",UVM_NONE)
        phase.drop_objection(this);
    endtask

    task reset_main_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"reset_main_phase start;",UVM_NONE)
        #30ps ;
        `uvm_info(get_name,"reset_main_phase end;",UVM_NONE)
        phase.drop_objection(this);
    endtask

    task wired_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"wired_phase start;",UVM_NONE)
        #35ps ;
        `uvm_info(get_name,"wired_phase end;",UVM_NONE)
        phase.drop_objection(this);
    endtask


    function void extract_phase(uvm_phase phase);
        `uvm_info(get_name(),"extract phase start;",UVM_NONE)
    endfunction

endclass

typedef class U ;

class U_check_connect_phase  extends uvm_bottomup_phase;
   virtual function void exec_func(uvm_component comp, uvm_phase phase);
      U Ucp ;
      if($cast(Ucp,comp))
        Ucp.check_connect_phase(phase);
   endfunction
   local static U_check_connect_phase m_inst;
   static const string type_name = "U_check_connect_phase";
   static function U_check_connect_phase get();
      if(m_inst == null)
         m_inst = new();
      return m_inst;
   endfunction
   `_protected function new(string name="U_check_connect_phase");
      super.new(name);
   endfunction
   virtual function string get_type_name();
      return type_name;
   endfunction
endclass


class U extends uvm_component ;

    `uvm_component_utils(U)

    function new(string name = "U", uvm_component parent = null);
        super.new(name,parent);
    endfunction

    function void build_phase(uvm_phase phase);
        uvm_domain common_domain ;
        super.build_phase(phase);
        common_domain = uvm_domain::get_common_domain();
        common_domain.add(U_check_connect_phase::get(),.after_phase(common_domain.find_by_name("connect")));
    endfunction

    function void check_connect_phase(uvm_phase phase);
        `uvm_info(get_name(),"check_connect_phase start;",UVM_NONE)
    endfunction

    task reset_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"reset phase start;",UVM_NONE)
        #10ps ;
        `uvm_info(get_name,"reset phase ended;",UVM_NONE)
        phase.drop_objection(this);
    endtask

    task main_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"main phase start;",UVM_NONE)
        #20ps ;
        `uvm_info(get_name,"main phase ended;",UVM_NONE)
        phase.drop_objection(this);
    endtask

    task shutdown_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info(get_name(),"shutdown phase start;",UVM_NONE)
        #8ps ;
        `uvm_info(get_name,"shutdown phase ended;",UVM_NONE)
        phase.drop_objection(this);
    endtask

    function void extract_phase(uvm_phase phase);
        uvm_component this_test ;
        `uvm_info(get_name(),"extract phase start;",UVM_NONE)
    endfunction


endclass

class my_test extends uvm_test ;

    `uvm_component_utils(my_test)

    function new(string name = "my_test", uvm_component parent = null);
        super.new(name,parent);
    endfunction

    function void build_phase(uvm_phase phase);
        A a ;
        U u ;
        super.build_phase(phase);
        a = A::type_id::create("a",this);
        u = U::type_id::create("u",this);
    endfunction

endclass





initial begin
    run_test("my_test") ;
end


endmodule
 楼主| 发表于 2013-4-23 16:43:34 | 显示全部楼层
在VCS上的运行结果如下:
Compiler version F-2011.12-SP1; Runtime version F-2011.12-SP1;  Apr 23 16:04 2013
----------------------------------------------------------------
UVM-1.1a.VCS
(C) 2007-2011 Mentor Graphics Corporation
(C) 2007-2011 Cadence Design Systems, Inc.
(C) 2006-2011 Synopsys, Inc.
(C) 2011      Cypress Semiconductor Corp.
----------------------------------------------------------------
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO phase_test.sv(145) @ 0: uvm_test_top.a [a] build_phase
UVM_INFO phase_test.sv(273) @ 0: uvm_test_top.u [u] check_connect_phase start;
UVM_INFO phase_test.sv(278) @ 0: uvm_test_top.u [u] reset phase start;
UVM_INFO phase_test.sv(212) @ 0: uvm_test_top.a [a] reset_main_phase start;
UVM_INFO phase_test.sv(188) @ 0: uvm_test_top.a [a] reset_p1_phase start
UVM_INFO phase_test.sv(190) @ 6: uvm_test_top.a [a] reset_p1_phase end
UVM_INFO phase_test.sv(196) @ 6: uvm_test_top.a [a] reset_p2_phase start
UVM_INFO phase_test.sv(220) @ 6: uvm_test_top.a [a] wired_phase start;
UVM_INFO phase_test.sv(280) @ 10: uvm_test_top.u [u] reset phase ended;
UVM_INFO phase_test.sv(198) @ 11: uvm_test_top.a [a] reset_p2_phase end
UVM_INFO phase_test.sv(204) @ 11: uvm_test_top.a [a] work_phase start;
UVM_INFO phase_test.sv(286) @ 11: uvm_test_top.u [u] main phase start;
UVM_INFO phase_test.sv(214) @ 30: uvm_test_top.a [a] reset_main_phase end;
UVM_INFO phase_test.sv(288) @ 31: uvm_test_top.u [u] main phase ended;
UVM_INFO phase_test.sv(294) @ 31: uvm_test_top.u [u] shutdown phase start;
UVM_INFO phase_test.sv(206) @ 37: uvm_test_top.a [a] work_phase end;
UVM_INFO phase_test.sv(296) @ 39: uvm_test_top.u [u] shutdown phase ended;
UVM_INFO phase_test.sv(222) @ 41: uvm_test_top.a [a] wired_phase end;
UVM_INFO phase_test.sv(228) @ 41: uvm_test_top.a [a] extract phase start;
UVM_INFO phase_test.sv(302) @ 41: uvm_test_top.u [u] extract phase start;

--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :   25
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[CFGPRT]     4
[RNTST]     1
[a]    12
[u]     8
$finish called from file "/auto/edatools/synopsys/vcs/v2011.12-SP1mx_uvm11a/etc/uvm-1.1/base/uvm_root.svh", line 408.
$finish at simulation time                   41
           V C S   S i m u l a t i o n   R e p o r t
Time: 41 ps
CPU Time:      0.620 seconds;       Data structure size:   0.3Mb
Tue Apr 23 16:05:08 2013
 楼主| 发表于 2013-4-23 16:48:42 | 显示全部楼层
本帖最后由 asic_wang 于 2013-4-23 16:50 编辑

总结起来,要组织一个自己的phase结构图,
有如下几点要点(如果不对或不够请大家补充):
(1)记得有两个参照系:common domain和uvm domain、
(2)想并行组织,用add函数的with_phase形参
(3)想串行组织,用add函数before_phase或者after_phase形参
(4)想把两个phase 的起点同步用sync函数
(5)想把两个phase 的终点同步用add函数的with_phase形参
发表于 2013-4-23 20:40:37 | 显示全部楼层
回复 1# asic_wang


   好
发表于 2013-4-23 22:38:52 | 显示全部楼层
非常的好!
发表于 2013-4-25 22:15:31 | 显示全部楼层
多谢, 明天好好学习,今天刚刚编译通过。 运行结果相同。


代码需要增加两句话:
`include "uvm_macros.svh“

import uvm_pkg::*;
 楼主| 发表于 2013-4-26 12:11:13 | 显示全部楼层
回复 37# usb_geek


    不需要,在vcs命令有  -ntb_opts uvm1-1就行了
发表于 2013-4-26 17:38:49 | 显示全部楼层
我试过了,好像不行呀,没有import usb_pkg::*, 不然怎么编译通过呢?

不过这可能是工具问题,小问题,你的代码我还没有消化,等有问题再好好请教。
发表于 2013-4-28 14:58:46 | 显示全部楼层
写成文档应该就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-29 02:25 , Processed in 0.026791 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表