UVM验证方法学_phase机制

这篇具有很好参考价值的文章主要介绍了UVM验证方法学_phase机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

phase机制是uvm最重要的几个机制之一,它使得uvm的运行仿真层次化,使得各种例化先后次序正确,保证了验证环境与DUT的正确交互。

目录

一、phase机制概述

二、phase执行顺序

(1)时间顺序

(2)空间顺序

三、phase机制中uvm树的遍历

四、phase的super

五、phase的跳转

六、phase的调试和超时退出

总结


一、phase机制概述

uvm中的phase按照是否消耗仿真时间分为function phase和task phase两类,不消耗仿真时间的为function phase,而消耗仿真时间的为task phase。

uvm中的phase:

uvm phase机制,UVM验证方法学,fpga开发,linux,模块测试,硬件工程,开发语言

phase机制的意义是使得UVM的运行层次化,使得各种例化先后次序正确。UVM的phase主要有9个,外加12个小phase,这12个小的phase称为run-time phase。其中除了run phase和12个小的phase是task之外,其余的都是function。比较常用的phase有build_phase、connect_phase、reset_phase、main_phase、run_phase、report_phase、final_phase等。

为什么要引入这12个小的phase?分成小的phase是为了实现更加精细化的控制。reset、configure、main、shutdown四个phase是核心,这四个phase通常模拟DUT的正常工作方式:

(1)在reset_phase对DUT进行复位、初始化等操作。

(2)在configure_phase则进行DUT的配置。

(3)在main_phase主要是DUT的运行。

(4)在shutdown_phase主要是一些与DUT断电相关的操作。

通过这种细分实现对DUT更加精确的控制,同时也可以让我们实现在phase间的跳转,更便于去构建一些场景。

二、phase执行顺序

phase的执行顺序可以分为时间和空间。

(1)时间顺序

先说时间,在时间层面所有的phase会按照顺序自上向下依次执行。其中12个小的phase与run_phase是并行的关系。

run_phase和main_phase之间的关系:
objection机制是UVM中唯一可以控制仿真开始和结束的方式。在task phase中,至少有一个task phase要在消耗第一条消耗仿真时间的语句执行之前挂起objection。
(1)如果12个分支中有一个phase(比如main_phase)挂起了objection ,那么run_phase 中则不需要挂起objection 就可以执行其中的代码;但是这时,run_phase的运行时间被动地受这个挂起objection的分支phase的控制。
(2)而如果在run_phase中挂起了objection,没有在main_phase中挂起,main_phase中的操作则不会执行,此时的运行时间完全由run_phase控制。

请注意不要混淆,这里的时间顺序并不是指消耗仿真时间,只有task phase才会消耗仿真时间!所有的function phase都会在0时刻完成。

对于task phase,uvm内置了phase的同步。只有同一个phase全部执行完毕,才会执行下一个phase。但是从整个环境的角度来看,各个task phase之间是没有空白的。

(2)空间顺序

再说空间,uvm中规定层次越高,优先级越高,层次即为在uvm树中的位置,uvm_top是树根,越靠近树根,则层次越高。

uvm phase机制,UVM验证方法学,fpga开发,linux,模块测试,硬件工程,开发语言

我们可以再思考一下,层次越高,就会越接近用户。我们会在uvm_test_top(也就是testcase)中启动不同的sequence,来实现不同的测试场景,而env则是在uvm_test_top中才会完成例化,向下依此类推。

值得注意的是,uvm的设计哲学就是在build_phase中完成例化,在connect_phase中完成连接,这种分块式设计。所以build_phase比较特殊,由于树形结构实例化必须从树根开始,也就是自顶向下运行。但是例如connect_phase则是自底向上运行,因为组件的连接必须从最基础的部件开始。所以对于空间来说:

只有build phase和final phase是自顶向下运行,其余phase都是自底向上运行。

可以使用print_topology来打印树形结构,可以清晰看到各个组件之间的关联。例如:

