Jump to content
DavidLarson

Bug: uvm_heartbeat does not respect the comps list

Recommended Posts

Hello,

 

I am using the uvm_heartbeat object in my test bench and found that it always watches for all objection activity under the context component. By definition, it should only watch for the list of components registered to it. I found this when registering only one component to watch (my interrupt handler) and even after the component had no activity long after several heartbeat windows, a fatal HBFAIL message was not issued.

 

Digging into the source code, I can see that the heartbeat keeps track of which components are registered by populating an associative array, like this:

 

  function void set_heartbeat (uvm_event e, ref uvm_component comps[$]);
    uvm_object c;
    foreach(comps[i]) begin
      c = comps[i];
      if(!m_cb.cnt.exists(c)) // <-- This is the code to track...
        m_cb.cnt[c]=0; // <-- which components are registered
      if(!m_cb.last_trigger.exists(c)) 
        m_cb.last_trigger[c]=0;
    end
    if(e==null && m_event==null) return;
    start(e);
  endfunction

 

 

Skipping forward to the uvm_heartbeat_callback class, a counter is incremented every time a component raises or lowers an objection. When a component isn't found in the "cnt" associative array, it should have ignored it, but instead it sets a new index and sets the value to 0:

 

  virtual function void raised (uvm_objection objection,
                                uvm_object obj,
                                uvm_object source_obj,
                                string description,
                                int count);
    if(obj == target) begin
      if(!cnt.exists(source_obj))
        cnt[source_obj] = 0; // <-- this is the bug
      cnt[source_obj] = cnt[source_obj]+1; // <-- BTW: isn't cnt[source_obj]++ faster?
      last_trigger[source_obj] = $realtime;
    end
  endfunction

 

Instead, the code should have been written like this:

 

  virtual function void raised (uvm_objection objection,
                                uvm_object obj,
                                uvm_object source_obj,
                                string description,
                                int count);
    if(obj == target) begin
      if(!cnt.exists(source_obj))
        return; // <-- bug fix
      cnt[source_obj]++; // <-- (seems like it should be faster)
      last_trigger[source_obj] = $realtime;
    end
  endfunction

I have tried this change in my workspace and it works well.

 

Thank you,

David

Share this post


Link to post
Share on other sites

Hi David,

I have such codes in heartbeat class:

  virtual task run_phase(uvm_phase phase); 
    uvm_callbacks_objection cb;
    uvm_heartbeat hb;
    uvm_event e;
    uvm_component comps[$];
    if (heartbeat_window == 0) begin
      return; 
    end
    e = new("e");
    assert($cast(cb, phase.get_objection()))
    else  
      `uvm_fatal("heartbeat", run_phase objection isn't the type of uvm_callbacks_objection. You need to define UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE!)
    hb = new(get_full_name(), m_context, cb);
    uvm_top.find_all("*", comps, m_context);

    hb.set_mode(UVM_ANY_ACTIVE);
    hb.set_heartbeat(e, comps); 
    fork    
      forever begin
        #heartbeat_window e.trigger();
      end     
    join_none
  endtask: run_phase

 

The VCS always reports assertion fail even though I defined UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE in define.svh or in command line.

The way of defining UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE:

in define.svh

 

`define UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE // For heartbeat

 

in command line:

./simv +UVM_TESTNAME=test +UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE -l run.log

If I defined UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE, phase.get_objection() should return the uvm_callbacks_objection type and the assert should be successful, but it doesn't. Why?

 

Thanks in advance!

 

Share this post


Link to post
Share on other sites

Hi mrforever,

 

It looks like you are passing in the UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE macro as a run-time argument. It needs to be passed in during the compilation phase with a +define.

 

Good luck and enjoy the heartbeat!

 

David

Share this post


Link to post
Share on other sites

Hi mrforever,

 

It looks like you are passing in the UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE macro as a run-time argument. It needs to be passed in during the compilation phase with a +define.

 

Good luck and enjoy the heartbeat!

 

David

 

Hi David,

  I am sorry that I ignored the compile-time. I have tried it, but it didn't work, still reporting the assertion error. Here is the corresponding script in Makefile

 

VCS =   vcs -sverilog -debug_all -picarchive -timescale=1ns/1ps \
        +acc +vpi \
        +define+UVM_OBJECT_MUST_HAVE_CONSTRUCTOR+UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE \

 

I have double checked the spelling of macro UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE, it's right. Is there anything i am missing? Why it didn't work when i defined the macro UVM_USE_CALLBACKS_OBJECTION_FOR_TEST_DONE in the file define.svh?

 

By the way, there is another issue about uvm_reg, could have a look at this:

http://forums.accellera.org/topic/1255-issue-about-read-write-only-register-via-backdoor/

 

Thanks in advance.

 

Regards

mrforever

Share this post


Link to post
Share on other sites

If you are using a pre-compiled version of the UVM library then the macro will not change it. If you are not using a pre-compiled UVM library, then I would contact the Synopsys FAE and ask them what needs to change in your compile flow. I'm sure that the fix is something simple.

Share this post


Link to post
Share on other sites

If you are using a pre-compiled version of the UVM library then the macro will not change it. If you are not using a pre-compiled UVM library, then I would contact the Synopsys FAE and ask them what needs to change in your compile flow. I'm sure that the fix is something simple.

 

Hi David, 

I think the UVM library which i am using isn't pre-compiled UVM library. The version of the UVM library is uvm-1.1d, which is downloaded from this site:

http://www.accellera.org/downloads/standards/uvm

 

Could you tell me the comunication way with Synopsys FAE? Thanks in advance!

Share this post


Link to post
Share on other sites

Hi mrforever,

 

I just checked the UVM 1.1d library and the macro still exists. (phew!) You should email your question to support@synopsys.com (I think that's the right address) and a FAE will get back to you.

 

Good luck!

 

David

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×