Jump to content


Recommended Posts


Included is the UVM Book example I modified to support UVM1.0.

 Example 5-16: Heartbeat

 To run:   %  irun $UVM_HOME/src/dpi/uvm_dpi.cc -incdir $UVM_HOME/src ex5-16_heartbeat.sv
`include "uvm_pkg.sv"

module test;

//UVM Library
import uvm_pkg::*;
`include "uvm_macros.svh"

// Declare an objection for the heartbeat mechanism
//uvm_objection hb_obj = new("hb_obj");  //1.0ea
uvm_callbacks_objection hb_obj = new("hb_obj");

class child_component extends uvm_component;
 int num_hb = 0;

 function new(string name, uvm_component parent);
   super.new(name, parent);
 endfunction : new

   `uvm_field_int(num_hb, UVM_DEFAULT)

 virtual task run_phase(uvm_phase phase);
   `uvm_info("HBS", $psprintf("####: NUM HB: %0d", num_hb), UVM_LOW);
   for (int i=0; i<num_hb; i++) begin
     // Raise an objection num_hb times - at #90 intervals
 endtask : run_phase
endclass : child_component

class parent_component extends uvm_agent;
 child_component child_0, child_1, child_2;

 function new(string name, uvm_component parent);
   super.new(name, parent);
 endfunction : new


 function void build_phase(uvm_phase phase);
   child_0 = child_component::type_id::create("child_0", this);
   child_1 = child_component::type_id::create("child_1", this);
   child_2 = child_component::type_id::create("child_2", this);
 endfunction : build_phase
endclass : parent_component

class simple_test extends uvm_test;
 parent_component parent_0;
 // Declare the heartbeat event and component
 uvm_event hb_e;
 uvm_heartbeat my_heartbeat;

 function new(string name, uvm_component parent);
   super.new(name, parent);
 endfunction : new


 function void build_phase(uvm_phase phase);
   set_config_int("parent_0.child_0", "num_hb", 3);
   set_config_int("parent_0.child_1", "num_hb", 5);
   set_config_int("parent_0.child_2", "num_hb", 2);
   parent_0 = parent_component::type_id::create("parent_0", this);
   my_heartbeat = new("my_heartbeat", this, hb_obj);
   hb_e = new("hb_e");
 endfunction : build_phase

 function void connect_phase(uvm_phase phase);
   uvm_component hb_l[$];
   // Set the heartbeat mode (default is UVM_ALL_ACTIVE)
   //    UVM_ALL_ACTIVE: All registered components must emit a heartbeat during the window
   //    UVM_ANY_ACTIVE: One or more components must emit a heartbeat during the window
   //    UVM_ONE_ACTIVE: Exactly one component must emit the heartbeat during the window
   void'( my_heartbeat.set_mode(UVM_ANY_ACTIVE));
   //void'( my_heartbeat.set_mode(UVM_ALL_ACTIVE));
   // Set the heartbeat event and component list
   my_heartbeat.set_heartbeat(hb_e, hb_l);
   // Add each component to the heartbeat component list
 endfunction : connect_phase

 function void start_of_simulation_phase(uvm_phase phase);
 endfunction  : start_of_simulation_phase

 virtual task run_phase(uvm_phase phase);
   repeat (10)  #100 hb_e.trigger;
 endtask : run_phase

endclass : simple_test


endmodule : test

I hope this helps!


Link to comment
Share on other sites

Hi Kathleen,

Thanks for providing example, it is really useful. I have a heartbeat example that was not working, hopefully I should be able to find out the root cause now.

When I ran the example (provided by you) using Questa 10.0a there is a message

# UVM_FATAL @ 1000: uvm_test_top [HBFAIL] Did not recieve an update of hb_obj on any component since last event trigger at time 500. The list of registered components is:

# uvm_test_top.parent_0.child_0

# uvm_test_top.parent_0.child_1

# uvm_test_top.parent_0.child_2

at end which comes up to signal no activity, is there a way to have message to show that components are Active (instead of print for no activity).



Link to comment
Share on other sites

  • 6 months later...

Myself, I'd prefer it if the uvm_heartbeat ran the check_phase of all the components that did not raise the objection. That way you can use its end-of-run check to determine why it's deadlocked.

It kinda stinks, though, that the uvm_heartbeat class has no virtual tasks or functions and doesn't register itself with the factory. This means you either have to edit the source to modify its functionality or write your own. It seems that this class violates some of the principals that the rest of UVM espouses. Is there a good reason for that?

Link to comment
Share on other sites


the phase tasks should be ONLY activated by the phaser (and not by any other object). there has been some discussion in the tsc to have the phase executing the extract,check,report phases upon errors which today simply end the simulation.

BTW: you can do that today without hacking the uvm core code:

1. make a report catcher and catch HBFAIL

2. upon a fail print object.display_objections()

3. force a jump in the phaser for all domains to extract()


Link to comment
Share on other sites


>It still doesn't make sense to me that the uvm_heartbeat is not something that can be derived from and replaced with the factory.

one of the topic for upcoming uvm releases is to make the uvm library itself more factory aware so that you can override objects used within the library


Link to comment
Share on other sites

  • 1 year later...

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.

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.

  • Create New...