Skip to Content

Required and Provided Interfaces in VMM 1.2

Posted on  by  from the site Verification Martial Arts
  John Aynsley, CTO, Doulos Before diving into more technical detail concerning VMM 1.2, let’s take some time to review a basic concept of transaction-level communication that often causes confusion, particularly for people more familiar with HDLs like Verilog and VHDL than with object-oriented software programming. This is the idea of the transaction-level interface. A transaction-level interface is a software interface that permits software components to communicate using a specific set of function calls (also known as method calls). In the case of VMM, the software components in question are VMM transactors, and the function calls are the VMM TLM methods such as b_transport, introduced in previous posts on this blog. Such transaction-level interfaces are often depicted diagrammatically as shown here: Ports and exports are depicted as if they were pins on the periphery of a component, which is accurate in a metaphorical sense, but misleading if taken too literally. A port is a structured way of representing the fact that the Producer transactor above makes a call to a specific function, and thus requires an implementation of that function in order to compile and run. On the other side, an export is a structured way of representing the fact that the Consumer transactor provides an implementation of a specific function. So although the diagram may appear to show two components with a structural connection between them, it actually shows the Producer making a call to a function implemented by the Consumer. What may appear to be a hardware connection turns out to be an object-oriented software dependency between Producer and Consumer. When it comes to combining multiple transactors, the types of the transaction-level interfaces have to be respected. The declarations of ports and exports are each parameterized with the type of the transaction object to be passed as a function argument: vmm_tlm_b_transport_port #(Producer, transaction) port; vmm_tlm_b_transport_export #(Consumer, transaction) export; The port, which requires a transaction-level interface of a given type, must be bound to an export that provides an interface of the same type. The type in question is provided by the second parameter transaction. The tlm_bind method effectively seals a contract between the transactor that requires the interface and the provider of the interface: producer.port.tlm_bind( consumer.export ); One benefit of transaction-level interfaces is that this connection is strongly typed, so the SystemVerilog compiler will catch any mismatch between the types of the port and the export. As well as binding a port to an export peer-to-peer, it is also possible to bind chains of ports or exports going up or down the component hierarchy, as shown diagrammatically below: Child-to-parent port bindings carry the function call up through the component hierarchy to the left, while parent-to-child export bindings carry the function call down through the component hierarchy to the right. A port-to-export binding is only permitted at the top level. At run-time, a method call to the appropriate function is made through the child port: port.b_transport(tx, delay); This will result in the corresponding function implementation being called directly, with no intervening channel to store the transaction en route. Transaction-level interfaces are fast, robust, and simple to use, which is why they have been incorporated into VMM. ShareThis
John Aynsley
  John Aynsley, CTO, Doulos Before diving into more technical detail concerning VMM 1.2, let’s take some time to review a basic concept of transaction-level communication that often causes confusion, particularly for people more familiar with HDLs like Verilog and VHDL than with object-oriented software programming. This is the idea of the transaction-level interface. A transaction-level interface is a software interface that permits software components to communicate using a specific set of function calls (also known as method calls). In the case of VMM, the software components in question are VMM transactors, and the function calls are the VMM TLM methods such as b_transport, introduced in previous posts on this blog. Such transaction-level interfaces are often depicted diagrammatically as shown here: Ports and exports are depicted as if they were pins on the periphery of a component, which is accurate in a metaphorical sense, but misleading if taken too literally. A port is a structured way of representing the fact that the Producer transactor above makes a call to a specific function, and thus requires an implementation of that function in order to compile and run. On the other side, an export is a structured way of representing the fact that the Consumer transactor provides an implementation of a specific function. So although the diagram may appear to show two components with a structural connection between them, it actually shows the Producer making a call to a function implemented by the Consumer. What may appear to be a hardware connection turns out to be an object-oriented software dependency between Producer and Consumer. When it comes to combining multiple transactors, the types of the transaction-level interfaces have to be respected. The declarations of ports and exports are each parameterized with the type of the transaction object to be passed as a function argument: vmm_tlm_b_transport_port #(Producer, transaction) port; vmm_tlm_b_transport_export #(Consumer, transaction) export; The port, which requires a transaction-level interface of a given type, must be bound to an export that provides an interface of the same type. The type in question is provided by the second parameter transaction. The tlm_bind method effectively seals a contract between the transactor that requires the interface and the provider of the interface: producer.port.tlm_bind( consumer.export ); One benefit of transaction-level interfaces is that this connection is strongly typed, so the SystemVerilog compiler will catch any mismatch between the types of the port and the export. As well as binding a port to an export peer-to-peer, it is also possible to bind chains of ports or exports going up or down the component hierarchy, as shown diagrammatically below: Child-to-parent port bindings carry the function call up through the component hierarchy to the left, while parent-to-child export bindings carry the function call down through the component hierarchy to the right. A port-to-export binding is only permitted at the top level. At run-time, a method call to the appropriate function is made through the child port: port.b_transport(tx, delay); This will result in the corresponding function implementation being called directly, with no intervening channel to store the transaction en route. Transaction-level interfaces are fast, robust, and simple to use, which is why they have been incorporated into VMM. ShareThis
Posted in
Syndicate content