TLM With Examples
TLM With Examples
TLM With Examples
TLM INTERFACE
PORTS IMP/EXPORTS
Set of
methods Get() Implementation for the methods
Put()
Peek()
PORT:
Set of methods put(),get(),peek()
A port must provides implementation
A port can be connected with port,export or imp ports.
If a component is initiator and sending the sata then it should
have put_port.
If a component is initiator and receiving the data then it
should have get_port.
TLM port is used to send transaction
Ports always parameterize by single parameter which is
of transaction type.
IMPLEMENTATION PORT:
get(),put() methods are implemented by the implementation port.
Ex: get_imp,put_imp
Put()/get() method should be implemented by
imp_ports otherwise it will get error.
Based on connect port/export it can send or receive transaction.
Imp_port always parametrized by two parameter which is of
transaction type and class name where we have
implementation of put method.
EXPORTS:
It will not implement any method
It forwards transaction from one component to another.
Connection type:
Port to port: connection from lower level component to higher level
component
Export to export: connection from higher level to lower level
Port to export: when connection component at the same level
hierarchy.
@shraddha_pawankar Date:2/08/23
Valid connection:
PORT TO PORT --- Valid connection
PORT TO IMP --- Valid connection
PORT TO EXPORT --- Valid connection
EXPORT TO EXPORT --- Valid connection
EXPORT TO IMP --- Valid connection
EXPORT TO PORT --- Invalid connection
TLM FIFO
1) uvm_tlm_fifo
2) uvm_tlm_analysis_fifo
uvm_tlm_fifo
1) TLM FIFO is a type of TLM PORT.
2) It provides communication between components using FIFO-
based approach.
3) It allows one to one communication.
@shraddha_pawankar Date:2/08/23
TLM FIFO
EXAMPLE :
`include "uvm_macros.svh"
import uvm_pkg::*;
int a=12;
//declare uvm blocking put port#(type of data) user defined name
uvm_blocking_put_port#(int) send;
function new(string name="",uvm_component parent);
super.new(name,parent);
//Instantiation of port with new method is mandatory
send=new("send",this);
endfunction
task run();
`uvm_info("Producer",$sformatf("sending data to consumer=
%0d",a),UVM_NONE)
//packets are send by calling put method
send.put(a);
endtask
endclass
//…………………………………………………………………………………………………………………//
//consumer(receiving side)
producer p;
consumer c;
endclass
//test class
class test extends uvm_test;
`uvm_component_utils(test);
env e;
function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction
task run_phase(uvm_phase
phase); #100
global_stop_request();
endtask
endclass
// top module
module tb;
test t;
initial
begin
t=new("TEST",null);
run_test();
end
endmodule
https://www.edaplayground.com/x/M3KH
@shraddha_pawankar Date:2/08/23
Example 2)
// WORKING TRANSACTION DATA IN tlm blocking port//
`include "uvm_macros.svh"
import uvm_pkg::*;
function new(string
name=""); super.new(name);
endfunction
endclass
//producer class
class producer extends uvm_component;
`uvm_component_utils(producer)
transaction tx;
integer i;
uvm_blocking_put_port#(transaction) send;
tx.randomize();
tx.print();
send.put(tx); //same as generator in SV
end
phase.drop_objection(this);
endtask
endclass
//consumer class
class consumer extends uvm_component;
`uvm_component_utils(consumer)
uvm_blocking_put_imp#(transaction,consumer) recv;
function new(string name="",uvm_component parent);
super.new(name,parent);
recv=new("recv",this);
endfunction
//test class
class test extends uvm_test;
`uvm_component_utils(test)
env e;
//top module
module tb;
test t;
initial
begin
t=new("TEST",null);
run_test();
end
endmodule
https://www.edaplayground.com/x/MjG_
Example 3)
//Independent Multiple TLM Blocking//
@shraddha_pawankar Date:2/08/23
include "uvm_macros.svh"
import uvm_pkg::*;
/////////////////////////////////////////////////////////////////////////
class producer extends uvm_component;
`uvm_component_utils(producer)
reg [7:0] a = 8'h12;
reg [15:0] b = 16'hffff;
reg [3:0] c = 4'hf;
uvm_blocking_put_port #(reg[7:0]) send1;
uvm_blocking_put_port #(reg[15:0]) send2;
uvm_blocking_put_port #(reg[3:0]) send3;
function new(input string inst="PROD",uvm_component c);
super.new(inst,c);
send1=new("SEND1",this);
send2=new("SEND2",this);
send3=new("SEND3",this);
endfunction
task run();
`uvm_info("PROD",$sformatf("Data Send a : %0x, b : %0x and c :
%0x", a,b,c),UVM_NONE)
send1.put(a);
send2.put(b);
send3.put(b);
endtask
endclass
//////////////////////////////////////////////////////////
class consumer extends uvm_component;
`uvm_component_utils(consumer)
`uvm_blocking_put_imp_decl(_ //used in consumer class
`uvm_blocking_put_imp_decl(_
`uvm_blocking_put_imp_decl(_
uvm_blocking_put_imp_1 #(reg[7:0],consumer) recv1;
uvm_blocking_put_imp_2 #(reg[15:0],consumer) recv2;
uvm_blocking_put_imp_3 #(reg[3:0],consumer) recv3;
recv1=new("RECV1",this);
recv2=new("RECV2",this);
recv3=new("RECV3",this);
endfunction
virtual task put_1(input reg[7:0] x );
`uvm_info("CONS:RECV1",$sformatf("the data is received :
%0x",x),UVM_NONE)
endtask
virtual task put_2(input reg[15:0] y);
`uvm_info("CONS:RECV2",$sformatf("the data is received :
%0X",y),UVM_NONE)
endtask
virtual task put_3(input reg[3:0] z);
`uvm_info("CONS:RECV3",$sformatf("the data is received :
%0X",z),UVM_NONE)
endtask
endclass
class test extends uvm_test;
`uvm_component_utils(test)
producer p;
consumer c;
function new(input string inst="TEST",uvm_component c);
super.new(inst,c);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
p=producer::type_id::create("PROD",this);
c=consumer::type_id::create("CONS",this);
endfunction
virtual function void connect_phase(uvm_phase
phase); super.connect_phase(phase);
p.send1.connect(c.recv1);
p.send2.connect(c.recv2);
p.send3.connect(c.recv3);
endfunction
virtual task run_phase(uvm_phase
phase); #100;
@shraddha_pawankar Date:2/08/23
global_stop_request();
endtask
endclass
module top_correct;
test t;
initial begin
t=new("TEST",null);
run_test();
end
endmodule