UVM_INFO @ 33626.00ns: reporter [UVMTOP] UVM testbench topology:
------------------------------------------------------------------
Name                       Type                        Size  Value
------------------------------------------------------------------
uvm_test_top               tc_sanity                   -     @471 
  fifo_env                 env                         -     @479 
    rd_agt                 rd_agent                    -     @495 
      drv                  rd_driver                   -     @621 
        rsp_port           uvm_analysis_port           -     @638 
        seq_item_port      uvm_seq_item_pull_port      -     @629 
      mon                  rd_monitor                  -     @770 
        ap                 uvm_analysis_port           -     @780 
      sqr                  rd_sequencer                -     @647 
        rsp_export         uvm_analysis_export         -     @655 
        seq_item_export    uvm_seq_item_pull_imp       -     @761 
        arbitration_queue  array                       0     -    
        lock_queue         array                       0     -    
        num_last_reqs      integral                    32    'd1  
        num_last_rsps      integral                    32    'd1  
    rdmon_scb_fifo         uvm_tlm_analysis_fifo #(T)  -     @564 
      analysis_export      uvm_analysis_imp            -     @608 
      get_ap               uvm_analysis_port           -     @599 
      get_peek_export      uvm_get_peek_imp            -     @581 
      put_ap               uvm_analysis_port           -     @590 
      put_export           uvm_put_imp                 -     @572 
    scb                    scoreboard                  -     @503 
      rd_port              uvm_blocking_get_port       -     @803 
      wr_port              uvm_blocking_get_port       -     @794 
    wr_agt                 wr_agent                    -     @487 
      drv                  wr_driver                   -     @939 
        rsp_port           uvm_analysis_port           -     @956 
        seq_item_port      uvm_seq_item_pull_port      -     @947 
      mon                  wr_monitor                  -     @965 
        ap                 uvm_analysis_port           -     @975 
      sqr                  wr_sequencer                -     @816 
        rsp_export         uvm_analysis_export         -     @824 
        seq_item_export    uvm_seq_item_pull_imp       -     @930 
        arbitration_queue  array                       0     -    
        lock_queue         array                       0     -    
        num_last_reqs      integral                    32    'd1  
        num_last_rsps      integral                    32    'd1  
    wrmon_scb_fifo         uvm_tlm_analysis_fifo #(T)  -     @511 
      analysis_export      uvm_analysis_imp            -     @555 
      get_ap               uvm_analysis_port           -     @546 
      get_peek_export      uvm_get_peek_imp            -     @528 
      put_ap               uvm_analysis_port           -     @537 
      put_export           uvm_put_imp                 -     @519 
------------------------------------------------------------------

我们可以用build_phase和connect_phase来举例,比如:

UVM_INFO @ 0: reporter [RNTST] Running test tc_sanity...
UVM_INFO ../tc/tc_sanity.sv(30) @ 0.00ns: uvm_test_top [uvm_test_top] build_phase active.
UVM_INFO ../ver/env.sv(33) @ 0.00ns: uvm_test_top.fifo_env [fifo_env] build_phase active.
UVM_INFO ../ver/scoreboard.sv(36) @ 0.00ns: uvm_test_top.fifo_env.scb [scb] build_phase active.
UVM_INFO ../ver/wr_agent/wr_agent.sv(32) @ 0.00ns: uvm_test_top.fifo_env.wr_agt [wr_agt] build_phase active.
UVM_INFO ../ver/wr_agent/wr_driver.sv(31) @ 0.00ns: uvm_test_top.fifo_env.wr_agt.drv [drv] build_phase active.
UVM_INFO ../ver/wr_agent/wr_monitor.sv(29) @ 0.00ns: uvm_test_top.fifo_env.wr_agt.mon [mon] build_phase active.
UVM_INFO ../ver/wr_agent/wr_sequencer.sv(28) @ 0.00ns: uvm_test_top.fifo_env.wr_agt.sqr [sqr] build_phase active.

UVM_INFO ../ver/scoreboard.sv(43) @ 0.00ns: uvm_test_top.fifo_env.scb [scb] connect_phase active.
UVM_INFO ../ver/wr_agent/wr_driver.sv(39) @ 0.00ns: uvm_test_top.fifo_env.wr_agt.drv [drv] connect_phase active.
UVM_INFO ../ver/wr_agent/wr_monitor.sv(38) @ 0.00ns: uvm_test_top.fifo_env.wr_agt.mon [mon] connect_phase active.
UVM_INFO ../ver/wr_agent/wr_sequencer.sv(33) @ 0.00ns: uvm_test_top.fifo_env.wr_agt.sqr [sqr] connect_phase active.
UVM_INFO ../ver/wr_agent/wr_agent.sv(42) @ 0.00ns: uvm_test_top.fifo_env.wr_agt [wr_agt] connect_phase active.
UVM_INFO ../ver/env.sv(46) @ 0.00ns: uvm_test_top.fifo_env [fifo_env] connect_phase active.
UVM_INFO ../tc/tc_sanity.sv(36) @ 0.00ns: uvm_test_top [uvm_test_top] connect_phase active.

