Nothing Special   »   [go: up one dir, main page]

TLM With Examples

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 13

@shraddha_pawankar Date:2/08/23

TRANSACTION LEVEL MODELLING

TLM – TRANSACTION LEVEL MODELLING


 Message Passing system
 Standard communication protocol
 TLM provides unidirectional,bidirectional or broadcasting
manner communication.
o We can use task and function to establish a connection.
 TLM is a higher level of abstraction,details like internal connections
are hidden.
 TLM supports multiple language.
Advantages
 Reusability
 Available with plug and play connection.
 Minimize time and effort to define TB Components.

TLM consist of port,interface,FIFO.

TLM INTERFACE

PORTS IMP/EXPORTS

Set of
methods Get() Implementation for the methods
Put()
Peek()

Port denoted by Square

Implementation port/Export denoted by circle.


@shraddha_pawankar Date:2/08/23

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

Que) Why we cant use mailbox instead of TLM ports.

MAILBOX TLM PORTS


Mailbox is purely system verilog TLM ports is standard
construct communication protocol
If we want to connect one
Not possible in mailbox component in SV with
another component in system
C
We can establish connection
using TLM
Mailbox is unidirectional TLM is bidirectional
It Is an lowest level of It is an highest level of
abstraction abstraction
It Is a lack of transaction TLM is transaction
level modelling based modelling.
Thy represent communication in
terms of transaction
Mailbox is interprocess TLM ports suited for
communication in software hardware verification
development

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

The `uvm_tlm_fifo class provides by UVM to implement TLM FIFO


It allows components to send and receive transaction in a synchronized
manner.
Methods like get(),put(),peek() etc.are implemented inside TLM_FIFO.
Get() operation:
 Return a transaction from TLM_FIFO. And also removes the
item from FIFO.
 If no items are available in the FIFO it will block and wait until
FIFO memory has atleast one entry.(Blocking call)
Put() operation:
 Return a transaction from the TLM_FIFO and without
removing the item from FIFO.
 Blocking call

APB generator driver APB Driver initiator

TLM FIFO

 In this case we used two initiator


 There is no synchronization(They working with different speed)
 To avoid data loss between two initiator, we used TLM FIFO.
 TLM FIFO establish communication between two initiator
 Temporary data stored in FIFO.
 We cannot establish direct communication between two ports,we
used TLM FIFO.
@shraddha_pawankar Date:2/08/23

EXAMPLE :

//*********TLM BLOCKING PORT***********//

`include "uvm_macros.svh"
import uvm_pkg::*;

// producer (sending side)

class producer extends uvm_component;


`uvm_component_utils(producer)

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)

class consumer extends uvm_component;


`uvm_component_utils(consumer)
@shraddha_pawankar Date:2/08/23

//declare uvm_blocking_put_imp #(type of data, class name where we


have implementation of put method),user defined name
uvm_blocking_put_imp#(int,consumer) recv;

function new(string name="",uvm_component parent);


super.new(name,parent);
//instantiation of new
method
recv=new("recv",this);
endfunction

task put(input int t); // implementation of put method happen in


receiver side
`uvm_info("Consumer",$sformatf("Data received :
%0d",t),UVM_NONE)
endtask
endclass

// connection between port and implementation port happen in higher


class(env,test using connect phase)
class env extends uvm_env;
`uvm_component_utils(env)

producer p;
consumer c;

function new(string name="",uvm_component parent);


super.new(name,parent);
endfunction
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

function void connect_phase(uvm_phase phase);


p.send.connect(c.recv);
endfunction
@shraddha_pawankar Date:2/08/23

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

function void build_phase(uvm_phase phase);


super.build_phase(phase);
e=env::type_id::create("ENV",this);
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

OUTPUT: # KERNEL: UVM_INFO /home/runner/testbench.sv(19) @ 0:


TEST.ENV.PROD [Producer] sending data to consumer=12
# KERNEL: UVM_INFO /home/runner/testbench.sv(37) @ 0: TEST.ENV.CONS
[Consumer] Data received : 12

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::*;

class transaction extends uvm_sequence_item;


`uvm_object_utils(transaction)
rand bit [3:0] a;
rand bit [3:0] b;

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;

function new(string name,uvm_component parent);


super.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);


super.build_phase(phase);
tx=transaction::type_id::create("tx");
send=new("send",this);
endfunction

task run_phase(uvm_phase phase);


phase.raise_objection(this);
for(i=0;i<10;i++) begin
@shraddha_pawankar Date:2/08/23

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

task put(input transaction


tx); tx.print();
endtask
endclass
//env class
class env extends uvm_env;
`uvm_component_utils(env)
producer p;
consumer c;

function new(string name="",uvm_component parent);


super.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);


p=producer::type_id::create("p",this);
c=consumer::type_id::create("c",this);
endfunction
@shraddha_pawankar Date:2/08/23

function void connect_phase(uvm_phase phase);


super.connect_phase(phase);
p.send.connect(c.recv);
endfunction
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

function void build_phase(uvm_phase phase);


super.build_phase(phase);
e=env::type_id::create("e",this);
endfunction
endclass

//top module
module tb;
test t;

initial
begin
t=new("TEST",null);
run_test();
end
endmodule

output: UVM_INFO /home/build/vlib1/vlib/uvm-


1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 'run' phase
is ready to proceed to the 'extract' phase

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;

function new(input string inst="CONS",uvm_component c);


super.new(inst,c);
@shraddha_pawankar Date:2/08/23

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

You might also like