TLM Interface Ports in e (Addition to clause 8)

This clause defines the support the e language provides for interface ports, used to implement Transaction Level Modeling (TLM) standard interfaces. These ports facilitate the transfer of transactions between verification components, taking advantage of the standardized, high level TLM communication mechanism.

interface_port

Purpose

Transfer transactions between e units or a combination of e units and external modules

Category

Unit member

Syntax

port-instance-name : [list of] direction interface_port of tlm-intf-type 
[using prefix=prefix | using suffix=suffix] [is instance] 

port-instance-name : [list of] export interface_port of tlm-intf-type [is instance] 

Syntax Examples

e_packet : in interface_port of tlm_put of packet is instance; 
p1 : out interface_port of tlm_nonblocking_transport of (packet, msg) is instance; 
p2 : export interface port of tlm_blocking_put is instance;  // export

Parameters

port-instance-name - A unique e identifier used to refer to the port or access its value.

direction - in or out. There is no default.

tlm-intf-type

For internal e TLM interface ports, the type (or types) you specify for the interface can be any legal e type.

External e TLM interface ports support transactions of a struct (or class) type only. Thus, for externally bound e TLM interface ports, the type (or types) you specify for the interface must be legal e types that inherit from any_struct.

using prefix=prefix

using suffix=suffix

Applies for e TLM input ports only. Specifies a prefix or suffix string to be attached to the predefined TLM methods for the given port.

Using a prefix or suffix ensures that there are no method name collisions if a port contains more than instance of an e TLM interface port tied to the same TLM interface.

(This syntax can be used only for the port instance members. It cannot be used in other declarations, such as declarations for parameters or variables.)

Description

An e TLM interface port type is parameterized with a specific TLM interface type. For example, if you define an e TLM interface port with the syntax interface_port of tlm_nonblocking_put, you have tied that port to the tlm_nonblocking_put interface. You can then use the set of methods (functions) predefined for that interface to exchange transactions.

Special Port Types

Export

An export interface port is a port whose enclosing unit does not implement the required interface methods. The interface methods are delegated to the connected unit. An export TLM input port in e is functionally equivalent to a SystemVerilog or SystemC export.

The following limitations apply to export interface ports:

  • The port shall have an outbound connection.
  • The port shall be connected (either directly or indirectly) to an input interface port or to an external port providing suitable interface functions.
  • The port shall have no inbound connection.
  • The port must be connected using the connect() (see below) method. The bind() constraints and the do_bind() routine are not applicable for it.

Analysis port

Analysis ports are ports featuring the tlm_analysis interface - a restricted write-only interface intended to share monitoring information for analysis purposes. They may have multiple outbound connections in support of broadcast implementations.

Defining Input e TLM interface ports

When a unit contains an instance member of an input TLM interface port, the unit must implement all methods required by the TLM interface type of that input port. The list of methods is predefined according to the standard TLM specification.

These methods must be defined before the port is defined. (If the methods and port are defined in the same module, however, the order does not matter.) If any of the required methods is missing, a compile time error shall be issued.

Example:

struct packet { 
    … 
}; 
unit server { 
    // The following four lines define the four methods required 
    // by the TLM interface tlm_put. 
    put(value : packet)@sys.any is {…}; 
    try_put(value: packet) : bool is {…}; 
    can_put() : bool is {…}; 
    ok_to_put() : tlm_event is {…}; 
    packet_in : in interface_port of tlm_put of packet is instance; 
}; 

In this example, the unit server implements the four methods/tasks which are required by the interface tlm_put of packet.

See below for a description of interface method semantics.

Binding e TLM interface ports

Binding Rules for TLM interface ports

A TLM output port can be bound to a TLM input port if the interface type of the output port is either the same as the interface type of the input port or subset of it (with exactly the same element type in the template parameter). For example, you can bind an output port of tlm_nonblocking_put to an input port of tlm_put, because the tlm_nonblocking_put interface is a subset of the tlm_put interface. Additionally:

  • Empty and undefined bindings are supported for e TLM interface ports.
  • Multiple binding is not supported for e TLM interface ports, except for analysis ports.
  • Unification of ports bound to the same external port is not supported for e TLM interface ports.
  • External e TLM interface ports are implicitly bound to external if they have a non-empty external_ovm_path().

Declarative and Procedural Binding

e TLM interface ports have to be bound before usage, similar to any other port. Binding can be done declaratively with keep bind() constraints or procedurally with a do_bind() or do_bind_unit() pseudo-routines.

Editorial note: The bind syntax is the same as for other e ports - need a cross reference to the syntax definition in clause 8 (currently 8.7.2.1 for declarative bind). Need to add section about procedural bind to clause 8 (issue filed)

Syntax examples for declarative binding
keep bind(port1, port2); 
keep bind(port3, external); 

Syntax examples for procedural binding
connect_ports() is also { 
  do_bind(port1, port2); 
  do_bind(port3, external); 
}

connect() - Language-Neutral Binding