可以清晰的看到build_phase的运行是自顶向下,而connect_phase的运行是自底向上。
 

三、phase机制中uvm树的遍历

其实在上面的代码中能够看到,build_phase中scoreboard执行是要先于wr_agent的,这是因为uvm中字典序所导致的。scoreboard的s在字典序中要先于w,如果将scoreboard的例化名称改为z_scoreboard,则会晚于wr_agent执行。实际使用中这种顺序理论上不应该产生影响,但是假如要求一定是某种固定的执行顺序,那么这种代码存在很高风险,应立即进行修改。

从树形结构上来说,scoreboard级别是高于agent中的组件的,但是他们build_phase的执行顺序其实并不确定。UVM中采用的是深度优先的原则,即会先执行完某一条树枝,才会去执行下一条树枝。例如agent和scoreboard,他们的层次相同,在执行时会先将agent中包含的组件全部执行完成,才去执行scoreboard,这就是深度优先原则。我们可以总结为:

横向按照字典序,纵向按照深度原则。

四、phase的super

通过super对父类的内容进行继承,其中build_phase的super语句最重要且必须存在,其他phase的super则可以省略。查看uvm源码,可以看到除了build_phase之外其他的phase几乎没有做任何相关的事情:

// phase methods
//--------------
// these are prototypes for the methods to be implemented in user components
// build_phase() has a default implementation, the others have an empty default

function void uvm_component::build_phase(uvm_phase phase);
  m_build_done = 1;
  build();
endfunction

// Backward compatibility build function

function void uvm_component::build();
  m_build_done = 1;
  apply_config_settings(print_config_matches);
  if(m_phasing_active == 0) begin
    uvm_report_warning("UVM_DEPRECATED", "build()/build_phase() has been called explicitly, outside of the phasing system. This usage of build is deprecated and may lead to unexpected behavior.");
  end
endfunction

// these phase methods are common to all components in UVM. For backward
// compatibility, they call the old style name (without the _phse)

function void uvm_component::connect_phase(uvm_phase phase);
  connect();
  return; 
endfunction
function void uvm_component::start_of_simulation_phase(uvm_phase phase);
  start_of_simulation();
  return; 
endfunction
function void uvm_component::end_of_elaboration_phase(uvm_phase phase);
  end_of_elaboration();
  return; 
endfunction
task          uvm_component::run_phase(uvm_phase phase);
  run();
  return; 
endtask
function void uvm_component::extract_phase(uvm_phase phase);
  extract();
  return; 
endfunction
function void uvm_component::check_phase(uvm_phase phase);
  check();
  return; 
endfunction
function void uvm_component::report_phase(uvm_phase phase);
  report();
  return; 
endfunction


// These are the old style phase names. In order for runtime phase names
// to not conflict with user names, the _phase postfix was added.

function void uvm_component::connect();             return; endfunction
function void uvm_component::start_of_simulation(); return; endfunction
function void uvm_component::end_of_elaboration();  return; endfunction
task          uvm_component::run();                 return; endtask
function void uvm_component::extract();             return; endfunction
function void uvm_component::check();               return; endfunction
function void uvm_component::report();              return; endfunction
function void uvm_component::final_phase(uvm_phase phase);         return; endfunction

// these runtime phase methods are only called if a set_domain() is done

task uvm_component::pre_reset_phase(uvm_phase phase);      return; endtask
task uvm_component::reset_phase(uvm_phase phase);          return; endtask
task uvm_component::post_reset_phase(uvm_phase phase);     return; endtask
task uvm_component::pre_configure_phase(uvm_phase phase);  return; endtask
task uvm_component::configure_phase(uvm_phase phase);      return; endtask
task uvm_component::post_configure_phase(uvm_phase phase); return; endtask
task uvm_component::pre_main_phase(uvm_phase phase);       return; endtask
task uvm_component::main_phase(uvm_phase phase);           return; endtask
task uvm_component::post_main_phase(uvm_phase phase);      return; endtask
task uvm_component::pre_shutdown_phase(uvm_phase phase);   return; endtask
task uvm_component::shutdown_phase(uvm_phase phase);       return; endtask
task uvm_component::post_shutdown_phase(uvm_phase phase);  return; endtask

