Automatic raise and drop objection with UVM-1.2

Variable uvm_sequence_base::starting_phase is deprecated and replaced by two new methods set_starting_phase and get_starting_phase, which prevent starting_phase from being modified in the middle of a phase.

 This change is not backward-compatible with UVM 1.1, though variable starting_phase, although deprecated, has not yet been removed from the base class library.

New method uvm_sequence_base::set_automatic_phase_objection causes raise_objection and drop_objection to be called automatically around a sequence, avoiding the need to call raise/drop_objection manually in one common situation.

Let’s understand it through below mentioned example.

import uvm_pkg :: *;

class my_seq_item extends uvm_sequence_item;
rand logic [7:0] addr;
rand logic [7:0] data;

constraint addr_range_cn {
addr inside {[10:20]};
}
constraint data_range_cn {
data inside {[100:200]};
}

uvm_object_utils_begin(my_seq_item) uvm_field_int(addr, UVM_ALL_ON| UVM_DEC)
uvm_field_int(data, UVM_ALL_ON| UVM_DEC) uvm_object_utils_end

function new(string name=”my_seq_item”);
super.new(name);
endfunction : new

virtual function string convert2string();
convert2string = $sformatf(“addr=%0d, data=%0d”, addr, data);
endfunction : convert2string
endclass : my_seq_item

class my_sequencer extends uvm_sequencer #(my_seq_item);
`uvm_component_utils (my_sequencer)

function new (string name=”my_sequencer”, uvm_component parent=null);
super.new(name, parent);
endfunction : new
endclass : my_sequencer

class my_driver extends uvm_driver #(my_seq_item);
`uvm_component_utils (my_driver)

function new (string name=”my_driver”, uvm_component parent=null);
super.new(name, parent);
endfunction : new

function void build_phase (uvm_phase phase);
super.build_phase(phase);
endfunction : build_phase

task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);

uvm_info(get_name(), $sformatf(“in driver after get_next_item my_seq_item= %s”, req.convert2string()), UVM_LOW); #50;

uvm_info(get_name(), $sformatf(“item_done called”), UVM_LOW);
seq_item_port.item_done();
end
endtask : run_phase
endclass : my_driver

class my_agent extends uvm_agent;
`uvm_component_utils (my_agent)
my_sequencer sqr;
my_driver drv;

function new (string name=”my_agent”, uvm_component parent=null);
super.new(name, parent);
endfunction : new

function void build_phase (uvm_phase phase);
super.build_phase(phase);
sqr = my_sequencer :: type_id :: create(“sqr”, this);
drv = my_driver :: type_id :: create(“drv”, this);
endfunction : build_phase

function void connect_phase (uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(sqr.seq_item_export);
endfunction : connect_phase
endclass : my_agent

class my_seq extends uvm_sequence #(my_seq_item);
`uvm_object_utils (my_seq)
function new(string name=”my_seq”);
super.new(name);

// The most common interaction with the starting phase
// within a sequence is to simply ~raise~ the phase’s objection
// prior to executing the sequence, and ~drop~ the objection
// after ending the sequence (either naturally, or
// via a call to ). In order to
// simplify this interaction for the user, the UVM
// provides the ability to perform this functionality
// automatically.

// From a timeline point of view, the automatic phase objection
// looks like:
//| start() is executed
//| –! Objection is raised !–
//| pre_start() is executed
//| pre_body() is optionally executed
//| body() is executed
//| post_body() is optionally executed
//| post_start() is executed
//| –! Objection is dropped !–
//| start() unblocks

// NEVER set the automatic phase objection bit to 1 if your sequence
// runs with a forever loop inside of the body, as the objection will
// never get dropped!
set_automatic_phase_objection(1);
endfunction : new

task body ();
uvm_create(req) if(!req.randomize()) begin uvm_fatal(get_name(), $sformatf(“Randomization failed”))
end
uvm_info (get_name(), $sformatf(“After randomizating in my_seq my_seq_item= %s”, req.convert2string()), UVM_LOW) uvm_send(req)
endtask : body
endclass : my_seq

