• sequence启动的三种方式


    1、seq相关的phase机制

    首先你需明确的是UVM的框架下,消耗时间的task的执行都在在uvm_component底下的objection的机制来实现的。也就是说phase的机制跟uvm_component是紧密相关的。
    uvm_sequence是一个uvm_object的类,uvm_sequencer是一个uvm_component的类。
    seq需要挂载在seqr上执行。

    run_time_phase.svh

    在前面我们讲过UVM_PHASE的机制,在execute函数的地方有对uvm_sequencer_base类型的做处理。

    • start_phase_sequence(phase):处理default_sequencer

    • 这里先做个遗留,到底这里是什么从外面获得default_sequencer的。

    方法一:利用default_sequence启动seq

    也只有在用default_sequence的方式启动seq的时候,start_phase != null,原因是如果是sqr的时候在uvm_task_phase.svh里面有介绍,会自己调用start_phase_sequence,里面会对seq.set_starting_phase(phase);进行set。
    前提
    对应uvm1.2版本,

    或者是my_seq.set_automatic_phase_objection(1);
    在start_phase_sequence里面已经指定了phase,seq.set_starting_phase(phase);

    命令行设置default_sequencer:
    +UVM_SET_DEFAULT_SEQUENCE=uvm_test_top.env.i_agt.sqr,main_phase,case0_sequence

    • 第一个参数是指定seqr的路径
    • 第二个参数是指定要执行的phase阶段
    • 第三个参数是指定你的seq
      uvm_config_db设置default_sequencer

    uvm_config_db#(uvm_object_wrapper)::set(this, "env.i_agt.sqr.main_phase", "default_sequence", case0_sequence::type_id::get());

    function void my_case0::build_phase(uvm_phase phase);
       case0_sequence my_seq;
       super.build_phase(phase);
       my_seq = new("my_seq");
       uvm_config_db#(uvm_sequence_base)::set(this, 
                                               "env.i_agt.sqr.main_phase", 
                                               "default_sequence", 
                                               my_seq);
    endfunction
    

    方法二:利用seq.start(seqr)显示启动

    前提:如果想用starting_phase的话,需要为其指定,不像default_sequencer那样,start_phase_sequence(phase)里面已经调用了set_starting_phase

    • 利用starting_phase来启动objection:直接调用seq.start(seqr)

    • 或者将my_seq.starting_phase=phase替换成my_seq.set_starting_phase这种写法。
    • 利用common的objection机制:直接调用seq.start(seqr)

    参考UVM_UG:


    方法三:利用uvm_do_on系列的宏

    `uvm_do系列的宏,我们知道这些宏最终都是调用的uvm_do_on_pri_with的宏。uvm_do系列的宏是可以在uvm_sequence_base以及其扩展类中才能调用的!

    • 当第一个参数是sequence类型的时候,会调用seq.start,也就是能启动seq。

    • my_seq.start() -> my_seq.body() -> uvm_do(my_seq_0) -> my_seq_0.start() -> my_seq_0.body()

    那么这里自然而言,我就会想可以在顶层这样做吗?

    刚刚入行的时候,总会有这些问题,为什么不能这么做的?
    首先宏是啥意思?在代码编译的时候,宏会依次展开,所以create_item/start_item/finish_item都会暴露出来,由于你是在uvm_sequencer中调用的,根据扩展关系,是找不到create_item/start_item/finish_item这些东西的啊,同学!!!!
    create_item/start_item/finish_item是在uvm_sequence_base里面定义的。
    也就是说uvm_do系列的宏是可以在uvm_sequence_base以及其扩展类中才能调用的!

    小结:从本质上讲,seq的启动都是调用了uvm_squence_base的start函数。
    下面简单来看一下;uvm_sequence_base::start(sqr)的源码:

    start

    • 设置m_sequencer和p_sequencer
    • 注册m_sequencer和sequence,将seq_id sqr_id等关联起来

    set_item_context
    m_register_sequence

    start

    start

    • pre_start/pre_body/body/post_body/post_start,是一些callback函数。
    • parent_sequence也有pre_do/mid_do/post_do的callback函数,但这些很不常用。
    • 重点关注body()的override就行。
    • m_sequence_exiting()将sequence从arb_sequence_q[]中删除。

    m_sequence_exiting

    真正sequence的跟driver交互的东西就是在body()里面实现的。

  • 相关阅读:
    [转]find高级用法
    svn服务器配置
    awk (一)
    Linux下恢复ext3文件系统误删除文件ext3grep
    cobbler无人值守安装操作系统
    Linux下virtualbox网络配置
    nginx+uwsgi来部署Django
    solaris 网络设置
    rpm 使用说明
    linux 下安装mysql
  • 原文地址:https://www.cnblogs.com/xuqing125/p/15909359.html
Copyright © 2020-2023  润新知