Sunteți pe pagina 1din 15

TLM_FIFO:

TLM put () & TLM get () methods are blocking in nature. In fact, during put () and get ()
method execution, there is a single process running which passes the control from the port to
the export & back again. So, in TLM terminology its called that TLM put () & TLM get ()
methods are blocking in nature.

Now there may be situations where Producers and Consumers both are expected to work
independently.In UVM, TLM provides a channel called uvm_tlm_fifo to facilitate this
feature. Using uvm_tlm_fifo, Producer can work in one process to create the transactions
while Consumer needs to operate on those transactions in another process.

uvm_tlm_fifo implements all the TLM interface methods, so Producer puts the transaction
into the TLM FIFO and Consumer independently extracts the transactions from the TLM
FIFO.

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

/// Transaction declaration

/// Data members

typedef enum {READ, WRITE} access_type;

class my_txn extends uvm_sequence_item;

`uvm_object_utils(my_txn)

rand access_type access;


rand bit [7:0] addr;
rand byte data;

// Constructor

function new (string name = "");


super.new (name);
endfunction: new

endclass: my_txn

/// Producer declaration


class producer extends uvm_component;
`uvm_component_utils(producer)

/// put port declaration

uvm_blocking_put_port # (my_txn) my_put_port;

/// Constructor

function new (string name, uvm_component parent);


super.new(name, parent);
my_put_port = new("my_put_port", this);
endfunction: new

/// Run task

task run phase (uvm_phase phase);


for(int i=1; i<11; i++)
begin
my_txn txn;
txn = my_txn::type_id::create("txn", this);
if (! txn.randomize ())
`uvm_error ("error, randomization")
my_put_port.put (txn);
`uvm_info("PID", $sformatf("Transaction no. %0d sent as %s", i,
txn.access.name()), UVM_LOW);
end
endtask: run_phase

endclass: producer

/// Consumer declaration

class consumer extends uvm_component;


`uvm_component_utils (consumer)

/// get port declaration

uvm_blocking_get_port # (my_txn) my_get_port;

/// Constructor

function new (string name, uvm_component parent);


super.new (name, parent);
my_get_port = new ("my_get_port", this);
endfunction

/// Run task

task run_phase (uvm_phase phase);


for(int ii=1; ii<11; ii++)
begin
my_txn t;
t = my_txn::type_id::create("t", this);
my_get_port.get(t);
`uvm_info("CID", $sformatf("Transaction no. %0d is received as %s",
ii, t.access.name()), UVM_LOW);
end
endtask: run_phase

endclass: consumer

/// Environment declaration

class env extends uvm_env;

/// Instance declaration

uvm_tlm_fifo #(my_txn) my_tlm_fifo;


producer p1;
consumer c1;

/// Constructor

function new (string name = "env");


super.new(name);
my_tlm_fifo = new("my_tlm_fifo", this);
endfunction: new

/// Build function

function void build_phase (uvm_phase phase);


super.build_phase(phase);
p1 = producer::type_id::create("p1", this);
c1 = consumer::type_id::create("c1", this);
endfunction: build_phase

// Connect function

function void connect_phase (uvm_phase phase);


p1.my_put_port.connect(my_tlm_fifo.put_export);
c1.my_get_port.connect(my_tlm_fifo.get_export);
endfunction: connect_phase

/// Run phase

task run_phase (uvm_phase phase);


phase.raise_objection(this);
#1000;
phase.drop_objection(this);
endtask: run_phase

endclass: env

module test;
env e;

initial
begin
e = new();
run_test();
end

endmodule: test
PUT:

Put () is one of the TLM method which can be used to communicate between a Producer& a
Consumer.

Port is the interface which calls put () method and export is the interface which provides the
implementation of put () method. That way, TLM communication is independent of the
Producer and Consumer abstraction level.

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

/////////// Transaction /////////////////////////

typedef enum {READ,WRITE} access_type;

class txn extends uvm_sequence_item;


