05、UVM的phase机制

news/2024/11/29 10:00:43/

目录

一、概述

二、9个phase执行机制

三、12个分支phase

四、UVM编译和运行顺序

UVM仿真开始

         UVM仿真结束


一、概述

SV的验证环境构建中,传统的硬件设计模型在仿真开始前,已经完成例化和连接了,而SV的软件部分对象例化则需要在仿真开始后执行。虽然对象例化通过调用构建函数new()来实现,但是单单通过new()函数无法解决在验证环境实现层次化时,无法保证例化的先后关系,以及各个组件在例化后的连接的顺序

如果需要实现高级功能,例如在顶层到到底层的配置时,SV也无法在底层组件例化之前完成对底层的配置逻辑。因此,UVM在验证环境构建时,引入了phase机制,通过该机制可以将UVM仿真阶段层次化不单单是各个phase的先后执行顺序,而且处于同一phase中的层次化组件之间的phase也有先后关系
 

二、9个phase执行机制

9个phase对应9个方法,且只有component具备这9个phase。也就是说如果类型是组件类型,则该类型一定有phase机制。

对于UVM组件,主要关心各个phase执行的先后顺序。在定义了各个phase虚方法后,UVM环境会按照phase的顺序分别调用这些方法。

这9个phase对于一个测试环境的生命周期而言,是有固定的先后执行顺序的,同时对于同一个phase中的组件,执行也会按照层次的顺序或者自顶向下或者自顶向上来执行。

对于build_phase,执行顺序按照自顶向下,这符合验证结构建设的逻辑,因为只有先例化高层组件,才会创建空间来容纳底层组件。

只有uvm_component及其继承于uvm_component的子类,才会按照phase机制将上面的9个phase先后执行完毕,这些phase在uvm_component中通过_phase的后缀完成了虚方法的定义,比如build_phase()可以定义一些组件例化和配置的任务。
 

class subcomp extends uvm_component;                 //1:继承c0mp0nent`uvm_component_utils(subcomp)                    //:2:宏注册function new(string name, uvm_component parent); //:3:newsuper.new(name, parent);endfunction//下面是九个阶段phasefunction void build_phase(uvm_phase phase);      //默认形式,把参数传进来`uvm_info("build_phase", "", UVM_LOW)endfunctionfunction void connect_phase(uvm_phase phase);`uvm_info("connect_phase", "", UVM_LOW)endfunctionfunction void end_of_elaboration_phase(uvm_phase phase);`uvm_info("end_of_elaboration_phase", "", UVM_LOW)endfunctionfunction void start_of_simulation_phase(uvm_phase phase);`uvm_info("start_of_simulation_phase", "", UVM_LOW)endfunctiontask run_phase(uvm_phase phase);`uvm_info("run_phase", "", UVM_LOW)endtaskfunction void extract_phase(uvm_phase phase);`uvm_info("extract_phase", "", UVM_LOW)endfunctionfunction void check_phase(uvm_phase phase);`uvm_info("check_phase", "", UVM_LOW)endfunctionfunction void report_phase(uvm_phase phase);`uvm_info("report_phase", "", UVM_LOW)endfunctionfunction void final_phase(uvm_phase phase);`uvm_info("final_phase", "", UVM_LOW)endfunction
endclassclass topcomp extends subcomp;  //继承了subcomp上面九个phasesubcomp c1, c2;...function void build_phase(uvm_phase phase);`uvm_info("build_phase", "", UVM_LOW)c1 = subcomp::type_id::create("c1", this);    //利用工厂创建对象  c1:实例名称 c2即parent:实例句柄c2 = subcomp::type_id::create("c2", this);endfunction
endclassclass test1 extends uvm_test;topcomp t1;...function void build_phase(uvm_phase phase);t1 = topcomp::type_id::create("t1", this);endfunction	
endclass

上方代码层次结构:

仿真结果:

总结:

这9个phase对于一个测试环境的生命周期而言,是有固定的先后执行顺序的,同时对于同一个phase中的组件,执行也会按照层次的顺序或者自顶向下或者自顶向上来执行。

从输出结果来看,build是一个自顶向下的执行顺序,先把顶层的t1创建出来,然后再创建t1里面的c1和c2,然后connect自底向上的执行顺序,先创建c1和c2然后再创建t1,其他也同样按照phase所规定的执行顺序进行创建。