不过为了代码风格的统一,我还是会给每个phase都加上。

五、phase的跳转

这里先说一下跳转,后面在专门讨论复位的时候会再次用到它,因为跳转对于复位实现来说是必要的。跳转中最难的地方在于清理和准备工作,组件之间的fifo需要全部清空,组件内部的队列也需要全部清空,如果清空做不好可能会引发很多未知问题。

跳转使用jump函数,比如:

            begin
                @(negedge this.wr_drv_if.wrst_n);
                phase.jump(uvm_reset_phase::get());
                `uvm_info(this.name,"2nd reset activated.",UVM_LOW)
            end

这里就是复位信号到来跳转至reset_phase。

当然能够做跳转的phase也有限制,在uvm_pre_reset_phase::get() 后的所有phase都可以:

uvm_build_phase::get();
uvm_connect_phase::get();
uvm_end_of_elaboration_phase::get();
uvm_start_of_simulation_phase::get();
uvm_run_phase::get();
uvm_pre_reset_phase::get();

// ----------------------------------------------------------
uvm_reset_phase::get();
uvm_post_reset_phase::get();
uvm_pre_configure_phase::get();
uvm_configure_phase::get();
uvm_post_configure_phase::get();
uvm_pre_main_phase::get();
uvm_main_phase::get();
uvm_post_main_phase::get();
uvm_pre_shutdown_phase::get();
uvm_shutdown_phase::get();
uvm_post_shutdown_phase::get();
uvm_extract_phase::get();
uvm_check_phase::get();
uvm_report_phase::get();
uvm_final_phase::get();

六、phase的调试和超时退出

除了使用uvm_info打印信息来帮助检查问题之外,uvm还提供命令行参数UVM_PHASE_TRACE来对phase机制进行调试。需要在仿真的命令后面加入:+UVM_PHASE_TRACE,或者加在makefile当中。

UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1381) @ 33626.00ns: reporter [PH/TRC/DONE] Phase 'common.report' (id=271) Completed phase
UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1403) @ 33626.00ns: reporter [PH/TRC/SCHEDULED] Phase 'common.final' (id=283) Scheduled from phase common.report
UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1124) @ 33626.00ns: reporter [PH/TRC/STRT] Phase 'common.final' (id=283) Starting phase
UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1381) @ 33626.00ns: reporter [PH/TRC/DONE] Phase 'common.final' (id=283) Completed phase
UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1403) @ 33626.00ns: reporter [PH/TRC/SCHEDULED] Phase 'common.common_end' (id=180) Scheduled from phase common.final
UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1124) @ 33626.00ns: reporter [PH/TRC/STRT] Phase 'common.common_end' (id=180) Starting phase
UVM_INFO /opt/Synopsys/VCS2014/etc/uvm-1.1/base/uvm_phase.svh(1381) @ 33626.00ns: reporter [PH/TRC/DONE] Phase 'common.common_end' (id=180) Completed phase

挂死是有时候会遇到的问题,一般是陷入了死循环无法终止。出现挂死的时候设置的drain_time就不会起作用,导致仿真无法结束。在uvm中通过uvm_root的set_timeout函数可以设置超时时间来强制结束(在top中使用$finish或者$stop是同样的效果)。

function void base_test::build_phase(uvm_phase phase);
    super.build_phase(phase);
    env = my_env::type_id::create("env", this);
    uvm_top.set_timeout(500ns, 0);
endfunction

set_timeout函数有两个参数,第一个参数是要设置的时间,第二个参数表示此设置是否可以被其后的其他set_timeout语句覆盖。如果达到规定时间后测试用例还没有运行完毕,则会给出一条uvm_fatal的提示信息,并退出仿真。


总结

phase机制是uvm最重要的几个机制之一,它使得uvm的运行仿真层次化,使得各种例化先后次序正确,保证了验证环境与DUT的正确交互。

验证平台是很复杂的,要搭建出一个验证平台是一件相当繁杂的事情,要正确地掌握并理顺这些步骤是一个相当艰难的过程。在不同时间做不同的事情,这就是uvm中phase的设计哲学。但是仅仅划分成phase是不够的,phase的自动执行功能极大地方便了用户。同时,phase机制的引入在很大程度上解决了因代码顺序杂乱可能会引发的问题,也在很大程度上减少了验证平台开发者的工作量。文章来源地址https://www.toymoban.com/news/detail-636992.html

到了这里,关于UVM验证方法学_phase机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 诙谐有趣的《UVM实战》笔记——第二章 一个简单的UVM验证平台

    某天白天在地铁上听鬼故事,结果晚上要睡觉时,故事里的情节都历历在目,给我鸡皮疙瘩起的~ 不过我倒是没有吓得睡不着,而是转念一想,为啥我学知识忘得很快,随便听的鬼故事却记得这么清楚咧? 那如果能像听鬼故事那样去学知识,是不是可以记得更牢固呢? 经过一

    2024年02月08日
    浏览(62)
  • (一)UVM验证平台搭建1

     UVM实战中实例源码下载:https://www.hzcourse.com/web/refbook/detail/5651/229 终于配置跑通 UVM实战中的实例了,下面是基于linux+vcs+verdi的环境配置 1、将下载的源码文件夹解压后共享到虚拟机中 2、需要重新配置setup.vcs文件 原始文件: 说明: 这个配置文件是基于csh的,安装的虚拟机不

    2024年02月12日
    浏览(44)
  • 从零开始,搭建一个简单的UVM验证平台(四)

    UVM前置基础: 1.UVM基础-factory机制、phase机制 2.UVM基础-组件(driver、monitor、agent...) 3.UVM基础-TLM通信机制(一) 4.UVM基础-TLM通信机制(二) ...还在更新 从零搭建一个UVM验证平台: 从零开始,搭建一个简单的UVM验证平台(一) 从零开始,搭建一个简单的UVM验证平台(二) 从

    2023年04月14日
    浏览(81)
  • UVM基础-TLM机制之analysis端口与FIFO

    TLM的analysis端口与FIFO 1 analysis端口        除了port,export,imp之外,TLM还提出了另一种端口,analysis类型的端口,analysis类型的端口也会区分port,export,imp。Analysis端口与所描述的端口的差异,主要体现在两个方面: 一个analysis_port/analysis_export可以连接多个analysis_imp,实现一

    2024年02月08日
    浏览(33)
  • (UVM验证学习13) apb和ahb的另外一些笔记

    APB slave端的要求比较灵活: 对于总线写入到slave的传输行为,写入的数据data既可以在PSEL为高时,在CLK的上升沿锁存;也可以当PSEL为高时,在PENABLE的上升沿锁存。区别就是前者会早一点,PENABLE要在CLK上升沿后才会被驱动拉高。 对于总线的读slave行为,数据只要在PWRITE=0,然后

    2024年02月08日
    浏览(39)
  • 1-搭建一个最简单的验证平台UVM,已用Questasim实现波形!

    1,背景知识 验证是用于找出DUT的bug,这个过程通常是把DUT放入一个验证平台中来实现的。 一个验证平台要实现如下基本功能: (1)验证平台要模拟DUT的各种真实使用情况,这意味着要给DUT施加各种激励,有正常的激励,也有异常的激励;有这种模式的激励,也有那种模式

    2024年02月14日
    浏览(42)
  • UVM在test组件内启动sequence/virtual sequence的方法

    在UVM中需要启动sequence的场景主要分为以下两种: 1. 在 uvm_test 组件中启动顶层 sequence 或者 virtual sequence 运行测例; 2. 在层次化sequence 的顶层 sequence 中启动 sub-sequence;virtual sequence中启动相应的sequence; 情况一:  在uvm_test 组件中启动顶层 sequence 或者 virtual sequence 运行测例

    2024年02月10日
    浏览(34)
  • 【UVM】-- UVM测试平台搭建与调试

    《UVM》实战中这个DUT的功能比较简单: 在clk的上升沿,且rst不为低电平的时候,将输入的信号直接发送出去,并且输出输入的使能信号; 在clk上升沿,如果rst为低电平,复位输出信号和使能信号 clk 时钟输入信号 rst_n 复位输入信号  rxd 8bit输入数据信号 rx_dv 输入使能信号

    2024年02月15日
    浏览(38)
  • UVM学习——搭建简单的UVM平台

      本专栏的博客均与 UVM 的学习相关,学习参考:  【1】UVM Tutorial  【2】张强著,UVM实战 (卷 Ⅰ)  【3】Download UVM (Standard Universal Verification Methodology) 本专栏的学习基本依照 资料【2】的主线,以【1】【3】资料作为参考。特别是【3】是官方的UVM手册,具有很高的可参考性

    2024年02月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包