`uvm_object_utils(txn)

rand bit [3:0] addr;


rand byte data;
rand access_type access;

function new (string name = "txn");


super.new(name);
endfunction: new

endclass: txn

///////////// Producer //////////////////////////

class producer extends uvm_component;


`uvm_component_utils(producer)

uvm_blocking_put_port #(txn) my_port;

function new (string name, uvm_component parent);


super.new(name, parent);
my_port = new ("my_port", this);
endfunction

task run_phase(uvm_phase phase);


for (int packet = 1; packet<11; packet++)
begin
txn t;
t = txn::type_id::create("t", this);
if(!t.randomize())
`uvm_error("error","In randomization")
`uvm_info("PID", $sformatf("Packet no. %d is sent %d %d %s",
packet,t.data,t.addr,t.access.name()), UVM_LOW)
my_port.put(t);
end
endtask: run_phase

endclass: producer

/////////// Consumer //////////////////////////

class consumer extends uvm_component;


`uvm_component_utils(consumer)

uvm_blocking_put_imp # (txn, consumer) my_export;

function new (string name, uvm_component parent);


super.new(name, parent);
my_export = new("my_export", this);
endfunction: new

task put (input txn t);


case(t.access)
READ: begin $display("Read transaction");
`uvm_info("CID", $sformatf("Packet is received %d %d %s",
t.data,t.addr,t.access.name()), UVM_LOW)
end

WRITE: begin $display("Write transaction");


`uvm_info("CID", $sformatf("Packet is received %d %d %s",
t.data,t.addr,t.access.name()), UVM_LOW)
end
endcase

endtask: put

endclass: consumer

///////////// Environment ///////////////

class env extends uvm_env;

function new (string name = "env");


super.new(name);
endfunction: new

producer p1;
consumer c1;

function void build_phase(uvm_phase phase);


super.build_phase(phase);
p1 = producer::type_id::create("p1", this);
c1 = consumer::type_id::create("c1", this);
endfunction: build_phase

function void connect_phase(uvm_phase phase);


p1.my_port.connect(c1.my_export);
endfunction: connect_phase

task run_phase(uvm_phase phase);


phase.raise_objection (this);
#1000;
phase.drop_objection(this);
endtask: run_phase

endclass: env

module top;
env e;

initial
begin
e = new();
run_test();
end

endmodule: top

GET:

Get () method performs the same the put() does only difference is that get() pulls the transaction from
the Producer yet put() push the transaction to the Consumer.

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

///////////// Transaction /////////////////

typedef enum {READ,WRITE} access_type;


class my_txn extends uvm_sequence_item;
`uvm_object_utils(my_txn)

/// Data members

rand bit [7:0] addr;


rand byte data;
rand access_type access;

function new (string name = "my_txn");


super.new(name);
endfunction: new

endclass: my_txn

///////////// Producer ///////////////////

class producer extends uvm_component;


`uvm_component_utils(producer)

///// Export Declaration

uvm_blocking_get_imp #(my_txn, producer) my_export;

//// Constructor

function new (string name, uvm_component parent);


super.new(name, parent);
my_export = new("my_export", this);
endfunction: new

//// get () task implementation

task get(output my_txn t);


my_txn tmp;
tmp = my_txn::type_id::create("tmp", this);
t = tmp;
if(!t.randomize())
`uvm_error("Error","In randomization")
`uvm_info ("PID", $sformatf("Transaction type %s %d %d is sent",
t.access.name(),t.addr,t.data), UVM_LOW)
endtask: get

endclass: producer

//////////// Consumer ///////////////////

class consumer extends uvm_component;


`uvm_component_utils(consumer)

//// Port Declaration

uvm_blocking_get_port #(my_txn) my_port;

function new (string name, uvm_component parent);


super.new(name, parent);
my_port = new("my_port", this);
endfunction: new

task run_phase(uvm_phase phase);


