TLM FIFO with NonBlocking ports
Table of Contents
In this example, Nonblocking ports are used to put and get the transactions to and from the TLM FIFO.
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_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; //Step-1. Declaraing the put port uvm_nonblocking_put_port# ( transaction ) trans_out; `uvm_component_utils( component_a ) //--------------------------------------- // Constructor //--------------------------------------- function new ( string name , uvm_component parent ); super . new ( name , parent ); trans_out = new ( "trans_out" , this ); //Step-2. Creating the port endfunction : new //--------------------------------------- // run_phase //--------------------------------------- virtual task run_phase ( uvm_phase phase ); phase.raise_objection ( this ); #100; 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 ) //Step-3. Calling put method to push transaction to TLM FIFO `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 ) phase.drop_objection ( this ); endtask : run_phase endclass : component_a |
As the port is nonblocking, try_put method is used to put trans to FIFO.
Implementing port in comp_b
class component_b extends uvm_component; transaction trans; //Step-1. Declaraing the get port uvm_nonblocking_get_port# ( transaction ) trans_in; `uvm_component_utils( component_b ) //--------------------------------------- // Constructor //--------------------------------------- function new ( string name , uvm_component parent ); super . new ( name , parent ); trans_in = new ( "trans_in" , this ); //Step-2. Create the port endfunction : new //--------------------------------------- // run_phase //--------------------------------------- virtual task run_phase ( uvm_phase phase ); phase.raise_objection ( this ); //#200; To execute try_get after try_put if ( trans_in.can_get ( ) ) begin //{ //Step-3. Checking is FIFO can send the packet `uvm_info(get_type_name(),$sformatf( " Before calling port get method" ) , UVM_LOW ) void ' ( trans_in.try_get ( trans ) ); //Step-4. Get the transaction from TLM FIFO `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 ) end //} else begin //{ `uvm_info(get_type_name(),$sformatf( " No entry, not able to get the trans" ) , UVM_LOW ) end //} phase.drop_objection ( this ); endtask : run_phase endclass : component_b |
As the port is nonblocking, the can_get and try_get method is used to get trans to FIFO.
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; //--------------------------------------- // Components Instantiation //--------------------------------------- component_a comp_a; component_b comp_b; //Step-1. Declaring the TLM FIFO uvm_tlm_fifo # ( transaction ) fifo_ab; `uvm_component_utils( environment ) //--------------------------------------- // Constructor //--------------------------------------- function new ( string name , uvm_component parent ); super . new ( name , parent ); endfunction : new //--------------------------------------- // build_phase - Create the components //--------------------------------------- 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 ); //Step-2. Creating the FIFO fifo_ab = new ( "fifo_ab" , this ); endfunction : build_phase //--------------------------------------- // Connect_phase //--------------------------------------- function void connect_phase ( uvm_phase phase ); //Step-3. Connecting FIFO put_export with producer port comp_a.trans_out.connect ( fifo_ab.put_export ); //Step-4. Connecting FIFO get_export with consumer port comp_b.trans_in.connect ( fifo_ab.get_export ); endfunction : connect_phase endclass : environment |
Simulator Output can_get() method executed before the try_put();
#100 delay added before the randomize() and try_put() method, which leads to execution of can_get() before try_put(). this leads to can_get() returing 0. So try_get() will not get excuted.
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_nonblocking_put_port - @1976 comp_b component_b - @2009 trans_in uvm_nonblocking_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(35) @ 0: uvm_test_top.env.comp_b [component_b] No entry, not able to get the trans UVM_INFO component_a.sv(31) @ 100: uvm_test_top.env.comp_a [component_a] tranaction randomized UVM_INFO component_a.sv(32) @ 100: uvm_test_top.env.comp_a [component_a] Printing trans, --------------------------------- Name Type Size Value --------------------------------- trans transaction - @2286 addr integral 4 'he wr_rd integral 1 'h0 wdata integral 8 'h4 --------------------------------- UVM_INFO component_a.sv(34) @ 100: uvm_test_top.env.comp_a [component_a] Before calling port put method UVM_INFO component_a.sv(36) @ 100: 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) @ 100: reporter [TEST_DONE] UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 100: reporter [UVM/REPORT/SERVER]
Simulator Output can_get() method executed after the try_put();
Adding #200 delay before can_get() method, which leads to returning 1 on calling can_get().
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_nonblocking_put_port - @1976 comp_b component_b - @2009 trans_in uvm_nonblocking_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_a.sv(31) @ 100: uvm_test_top.env.comp_a [component_a] tranaction randomized UVM_INFO component_a.sv(32) @ 100: 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(34) @ 100: uvm_test_top.env.comp_a [component_a] Before calling port put method UVM_INFO component_a.sv(36) @ 100: uvm_test_top.env.comp_a [component_a] After calling port put method UVM_INFO component_b.sv(29) @ 200: uvm_test_top.env.comp_b [component_b] Before calling port get method UVM_INFO component_b.sv(31) @ 200: uvm_test_top.env.comp_b [component_b] After calling port get method UVM_INFO component_b.sv(32) @ 200: 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 /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 200: reporter [TEST_DONE] UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 200: reporter [UVM/REPORT/SERVER]