打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
谈谈UVM中的sequence机制
userphoto

2016.02.21

关注
  接前面的问题,仿真停在0时刻,可以从后往前来推这个问题。

 driver是直接与物理接口相连的组件,主要的行为主要体现在main_phase()中
class my_driver extends uvm_driver;
........
    task my_driver::main_phase(phase):
           super.main_phase(phase)
           forever begin
               seq_item_port.get_next_item(req);
               .....
              seq_item_port.item_done();
             end
       endtask
....
endclass

    seq_item_port 并不会再my_driver的成员变量中出现,它在uvm_driver类中。它是用于连接driver和sequencer的一个端口。driver要想驱动总线发送数据首先要从这个端口获得transaction,如代码中的get_next_item。因此一旦物理总线上没有出现数据首先检查,driver是否收到了来自sequencer的激励。

  sequencer的结构非常简单,当driver要驱动数据,向sequencer申请一个item,sequencer会把相应的sequence发送给driver。

  一个简单的sequence主要的行为在body()中。

  class my_sequence extends uvm_sequence #(my_transaction)
  .......
       virtual task body();
           if(starting_phase != null)
               starting_phapse.raise_objection(this);
           repeat(10) begin
               `uvm_do(m_trans)
           end
           #100;
           if(starting_phase != null)
               starting_phase.drop_objection(this);
       endtask
   endclass

  当sequence启动起来后,会自动执行body方法,`uvm_do宏每执行一次就会向uvm_sequencer发送一个transaction,它产生一个trans是不消耗仿真时间的,将trans传给sequencer也不消耗时间,但是driver需要消耗时间完成一个trans的驱动,只有当driver调用item_done之后,一次uvm_do宏才算执行完毕,进入下一个uvm_do的执行。当所有的uvm_do执行完毕之后,driver会停在get_next_item。

  drop_objection之后,就会进入$finish(),结束整个仿真。

////////////////////////////////////////////////////////////////////////////////////////////////
  需要注意的是:如果想要执行一些耗费时间的代码,至少要在此phase下raise一次objection,这个结论只适用于run_time的phase。如果没有任何objection被raise,消耗时间的代码将不会被执行,直接跳到下一个phase,例如曾经碰到过这样一个问题。在driver中main_phase之前reset_phase中将dut的信号进行reset,需要在reset_phase中单独raise_objection,否则reset_phase不会被执行,因为sequence中的raise_objection只是针对了driver中的main_phase。
////////////////////////////////////////////////////////////////////////////////////////////////

  my_sequence中的raise_objection和drop_objection是属于phase的一个函数,但是uvm_sequence是一个uvm_object,而phase是属于component的一个概念。因此用starting_phase != null来判断。starting_phase实际上是uvm_sequence指向phase的一个指针,当sequencer在main_phase中启动default_sequence时,sequencer就将phase赋值给sequence中的这个指针,从而满足了starting_phase!= null的这个条件。


  那么sequence是如何启动的,一般由手动启动和自动启动两种方法。一般都是使用自动启动的方法。
  class my_test extends uvm_test;
   .......
   function void my_test::build_phase(uvm_phase phase);
       super.build_phase(phase);
       uvm_config_db#(uvm_object_wrapper)::set(this,'env.i_agt.sqr.main_phase','default_sequence',my_sequence::type_id::get());
    endfunction
   endclass

  config_db的set语句就是通知sequencer,让其在运行到main_phase的时候自动启动前面定义的my_sequence,就是这里让sequence自动启动了。如果在这里把default_sequence定义为sequence_1,那么就会自动启动sequence_1。因此一旦发现sequence没有进入body的部分,说明sequence没有启动起来,一定是config_db的问题。

  
 
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
UVM系统验证基础知识1(基于UVM的verilog验证 )
 UVM:: drop all objection forcelly
Guide to signing unsigned drivers
Spice 分析(3) – 编写 Spice Client
C# Sqlite 序列
驱动自定义回调例程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服