在所有的phase中,只有run_phase方法是一个可以耗时的任务,这意味着该方法可以完成一些等待、激励、采样的任务。对于其它phase对于的方法都是函数必须立即返回(0耗时)。在run_phase中,如果要完成测试,通常需要组织下面的激励序列:上电、复位、寄存器配置、发送主要测试内容、等待DUT完成测试。
 

三、12个分支phase(run_phase的细分phase)

发送激励的一种简单方式是,在run_phase中完成上面所有的激励,另一种方式是,可以将上面几种典型序列划分到不同区间,让对应的激励按区间顺序发送的话,可以让测试更有层次。因此run_phase又可以分为以下12个phase:

  • pre_reset_phase
  • reset_phase
  • post_reset_phase
  • pre_configure_phase
  • configure_phase
  • post_configure_phase
  • pre_main_phase
  • main_phase
  • post_main_phase
  • pre_shutdown_phase
  • shutdown_phase
  • post_shutdown_phase
     

 实际上run_phase任务和上面细分的12个phase是并行的,即在start_of_simulation_phase任务执行以后,run_phase和reset_phase开始执行,而在shutdown_phase执行完成之后,需要等待run_phase执行完才可以进入extract_phase。

注:路桑建议工作中可以不用12细分phase,那9个phase足够用了
 

四、UVM编译和运行顺序

0时刻前首先在加载硬件模型调用仿真器之前,需要完成编译和建模阶段。
run0或0时刻:接下来在开始仿真之前,会分别执行硬件的always/initial语句,以及UVM的调用测试方法run_test和几个phase,分别是build、connect、end_of_elaboration、start_of_simulation。
开始仿真:在开始仿真后,将会执行run_phase或者对应的12个细分phase。
结束仿真:在仿真结束后,将会执行剩余的phase,分别是extract、check、report和final。
 

UVM仿真开始

要在仿真开始时建立验证环境,可以选择:

  • 可以通过全局函数(由uvm_pkg提供)run_test()来选择性地指定要运行哪一个uvm_test。这里的test类均继承于uvm_test。这样的话,指定的test类将被例化并指定为顶层的组件。一般而言,run_test()函数可以在合适module/program中的initial进程块中调用。
  • 如果没有任何参数传递给run_test(),那么可以在仿真时通过传递参数+UVM_TESTNAME=<test_name>,来指定仿真时调用的uvm_test。即便run_test()函数在调用时已经有test名称传递,在仿真时也可以从顶层覆盖已指定的test。此方式不需要执行编译,灵活选择test。

无论上面哪一种方式,都必须在顶层调用全局函数run_test(),而全局函数run_test()的重要性,正是从uvm_root创建了一个UVM世界。

task run_test(string test_name="");uvm_root top;uvm_coreservice_t cs;cs = uvm_coreservice_t::get();top = cs.get_root();top.run_test(test_name);
endtask

UVM顶层类uvm_root,该类也继承于uvm_component,它也是UVM环境结构中的一员,而它可以作为顶层结构类。它提供了一些像run_test()的这种方法,来充当了UVM世界中的核心角色。在uvm_pkg中,有且只有一个顶层类uvm_root所例化的对象,即uvm_top。

uvm_top的核心作用包括:

  • 作为隐形的UVM验证结构的顶层,任何其它的组件实例都在它之下,通过创建组件时指定parent来构成层次。如果parent设置为null,那么它将作为uvm_top的子组件。
  • 控制所有组件的phase顺序。
  • 索引功能。通过层次名称来索引组件实例。
  • 报告配置。通过uvm_top来全局配置报告的繁简度。
  • 全局报告设备。由于可以全局访问到uvm_top实例,所以UVM报告设备在组件内部和组件外部(例如module和sequence)都可以访问。

通过uvm_top调用方法run_test(test_name),uvm_top做了如下的初始化:

  • 得到正确的test_name。
  • 初始化objection机制(控制仿真退出)。
  • 创建uvm_test_top实例。
  • 调用phase控制方法,安排所有组件的phase方法执行顺序。
  • 等待所有phase执行结束,关闭phase控制进程。
  • 报告总结和结束仿真。
     

UVM仿真结束

UVM结束仿真的机制有且只有一种,那就是利用objection挂起机制来控制仿真结束。uvm_objection类提供了一种供所有component和sequence共享的计数器,如果有组件来挂起objection,那么它还应该记得落下objection。参与到objection机制中的参与组件,可以独立的各自挂起objection,来防止run_phase退出,但是只有这些组件都落下objection后,uvm_objection共享的counter才会变为0,这意味run_phase退出的条件满足,因此可以退出run_phase。

