uvm heartbeat example

uvm_heartbeat example

Adding uvm_heratbeat logic to the testbench

  • The testbench in the below example consists of a component comp_a
  • In the run phase of comp_a, a loop is running with a delay of 50
  • This example shows the implementation of the uvm heartbeat, to monitor the idle condition of comp_a
Testbench hierarchy is,

———————————————–
Name          Type
———————————————–
uvm_test_top      basic_test
env                  environment
comp_a       component_a
———————————————–

component_a code

Below is the complete code of component_a,
which has a loop in run_phase which raises the objection with a 50ns delay between the iterations.

*Objection is declared in the top file.

class component_a extends uvm_component;
  
  `uvm_component_utils(component_a)
  
  //--------------------------------------- 
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction : new
   
  //---------------------------------------
  // run_phase 
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    `uvm_info(get_type_name(),$sformatf(" [ Comp-A ] 
                              Objection raised "),UVM_LOW)
    
    for(int i=0;i<10;i++) begin //{
      `uvm_info(get_type_name(),$sformatf(" [ Comp-A ] 
                                Idx-%0d raising obje objection",i),UVM_LOW)
      obje.raise_objection(this);
      #50;
    end //}   
    
    phase.drop_objection(this);
  endtask : run_phase

endclass : component_a

env code without a heartbeat logic

Below is the environment code without heartbeat logic.

class environment extends uvm_env;
  
  //---------------------------------------
  // Components Instantiation
  //---------------------------------------
  component_a comp_a;
  
  `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);
  endfunction : build_phase
endclass : environment

env code with a heartbeat logic

Below are the steps to set up the uvm heartbeat,

Declare the heartbeat and event

The event is the event at which the heartbeat monitor looks for idleness of components

  uvm_heartbeat heart_beat;
  uvm_event     hb_event;

Create the heartbeat and event

    heart_beat = new("heart_beat", this, obje);
    hb_event   = new("hb_event");

Set the mode

This will tell the heartbeat about the active condition of the testbench

UVM_ALL_ACTIVE – all components
UVM_ONE_ACTIVE – exactly one component
UVM_ANY_ACTIVE – any component

  heart_beat.set_mode(UVM_ALL_ACTIVE);

Setup the heartbeat event

  heart_beat.set_heartbeat(hb_event,hb);

Add the components to be monitored

By using the add method, the component can be added for monitoring.

  heart_beat.add(comp_a);

Start the heartbeat

  heart_beat.start(hb_event);

Trigger the event to monitor

  virtual task run_phase(uvm_phase phase);
    heart_beat.start(hb_event);
    
    repeat(10) begin //{
      #100;
      `uvm_info(get_type_name(),$sformatf(" [ Env ] Triggering hb_event"),UVM_LOW)
      hb_event.trigger();
    end //}
  endtask : run_phase  

Complete env code,

class environment extends uvm_env;
  
  //---------------------------------------
  // Components Instantiation
  //---------------------------------------
  component_a comp_a;
  
  uvm_heartbeat heart_beat;
  uvm_event     hb_event;
  
  `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);
    
    heart_beat = new("heart_beat", this, obje);
    hb_event   = new("hb_event");
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase 
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    uvm_component hb[$];
    heart_beat.set_mode(UVM_ALL_ACTIVE);
    heart_beat.set_heartbeat(hb_event,hb);
    heart_beat.add(comp_a);
  endfunction : connect_phase
  
  //---------------------------------------
  // run_phase 
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    heart_beat.start(hb_event);
    
    repeat(10) begin //{
      #100;
      `uvm_info(get_type_name(),$sformatf(" [ Env ] Triggering hb_event"),UVM_LOW)
      hb_event.trigger();
    end //}
  endtask : run_phase  
endclass : environment

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top basic_test - @1858
 env environment - @1927
 comp_a component_a - @1959
--------------------------------------
UVM_INFO component_a.sv(21) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Objection raised 
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-0 raising obje objection
UVM_INFO component_a.sv(24) @ 50: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-1 raising obje objection
UVM_INFO environment.sv(55) @ 100: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_a.sv(24) @ 100: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-2 raising obje objection
UVM_INFO component_a.sv(24) @ 150: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-3 raising obje objection
UVM_INFO environment.sv(55) @ 200: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_a.sv(24) @ 200: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-4 raising obje objection
UVM_INFO component_a.sv(24) @ 250: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-5 raising obje objection
UVM_INFO environment.sv(55) @ 300: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_a.sv(24) @ 300: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-6 raising obje objection
UVM_INFO component_a.sv(24) @ 350: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-7 raising obje objection
UVM_INFO environment.sv(55) @ 400: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_a.sv(24) @ 400: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-8 raising obje objection
UVM_INFO component_a.sv(24) @ 450: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-9 raising obje objection
UVM_INFO environment.sv(55) @ 500: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 500: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 500: reporter [UVM/REPORT/SERVER]

Click to execute on   

Output Analysis

In the above simulation result, we could see that there is no FATAL message from the uvm_heartbeat, this is because the comp_a is always active between the heartbeat the event triggers.

comp_a loop delay value is 50 and the event trigger interval is 100.

So between the heartbeat event trigger, there will be one iteration of the loop.

Fatal From HeartBeat Monitor / Detecting Inactive condition of the testbench

This example is same as the previous example, the comp_a is shown as inactive to the uvm heartbeat so that the uvm heartbeat should detect the same.

As mentioned before, UVM_heartbeat watches for an activity in the comp_a and if it finds that there is no activity in the specified interval of time (between the event triggering), then uvm_heratbeat issue a fatal message which leads to the end of the simulation.

In order to make no activity within the heartbeat event triggering time, let’s make the delay of loop more than the heartbeat event triggering time.

comp_a delay modification

  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    `uvm_info(get_type_name(),$sformatf(" [ Comp-A ] 
                              Objection raised "),UVM_LOW)
    
    for(int i=0;i< 10;i++) begin //{
      `uvm_info(get_type_name(),$sformatf(" [ Comp-A ] 
                                Idx-%0d raising obje objection",i),UVM_LOW)
      obje.raise_objection(this);
      
      //Variable delay
      #(50*i);
    end //}   
    
    phase.drop_objection(this);
  endtask : run_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top basic_test - @1858
 env environment - @1927
 comp_a component_a - @1959
--------------------------------------
UVM_INFO component_a.sv(21) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Objection raised 
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-0 raising obje objection
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-1 raising obje objection
UVM_INFO component_a.sv(24) @ 50: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-2 raising obje objection
UVM_INFO environment.sv(55) @ 100: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_a.sv(24) @ 150: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-3 raising obje objection
UVM_INFO environment.sv(55) @ 200: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_a.sv(24) @ 300: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-4 raising obje objection
UVM_INFO environment.sv(55) @ 300: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO environment.sv(55) @ 400: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_FATAL @ 400: uvm_test_top.env [HBFAIL] Did not recieve an update of obje for component uvm_test_top.env.comp_a since 
last event trigger at time 300 : last update time was 300
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 400: reporter [UVM/REPORT/SERVER] 

Click to execute on   

Adding multiple components to uvm_heartbeat

In the previous example, only one component comp_a is monitored by the uvm_heartbeat. In this example along with the comp_a will add one more component comp_b to the heartbeat monitor.

Testbench hierarchy is,

———————————————–
Name          Type
———————————————–
uvm_test_top      basic_test
env                  environment
comp_a       component_a
comp_b       component_b
———————————————–

On comparing to the previous example, the only extra code w.r.t heartbeat is adding comp_b to monitor.

By using the add method, component comp_b can be added for monitoring.

  heart_beat.add(comp_b);

As there are two components, we will set the mode as any component is active,

  heart_beat.set_mode(UVM_ANY_ACTIVE);

Complete env code,

class environment extends uvm_env;
  
  //---------------------------------------
  // Components Instantiation
  //---------------------------------------
  component_a comp_a;
  component_b comp_b;
  
  uvm_heartbeat heart_beat;
  uvm_event     hb_event;
  
  `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);
    
    heart_beat = new("heart_beat", this, obje);
    hb_event   = new("hb_event");
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase 
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    uvm_component hb[$];
    heart_beat.set_mode(UVM_ANY_ACTIVE);
    heart_beat.set_heartbeat(hb_event,hb);
    heart_beat.add(comp_a);
    heart_beat.add(comp_b);
  endfunction : connect_phase
  
  //---------------------------------------
  // run_phase 
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    
    heart_beat.start(hb_event);
    
    repeat(20) begin //{
      #60;
      hb_event.trigger();
      `uvm_info(get_type_name(),$sformatf(" [ Env ] Triggering hb_event"),UVM_LOW)
    end //}

  endtask : run_phase  
endclass : environment

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top basic_test - @1861
 env environment - @1930
 comp_a component_a - @1962
 comp_b component_b - @1993
--------------------------------------
UVM_INFO component_b.sv(21) @ 0: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Objection raised 
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-0 raising obje objection
UVM_INFO component_a.sv(21) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Objection raised 
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-0 raising obje objection
UVM_INFO component_b.sv(24) @ 30: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-1 raising obje objection
UVM_INFO component_a.sv(24) @ 50: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-1 raising obje objection
UVM_INFO environment.sv(61) @ 60: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 60: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-2 raising obje objection
UVM_INFO component_b.sv(24) @ 90: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-3 raising obje objection
UVM_INFO component_a.sv(24) @ 100: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-2 raising obje objection
UVM_INFO environment.sv(61) @ 120: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 120: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-4 raising obje objection
UVM_INFO component_a.sv(24) @ 150: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-3 raising obje objection
UVM_INFO component_b.sv(24) @ 150: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-5 raising obje objection
UVM_INFO environment.sv(61) @ 180: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 180: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-6 raising obje objection
UVM_INFO component_a.sv(24) @ 200: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-4 raising obje objection
UVM_INFO component_b.sv(24) @ 210: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-7 raising obje objection
UVM_INFO environment.sv(61) @ 240: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 240: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-8 raising obje objection
UVM_INFO component_b.sv(24) @ 270: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-9 raising obje objection
UVM_INFO environment.sv(61) @ 300: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 300: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 300: reporter [UVM/REPORT/SERVER] 

Click to execute on   

Heartbeat with All Components active mode

This example is same as the previous example, the only change is monitoring mode.

The monitoring mode is changed to monitor all the components. i.e, comp_a and comp_b if one of the components is inactive then the heartbeat will give the FATAL message.

Setting the heartbeat mode as ALL_ACTIVE.

heart_beat.set_mode(UVM_ALL_ACTIVE);

Complete env code,

class environment extends uvm_env;
  
  //---------------------------------------
  // Components Instantiation
  //---------------------------------------
  component_a comp_a;
  component_b comp_b;
  
  uvm_heartbeat heart_beat;
  uvm_event     hb_event;
  
  `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);
    
    heart_beat = new("heart_beat", this, obje);
    hb_event   = new("hb_event");
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase 
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    uvm_component hb[$];
    heart_beat.set_mode(UVM_ALL_ACTIVE);
    heart_beat.set_heartbeat(hb_event,hb);
    heart_beat.add(comp_a);
    heart_beat.add(comp_b);
  endfunction : connect_phase
  
  //---------------------------------------
  // run_phase 
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    
    heart_beat.start(hb_event);
    
    repeat(20) begin //{
      #60;
      hb_event.trigger();
      `uvm_info(get_type_name(),$sformatf(" [ Env ] Triggering hb_event"),UVM_LOW)
    end //}

  endtask : run_phase  
endclass : environment

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top basic_test - @1861
 env environment - @1930
 comp_a component_a - @1962
 comp_b component_b - @1993
--------------------------------------
UVM_INFO component_b.sv(21) @ 0: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Objection raised 
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-0 raising obje objection
UVM_INFO component_a.sv(21) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Objection raised 
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-0 raising obje objection
UVM_INFO component_b.sv(24) @ 30: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-1 raising obje objection
UVM_INFO component_a.sv(24) @ 50: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-1 raising obje objection
UVM_INFO environment.sv(61) @ 60: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 60: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-2 raising obje objection
UVM_INFO component_b.sv(24) @ 90: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-3 raising obje objection
UVM_INFO component_a.sv(24) @ 100: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-2 raising obje objection
UVM_INFO environment.sv(61) @ 120: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 120: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-4 raising obje objection
UVM_INFO component_a.sv(24) @ 150: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-3 raising obje objection
UVM_INFO component_b.sv(24) @ 150: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-5 raising obje objection
UVM_INFO environment.sv(61) @ 180: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 180: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-6 raising obje objection
UVM_INFO component_a.sv(24) @ 200: uvm_test_top.env.comp_a [component_a] [ Comp-A ] Idx-4 raising obje objection
UVM_INFO component_b.sv(24) @ 210: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-7 raising obje objection
UVM_INFO environment.sv(61) @ 240: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_INFO component_b.sv(24) @ 240: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-8 raising obje objection
UVM_INFO component_b.sv(24) @ 270: uvm_test_top.env.comp_b [component_b] [ Comp-B ] Idx-9 raising obje objection
UVM_INFO environment.sv(61) @ 300: uvm_test_top.env [environment] [ Env ] Triggering hb_event
UVM_FATAL @ 300: uvm_test_top.env [HBFAIL] Did not recieve an update of obje for component uvm_test_top.env.comp_a 
since last event trigger at time 240 : last update time was 200
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 300: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