UVM: TLM Interfaces (Ports, Exports, FIFOs)

Prod/Consumer example - put

  • This example is about how two components can communicate on a TLM channel by using some of the TLM interface methods.
  • So, let us say a producer wants to produce information or the consumer wants to consume the transactions. Thus, there are 2 ways in which producer and consumer can transfer the info between producer and consumer.
    • First: the producer is doing a put into the consumer.
    • Second: the consumer gets or pulls from the producer and gets info directly into itself.
  • Example code:
class producer extends uvm_component;
 uvm_blocking_put_port #() put_port; //1 parameter
 function new(string name, uvm_component parent);
  put_port = new("put_port", this);
...
 endfunction
 virtual task run();
  simple_trans t;
  for(int i = 0; i < N; i++) begin
   //Generate t.
   put_port.put(t);
  end
 endtask


Example on the consumer (put port):
----------------------------------------
class consumer extends uvm_component;
 uvm_blocking_put_imp #(simple_trans, consumer) put_export;
 ...
 task put (simple_trans t);
  case(t.kind)
   READ: //Do read.
   WRITE: //Do Write.
  endcase
 endtask
endclass

Prod/Consumer example - get

class get_consumer extends uvm_consumer;
 uvm_blocking_get_port #() get_port;
 function new(string name, uvm_component parent);
   get_port = new("get_port", this);
...
 endfunction
 virtual task run();
   simple_trans t;
   for(int i = 0; i < N; i++) begin
    //Generate t.
    get_port.get(t);
   end
  endtask
---------------------------------------

class get_producer extends uvm_component;
 uvm_blocking_get_imp #(simple_trans, get_producer) get_export;
 ...
 task get(output simple_trans t);
  simple_trans tmp = new();
  //Assign values to tmp.
 t = tmp;
  endtask
 endclass

TLM FIFO Channel:
  • Multiple transactions to be communicated.
    • The producer need not wait until the consumer consumes each transaction.
    • TLM FIFO (uvm_tlm_fifo) will have get/port functionality.
    • one-to-one connection - connect two components.
Connecting Producer to Consumer:

class my_env extends uvm_env;
 ...
 virtual function void connect();
  // component.port.connect(target.export);
  producer.blocking_put_port.connect(fifo.put_export);
  get_consumer.get_port.connect(fifo.get_export);
 ...
 endfunction
endclass

Analysis Ports:
  • Analysis ports support 1: many connections (uvm_analysis_port)
  • Used by coverage collectors and score boards.
  • The analysis port contains a list of analysis_exports that are connected to it.
  • When the component calls analysis_port.write(), theanalysis_port cycles through the list and calls the write() method of each connected export.

class my_env extends uvm_env;
   get_ap_component g;
   sub1 s1;
   sub2 s2;
 ...
 function void connect();
    g.ap.connect(s1.analysis_export);
    g.ap.connect(s2.analysis_export);
    ...
   endfunction
endclass


  • Analysis Ports: Used for communication between one component to multiple components (typically to broadcast info).
  • Analysis FIFOs: Extended from TLM FIFO
    • It provides an "implementation" style export.
    • The implementation of "write" will place the date into a FIFO.
Example:
FIG: Example usage of Analysis Ports and FIFOs

General points to know on TLM:

1. A transaction is a class object that abstracts some information to be communicated between two components.

2. "write()" TLM interface is a non-blocking task.

3. Difference between a TLM port and Analysis port: Analysis port supports 1 to many connections while TLM ports support only one to one connections.

Comments