Вы находитесь на странице: 1из 5

Extend run_phase using set_drain_time and all_dropped

callback after all objection drops


It is more often that two or more components in verification environment are not in sync with each
other. And there may be a case where driver/transmitter finish it's job first and call item_done. After
item_done is called from driver and if there is no action pending in sequence then start method of
sequence finishes and objection is also dropped.
But we want that simulation (more precisely we can say run_phase) should extend to some more time
after all objection are dropped, so that other components which are late with respect to driver can
finish it's job. We can achieve this by using set_drain_time in UVM.

`timescal
e 1ns/1ns
`include "uvm.sv"
import uvm_pkg::*;
`include "uvm_macros.svh"

// In this example, a drain time of 10 is set on the component.


// The component then forks 4 processes which consume different
// amounts of time. When the last process is done (time 85),
// the drain time takes effect. The test is completed at time 95.
class my_agent extends uvm_agent;
`uvm_component_utils(my_agent)
function new (string name="my_agent", uvm_component parent=null);
super.new(name, parent);
endfunction : new

virtual task run_phase(uvm_phase phase);


// Run a bunch of processes in parallel
fork
doit(phase, 85);
doit(phase, 55);
join
endtask : run_phase

// A simple task that consumes some time.


task doit (uvm_phase phase, time delay);
static int s_inst = 0;
int inst = s_inst++;

//Raise an objection before starting the activity


phase.raise_objection(this);
uvm_report_info(get_name(), $sformatf("Starting doit (%0d) with delay %0t",
inst, delay), UVM_NONE);
#delay;
uvm_report_info(get_name(), $sformatf("Ending doit (%0d)", inst), UVM_NONE);

//Drop the objection when done


phase.drop_objection(this);
endtask : doit
endclass : my_agent

class my_env extends uvm_test;


my_agent agent;
`uvm_component_utils(my_env)

function new (string name="my_env", 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

virtual task run_phase(uvm_phase phase);


// Run a bunch of processes in parallel
fork
doit(phase, 35);
doit(phase, 60);
join
endtask : run_phase

// A simple task that consumes some time.


task doit (uvm_phase phase, time delay);
static int s_inst = 0;
int inst = s_inst++;

//Raise an objection before starting the activity


phase.raise_objection(this);
uvm_report_info(get_name(), $sformatf("Starting doit (%0d) with delay %0t",
inst, delay), UVM_NONE);
#delay;
uvm_report_info(get_name(), $sformatf("Ending doit (%0d)", inst), UVM_NONE);

//Drop the objection when done


phase.drop_objection(this);
endtask : doit
endclass : my_env

class my_test extends uvm_test;


my_env env;
`uvm_component_utils(my_test)

function new (string name, uvm_component parent);


super.new(name, parent);
endfunction : new

function void build_phase (uvm_phase phase);


super.build_phase(phase);
env = my_env :: type_id::create("env", this);
endfunction : build_phase

virtual task run_phase(uvm_phase phase);


// Set a drain time on the objection if needed
`uvm_info("drain", "Setting drain time of 10", UVM_NONE)
// uvm-1.1d or earlier (depricated in uvm-1.2
//uvm_test_done.set_drain_time(this,10);
// uvm-1.2
phase.phase_done.set_drain_time(this,10);

// Run a bunch of processes in parallel


fork
doit(phase, 25);
doit(phase, 50);
join
endtask : run_phase
// A simple task that consumes some time.
task doit (uvm_phase phase, time delay);
static int s_inst = 0;
int inst = s_inst++;

//Raise an objection before starting the activity


phase.raise_objection(
this, // uvm_object obj
"", // string description=""
1 // int count=1, default value = 1 which increment
objection count by 1
);

uvm_report_info(get_name(), $sformatf("Starting doit (%0d) with delay %0t",


inst, delay), UVM_NONE);
#delay;
uvm_report_info(get_name(), $sformatf("Ending doit (%0d)", inst), UVM_NONE);

//Drop the objection when done


phase.drop_objection(
this, // uvm_object obj
"", // string description=""
1 // int count=1, default value = 1 which decrement
objection count by 1
);
endtask : doit
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 top.sv(98) @ 0: uvm_test_top [drain] Setting drain time of 10
// UVM_INFO @ 0: uvm_test_top [uvm_test_top] Starting doit (0) with delay 25
// UVM_INFO @ 0: uvm_test_top [uvm_test_top] Starting doit (1) with delay 50
// UVM_INFO @ 0: uvm_test_top.env [env] Starting doit (0) with delay 35
// UVM_INFO @ 0: uvm_test_top.env [env] Starting doit (1) with delay 60
// UVM_INFO @ 0: uvm_test_top.env.agent [agent] Starting doit (0) with delay 85
// UVM_INFO @ 0: uvm_test_top.env.agent [agent] Starting doit (1) with delay 55
// UVM_INFO @ 25: uvm_test_top [uvm_test_top] Ending doit (0)
// UVM_INFO @ 35: uvm_test_top.env [env] Ending doit (0)
// UVM_INFO @ 50: uvm_test_top [uvm_test_top] Ending doit (1)
// UVM_INFO @ 55: uvm_test_top.env.agent [agent] Ending doit (1)
// UVM_INFO @ 60: uvm_test_top.env [env] Ending doit (1)
// UVM_INFO @ 85: uvm_test_top.env.agent [agent] Ending doit (0)
// UVM_INFO /home/shahs/gotcha/uvm/uvm-1.2/src/base/uvm_objection.svh(1271) @ 95:
reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
// UVM_INFO /home/shahs/gotcha/uvm/uvm-1.2/src/base/uvm_report_server.svh(847) @
95: reporter [UVM/REPORT/SERVER]

Вам также может понравиться