Jump to content

UVM EVENT or SV issue ?? Strange thread issue....Try if you want to see magic


Recommended Posts

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.

Link to comment
Share on other sites

Both cases do exectly what you are instructing in your code.

The fatal in case 1 comes from waiting for the 2nd event which never happens. See the log-file here:

 UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]  questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test uvm_top_test...
# UVM_INFO case1-uvm_event.sv(91) @ 0: uvm_test_top [uvm_top_test] Starting run phase for uvm_test_top
# ----------------------------------------------
# Name              Type             Size  Value
# ----------------------------------------------
# <unnamed>         uvm_root         -     @13  
#   uvm_test_top    uvm_top_test     -     @466
#     simple_comp   uvm_simple_comp  -     @473
#       u_top_comp  uvm_top_comp     -     @480
# ----------------------------------------------
# UVM_INFO case1-uvm_event.sv(44) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] calling wait_for_match 1
# UVM_INFO case1-uvm_event.sv(20) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] Before trigger HI
# UVM_INFO case1-uvm_event.sv(40) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] calling message receiver task
# UVM_INFO case1-uvm_event.sv(28) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] Before trigger 1
# UVM_INFO case1-uvm_event.sv(30) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] After trigger 0
# UVM_INFO case1-uvm_event.sv(22) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] After trigger HI
run -a
# UVM_INFO case1-uvm_event.sv(64) @ 100: uvm_test_top.simple_comp [uvm_simple_comp] calling wait_for_match 2
# UVM_INFO case1-uvm_event.sv(20) @ 100: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] Before trigger Hello
# UVM_FATAL verilog_src/uvm-1.1d/src/base/uvm_phase.svh(1251) @ 9200000000000: reporter [PH_TIMEOUT] Default timeout of 9200000000000 hit, indicating a probable testbench issue
#

This is caused by the topdown execution of the components in your hierarchy.

case 2 looks differently:

# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]  questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test uvm_top_test...
# UVM_INFO case2-uvm_event.sv(135) @ 0: uvm_test_top [uvm_top_test] Starting run phase for uvm_test_top
# ----------------------------------------------
# Name              Type             Size  Value
# ----------------------------------------------
# <unnamed>         uvm_root         -     @13  
#   uvm_test_top    uvm_top_test     -     @466
#     simple_comp   uvm_simple_comp  -     @473
#       u_top_comp  uvm_top_comp     -     @480
# ----------------------------------------------
# UVM_INFO case2-uvm_event.sv(67) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] calling wait_for_match 1
# UVM_INFO case2-uvm_event.sv(27) @ 0: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] Before trigger HI
run -a
# UVM_INFO case2-uvm_event.sv(98) @ 100: uvm_test_top.simple_comp [uvm_simple_comp] calling wait_for_match 2
# UVM_INFO case2-uvm_event.sv(27) @ 100: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] Before trigger Hello
# UVM_INFO case2-uvm_event.sv(39) @ 100: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] Before trigger 2
# UVM_INFO case2-uvm_event.sv(43) @ 100: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] After trigger 0
# UVM_INFO case2-uvm_event.sv(31) @ 100: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] After trigger Hello
# UVM_INFO case2-uvm_event.sv(157) @ 100: uvm_test_top [uvm_top_test] Ending run phase for uvm_test_top
# UVM_INFO case2-uvm_event.sv(31) @ 100: uvm_test_top.simple_comp.u_top_comp [uvm_top_comp] After trigger HI
# UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_objection.svh(1267) @ 100: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase

 

case1-uvm_event.sv case2-uvm_event.sv

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...