TLM FIFO
TLM FIFO Example
The TLM FIFO provides storage for the transactions between the two independently running processes.
FIFO can be used as a buffer between the producer and consumer
TLM FIFO consists of put and get methods
Producer port is connected to the put_export of the FIFO
Consumer port is connected to the get_export of the FIFO
TLM TesetBench Components are,
————————————————————–
Name Type
————————————————————–
uvm_test_top basic_test
env environment
comp_a component_a
trans_out uvm_blocking_put_port
comp_b component_b
trans_in uvm_blocking_get_port
fifo_ab uvm_tlm_fifo #(T)
get_ap uvm_analysis_port
get_peek_export uvm_get_peek_imp
put_ap uvm_analysis_port
put_export uvm_put_imp
————————————————————–
Implementing port in comp_a
class
component_a
extends
uvm_component;
transaction trans;
uvm_blocking_put_port#
(
transaction
)
trans_out;
`uvm_component_utils(
component_a
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_out
=
new
(
"trans_out"
,
this
);
endfunction
:
new
virtual
task
run_phase
(
uvm_phase phase
);
phase.raise_objection
(
this
);
trans
=
transaction
:
:
type_id
:
:
create
(
"trans"
,
this
);
void
'
(
trans.
randomize
(
)
);
`uvm_info(get_type_name(),$sformatf(
" tranaction randomized"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Printing trans, \n %s"
,
trans.sprint
(
)
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Before calling port put method"
)
,
UVM_LOW
)
trans_out.
put
(
trans
);
`uvm_info(get_type_name(),$sformatf(
" After calling port put method"
)
,
UVM_LOW
)
phase.drop_objection
(
this
);
endtask
:
run_phase
endclass
:
component_a
Implementing port in comp_b
class
component_b
extends
uvm_component;
transaction trans;
uvm_blocking_get_port#
(
transaction
)
trans_in;
`uvm_component_utils(
component_b
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_in
=
new
(
"trans_in"
,
this
);
endfunction
:
new
virtual
task
run_phase
(
uvm_phase phase
);
phase.raise_objection
(
this
);
`uvm_info(get_type_name(),$sformatf(
" Before calling port get method"
)
,
UVM_LOW
)
trans_in.
get
(
trans
);
`uvm_info(get_type_name(),$sformatf(
" After calling port get method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Printing trans, \n %s"
,
trans.sprint
(
)
)
,
UVM_LOW
)
phase.drop_objection
(
this
);
endtask
:
run_phase
endclass
:
component_b
Implementing TLM FIFO in env
Below are the steps to implement TLM FIFO,
Declare the TLM FIFO
Create the FIFO
Connect the TLM FIFO put_export with producer port
Connect the TLM FIFO get_export with consumer port
class
environment
extends
uvm_env;
component_a comp_a;
component_b comp_b;
uvm_tlm_fifo #
(
transaction
)
fifo_ab;
`uvm_component_utils(
environment
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
endfunction
:
new
function
void
build_phase
(
uvm_phase phase
);
super
.build_phase
(
phase
);
comp_a
=
component_a
:
:
type_id
:
:
create
(
"comp_a"
,
this
);
comp_b
=
component_b
:
:
type_id
:
:
create
(
"comp_b"
,
this
);
fifo_ab
=
new
(
"fifo_ab"
,
this
);
endfunction
:
build_phase
function
void
connect_phase
(
uvm_phase phase
);
comp_a.trans_out.connect
(
fifo_ab.put_export
);
comp_b.trans_in.connect
(
fifo_ab.get_export
);
endfunction
:
connect_phase
endclass
:
environment
Simulator Output
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
---------------------------------------------------------
Name Type Size Value
---------------------------------------------------------
uvm_test_top basic_test - @1840
env environment - @1909
comp_a component_a - @1941
trans_out uvm_blocking_put_port - @1976
comp_b component_b - @2009
trans_in uvm_blocking_get_port - @2044
fifo_ab uvm_tlm_fifo #(T) - @2010
get_ap uvm_analysis_port - @2214
get_peek_export uvm_get_peek_imp - @2144
put_ap uvm_analysis_port - @2179
put_export uvm_put_imp - @2109
---------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1883
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO component_a.sv(32) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_a.sv(34) @ 0: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO component_b.sv(28) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO component_b.sv(29) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1883
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Click to execute on
❮ Previous Next ❯
Nonblocking can_get method
NonBlocking Get Port Imp port
This example is a continuation of the previous example with the can_get method implemented.
Before calling the trans_in.try_get() method comp_b checks for the comp_a status by calling trans_in.can_get() method. On calling trans_in.can_get() comp_a can respond with 1 if it’s ready to send the transaction packet, otherwise 0.
In order to add can_get() method, there are two additional steps on top of steps followed in the previous example.
1. In comp_b before calling the try_get method, Call can_get() method and check for the comp_a status
if
(
trans_in.can_get
)
begin
`uvm_info(get_type_name(),$sformatf(
" component_a can send the transaction"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Requesting transaction."
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Before calling port get method"
)
,
UVM_LOW
)
if
(
trans_in.try_get
(
trans
)
)
begin
`uvm_info(get_type_name(),$sformatf(
" recived transaction
from get method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Printing trans, \n %s"
,
trans.sprint
(
)
)
,
UVM_LOW
)
end
else
begin
`uvm_info(get_type_name(),$sformatf(
" Not recived transaction
from get method"
)
,
UVM_LOW
)
end
`uvm_info(get_type_name(),$sformatf(
" After calling port get method"
)
,
UVM_LOW
)
end
else
begin
`uvm_info(get_type_name(),$sformatf(
" component_a is not ready to send
the transaction"
)
,
UVM_LOW
)
end
2. Implement the can_get() method in comp_a
virtual
function
bit
can_get
(
);
`uvm_info(get_type_name(),$sformatf(
" component_b requested for status"
)
,
UVM_LOW
)
return
0;
endfunction
Simulator Output With can_get() return value 1 .
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @335
env environment - @348
comp_a component_a - @357
trans_out uvm_nonblocking_get_imp - @366
comp_b component_b - @376
trans_in uvm_nonblocking_get_port - @385
------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Checking component_a status to get the transaction
UVM_INFO component_a.sv(40) @ 0: uvm_test_top.env.comp_a [component_a] component_b requested for status
UVM_INFO component_b.sv(29) @ 0: uvm_test_top.env.comp_b [component_b] component_a can send the transaction
UVM_INFO component_b.sv(30) @ 0: uvm_test_top.env.comp_b [component_b] Requesting transaction.
UVM_INFO component_b.sv(31) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] Recived transaction imp port get request
UVM_INFO component_a.sv(28) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @418
addr integral 4 'h3
wr_rd integral 1 'h1
wdata integral 8 'h6
---------------------------------
UVM_INFO component_a.sv(31) @ 0: uvm_test_top.env.comp_a [component_a] Sendting trans packet
UVM_INFO component_b.sv(34) @ 0: uvm_test_top.env.comp_b [component_b] recived transaction from get method
UVM_INFO component_b.sv(35) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @418
addr integral 4 'h3
wr_rd integral 1 'h1
wdata integral 8 'h6
---------------------------------
UVM_INFO component_b.sv(41) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE]
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Simulator Output With can_get() return value 0 .
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @335
env environment - @348
comp_a component_a - @357
trans_out uvm_nonblocking_get_imp - @366
comp_b component_b - @376
trans_in uvm_nonblocking_get_port - @385
------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Checking component_a status to get the transaction
UVM_INFO component_a.sv(40) @ 0: uvm_test_top.env.comp_a [component_a] component_b requested for status
UVM_INFO component_b.sv(45) @ 0: uvm_test_top.env.comp_b [component_b] component_a is not ready to send the transaction
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE]
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Click to execute on
Output Analysist
In the second output with the return value set to ‘0’, we can see that as the return value is ‘0’ from comp_a, uvm_infos before and after the try_get method of comp_b and uvm_infos inside try_get method of comp_a are not getting executed.
❮ Previous Next ❯
Nonblocking TLM port and Imp Port
NonBlocking Get Port Get Imp Port
This example shows how to declare, create and connect the TLM non-blocking get ports, implementing and using the TLM non-blocking get methods. In this example blocking ports of the previous example ( TLM Get ports and imp_ports ) are replaced with the non-blocking get ports. It is preferred to refer to TLM Get ports and imp_ports example before going through this example.
TLM TesetBench Components are,
———————————————————-
Name Type
———————————————————-
uvm_test_top basic_test
env environment
comp_a component_a
trans_out uvm_nonblocking_get_imp
comp_b component_b
trans_in uvm_nonblocking_get_port
———————————————————-
Declare and Create TLM Get Port in comp_b
class
component_b
extends
uvm_component;
transaction trans;
uvm_nonblocking_get_port#
(
transaction
)
trans_in;
`uvm_component_utils(
component_b
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_in
=
new
(
"trans_in"
,
this
);
endfunction
:
new
virtual
task
run_phase
(
uvm_phase phase
);
phase.raise_objection
(
this
);
`uvm_info(get_type_name(),$sformatf(
" Requesting transaction."
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Before calling port get method"
)
,
UVM_LOW
)
if
(
trans_in.try_get
(
trans
)
)
begin
`uvm_info(get_type_name(),$sformatf(
" recived transaction
from get method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Printing trans, \n %s"
,
trans.sprint
(
)
)
,
UVM_LOW
)
end
else
`uvm_info(get_type_name(),$sformatf(
" Not recived transaction
from get method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" After calling port get method"
)
,
UVM_LOW
)
phase.drop_objection
(
this
);
endtask
:
run_phase
endclass
:
component_b
try_get() method is used to receive the transaction form comp_b. try_get() methods returns ‘1’ on successful receive of transaction, otherwise ‘0’.
Declare and Create TLM Imp_port in comp_a
class
component_a
extends
uvm_component;
uvm_nonblocking_get_imp#
(
transaction
,
component_a
)
trans_out;
`uvm_component_utils(
component_a
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_out
=
new
(
"trans_out"
,
this
);
endfunction
:
new
virtual
function
bit
try_get
(
output
transaction trans
);
`uvm_info(get_type_name(),$sformatf(
" Recived transaction
imp port get request"
)
,
UVM_LOW
)
trans
=
transaction
:
:
type_id
:
:
create
(
"trans"
,
this
);
void
'
(
trans.
randomize
(
)
);
`uvm_info(get_type_name(),$sformatf(
" tranaction randomized"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Printing trans, \n %s"
,
trans.sprint
(
)
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Sendting trans packet"
)
,
UVM_LOW
)
return
1;
endfunction
virtual
function
bit
can_get
(
);
endfunction
endclass
:
component_a
Note:
As the port is nonblocking, methods should be implemented as function not task.
* Implementing and using of can_put is shown in the next example
Connecting TLM Port and Imp Port in env
function
void
connect_phase
(
uvm_phase phase
);
comp_b.trans_in.connect
(
comp_a.trans_out
);
endfunction
:
connect_phase
Simulator Output
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @335
env environment - @348
comp_a component_a - @357
trans_out uvm_nonblocking_get_imp - @366
comp_b component_b - @376
trans_in uvm_nonblocking_get_port - @385
------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Requesting transaction.
UVM_INFO component_b.sv(28) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] Recived transaction imp port get request
UVM_INFO component_a.sv(28) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @412
addr integral 4 'h3
wr_rd integral 1 'h1
wdata integral 8 'h6
---------------------------------
UVM_INFO component_a.sv(31) @ 0: uvm_test_top.env.comp_a [component_a] Sendting trans packet
UVM_INFO component_b.sv(31) @ 0: uvm_test_top.env.comp_b [component_b] recived transaction from get method
UVM_INFO component_b.sv(32) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @412
addr integral 4 'h3
wr_rd integral 1 'h1
wdata integral 8 'h6
---------------------------------
UVM_INFO component_b.sv(37) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE]
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Click to execute on
The next example shows the implementation of the try_put() method.
❮ Previous Next ❯
Connecting TLM Get port imp port
TLM Get Port Get Imp port
This example shows connection TLM get port and get imp port.
In the components with TLM put ports,
The producer component initiates the transaction and sends it to consumer component
The producer component will be implemented with TLM put port and Consumer component with TLM imp_port
put method has to be implemented in the consumer
Whereas in with TLM get ports,
The consumer component will request for the transaction
The consumer component will be implemented with TLM get port and Producer with TLM imp_port
get method has to be implemented in the producer
Below are the steps to implement a TLM get port between comp_a and comp_b.
Declare and Create TLM Get Port in comp_b
Declare and Create TLM Imp Port in comp_a
Connect TLM Port and Imp Port in env
Call interface method in comp_b to get the transaction
Implement an interface method in comp_a to randomize and send the transaction
TLM Get port TesetBench Components are,
—————————————————————
Name Type
—————————————————————
uvm_test_top basic_test
env environment
comp_a component_a
trans_out uvm_blocking_get_imp
comp_b component_b
trans_in uvm_blocking_get_port
—————————————————————
Implementing TLM get port in comp_b (Consumer)
class
component_b
extends
uvm_component;
transaction trans;
uvm_blocking_get_port#
(
transaction
)
trans_in;
`uvm_component_utils(
component_b
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_in
=
new
(
"trans_in"
,
this
);
endfunction
:
new
virtual
task
run_phase
(
uvm_phase phase
);
phase.raise_objection
(
this
);
`uvm_info(get_type_name(),$sformatf(
" Requesting transaction."
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Before calling port get method"
)
,
UVM_LOW
)
trans_in.
get
(
trans
);
`uvm_info(get_type_name(),$sformatf(
" After calling port get method"
)
,
UVM_LOW
)
trans.
print
(
);
phase.drop_objection
(
this
);
endtask
:
run_phase
endclass
:
component_b
Implementing TLM get imp port in comp_a (Producer)
class
component_a
extends
uvm_component;
uvm_blocking_get_imp#
(
transaction
,
component_a
)
trans_out;
`uvm_component_utils(
component_a
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_out
=
new
(
"trans_out"
,
this
);
endfunction
:
new
virtual
task
get
(
output
transaction trans
);
`uvm_info(get_type_name(),$sformatf(
" Recived transaction imp port
get request"
)
,
UVM_LOW
)
trans
=
transaction
:
:
type_id
:
:
create
(
"trans"
,
this
);
void
'
(
trans.
randomize
(
)
);
`uvm_info(get_type_name(),$sformatf(
" tranaction randomized"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Printing trans, \n %s"
,
trans.sprint
(
)
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Sendting trans packet"
)
,
UVM_LOW
)
endtask
endclass
:
component_a
Connecting get port with get imp port in env
function
void
connect_phase
(
uvm_phase phase
);
comp_b.trans_in.connect
(
comp_a.trans_out
);
endfunction
:
connect_phase
Simulator Output
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
---------------------------------------------------
Name Type Size Value
---------------------------------------------------
uvm_test_top basic_test - @1839
env environment - @1908
comp_a component_a - @1940
trans_out uvm_blocking_get_imp - @1975
comp_b component_b - @2008
trans_in uvm_blocking_get_port - @2043
---------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Requesting transaction.
UVM_INFO component_b.sv(28) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] Recived transaction imp port get request
UVM_INFO component_a.sv(28) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'ha
wr_rd integral 1 'h0
wdata integral 8 'h57
---------------------------------
UVM_INFO component_a.sv(31) @ 0: uvm_test_top.env.comp_a [component_a] Sendting trans packet
UVM_INFO component_b.sv(30) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'ha
wr_rd integral 1 'h0
wdata integral 8 'h57
---------------------------------
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Click to execute on
❮ Previous Next ❯
Nonblocking can_put method
can_put method
This example is a continuation of the previous example with the can_put method implemented.
Before calling the trans_out.try_put() method comp_a checks for the comp_b status by calling trans_out.can_put() method. On calling trans_out.can_put() comp_b can respond with 1 if it’s ready to accept the transaction packet, otherwise 0.
In order to add can_put() method, there are two additional steps on top of steps followed in the previous example.
1. In comp_a before calling the try_put method, Call can_put() method and check for the comp_b status
if
(
trans_out.can_put
)
begin
`uvm_info(get_type_name(),$sformatf(
" Before calling port put method"
)
,
UVM_LOW
)
trans_out.try_put
(
trans
);
`uvm_info(get_type_name(),$sformatf(
" After calling port put method"
)
,
UVM_LOW
)
end
else
`uvm_info(get_type_name(),$sformatf(
" component_b is not ready to accept the packet"
)
,
UVM_LOW
)
2. Implement the can_put() method in comp_b
virtual
function
bit
can_put
(
);
`uvm_info(get_type_name(),$sformatf(
" Inside can_put method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Sending can_put status as 1"
)
,
UVM_LOW
)
return
1;
endfunction
Simulator Output With can_put() return value 1 .
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1839
env environment - @1908
comp_a component_a - @1940
trans_out uvm_nonblocking_put_port - @1975
comp_b component_b - @2008
trans_in uvm_nonblocking_put_imp - @2043
------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO component_b.sv(33) @ 0: uvm_test_top.env.comp_b [component_b] Inside can_put method
UVM_INFO component_b.sv(34) @ 0: uvm_test_top.env.comp_b [component_b] Sending can_put status as 1
UVM_INFO component_a.sv(33) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Inside try_put method
UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Recived trans On IMP Port
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO component_a.sv(35) @ 0: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Simulator Output With can_put() return value 0 .
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1839
env environment - @1908
comp_a component_a - @1940
trans_out uvm_nonblocking_put_port - @1975
comp_b component_b - @2008
trans_in uvm_nonblocking_put_imp - @2043
------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO component_b.sv(33) @ 0: uvm_test_top.env.comp_b [component_b] Inside can_put method
UVM_INFO component_b.sv(34) @ 0: uvm_test_top.env.comp_b [component_b] Sending can_put status as 1
UVM_INFO component_a.sv(38) @ 0: uvm_test_top.env.comp_a [component_a] component_b is not ready to accept the packet
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Click to execute on
Output Analysis
In the second output with the return value set to ‘0’, we can see that as the return value is ‘0’ from comp_b, uvm_infos before and after the try_put method of comp_a and uvm_infos inside try_put method of comp_b are not getting executed.
❮ Previous Next ❯
Nonblocking TLM port and Imp Port
NonBlocking Port Imp Port
This example shows how to declare, create and connect the TLM non-blocking ports, implementing and using the TLM non-blocking methods. In this example blocking ports of the previous example (Connecting TLM Port and Imp Port ) are replaced with the non-blocking ports. It is preferred to refer to Connecting TLM Port and Imp Port example before going through this example.
Below are the steps to implement a TLM Communication mechanism between comp_a and comp_b.
Declare and Create TLM Port in comp_a
Declare and Create TLM Imp Port in comp_b
Connect TLM Port and Imp Port in env
Call interface method in comp_a to send the transaction
Implement interface methods in comp_b to receive the transaction
TLM TesetBench Components are,
———————————————————-
Name Type
———————————————————-
uvm_test_top basic_test
env environment
comp_a component_a
trans_out uvm_nonblocking_put_port
comp_b component_b
trans_in uvm_nonblocking_put_imp
———————————————————-
Declare and Create TLM Port in comp_a
class
component_a
extends
uvm_component;
uvm_nonblocking_put_port #
(
transaction
)
trans_out;
`uvm_component_utils(
component_a
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_out
=
new
(
"trans_out"
,
this
);
endfunction
:
new
virtual
task
run_phase
(
uvm_phase phase
);
endtask
:
run_phase
endclass
:
component_a
Declare and Create TLM Port in comp_b
class
component_b
extends
uvm_component;
transaction trans;
uvm_nonblocking_put_imp #
(
transaction
,
component_b
)
trans_in;
`uvm_component_utils(
component_b
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_in
=
new
(
"trans_in"
,
this
);
endfunction
:
new
endclass
:
component_b
Connect TLM Port and Imp Port in env
function
void
connect_phase
(
uvm_phase phase
);
comp_a.trans_out.connect
(
comp_b.trans_in
);
endfunction
:
connect_phase
Call interface method in comp_a to send the transaction
As the port declared is a nonblocking port, the try_put method has to be used for sending the transaction packet.
void
'
(
trans.
randomize
(
)
);
trans_out.try_put
(
trans
);
Implement an interface method in comp_b to receive the transaction
1. In order to receive the transaction on nonblocking imp port try_put and can_put methods has to be implemented.
Note:
As the port is nonblocking, methods should be implemented as function not task.
In the blocking example, the put method is implemented as a task.
virtual
function
try_put
(
transaction trans
);
`uvm_info(get_type_name(),$sformatf(
" Inside try_put method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Recived trans On IMP Port"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint(
)
)
,
UVM_LOW
)
endfunction
virtual
function
bit
can_put
(
);
endfunction
* Implementing and using of can_put is shown in the next example
2. Complete comp_b code
class
component_b
extends
uvm_component;
transaction trans;
uvm_nonblocking_put_imp#
(
transaction
,
component_b
)
trans_in;
`uvm_component_utils(
component_b
)
function
new
(
string
name
,
uvm_component parent
);
super
.
new
(
name
,
parent
);
trans_in
=
new
(
"trans_in"
,
this
);
endfunction
:
new
virtual
function
bit
try_put
(
transaction trans
);
`uvm_info(get_type_name(),$sformatf(
" Inside try_put method"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(
" Recived trans On IMP Port"
)
,
UVM_LOW
)
`uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint(
)
)
,
UVM_LOW
)
endfunction
virtual
function
bit
can_put
(
);
endfunction
endclass
:
component_b
Simulator Output
UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1839
env environment - @1908
comp_a component_a - @1940
trans_out uvm_nonblocking_put_port - @1975
comp_b component_b - @2008
trans_in uvm_nonblocking_put_imp - @2043
------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO component_a.sv(32) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Inside try_put method
UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Recived trans On IMP Port
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans,
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
addr integral 4 'he
wr_rd integral 1 'h0
wdata integral 8 'h4
---------------------------------
UVM_INFO component_a.sv(34) @ 0: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
Click to execute on
The next example shows the implementation of the can_put() method.
❮ Previous Next ❯
TLM Analysis FIFO
TLM Analysis FIFO
An analysis_fifo is a uvm_tlm_fifo#(T) with an unbounded size and a write Method
It can be used any place a uvm_analysis_imp is used
Typical usage is as a buffer between a uvm_analysis_port in an initiator component and TLM1 target component
TLM Analysis FIFO Classes
uvm_tlm_analysis_fifo#(T) An analysis_fifo is a uvm_tlm_fifo#(T) with an unbounded size and a write method
Ports
analysis_export #(T)
The analysis_export provides the write method to all connected analysis ports and parent exports
function void write (T t)
Methods
new
This is a constructor method used for the creation of TLM Analysis FIFO
function new (string name,
uvm_component parent = null);
❮ Previous Next ❯
UVM TLM FIFO
The TLM FIFO provides storage for the transactions between two independently running processes. We have seen put and get methods operates with only one outstanding transaction at a time i.e it is allowed to send the transaction Only after consumption of the previously sent transaction, in this case, the sender and receiver must be in sync else lead to blocking in one of the components.
What if the case where the sender needs not wait for the receiver acknowledgment, it just wants to store it in memory and the receiver can consume whenever required. in this sender and The receiver needs not to be in sync. Yes With TLM FIFO it is possible.
TLM FIFO
In TLM FIFO, the sender pushes the transactions to FIFO and whenever it required reiver pops it out or fetches from the FIFO
Transactions are put into the FIFO via the put_export method
Transactions are fetched from the FIFO via the get_peek_export method
As its FIFO (First In First Out), transactions are fetched from the FIFO in the order they are put
TLM FIFO Classes
This class provides storage of transactions between two independently running processes
TLM FIFO Methods
new
This is a constructor method used for the creation of TLM FIFO
function
new
(
string
name
,
uvm_component parent
,
int
size
=
1
);
The name and parent are the normal uvm_component constructor arguments
The size indicates the maximum size of the FIFO; a value of zero indicates no upper bound
size
Calling size() returns the size of the FIFO
A return value of 0 indicates the FIFO capacity has no limit
used
Returns the number of entries put into the FIFO
is_empty
Returns 1 when there are no entries in the FIFO, 0 otherwise
is_full
Returns 1 when the number of entries in the FIFO is equal to its size, 0 otherwise
flush
Calling flush method will Remove all entries from the FIFO
after the flush method call used method returns 0 and the is_empty method returns 1
Summary of TLM FIFOs
TLM FIFO
Next Section: TLM Analysis FIFO
For TLM Examples refer to TLM Examples
❮ Previous Next ❯