UVM phase机制

UVM Phase

参考链接:添加链接描述

  • build phase
  • connet phase
  • run phase (objection drop)
  • report phase
  • final phase

在uvm_component组件内,注册到factory机制的组件,一般内部都会有运行phase的function或task,保证在验证过程,环境能够有序执行,完成验证任务。UVM提供了两大类phase,一类是用function实现的function phase,一类是用task实现的task phase,两大类phase各有各的特点和使用场景。UVM的完整phase机制包括下图所示内容。

uvm利用phase机制实现了各个组件之间的同步。因为每个组件都包括一些预定义的同名phase,在没有执行完所有组件的当前phase之前绝对不会去执行所有组件的下一个phase。

1.phase机制存在的意义:

  • 传统的硬件设计模型在仿真开始之前就已经完成了例化和连接,而SV的软件部分对象例化则在仿真开始之后执行
  • 只通过new()函数对对象例化,无法解决一个重要问题,就是验证环境在实现层次化时,如何保证例化的先后关系,以及各个组件在例化后的连接
  • 引入phase机制,通过该机制可以将UVM仿真阶段层次化
  • 层次化不仅仅指各个phase的先后执行顺序,处于同一phase中的层次化组件之间的phase也有先后关系

phase的分类
在这里插入图片描述
在这里插入图片描述

phase按照运行顺序可分为三大类:

前四种属于build time phase

第五种为run time phase

后四种属于clean_up phase

2.phase执行

在这里插入图片描述

在run_phase中,用户如果要完成测试,通常需要组织下面的激励序列:

上电

复位

寄存器配置

发送主要测试内容

等待DUT完成测试
需要注意的地方有:

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

只有uvm_component及其继承uvm_component的子类,才会按照phase机制将上面九个phase先后执行完毕

3. 仿真开始

