TLM Ports in UVM

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

TLM PORTS

Transaction Level Modeling


1

TLM PORTS
Introduction
It is necessary to manage most of the verification tasks, such as generating stimulus and
collecting coverage data, at the transaction level, which is the natural way verification
engineers tend to think of the activity of a system. UVM provides a set of transaction-level
communication interfaces and channels that you can use to connect components at the
transaction level.

TLM models are at a higher level of abstraction, and more closely match the level of
abstraction at which the verification engineers or design engineers think about the intended
functionality. This makes it easier to write the models and easier for other engineers to
understand them.

Let’s understand this concept with a basic example.

In Transaction Level Modelling, different components or modules communicate using


transaction objects. A TLM port defines a set of methods (API) used for a particular
connection while the actual implementation of these methods is called TLM exports.

A connection between the TLM port and the export establishes a mechanism of communication
between the two components.

uvm_blocking_put_port

Yaswanth B
2

Producer:

class producer extends uvm_component;


uvm_blocking_put_port #(trans) put_port;

function new(string name,uvm_component parent);


put_port=new(“put_port”,this);
endfunction

virtual task run_phase (uvm_phase phase);


trans tx;
for(int i=0; i<n; i++)
begin
put_port.put(tx);
end
endtask
endclass

Consumer:

class consumer extends uvm_component;


uvm_blocking_put_export #(trans,consumer) put_export;

virtual task put (trans tx);


case(tx.kind)
…..
endcase
endtask
endclass

Connection:

class env extends uvm_env;


producer p;
consumer c;

function void connect_phase (connect_phase phase);


p.put_port.connect(c.put_export);
endfunction
endclass

Yaswanth B
3

In above mentioned example a producer can communicate with a consumer using a simple
TLM port. The producer can create a transaction and “put” to the TLM port, while the
implementation of the “put” method which is also called TLM export would be in the
consumer that reads the transaction created by the producer, thus establishing a channel of
communication while connect in class env in function connect().

Uvm_blocking_get_port

Export port

Declaration: Declaration:
uvm_blocking_get_imp #(t,imp) get_export; uvm_blocking_get_port #(T) get_port;
Method defined:ed: Method defined:ed:
task get(T); .get(T);

Connection:
IMP -> class name where
c.get_port.connect(p.get_export);
implementation is
declared.

Here is “Producer”

Producer:

class consumer extends uvm_component;


uvm_blocking_get_export #(trans,producer) get_export;

virtual task put (trans tx);


trans t=new();
tx=t;
endtask
endclass

Yaswanth B
4

Consumer:

Class consumer extends uvm_component;


uvm_blocking_get_port #(trans) get_port;

function new(string name,uvm_component parent);


get_port=new(“get_port”,this);
endfunction

virtual task run_phase(uvm_phase phase);


trans tx;
for(int i=0; i<n; i++)
begin
get_port.get(tx);
end
endtask
endclass

Connection:

class env extends uvm_env;


producer p;
consumer c;
function void connect_phase (connect_phase phase);
c.get_port.connect(p.get_export);
endfunction
endclass

In above mentioned example a consumer can communicate with a producer using a simple
TLM port. The consumer can create a transaction and “get” to the TLM port, while the
implementation of the “get” method which is also called TLM export would be in the
producer that reads the transaction created by the consumer, thus establishing a channel of
communication while connect in class env in function connect().

Yaswanth B
5

Types of TLM ports/exports/imp:

1. Unidirectional Ports:
1. uvm_*_put_**
2. uvm_*_get_**
3. uvm_*_peek_**
4. uvm_*_get_peek_**
2. Bidirectional Ports:
1. uvm_*_master_**
2. uvm_*_slave_**
3. uvm_*_transport_**
3. Analysis Port
1. uvm_analysis_**

Note: Consider the following


** port/export/imp
* blocking/nonblocking/combined

TLM_FIFO:

Yaswanth B
6

A TLM FIFO is used for Transactional communication if both the producing component and
the consuming component need to operate independently. In this case (as shown above), the
producing component generates transactions and “puts” into FIFO, while the consuming
component gets one transaction at a time from the FIFO and processes it.

uvm_analysis_port

Analysis ports/FIFOs are another transactional communication channel meant for a


component to distribute (or broadcast) transactions to more than one component.

We can say like normal put_port/get_port: One-to-one connection means one component
puts the transaction and only one component gets the transaction.

While analysis_port: One-to-many connection means one component broadcasts the


transactions to the multiple components.

It has only single Non-blocking function – write( ).

Yaswanth B
7

Hierarchical Connections:

When there is a need to connect ports/exports of the child class to the parent class then it can
be connected as shown in the below figure:

General Rules for TLM Connections


• The connect method of the child component port is always invoked with the child
component export as the argument.
• When connecting child ports to parent ports, the connect() method of the child port is
called with the parent port as the argument.
• When connecting child exports to parent exports, the connect() method of the parent
export is called with the child export as the argument.

Yaswanth B

You might also like