Blocking and Non-blocking Communication Using the TLI
Posted by John Aynsley on March 31st, 2011
John Aynsley, CTO, Doulos
In the previous blog post I introduced the VCS TLI Adapters for transaction-level communication between SystemVerilog and SystemC. Now let’s look at the various coding styles supported by the TLI Adapters, and at the same time review the various communication options available in VMM 1.2.
We will start with the options for sending transactions from SystemVerilog to SystemC. VMM 1.2 allows transactions to be sent through the classic VMM channel or through the new-style TLM ports, which come in blocking- and non-blocking flavors. Blocking means that the entire transaction completes in one function call, whereas non-blocking interfaces may required multiple function calls in both directions to complete a single transaction:
On the SystemVerilog side, transactions can be sent out through blocking or non-blocking TLM ports, through VMM channels or through TLM analysis ports. On the SystemC side, transactions can be received by b_transport or nb_transport, representing the loosely-timed (LT) and approximately-timed (AT) coding styles, respectively, or through analysis exports. In the TLM-2.0 standard any socket supports both the LT and AT coding styles, although SystemVerilog does not offer quite this level of flexibility, and hence neither does the TLI.
Now we will look at the options for sending transactions from SystemC back to SystemVerilog. Not surprisingly, they mirror the previous case:
On the SystemC side, transactions can be sent out from LT or from AT initiators or through analysis ports. On the SystemVerilog side, transactions can be received by exports for blocking- or non-blocking transport, by vmm_channels, or by analysis subscribers.
Note the separation of the transport interfaces from the analysis interfaces in either direction. The transport interfaces are used for modeling transactions in the target application domain, whereas the analysis interfaces are typically used internally within the verification environment for coverage collection or checking.
In the SystemVerilog and SystemC source code, the choice of which TLI interface to use is made when binding ports, exports, or sockets to the TLI Adapter, for example:
import vmm_tlm_binds::*; // For port/export
import vmm_channel_binds::*; // For channel
tli_tlm_bind(m_xactor.m_b_port, vmm_tlm::TLM_BLOCKING_EXPORT, “sv_tlm_lt”);
tli_tlm_bind(m_xactor.m_nb_port, vmm_tlm::TLM_NONBLOCKING_EXPORT, “sv_tlm_at”);
tli_tlm_bind(m_xactor.m_b_export, vmm_tlm::TLM_BLOCKING_PORT, “sc_tlm_lt”);
tli_tlm_bind(m_xactor.m_nb_export, vmm_tlm::TLM_NONBLOCKING_PORT, “sc_tlm_at”);
tli_channel_bind(m_xactor.m_out_at_chan, “sv_chan_at”, SV_2_SC_NB);
tli_tlm_bind_initiator(m_scmod->init_socket_lt, LT, “sc_tlm_lt”,true);
tli_tlm_bind_initiator(m_scmod->init_socket_at, AT, “sc_tlm_at”,true);
tli_tlm_bind_target (m_scmod->targ_socket_lt, LT, “sv_tlm_lt”,true);
tli_tlm_bind_target (m_scmod->targ_socket_at, AT, “sv_tlm_at”,true);
tli_tlm_bind_target (m_scmod->targ_socket_chan_at, AT, “sv_chan_at”,true);
Note how the tli_tlm_bind calls require you to specify in each case whether the LT or AT coding style is being used. The root cause of this inflexibility is certain language restrictions in SystemVerilog, in particular the lack of multiple inheritance, which makes it harder to create sockets that support multiple interfaces. Hence, in SystemVerilog, the blocking- and non-blocking interfaces get partitioned across multiple ports and exports. In the SystemC TLM-2.0 standard there is only a single kind of initiator socket and a single kind of target socket, each able to forward method calls of any of the core interfaces, namely, the blocking transport, non-blocking transport, direct memory, and debug interfaces.
In summary, the VCS TLI provides a simple and straightforward mechanism for passing transaction in both directions between SystemVerilog and SystemC by exploiting the TLM-2.0 standard.