必须要在顶层test中调用全局函数,两种方式run_test()

  • 通过全局函数(由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参数传递,也可以通过+UVM_TESTNAME=<test_name>从顶层覆盖指定的test
  • 在uvm_pkg中,有且只有一个顶层类uvm_root例化对象,即uvm_top uvm_top的核心职责:
    作为隐形的UVM的顶层,任何其他的组件实例都是在它之下,通过创建组件时指定parent来构建层次

如果component在创建时,parent为null,那么它将作为uvm_top的子组件

  • phase顺序控制
  • 索引功能
  • 报告机制

全局报告设备
通过uvm_top调用方法run_test(),uvm_top做了如下的初始化:

得到正确的test_name
初始化objection机制
创建uvm_test_top实例
调用phase控制方法,安排所有组件的phase方法执行顺序
等待所有phase执行结束,关闭phase控制进程

报告总结和结束仿真

4.仿真结束

objection机制
结束仿真的机制有且只有一个,就是利用objection挂起机制来控制仿真结束。

uvm_objection类提供了一种供所有component和sequence共享的计数器。如果有组件挂起objection,还应该落下objection
使用objection机制的各组件可以独立挂起objection,防止run_phase退出。当所有的组件都落下objection后,uvm_objection共享的counter才会变成0,才会退出run_phase

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

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

在run_phase阶段,至少要有一个组件把objection挂起,否则uvm会退出run_phase,进入后面的phase
要在componnent中挂起objection,建议在一进入run_phase()后就挂起,保证objection counter及时被增加
使用建议:
1.对于component()而言,用户可以在run_phase()中使用phase.raise_objection()/phase.drop_object()来控制run phase 退出
2.最好为description字符串参数提供说明,有利于后期的调试
3.使用默认的count值
4.对于uvm_top或者uvm_test_top尽可能少使用set_drain_time()

class my_driver extends uvm_driver;
	'uvm_component_utils(my_driver)
	function new(string name = "my_driver", uvm_component parent = null);
		super.new(name,parent);
		'uvm_info("my_driver","new is called",UVM_LOW);
	endfunction
	extern virtual task main_phase(uvm_phase phase);
endclass
task my_driver::main_phase(uvm_phase pahse);
	phase.raise_objection(this);//开启phase
	'uvm_info("my_driver","main_pahse is called",UVM_LOW);
	top_tb.rxd <= 8'b0;
	top_tb.rx_dv <= 1'b0;
	while(!top_tb.rst_n)
		@(posedge top_tb.clk);
	for(int i = 0; i < 256; i++)begin
      @(posedge top_tb.clk);
      top_tb.rxd <= $urandom_range(0, 255);
      top_tb.rx_dv <= 1'b1;
      `uvm_info("my_driver", "data is drived", UVM_LOW);
   end
   @(posedge top_tb.clk);
   top_tb.rx_dv <= 1'b0;
   phase.drop_objection(this);//结束phase
endtask

raise_phase和drop_phase都是成对出现的,raise_phase语句必须出现在run_phase中第一条消耗时间的语句之前,否则无法起作用
sequence中,一般在body()方法中调用raise_objection()和drop_objection()方法

5.phase机制的运行停止机制

回顾一下,uvm的verbosity机制中,如果突发uvm_fatal,仿真会直接结束,那么如果突发uvm_error,其实仿真是不会直接停止的,会运行到最后,或者运行到uvm_error的出现的最大次数后,仿真停止。实际上,如果在build_phase中突发uvm_error,验证环境也会直接结束,屏幕打印会出现uvm_fatal,这是为什么?uvm_phase机制的build_phase是建立uvm树形结构的主要phase,那么如果在build_phase中发生了uvm_error,uvm会认为无法建立树形结构,或者环境的重要参数无法获取,也就没有继续仿真的必要,因此会直接停掉。

实际上,不止build_phase,在end_of_elaboration_phase及其之前的function phase中,如果发生uvm_error,uvm都会认为发生了致命错误而停止仿真。

这个机制在大型设计中十分有帮助,因为大型设计里,编译和初始化往往要花费大量的时间,如果都用uvm_fatal,那么就会形成一个现象,就是修复一个uvm_fatal,运行一次,又会出现另一个uvm_fatal,效率十分低下。如果将end_of_elaboration_phase之前的phase的uvm_fatal全部改为uvm_error,可以极大提升仿真效率。

另外,UVM还提供了仿真超时停止的设定,可以在某个组件中,一般是base_test中,使用uvm_root.set_timeout(500ns, 0)的形式设置。这句话的含义是,仿真环境运行500ns后停止。uvm_root的set_timeout函数有两个参数,一个是时间,也就是运行多久后仿真停止,作为运行时间的上限,第二个参数是是否可以被其后的其他set_timeout函数所覆盖。如果是1,则可以被后面运行到的set_timeout函数覆盖。如果是0则不可以。

   实际上,uvm提供了一个超时的宏定义:UVM_DEFAULT_TIMEOUT 9200s,也就是说,uvm最大可以运行9200s,这个数字对于eda仿真来讲,是非常大的。在这种机制下,uvm还可以通过在仿真选项上传参,来修改这个值,以达到设置仿真超时的效果,用法如下:
<vcs sim command> +UVM_TIMEOUT=1000ns, YES”

UVM_TIMEOUT包括两个参数,一个是超时的具体时间,另一个是是否可以被覆盖。

总结一下:
uvm提供了两种仿真运行超时时间的设定方式:
**1是通过uvm_root.set_timeout(时间,0/1),**参数两个含义,一个是超时的具体实践上限,另一个是是否可以被后面的set_timeout所覆盖。
**2是通过仿真命令传参,**使用方式为: +UVM_TIMEOUT=”时间,YES/NO”,第一参数为超时时间,第二个参数为是否可以被覆盖。
uvm内置了仿真最长时间宏:UVM_DEFAULT_TIMEOUT 9200s,最长可运行9200s,改变这个宏也可以改变超时时间。

phase机制的调试
phase机制在运行过程中,如果组件很多,那么debug会显得十分复杂,uvm也提供了phase的调试手段,可以在命令行输入: +UVM_PHASE_TRACE,进行phase的打印调试输出,方便debug。

build_phase、connect_phase一般不在最底层的类用,因为底层的类是被例化和链接的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值