UVM糖果爱好者教程 - 11.Sequence Item Port

UVM driver和UVM sequencer使用UVM sequence item port和export进行连接。本文将解释sequence item port如何工作。Agent中,我们seq_item_portjelly-bean driver(jb_drvrsequence item port(连接到jelly-bean sequencer)的sequence item export(seq_item_export),jb_seqr如下所示:

jb_drvr.seq_item_port.connect ( jb_seqr.seq_item_export );

driver调用get_next_item()以获取jelly-bean传输(jb_tx),

seq_item_port.get_next_item ( jb_tx );

然后在最后调用item_done()

seq_item_port.item_done ();

我们将在这篇文章中看看上面的代码是如何工作的。sequence item port有关的类图如下所示。UVM标准库类以粉色显示,专用于该jelly_bean_transaction类型的UVM类以黄色显示。

                                                与sequence item port相关的类图

Sequence Item Port

jelly-bean driver的seq_item_port 是用 jelly_bean_transaction 限定的 uvm_seq_item_pull_port类。 uvm_seq_item_pull_port 类定义在 src/tlm1/uvm_sqr_connections.svh文件中,并且有两个宏组成。
  • `UVM_SEQ_PORT
  • `UVM_SEQ_ITEM_PULL_IMP

以下伪代码显示了这些宏如何扩展。

class uvm_seq_item_pull_port #( type REQ = jelly_bean_transaction, 
                                type RSP = REQ )
  extends uvm_port_base #( uvm_sqr_if_base #(REQ, RSP) );
 
   // `UVM_SEQ_PORT( `UVM_SEQ_ITEM_PULL_MASK, "uvm_seq_item_pull_port" )
   //  |              |
   //  |              V
   //  |           ( `UVM_SEQ_ITEM_GET_NEXT_ITEM_MASK      | 
   //  |             `UVM_SEQ_ITEM_TRY_NEXT_ITEM_MASK      |
   //  |             `UVM_SEQ_ITEM_ITEM_DONE_MASK          |
   //  |             `UVM_SEQ_ITEM_HAS_DO_AVAILABLE_MASK   |
   //  |             `UVM_SEQ_ITEM_WAIT_FOR_SEQUENCES_MASK |
   //  |             `UVM_SEQ_ITEM_PUT_RESPONSE_MASK       |
   //  |             `UVM_SEQ_ITEM_PUT_MASK                |
   //  |             `UVM_SEQ_ITEM_GET_MASK                |
   //  |             `UVM_SEQ_ITEM_PEEK_MASK ) = 9'h1FF
   //  V
 
   function new( string        name,
                 uvm_component parent,
                 int           min_size = 0,
                 int           max_size = 1 );
      super.new( name, parent, UVM_PORT, min_size, max_size );
      m_if_mask = 9'h1FF;
   endfunction // new
 
   //  |
   //  +--> `UVM_TLM_GET_TYPE_NAME( "uvm_seq_item_pull_port" )
 
   virtual function string get_type_name();
      return "uvm_seq_item_pull_port";
   endfunction // get_type_name
 
   // `UVM_SEQ_ITEM_PULL_IMP( this.m_if, 
   //  |                      jelly_bean_transaction, 
   //  |                      jelly_bean_transaction, t, t )
   //  V
 
   task get_next_item( output jelly_bean_transaction t );
      this.m_if.get_next_item( t );
   endtask // get_next_item
 
   task try_next_item( output jelly_bean_transaction t );
      this.m_if.try_next_item( t );
   endtask // try_next_item
 
   function void item_done( input jelly_bean_transaction t = null );
      this.m_if.item_done( t );
   endfunction // item_done
 
   task wait_for_sequences();
      this.m_if.wait_for_sequences();
   endtask // wait_for_sequences
 
   function bit has_do_available();
      return this.m_if.has_do_available();
   endfunction // has_do_available
 
   function void put_response( input jelly_bean_transaction t );
      this.m_if.put_response( t );
   endfunction // put_response
 
   task get( output jelly_bean_transaction t );
      this.m_if.get( t );
   endtask // get
 
   task peek( output jelly_bean_transaction t );
      this.m_if.peek( t );
   endtask // peek
 
   task put( input jelly_bean_transaction t );
      this.m_if.put( t );
   endtask // put
 
   // end of macro expansion
 
   bit print_enabled;
endclass // uvm_seq_item_pull_port

正如你在上面看到的那样,get_next_item()item_done()的工作只是代表this.m_if的工作,仅仅是调用this.m_if中的方法(第39和47行)。但是什么this.m_if在回答这个问题之前,让我们看看连接的另一端。

