UVM基础之------uvm_transaction

uvm_transaction继承自uvm_object,添加了timing和recording接口,该类是uvm_sequence_item的基类。下边将做剖析
1. 这个类提供了时间戳属性(timestamp properties),通知事件(notification events),和交易记录(transaction recording)支持。
2. 使用这个类作为用户定义的基础交易是弃用。其子类uvm_sequence_item应当作为基类为所有用户定义的事务类型。
3. 这个API的使用意图是在sequence item执行过程中通过调用uvm_component < uvm_driver >::accept_tr uvm_component::begin_tr uvm_component::end_tr。从而设置对应的时间戳(accept_time,begin_time,and end_tr),触发对应的event(begin_event and end_event),如果启用,记录事务内容特定于供应商的事务数据库。
4. Note that start_item/finish_item (or `uvm_do* macro) executed from a uvm_sequence #(REQ,RSP) will automatically trigger the begin_event and end_events via calls to begin_tr and end_tr.
5. 虽然方便,但是触发这些事件通常应该由drivers去标记事务执行期间的进展,标志着一个事务执行期间的进展。 To allow the driver to control sequence item timestamps, events, and recording, you must add +define+UVM_DISABLE_AUTO_ITEM_RECORDING when compiling the UVM package. 
6. 另外,用户可能使用事务的event pool,events,定义自定义events驱动触发和序列等。任何中间事件等标记的地址和数据的开始阶段事务执行可以通过events pools实现。
7. In pipelined protocols, the driver may release a sequence (return from finish_item() or it’s `uvm_do macro) before the item has been completed.  If the driver uses the begin_tr/end_tr API in uvm_component, the sequence can wait on the item’s end_event to block until the item was fully executed, as in the following example.
8. task uvm_execute(item, ...);
    // can use the `uvm_do macros as well
    start_item(item);
    item.randomize();
    finish_item(item);
    item.end_event.wait_on();
    // get_response(rsp, item.get_transaction_id()); //if needed
endtask

9. A simple two-stage pipeline driver that can execute address and data phases concurrently might be implemented as follows:
task run();
    // this driver supports a two-deep pipeline
    fork
      do_item();
      do_item();
    join
endtask
 
 
task do_item();
 
  forever begin
    mbus_item req; 
    lock.get(); 
    seq_item_port.get(req); // Completes the sequencer-driver handshake 
    accept_tr(req); 
      // request bus, wait for grant, etc. 
    begin_tr(req); 
      // execute address phase 
    // allows next transaction to begin address phase
    lock.put(); 
      // execute data phase
      // (may trigger custom "data_phase" event here) 
    end_tr(req); 
  end 
endtask: do_item

1.变量
 
  local integer m_transaction_id = -1;//id
 
  local time    begin_time=-1;//开始记录的时间
  local time    end_time=-1;//结束记录的时间
  local time    accept_time=-1;//被接受的时间
 
  local uvm_component initiator;//本实例所属的component
  local integer       stream_handle;//本实例所属的流
  local integer       tr_handle;//本实例的handle,即本实例的一个索引值,在某个地方记录了这个tr.    
  local bit           record_enable = 0;//记录使能
  local uvm_recorder  m_recorder;//记录器
 
  const uvm_event_pool events = new; 
  uvm_event begin_event; 
  uvm_event end_event;

 2.function uvm_transaction::new (string name="",
                               uvm_component initiator = null);//该函数设置实例的名字,所属的
 
component,transaction_id,开始事件,结束事件
 
3.function void uvm_transaction::set/get_transaction_id(integer id);对m_transaction_id的访问 
4.function void uvm_transaction::set/get_initiator(uvm_component initiator);对initiator的访问 
5.function uvm_event_pool uvm_transaction::get_event_pool();//返回events 
6.function bit uvm_transaction::is_active();//测试tr_handle是否为空
 7.下列函数顾名思意
 
   function time uvm_transaction::get_begin_time ();
 
   function time uvm_transaction::get_end_time ();
 
   function time uvm_transaction::get_accept_time ();
 
   function integer uvm_transaction::get_tr_handle ();
 
   function void uvm_transaction::disable_recording ();
 
   function bit uvm_transaction::is_recording_enabled ();
