Jump to content

AK_K

Members
  • Posts

    1
  • Joined

  • Last visited

AK_K's Achievements

Member

Member (1/2)

0

Reputation

  1. I am facing strange issue with UVM event and threading. I have two threads waiting on one UVM_EVENT. one thread is from the same class where event is getting generated while other thread is called upper parent class. only one thread sees the event while both should see the event. i can no_of_waiters also getting 0 after event triggered and before i can see count 2. I have narrowed down actual problem to following examle code and tried at EDA playground and i dont understand why case 1 does not work. Please explain me if you have any idea. Case 1: Not working code import uvm_pkg::*; `include "uvm_macros.svh" class uvm_top_comp extends uvm_component; `uvm_component_utils(uvm_top_comp) uvm_event msg_seen; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); endfunction task wait_for_match(string sa); `uvm_info("EVENT_ORDER",$sformatf("Wait before trigger %s",sa), UVM_LOW) msg_seen.wait_trigger(); `uvm_info("EVENT_ORDER", $sformatf("wait After trigger %s",sa), UVM_LOW) endtask task message_receiver(); `uvm_info("EVENT_ORDER", $sformatf("Before trigger %0d",msg_seen.get_num_waiters()), UVM_LOW) msg_seen.trigger(); `uvm_info("EVENT_ORDER", $sformatf("After trigger %0d",msg_seen.get_num_waiters()), UVM_LOW) endtask task run_phase(uvm_phase phase); super.run(); msg_seen = new("msg_seen"); fork begin message_receiver(); end join_none wait_for_match("HI"); endtask endclass class uvm_simple_comp extends uvm_component; `uvm_component_utils(uvm_simple_comp) uvm_top_comp u_top_comp; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); u_top_comp = uvm_top_comp::type_id::create("u_top_comp", this); endfunction task s_setup(); u_top_comp.wait_for_match("Hello"); endtask task run_phase(uvm_phase phase); //nothing done here endtask endclass class uvm_top_test extends uvm_test; `uvm_component_utils(uvm_top_test) uvm_simple_comp simple_comp; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); simple_comp = uvm_simple_comp::type_id::create("simple_comp",this); endfunction task run_phase(uvm_phase phase); `uvm_info("PHASE_ORDER", $sformatf("Starting run phase for %s",get_full_name()), UVM_LOW) phase.raise_objection(this); uvm_top.print(); #100; simple_comp.s_setup(); phase.drop_objection(this); `uvm_info("PHASE_ORDER", $sformatf("Ending run phase for %s",get_full_name()), UVM_LOW) endtask endclass module test_module(); initial begin run_test("uvm_top_test"); end endmodule ---------------------- Strange is when i move my event generating method to test, both thread sees the event. what can be wrong with this ? is my expectation not right in above case that both thread should see the event ? ------------------------------------------------------------ Case 2: Working code import uvm_pkg::*; `include "uvm_macros.svh" class uvm_top_comp extends uvm_component; `uvm_component_utils(uvm_top_comp) uvm_event msg_seen; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); endfunction task wait_for_match(string sa); `uvm_info("EVENT_ORDER",$sformatf("Wait before trigger %s",sa), UVM_LOW) msg_seen.wait_trigger(); `uvm_info("EVENT_ORDER", $sformatf("wait After trigger %s",sa), UVM_LOW) endtask task message_receiver(); `uvm_info("EVENT_ORDER", $sformatf("Before trigger %0d",msg_seen.get_num_waiters()), UVM_LOW) msg_seen.trigger(); `uvm_info("EVENT_ORDER", $sformatf("After trigger %0d",msg_seen.get_num_waiters()), UVM_LOW) endtask task run_phase(uvm_phase phase); super.run(); msg_seen = new("msg_seen"); fork begin //message_receiver(); end join_none wait_for_match("HI"); endtask endclass class uvm_simple_comp extends uvm_component; `uvm_component_utils(uvm_simple_comp) uvm_top_comp u_top_comp; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); u_top_comp = uvm_top_comp::type_id::create("u_top_comp", this); endfunction task s_setup(); u_top_comp.wait_for_match("Hello"); endtask task run_phase(uvm_phase phase); //nothing done here endtask endclass class uvm_top_test extends uvm_test; `uvm_component_utils(uvm_top_test) uvm_simple_comp simple_comp; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); simple_comp = uvm_simple_comp::type_id::create("simple_comp",this); endfunction task run_phase(uvm_phase phase); `uvm_info("PHASE_ORDER", $sformatf("Starting run phase for %s",get_full_name()), UVM_LOW) phase.raise_objection(this); uvm_top.print(); #100; fork begin simple_comp.u_top_comp.message_receiver(); end join_none simple_comp.s_setup(); phase.drop_objection(this); `uvm_info("PHASE_ORDER", $sformatf("Ending run phase for %s",get_full_name()), UVM_LOW) endtask endclass module test_module(); initial begin run_test("uvm_top_test"); end endmodule Please explain in detail if you see why case 1 should not work.
×
×
  • Create New...