class my_test extends uvm_test;
`uvm_component_utils (my_test)
my_agent agent;

function new (string name=”my_test”, uvm_component parent=null);
super.new(name, parent);
endfunction : new

function void build_phase (uvm_phase phase);
super.build_phase(phase);
agent = my_agent::type_id::create(“agent”, this);
endfunction : build_phase

task run_phase(uvm_phase phase);
my_seq seq;
uvm_phase starting_phase;
bit automatic_phase_objection_status;
seq = my_seq::type_id::create (“seq”);
// Function: set_starting_phase
// Sets the ‘starting phase’.
seq.set_starting_phase(phase);

// If set_automatic_phase_objection is not called in new (constructor)
// of sequence then can be calleb from test-case
// seq.set_automatic_phase_objection(1);

fork
begin
#30;
// Function: get_starting_phase
// Returns the ‘starting phase’.
// If non-null, the starting phase specifies the phase in which this
// sequence was started.
starting_phase = seq.get_starting_phase();
`uvm_info(get_name(),
$sformatf(“starting_phase:%s”, starting_phase.get_full_name()), UVM_LOW)

// Function: get_automatic_phase_objection
// Returns (and locks) the value of the ‘automatically object to
// starting phase’ bit.
//
// If 1, then the sequence will automatically raise an objection
// to the starting phase (if the starting phase is not ~null~) immediately
// prior to <pre_start> being called. The objection will be dropped
// after <post_start> has executed, or <kill> has been called.
automatic_phase_objection_status = seq.get_automatic_phase_objection();
`uvm_info(get_name(),
$sformatf(“during seq is running, get_automatic_phase_objection returns :%b”, automatic_phase_objection_status), UVM_LOW)
end
join_none
seq.start(agent.sqr);
automatic_phase_objection_status = seq.get_automatic_phase_objection();
`uvm_info(get_name(),
$sformatf(“After seq finished, get_automatic_phase_objection returns :%b”, automatic_phase_objection_status), UVM_LOW)
endtask : run_phase
endclass : my_test

module top();
initial begin
run_test(“my_test”);
end
endmodule : top

//Output:
// UVM_INFO @ 0: reporter [RNTST] Running test my_test…
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top.agent.sqr.seq raised 1 objection(s) (automatic phase objection): count=1 total=1
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top.agent.sqr added 1 objection(s) to its total (raised from source object , automatic phase objection): count=0 total=1
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top.agent added 1 objection(s) to its total (raised from source object , automatic phase objection): count=0 total=1
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top added 1 objection(s) to its total (raised from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=1
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_top added 1 objection(s) to its total (raised from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=1
// UVM_INFO testbench.sv(118) @ 0: uvm_test_top.agent.sqr@@seq [seq] After randomizating in my_seq my_seq_item= addr=19, data=140
// UVM_INFO testbench.sv(50) @ 0: uvm_test_top.agent.drv [drv] in driver after get_next_item my_seq_item= addr=19, data=140
// UVM_INFO testbench.sv(158) @ 30: uvm_test_top [uvm_test_top] starting_phase:common.run
// UVM_INFO testbench.sv(170) @ 30: uvm_test_top [uvm_test_top] during seq is running, get_automatic_phase_objection returns :1
// UVM_INFO testbench.sv(52) @ 50: uvm_test_top.agent.drv [drv] item_done called
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr.seq dropped 1 objection(s) (automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr.seq all_dropped 1 objection(s) (automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr subtracted 1 objection(s) from its total (dropped from source object , automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr subtracted 1 objection(s) from its total (all_dropped from source object , automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent subtracted 1 objection(s) from its total (dropped from source object , automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent subtracted 1 objection(s) from its total (all_dropped from source object , automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top subtracted 1 objection(s) from its total (all_dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (all_dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0
// UVM_INFO uvm-1.2/src/base/uvm_objection.svh(1271) @ 50: reporter [TEST_DONE] ‘run’ phase is ready to proceed to the ‘extract’ phase
// UVM_INFO testbench.sv(176) @ 50: uvm_test_top [uvm_test_top] After seq finished, get_automatic_phase_objection returns :1
// UVM_INFO uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER]

Leave a Comment

Your email address will not be published. Required fields are marked *

error: Content is protected !!
Scroll to Top