8. 下列函数只是一个hook,可以被相应的函数在恰当的地方调用
 
   function void uvm_transaction::do_accept_tr();
 
   function void uvm_transaction::do_begin_tr();
 
   function void uvm_transaction::do_end_tr();
   //下述三个方法用于实现uvm_object里面的方法,
   function void uvm_transaction::do_print (uvm_printer printer);//打印accept/begin/end time,initiator的名字 
   function void uvm_transaction::do_copy (uvm_object rhs);//做一些copy,把各个内部变量做copy 
   function void uvm_transaction::do_record (uvm_recorder recorder);//记录initiator和accept time
 9.function void uvm_transaction::enable_recording (string stream, uvm_recorder recorder=null);//根据stream生产stream_handle,使能enable_record
      If transaction recording is on, then a call to record is made when the transaction is started and when it is ended.
10.function void uvm_transaction::accept_tr (time accept_time = 0);//生成或者设置accept_time,并触发accept_event,调用do_accept_tr
       1. Calling accept_tr indicates that the transaction item has been received by a consumer component.
       2.Typically a <uvm_driver> would call uvm_component::accept_tr, which calls this method-- upon return from a get_next_item(), get(), or peek() call on its sequencer port, <uvm_driver::seq_item_port>.
      3.With some protocols, the received item may not be started immediately after it is accepted.  For example, a bus driver, having accepted a request transaction, may still have to wait for a bus grant before begining to execute the request.

      4. This function performs the following actions: 
           1. The transaction’s internal accept time is set to the current simulation time, or to accept_time if provided and non-zero.  The accept_time may be any time, past or future.
          2. The transaction’s internal accept event is triggered.  Any processes waiting on the this event will resume in the next delta cycle.
          3. The do_accept_tr method is called to allow for any post-accept action in derived classes.

11.function integer uvm_transaction::begin_tr (time begin_time=0); 调用12
     1. 这个function表明transaction已经启动,并不是另一个transaction的child
     2. Typically a <uvm_driver> would call uvm_component::begin_tr, which calls this method, before actual execution of a sequence item transaction.  Sequence items received by a driver are always a child of a parent sequence.  In this case, begin_tr obtains the parent handle and delegates to begin_child_tr.
     3. This function performs the following actions: 
          1. The transaction’s internal start time is set to the current simulation time, or to begin_time if provided and non-zero.  The begin_time may be any time, past or future, but should not be less than the accept time.
          2. If recording is enabled, then a new database-transaction is started with the same begin time as above.
          3. The do_begin_tr method is called to allow for any post-begin action in derived classes.
          4. The transaction’s internal begin event is triggered.  Any processes waiting on this event will resume in the next delta cycle.

12.function integer uvm_transaction::m_begin_tr (time begin_time=0,
                                              integer parent_handle=0,
                                              bit has_parent=0);//设置begin_time;
 
   如果record_enable,首先核查本tr_handle是否在recorder中,如果已在,则打印end_tr,否则进行记录,并返回tr_handle,如果有父handle,则在tr_handle和parent_handle间建立连接,最后检查tr_handle是否有效。
 
如果record_enable==0,则tr_handle=0;然后调用do_begin_tr();然后触发begin_event,最后返回tr_handle。
 
13.function integer uvm_transaction::begin_child_tr (time begin_time=0,
                                                  integer parent_handle=0);//调用12,设置has_parent==1.
 
14.function void uvm_transaction::end_tr (time end_time=0, bit free_handle=1);//设置end_time,调用do_end_tr,调用recorder.edn_tr, recorder.free_tr,最后触发end_event
This function indicates that the transaction execution has ended.  Generally, a consumer component ends execution of the transactions it receives.
 
You must have previously called begin_tr or begin_child_tr for this call to be successful.
 
Typically a <uvm_driver> would call uvm_component::end_tr, which calls this method, upon completion of a sequence item transaction.  Sequence items received by a driver are always a child of a parent sequence.  In this case, begin_tr obtain the parent handle and delegate to begin_child_tr.
This function performs the following actions
 
    The transaction’s internal end time is set to the current simulation time, or to end_time if provided and non-zero.  The end_time may be any time, past or future, but should not be less than the begin time.
    If recording is enabled and a database-transaction is currently active, then the record method inherited from uvm_object is called, which records the final property values.  The transaction is then ended.  If free_handle is set, the transaction is released and can no longer be linked to (if supported by the implementation).
    The do_end_tr method is called to allow for any post-end action in derived classes.
    The transaction’s internal end event is triggered.  Any processes waiting on this event will resume in the next delta cycle.







原文地址:https://www.cnblogs.com/bob62/p/3871858.html