External binding of TLM ports in a lnaguage-neutral way shall be supported by the simulation environment. The port method connect() is provided for this purpose. Use connect() when you want to bind two ports which are not both defined in the same language. For example, you can use this method to bind a SystemC port to a SystemVerilog port from e. For uniformity, connect() may be used to procedurally bind together e ports as well.

The connect() method shall be called once during the connect_ports() phase. The effect of this method is immediate - it shall issue an error in case of any mismatch (wrong external path, mismatching interface types, unsupported multiple binding, and so on).

Syntax of connect()
<port1-exp>.connect(<port2-exp>)
<port1-exp>.connect(empty|undefined)
<port1-exp>.connect(“external path”)

Syntax examples for connect()
env.agent[1].my_port.connect(env.agent[2].my_export)
env.agent.monitor.port.connect(empty);

Description

The following restrictions shall apply to connections created by calling connect().

If port1 is an output port:

  • It can be connected to other e output port, e export port, or e input port.
  • It can be connected to empty. In this case, this must be the only outbound connection it has. In this case, invoking a method on this port is like calling an empty method.
  • In can be connected to undefined. In this case, this must be the only outbound connection it has. In this case, invoking a method on this port will cause to run time error.
  • It can be connected to specific external port, by specifying the external port path. This external port can be of any direction.

