uvm_heartbeat应用案例
一、将uvm_heratbeat逻辑添加到测试台中
- 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
二、代码实现
2.1、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.
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
2.2、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
2.3、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
heart_beat.set_mode(UVM_ALL_ACTIVE);
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
-
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);
-
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
2.4、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]
- 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.