Sequence Item Export

seq_item_export是jelly-bean sequencer是一个jelly_bean_transaction限定的uvm_seq_item_pull_imp类型的类uvm_seq_item_pull_imp类也被定义的src/tlm1/uvm_sqr_connections.svh,由两个宏:

  • `UVM_IMP_COMMON
  • `UVM_SEQ_ITEM_PULL_IMP

以下伪代码显示了这些宏如何扩展。

class uvm_seq_item_pull_imp 
  #( type REQ = jelly_bean_transaction,
     type RSP = REQ,
     type IMP = uvm_sequencer #( jelly_bean_transaction, 
                                 jelly_bean_transaction ) )
  extends uvm_port_base #( uvm_sqr_if_base #( REQ, RSP ) );
 
   // `UVM_IMP_COMMON( `UVM_SEQ_ITEM_PULL_MASK, "uvm_seq_item_pull_imp",
   //  |               uvm_sequencer #( jelly_bean_transaction,
   //  |                                jelly_bean_transaction ) )
   //  V
 
   local uvm_sequencer #( jelly_bean_transaction, 
                          jelly_bean_transaction ) m_imp;
 
   function new( string name, 
                 uvm_sequencer #( jelly_bean_transaction,
                                  jelly_bean_transaction ) imp );
      super.new( name, imp, UVM_IMPLEMENTATION, 1, 1 );
      m_imp     = imp;
      m_if_mask = 9'h1FF;
   endfunction // new
 
   //  |
   //  +--> `UVM_TLM_GET_TYPE_NAME( "uvm_seq_item_pull_imp" )
 
   virtual function string get_type_name();
      return "uvm_seq_item_pull_imp";
   endfunction // get_type_name
 
   // `UVM_SEQ_ITEM_PULL_IMP( m_imp, 
   //  |                      jelly_bean_transaction, jelly_bean_transaction,
   //  |                      t, t )
   //  V
 
   task get_next_item( output jelly_bean_transaction t );
      m_imp.get_next_item( t );
   endtask // get_next_item
 
   task try_next_item( output jelly_bean_transaction  t );
      m_imp.try_next_item( t );
   endtask // try_next_item
 
   function void item_done( input jelly_bean_transaction t = null );
      m_imp.item_done( t );
   endfunction // item_done
 
   task wait_for_sequences(); 
      m_imp.wait_for_sequences();
   endtask // wait_for_sequences
 
   function bit has_do_available();
      return m_imp.has_do_available();
   endfunction // has_do_available
 
   function void put_response( input jelly_bean_transaction t );
      m_imp.put_response( t );
   endfunction // put_response
 
   task get( output jelly_bean_transaction t );
      m_imp.get( t );
   endtask // get
 
   task peek( output jelly_bean_transaction t ); 
      m_imp.peek( t );
   endtask // peek
 
   task put( input jelly_bean_transaction t );
      m_imp.put( t );
   endtask // put
 
endclass // uvm_seq_item_pull_imp

uvm_seq_item_pull_port相似uvm_seq_item_pull_imp类拥有get_next_item()item_done()方法,并将他们的工作委托给m_impm_imp就是 sequence item export所属的sequencer。

Connection

现在让我们连接sequence item port and the sequence item export以下序列图显示了连接中涉及的步骤。


    UVM driver实例化seq_item_port(步骤1),并且UVM sequencer实例化seq_item_export(步骤2)。

  • 当seq_item_port.connect(jb_seqr.seq_item_export)被调用时,它seq_item_export被存储在称为m_provided_by(步骤3)的数组中,
  • 在进入end_of_elaboration_phase之前,resolve_bindings()函数被调用。该函数遍历端口连接并将“implementation” 存储到称为m_imp_list(步骤4)的数组中。该函数检查实现的数量。如果它是1,则函数将实现存储为m_if(步骤5)。这是m_if序列项目端口委托其作业。如果实现的数量为0,seq_item_port则保持不连接。如果实现的数量超过1个,那就是错误。
  • 当seq_item_port.get_next_item()被调用时,任务调用get_next_item()的seq_item_export,这反过来又调用uvm_sequencer 的 get_next_item()(步骤6和7)。
  • 类似地,当seq_item_port.item_done()被调用时,函数调用seq_item_export的item_done(),这反过来又调用uvm_sequencer的item_done()(步骤8和9)。

我希望这篇文章能帮助你理解顺序项目端口的工作原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值