for (int i=1; i<11; i++)
begin
my_txn txn;
`uvm_info("CID", $sformatf("Transaction no. %0d is asked for", i),
UVM_LOW)
my_port.get(txn);
`uvm_info("CID", $sformatf("Transaction type %s %d %d is received",
txn.access.name(),txn.addr,txn.data), UVM_LOW)
end
endtask: run_phase

endclass: consumer

/////////// Env /////////////////////////

class env extends uvm_env;

producer p1;
consumer c1;

function new (string name = "env");


super.new(name);
endfunction: new

//// Build Function

function void build_phase (uvm_phase phase);


super.build_phase(phase);
p1 = producer::type_id::create("p1", this);
c1 = consumer::type_id::create("c1", this);
endfunction: build_phase

//// Connect Function

function void connect_phase (uvm_phase phase);


c1.my_port.connect(p1.my_export);
endfunction: connect_phase

//// Run Task

task run_phase (uvm_phase phase);


phase.raise_objection(this);
#1000;
phase.drop_objection(this);
endtask: run_phase

endclass: env

module test;

env e; // Environment Instantiation

initial
begin
e = new();
run_test();
end

endmodule: test
UVM_ANALYSIS_PORT:

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

/// Data members

typedef enum {READ, WRITE} access_type;

class my_txn extends uvm_sequence_item;

`uvm_object_utils(my_txn)

rand access_type access;


rand bit [7:0] addr;
rand byte data;

// Constructor

function new (string name = "");


super.new(name);
endfunction: new

endclass: my_txn

class producer extends uvm_component;


`uvm_component_utils(producer)

uvm_analysis_port #(my_txn) analysis_port;

function new (string name, uvm_component parent);


super.new(name, parent);
analysis_port = new("analysis_port", this);
endfunction: new

/// Run task

task run_phase (uvm_phase phase);


for(int i=1; i<11; i++)
begin
my_txn txn;
txn = my_txn::type_id::create("txn", this);
if(!txn.randomize())
`uvm_error("error","randomization")
`uvm_info("PID", $sformatf("Transaction no. %0d sent as %s", i,
txn.access.name()), UVM_LOW)
analysis_port.write(txn);
end
endtask: run_phase

endclass: producer

class subscriber extends uvm_component;


`uvm_component_utils(subscriber)

uvm_analysis_imp #(my_txn,subscriber) analysis_export;


function new (string name, uvm_component parent);
super.new(name, parent);
analysis_export = new("analysis_export", this);
endfunction

virtual function void write(my_txn t1);


`uvm_info("subscriber",$sformatf("Transaction no received as %s",
t1.access.name()), UVM_LOW)
endfunction

endclass

/// Environment declaration

class env extends uvm_env;

/// Instance declaration

producer p1;
subscriber s0,s1;

/// Constructor

function new (string name = "env");


super.new(name);
endfunction: new

/// Build function

function void build_phase (uvm_phase phase);


super.build_phase(phase);
p1 = producer::type_id::create("p1", this);
s0 = subscriber::type_id::create("s0", this);
s1 = subscriber::type_id::create("s1", this);
endfunction: build_phase

// Connect function

function void connect_phase (uvm_phase phase);


p1.analysis_port.connect(s0.analysis_export);
p1.analysis_port.connect(s1.analysis_export);
endfunction: connect_phase

/// Run phase

task run_phase (uvm_phase phase);


phase.raise_objection(this);
#1000;
phase.drop_objection(this);
endtask: run_phase

endclass: env

module top;
env e;

initial
begin
e = new();
run_test();
end

endmodule

PORT_EXPORT:

This example illustrates basic TLM connectivity using the blocking put inteface.

port-to-port leaf1s out port is connected to its parents (comp1) out port
port-to-export comp1s out port is connected to comp2s in export
export-to-export comp2s in export is connected to its childs (subcomp2) in export
export-to-imp subcomp2s in export is connected leaf2s in imp port.
imp-to-implementationleaf2s in imp port is connected to its implementation, leaf2

import uvm_pkg:: *;