对于uvm_objection类,用来反停止的控制方法包括:

//挂起objection
raise_objection(uvm_object obj=null, string description="", int count=1)
//落下objection
drop_objection(uvm_object obj=null, string description="", int count=1)
//设置退出时间
set_drain_time(uvm_object obj=null, time drain)

这几种方法,对于component()而言,可以在run_phase()中使用phase.raise_objection()或者phase.drop_objection()来控制run_phase退出。最好为参数description字符串提供说明,利于后期的调试,应该使用默认count值,对于uvm_top或者uvm_test_top应该尽可能少地使用set_drain_time()。
 

objection防止仿真退出

class test1 extends uvm_test;...task run_phase(uvm_phase phase);phase.raise_objection(this);      //this:当前的组件  当前的组件在当前的phase挂起了objection`uvm_info("run_phase", "entered...", UVM_LOW)#1us;                             //1us后`uvm_info("run_phase", "exited...", UVM_LOW)phase.drop_objection(this);       //当前的组件在当前的phase了落下endtask
endclasshou


http://www.ppmy.cn/news/380590.html

相关文章

Clock and Jitter Phase Noise

1、Jitter定义 定义1&#xff08;SONET规范&#xff09;&#xff1a;抖动可以定义为数字信号在重要时点上偏离理想时间位置的短期变化。 2、Total Jitter表征方式 2.1、周期抖动&#xff08;Period Jitter&#xff09;&#xff0c;与理想时钟无关&#xff0c;不累积 Period j…

Phase机制之-phase_jump的使用场景

Phase机制之-phase_jump的使用场景 应用场景&#xff1a;在验证复位时&#xff0c;需要对正在运行的测试平台进行复位&#xff0c;再次拉高复位信号后&#xff0c;DTU输出的信号是否正确&#xff1f; 采用phase_jump可以使整个测试平台复位&#xff0c;并且再次复位后&#xff…

phaser

phaser 常见的资源资源加载回调事件显示对象**Image****Sprite****Text****Graphics**常用显示对象属性Phaser中的显示对象容器组的创建Phaser如何渲染显示对象camera state &#xff08;类似vue中的router&#xff09;state使用方式state实现多页面原理state生命周期与工作原理…

UVM世界观之七:phase机制(上)

本文转自&#xff1a;http://www.eetop.cn/blog/html/28/1561828-2331501.html 在之前SV的篇章中&#xff0c;读者可以看到&#xff0c;传统的硬件设计模型在仿真开始前&#xff0c;已经完成例化和连接了&#xff1b;而SV的软件部分&#xff0c;类的例化则需要在仿真开始后完成…

UVM内phase的执行顺序

phase间的执行顺序 UVM内所有的phase如下图所示&#xff0c;不同phase间的执行顺序从时间上讲是从上往下执行&#xff0c;而run_phase和下图最右边的12个phase是并行执行的。 所有conponent的相应phase结束了&#xff0c;验证平台才会进入下一个phase。只有所有componennt的r…

UVM的phase机制(Ⅰ)

uvm存在phase机制&#xff0c;每个phase完成对应的功能。将所有的程序分解在不同的phase中执行&#xff0c;保证了验证环境的验证代码的执行顺序。并且每个phase完成对应的功能&#xff0c;使验证环境运行仿真层次化&#xff0c;让各种组件的例化次序正确&#xff0c;环境的执行…

Phase机制

目录 一.Phase机制的意义&#xff1f; 二.Phase图表 三.phase的执行顺序 1.UVM中不同phase的执行顺序 2.兄弟关系component的phase执行顺序 3.叔侄关系component的phase执行顺序 4. task phase的执行顺序 四.phase的其他知识 1.super.phase 2.uvm_error 3.phase的跳转 …

mybatis的一级缓存和二级缓存

目录 1、简介 2、Mybatis缓存 3、一级缓存 3.1、初体验测试 3.2、一级缓存失效的四种情况 4、二级缓存 4.1、使用步骤 4.2、结论 5、缓存原理 1、简介 什么是缓存 [ Cache ]&#xff1f; 存在内存中的临时数据。将用户经常查询的数据放在缓存&#xff08;内存&…