If port1 is an export port:

  • It can be connected to other e export port or to other e input port
  • It can be connected to specific external port, by specifying the external port path. This external port must be input port or an export port.
  • Connecting to an external path:

    • For SystemVerilog or SystemC, the external path must be quasi-static (full path from the top level scope).
    • For e, the external path is an e-path, beginning with “sys”.

    Supported TLM Interfaces

    Editorial note: Need to introduce the type tlm_event as a built-in. Discuss whether it must remain in a special scope (tlm::tlm_event) or is it OK to migrate to main.

    Supported Unidirectional TLM Interfaces

    Note Nonblocking TLM interface calls are zero-delay calls. The blocking interface calls, which correspond to e TCM methods, consume an additional Specman tick and one cycle of simulation time.

    Table 1 Supported TLM Interfaces and Related Methods

    Blocking Unidirectional Interfaces
    TLM InterfaceInterface Methods
    tlm_blocking_put of type
    put(value:type)@sys.any 
    tlm_blocking_get of type
    get(value:*type)@sys.any
    tlm_blocking_peek of type
    peek(value:*type)@sys.any
    tlm_blocking_get_peek of type
    get(value:*type)@sys.any 
    peek(value:*type)@sys.any 
    

    Nonblocking Unidirectional Interfaces
    TLM InterfaceInterface Methods
    tlm_nonblocking_put of type
    try_put(value:type) : bool 
    can_put() : bool 
    ok_to_put() : tlm_event 
    
    tlm_nonblocking_get of type
    try_get(value:*type) : bool 
    can_get() : bool 
    ok_to_get() : tlm_event 
    
    tlm_nonblocking_peek of type
    try_peek(value:*type) : bool 
    can_peek() : bool 
    ok_to_peek() : tlm_event 
    
    tlm_nonblocking_get_peek of type
     try_get(value:*type) : bool 
    can_get() : bool 
    ok_to_get() : tlm_event 
    try_peek(value:*type) : bool 
    can_peek() : bool 
    ok_to_peek() : tlm_event 
    

    Combined Unidirectional Interfaces (Blocking and Nonblocking)
    TLM InterfaceInterface Methods
    tlm_put of type
    put(value:type)@sys.any 
    try_put(value:type) : bool 
    can_put() : bool 
    ok_to_put() : tlm_event 
    
    tlm_get of type
    get(value:*type)@sys.any 
    try_get(value:*type) : bool 
    can_get() : bool 
    ok_to_get() : tlm_event 
    
    tlm_peek of type
    peek(value:*type)@sys.any 
    try_peek(value:*type) : bool 
    can_peek() : bool 
    ok_to_peek() : tlm_event 
    

    Supported Bidirectional TLM Interfaces

    Note Nonblocking TLM interface calls are zero-delay calls. The blocking interface calls, which correspond to e TCM methods, consume an additional Specman tick and one cycle of simulation time.

    Table 2 Supported Bidirectional TLM Interfaces and Related Methods

    Blocking Bidirectional Interfaces
    TLM InterfaceInterface Methods
    tlm_blocking_master of (req-type, rsp-type)
    put(value: req-type)@sys.any 
    get(value: *rsp-type)@sys.any 
    peek(value: *rsp-type)@sys.any 
    
    tlm_blocking_slave of (req-type, rsp-type)
    put(value: rsp-type)@sys.any 
    get(value: *req-type)@sys.any 
    peek(value: *req-type)@sys.any 
    
    tlm_blocking_transport of (req-type, rsp-type)
    transport(request: req-type, 
    response: *rsp-type)@sys.any 
    

    Nonblocking Bidirectional Interfaces
    TLM InterfaceInterface Methods
    tlm_nonblocking_master of (req-type, rsp-type)
    try_put(value: req-type) : bool 
    can_put() : bool 
    ok_to_put() : tlm_event 
    try_get(value: *rsp-type): bool 
    can_get(): bool 
    ok_to_get(): tlm_event 
    try_peek(value: *rsp-type): bool 
    can_peek(): bool 
    ok_to_peek(): tlm_event 
    
    tlm_nonblocking_slave of (req-type, rsp-type)
    try_put(value: rsp-type) : bool 
    can_put() : bool 
    ok_to_put() : tlm_event 
    try_get(value: *req-type): bool 
    can_get(): bool 
    ok_to_get(): tlm_event 
    try_peek(value: *req-type): bool 
    can_peek(): bool 
    ok_to_peek(): tlm_event 
    
    tlm_nonblocking_transport of (req-type, rsp-type)
    nb_transport(request: req-type, 
    response: *rsp-type): bool 
    

    Combined Bidirectional Interfaces (Blocking plus Nonblocking)
    TLM InterfaceInterface Methods
    tlm_master of (req-type, rsp-type)
    put(value: req-type)@sys.any 
    get(value: *rsp-type)@sys.any 
    peek(value: *rsp-type)@sys.any 
    try_put(value: req-type): bool 
    can_put(): bool 
    ok_to_put(): tlm_event 
    try_get(value: *rsp-type): bool 
    can_get(): bool 
    ok_to_get(): tlm_event 
    try_peek(value: *rsp-type): bool 
    can_peek(): bool 
    ok_to_peek(): tlm_event 
    
    tlm_slave of (req-type, rsp-type)
    put(value: rsp-type)@sys.any 
    get(value: *req-type)@sys.any 
    peek(value: *req-type)@sys.any 
    try_put(value: rsp-type): bool 
    can_put(): bool 
    ok_to_put(): tlm_event 
    try_get(value: *req-type): bool 
    can_get(): bool 
    ok_to_get(): tlm_event 
    
    lm_transport of (req-type, rsp-type)
    transport(request: req-type, 
    response: *rsp-type)@sys.any 
    nb_transport(request: req-type, 
    response: *rsp-type): bool 
    

    Supported Analysis TLM Interface

    Table 3 Supported Analysis TLM Interface and Related Methods

    TLM InterfaceInterface Methods
    tlm_analysis of type
    write(value : type) 
    

    Required Semantics of TLM Interface Methods

    TLM Interface Methods need to be implemented for each interface type. These methods are activated in response to a port interface call. As users of the e language define new interface types, they will have to provide implementations to the interface methods. The following section defines the expected semantics of the various Interface Methods.

    put(value:type)
    The put() method passes on a value into the port, making it available for connected ports to read. This call shall block if the port is not ready to handle the transfer of the value.

    try_put(value:type) : bool
    The try_put() method is non-blocking. If the port is ready to handle a put operation, the value is passed on and the method returns TRUE. Otherwise the method returns FALSE, and the value is not passed on.

    can_put() : bool
    The can_put() method returns TRUE if the port is ready to handle a put operation (a call to put() will not block). FALSE is returned if the port is not ready to handle a put operation (a call to put() would block).

    ok_to_put() : tlm_event
    The method ok_to_put() returns an event that will trigger each time the port is ready to handle a put operation. The returned event may be used to invoke the user code producing the next put operation.

    get(value:*type)
    The get() method returns the value that is read from the port (the value is passed by reference in the parameter). This call blocks if no value is available to be read.

    try_get(value:*type) : bool
    The try_get() non-blocking method returns TRUE and the read value if the port can be read. FALSE is returned if the port is not ready to be read (the get() operation would block).

    can_get() : bool
    The method can_get() returns TRUE if a get operation can be performed without blocking. FALSE is returned otherwise.

    ok_to_get() : tlm_event
    The method ok_to_get() returns an event that will trigger each time the port is ready for a get operation (data is available for reading). The returned event can be used to trigger user code performing a get operation.

    peek(value:*type)
    The peek() method returns the next value ready to be read from a port. Peek() doesn't consume the value - a subsequent get() call will return the same value. Peek() shall block if no value is ready to be read, and return only when the next value is available.

    try_peek(value:*type) : bool
    The try_peek() non-blocking method returns TRUE and the read value if the port can be read. FALSE is returned if the port is not ready to be read (the peek() operation would block). This method doesn't consume the read value.

    can_peek() : bool
    The method can_peek() returns TRUE if a peek operation can be performed without blocking. FALSE is returned otherwise.

    ok_to_peek() : tlm_event
    The ok_to_peek() method returns an event that triggers each time the port is ready for a peek operation (data is available to be read). The returned event can be used to trigger user code that monitors (performs a non-destructive inspection) the ports output.

    transport(request: req-type, response: *rsp-type)
    The transport() method implements the equivalent of a procedure call, or a bidirectional atomic transfer. The first parameter contains the input to the procedure. The second parameter passes back the output (by reference). The method may consume time, depending on the user-level implementation of this method for a particular interface.

    write(value : type)
    The write() method passes on a value into an analysis port. The method is non-blocking, because analysis ports should always be ready to be written.
    Topic revision: r10 - 2010-03-03 - 16:22:32 - YaronKashai
     
    Copyright © 2008-2025 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
    Ideas, requests, problems regarding TWiki? Send feedback