For the following Code ::
class write_txn ;
rand int unsigned b ;
endclass
class apb_gen extends uvm_component ;
`uvm_component_utils(apb_gen)
uvm_blocking_put_port #( write_txn ) put_port ;
function new ( string name , uvm_component parent ) ;
super.new(name,parent) ; // Else Error !!
put_port = new("put_port",this);
endfunction
task run_phase ( uvm_phase phase ) ;
write_txn t ;
`uvm_info(get_name()," run_phase Started",UVM_NONE)
t = new();
for ( int i = 0 ; i < 4 ; i ++ )
begin
void'(t.randomize() ) ;
`uvm_info(get_name()," Waiting for put ",UVM_NONE)
put_port.put(t) ;
`uvm_info(get_name()," put done ",UVM_NONE)
end
endtask
class apb_drv extends uvm_component ;
`uvm_component_utils(apb_drv)
uvm_blocking_get_port #( write_txn ) get_port ;
function new ( string name , uvm_component parent ) ;
super.new(name,parent) ; // Else Error !!
get_port = new("get_port",this);
endfunction
task run_phase ( uvm_phase phase ) ;
write_txn t ;
`uvm_info(get_name()," run_phase Started",UVM_NONE)
phase.raise_objection(this);
#2 ;
for ( int i = 0 ; i < 4 ; i ++ )
begin
`uvm_info(get_name()," Waiting for get() ",UVM_NONE)
get_port.get(t) ;
$display("TIME:%0t Got %0p",$time,t);
end
phase.drop_objection(this);
endtask
// In class apb_agent
apb_gen apb_genh ;
apb_drv apb_drvh ;
uvm_tlm_fifo #(write_txn) fifoh;
function new ( string name , uvm_component parent ) ;
super.new(name,parent) ; // Else Error !!
fifoh = new("fifoh",this); // NOTE :: Size is Default 1 !!
apb_genh = new("apb_genh",this);
apb_drvh = new("apb_drvh",this);
endfunction
function void connect_phase ( uvm_phase phase ) ;
apb_genh.put_port.connect(fifoh.put_export);
apb_drvh.get_port.connect(fifoh.get_export);
endfunction
inital
run_test("apb_agent") ;
I see the Output as follows ::
UVM_INFO @ 0: reporter [RNTST] Running test apb_agent...
UVM_INFO @ 0: uvm_test_top.apb_drvh [apb_drvh] run_phase Started
UVM_INFO @ 0: uvm_test_top.apb_genh [apb_genh] run_phase Started // [Q1]
UVM_INFO @ 0: uvm_test_top.apb_genh [apb_genh] Waiting for put
UVM_INFO @ 0: uvm_test_top.apb_genh [apb_genh] put done
UVM_INFO @ 0: uvm_test_top.apb_genh [apb_genh] Waiting for put
UVM_INFO @ 2: uvm_test_top.apb_drvh [apb_drvh] Waiting for get()
TIME:2 Got '{b:'h6875b355}
UVM_INFO @ 2: uvm_test_top.apb_drvh [apb_drvh] Waiting for get()
TIME:2 Got '{b:'h6875b355} // [Q2]
UVM_INFO @ 2: uvm_test_top.apb_drvh [apb_drvh] Waiting for get()
UVM_INFO @ 2: uvm_test_top.apb_genh [apb_genh] put done
UVM_INFO @ 2: uvm_test_top.apb_genh [apb_genh] Waiting for put
UVM_INFO @ 2: uvm_test_top.apb_genh [apb_genh] put done
UVM_INFO @ 2: uvm_test_top.apb_genh [apb_genh] Waiting for put
UVM_INFO @ 2: uvm_test_top.apb_genh [apb_genh] put done
TIME:2 Got '{b:'h64617ef6} // [Q3]
UVM_INFO @ 2: uvm_test_top.apb_drvh [apb_drvh] Waiting for get()
TIME:2 Got '{b:'h64617ef6}
I expect all get() Output to be different but I don’t observe the same .
My Questions are as follows ::
[Q1] I understand that " run_phase of apb_drvh " is displayed before apb_genh but why does " Waiting for put " && " put done " get displayed after " [apb_genh] run_phase Started "
( i.e run_phase Starts for apb_genh ) since nothing blocks in apb_drvh till that point ??
[Q2] Why do both 2nd get() give Same output as 1st get ?? .
Sequence of execution should be as follows ::
First put() is done then 2nd put() blocks . get() Unblocks for i == 0 ( Should give what we put() ) then blocks again ( for i == 1 ) .
put() unblocks ( for i == 1 ) followed by put() again blocking ( for i == 2 ) .
get() Unblocks for i == 1 ( Should give what we put() 2nd time ) and then again blocks ( for i == 2 ) .
[Q3] Why is 3rd get() different than 2nd ??