UVM-phase机制

1.UVM Phase

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

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

在定义了各个虚方法后,UVM环境会按照phase的顺序分别调用这九种phase

  • phase按照是否消耗仿真时间的特性,可以分成两大类:一类是function phase 八种,一类是task phase 一种,run_phase又可以细分为十二种
  • phase只有run_phase是一个可以消耗时间的任务,这意味着该phase可以完成一些等待、激励、采样的任务;其他的phase都是函数,必须立即返回
  • phase对于function phase ,在同一时间只有一个phase在执行;但是task phase中,run_phase和pre_reset_phase等12个小的phase并行运行
    为了避免不必要的干扰,用户可以选择run_phase或者12个phase中的若干来完成激励,但不要将它们混合使用,容易导致执行关系不明确。

2.phase的执行

在这里插入图片描述
phase按照运行顺序可分为三大类:

  • 前四种属于build time phase

  • 第五种为run time phase

  • 后四种属于clean_up phase
    在run_phase中,用户如果要完成测试,通常需要组织下面的激励序列:

  • 上电

  • 复位

  • 寄存器配置

  • 发送主要测试内容

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

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

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

UVM世界中的编译和运行顺序:在这里插入图片描述

  • 首先在加载硬件模型调用仿真器之前,需要完成编译和建模阶段
    -phase 开始仿真之前,分别执行硬件的always/initial语句,以及UVM的调用测试方法run_test和几个phase,分别是build_phase,connect_phase,end_of_elaboration_phase,start_of_simulation_phase;

  • phase 在仿真开始后,执行run_phase或对应的12个细分的phase;

  • phase 在仿真结束后,执行剩余的phase,分别是extract_phase,check_phase,report_phase,final_phase
    对phase机制的建议:

  • 尽量不使用12个细分的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.仿真结束

4.1 objection机制

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

  • uvm_objection类提供了一种供所有componentsequence共享的计数器。如果有组件挂起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()方法

参考:
https://blog.csdn.net/bleauchat/article/details/90673946

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值