`include "uvm_macros.svh"

class trans extends uvm_transaction;

rand int unsigned addr;


rand int unsigned data;
rand bit write;

endclass

class leaf1 extends uvm_component; //leaf1


`uvm_component_utils(leaf1)

uvm_blocking_put_port#(Trans) out_l1;

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


super.new(name, parent);
out_l1 = new("out_l1",this);
`uvm_info(get_full_name (),"new fun in leaf1",UVM_LOW)
endfunction

virtual task run();


trans t;
t = new;
repeat(5)
begin
if(!t.randomize()with {write == 1'b1;})
`uvm_error("randomization failed","leaf1")
`uvm_info(get_full_name(),$psprintf("addr = %d, data =%d,
write = %b",t.addr,t.data,t.write),UVM_LOW)
out_l1.put(t);
end
endtask

endclass //leaf1

class comp1 extends uvm_component; //comp1


`uvm_component_utils(comp1)

uvm_blocking_put_port #(trans) out_c1;


leaf1 le1;

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


super.new(name,parent);
endfunction

virtual function void build();


out_c1 = new("out_c1",this);
le1 = new("le1",this);
`uvm_info(get_full_name(),"build in comp1",UVM_LOW)
endfunction

virtual function void connect();


le1.out_l1.connect(out_c1);
`uvm_info(get_full_name(),"connect in comp1",UVM_LOW)
endfunction

endclass //comp1

class leaf2 extends uvm_component(); //leaf2


`uvm_component_utils(leaf2)

uvm_blocking_put_imp #(trans,leaf2) in_l2;

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


super.new(name,parent);
in_l2 = new("in_l2",this);
`uvm_info(get_full_name(),"new fun in leaf2",UVM_LOW)
endfunction
task put(trans t);
`uvm_info(get_full_name(),$psprintf("addr = %d,data =%d,
write = %b",t.addr,t.data,t.write),UVM_LOW)//13
endtask

endclass //leaf2

class subcomp2 extends uvm_component; //subcomp2


`uvm_component_utils(subcomp2)

uvm_blocking_put_export #(trans) in_sub;

leaf2 le2;

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


super.new(name,parent);

`uvm_info(get_full_name(),"new fun in subcomp2",UVM_LOW)


endfunction

virtual function void build();


in_sub = new("in_sub",this);
le2 = new("le2",this);
`uvm_info(get_full_name(),"buildinsubcomp2",UVM_LOW)
endfunction

virtual function void connect();


in_sub.connect(le2.in_l2);
`uvm_info(get_full_name(),"connect in comp2",UVM_LOW)
endfunction

endclass //subcomp2

class comp2 extends uvm_component; //comp2

`uvm_component_utils(comp2)

uvm_blocking_put_export #(trans) in_c2;

subcomp2 subcomp;

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


super.new(name,parent);
`uvm_info(get_full_name(),"new fun in comp2",UVM_LOW)
endfunction

virtual function void build();


in_c2 = new("in_c2",this);
subcomp = new("subcomp",this);
`uvm_info(get_full_name(),"build in comp2",UVM_LOW)
endfunction

virtual function void connect();


in_c2.connect(subcomp.in_sub);
`uvm_info(get_full_name(),"connect in comp2",UVM_LOW)
endfunction

endclass //comp2

class env extends uvm_component; //environment


`uvm_component_utils(env)

comp1 comp1_i;
comp2 comp2_i;

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


super.new(name,parent);
`uvm_info(get_full_name(),"new fun in env",UVM_LOW)
endfunction

virtual function void build();


comp1_i = comp1::type_id::create("comp1_i",this);
comp2_i = comp2::type_id::create("comp2_i",this);
`uvm_info(get_full_name(),"build in env",UVM_LOW)
endfunction

virtual function void connect();


comp1_i.out_c1.connect(comp2_i.in_c2);
`uvm_info(get_full_name(),"connect in env",UVM_LOW)
endfunction

endclass //environment

module tb();

env e = new("env");

initial
run_test();

endmodule

S-ar putea să vă placă și