Verification Martial Arts: A Verification Methodology Blog

Blocking/Non-blocking Transport Adaption in VMM 1.2

Posted by John Aynsley on September 1st, 2010

John Aynsley, CTO, Doulos

One neat feature of the SystemC TLM-2.0 standard is the ability provided by the so-called simple target socket to perform automatic adaption between the blocking and non-blocking transport calls; an initiator that calls b_transport can be connected to a target that implements nb_transport, and vice-versa. VMM 1.2 provides similar functionality using the vmm_connect utility.

vmm_connect serves four distinct purposes in VMM 1.2.

•    Connecting one channel port to another channel port, taking account of whether each channel port is null or actually refers to an existing channel object
•    Connecting a notify observer to a notification
•    Binding channels to transaction-level ports and exports
•    Binding a transaction-level port to a transaction-level export where one uses the blocking
transport interface and the other the non-blocking transport interface. This is the case we are considering here.

When making transaction-level connections I think of vmm_connect as covering the “funny cases”.

To illustrate, suppose we have a transactor that acts as an initiator and calls b_transport. The following code fragment also serves as a reminder of how to use the blocking transport interface in VMM:

class initiator extends vmm_xactor;
`vmm_typename(initiator)

vmm_tlm_b_transport_port  #(initiator, vmm_tlm_generic_payload) m_b_port;

virtual task run_ph;
forever begin: loop
vmm_tlm_generic_payload tx;

// Create valid generic payload
assert( randomized_tx.randomize() with {…} )
else `vmm_error(log, “tx.randomize() failed”);

$cast(tx, randomized_tx.copy());

// Send copy through port
m_b_port.b_transport(tx, delay);

// Check response status
assert( tx.m_response_status == vmm_tlm_generic_payload::TLM_OK_RESPONSE );


Further, suppose we have another transactor that acts as a target for nb_transport calls, and which therefore implements nb_transport_fw to receive the request and subsequently calls nb_transport_bw to send the response. The code fragment below is just an outline, but it does show the main idea that non-blocking transport allows timing points to be modeled by having multiple method calls in both directions (as opposed to a single method call in one direction for b_transport):

class target extends vmm_xactor;
`vmm_typename(target)

vmm_tlm_nb_transport_export #(target, vmm_tlm_generic_payload) m_nb_export;

// Implementation of nb_transport method
virtual function vmm_tlm::sync_e nb_transport_fw(
int id=-1, vmm_tlm_generic_payload trans,
ref vmm_tlm::phase_e ph, ref int delay);

-> ev;
return vmm_tlm::TLM_ACCEPTED;
endfunction : nb_transport_fw

// Process to send response by calling nb_transport on backward path
virtual task run_ph;
forever  begin: loop
vmm_tlm::phase_e phase = vmm_tlm::BEGIN_RESP;
@(ev);
tx.m_response_status = vmm_tlm_generic_payload::TLM_OK_RESPONSE;
status = m_nb_export.nb_transport_bw(tx, phase, delay);
end
endtask: run_ph

Now for the main point. We can use tlm_connect to bind the two components together, despite the fact that one uses blocking calls and the other non-blocking calls:

virtual function void build_ph;
m_initiator = new( “m_initiator”, this );
m_target    = new( “m_target”,    this );
endfunction: build_ph

virtual function void connect_ph;

vmm_connect #(.D(vmm_tlm_generic_payload))::tlm_transport_interconnect(
m_initiator.m_b_port, m_target.m_nb_export, vmm_tlm::TLM_NONBLOCKING_EXPORT);

endfunction: connect_ph

That’s all there is to it! Notice that tlm_transport_interconnect is a static method of vmm_connect so its name is prefixed by the scope resolution operator and an instantiation of the vmm_connect parameterized class with the appropriate transaction type, namely the generic payload. The first argument is the port, the second argument the export, and the third argument indicates that it is the export that is non-blocking.
It is also possible to connect a non-blocking initiator to a blocking target: you would simply replace TLM_NONBLOCKING_EXPORT with TLM_NONBLOCKING_PORT. The objective of this post has been to show that VMM has all the bases covered when it comes to connecting together transaction-level ports.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Google Buzz
  • LinkedIn
  • RSS
  • Twitter

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>