Hi,
I want to trigger a uvm_event after the second “uvm_do_with” statement executed. but now, the uvm_event and the first “uvm_do_with” statement execute at the same time.
what should i do ?
`ifndef MPU_START_SEQUENCE__SV
`define MPU_START_SEQUENCE__SV
class mpu_start_sequence extends uvm_sequence #(mpu_start_item);
`uvm_object_utils(mpu_start_sequence)
rand bit seq_en;
rand bit[31:0] seq_addr;
uvm_event START_EV = uvm_event_pool::get_global("START_EV");
extern function new(string name = "mpu_start_sequence");
extern virtual task body();
endclass
function mpu_start_sequence::new(string name = "mpu_start_sequence");
super.new(name);
set_automatic_phase_objection(1);
endfunction
task mpu_start_sequence::body();
begin
`uvm_do_with(req, {en == 1; addr == 0;});
`uvm_do_with(req, {en == 0;});
end
START_EV.trigger();
endtask
`endif
I found the problem, is my mistake.
The use of wait_on() is improper in passive monitor, result in scoreboard get invalid transaction.
Now, the complete code is as follow
`ifndef MPU_START_SEQUENCE__SV
`define MPU_START_SEQUENCE__SV
class mpu_start_sequence extends uvm_sequence #(mpu_start_item);
`uvm_object_utils(mpu_start_sequence)
uvm_event START_EV = uvm_event_pool::get_global("START_EV");
extern function new(string name = "mpu_start_sequence");
extern virtual task body();
endclass
function mpu_start_sequence::new(string name = "mpu_start_sequence");
super.new(name);
set_automatic_phase_objection(1);
endfunction
task mpu_start_sequence::body();
`uvm_do_with(req, {en == 1; addr == 0;});
`uvm_do_with(req, {en == 0;});
START_EV.trigger();
endtask
`endif
`ifndef MPU_STOP_MONITOR__SV
`define MPU_STOP_MONITOR__SV
class mpu_stop_monitor extends uvm_monitor;
`uvm_component_utils(mpu_stop_monitor)
virtual mpu_stop_if VIF;
uvm_analysis_port #(mpu_stop_item) ap;
uvm_event START_EV = uvm_event_pool::get_global("START_EV");
extern function new(string name, uvm_component parent);
extern task main_phase(uvm_phase phase);
endclass
function mpu_stop_monitor::new(string name, uvm_component parent);
super.new(name, parent);
ap = new("ap", this);
endfunction
task mpu_stop_monitor::main_phase(uvm_phase phase);
mpu_stop_item item;
mpu_stop_item cloned_item;
item = mpu_stop_item::type_id::create("item");
START_EV.wait_on();
forever begin
@(VIF.icb) begin
item.a = VIF.icb.a;
end
$cast(cloned_item, item.clone());
ap.write(cloned_item);
end
endtask
`endif
`ifndef MFETCH_SCOREBOARD__SV
`define MFETCH_SCOREBOARD__SV
class mfetch_scoreboard extends uvm_scoreboard;
`uvm_component_utils(mfetch_scoreboard)
uvm_blocking_get_port #(mpu_stop_item) gp_mpu_stop_agt;
uvm_blocking_get_port #(mpu_stop_item) gp_mpu_stop_mdl;
mpu_stop_item expect_mpu_stop_item, actual_mpu_stop_item;
uvm_event START_EV = uvm_event_pool::get_global("START_EV");
extern function new(string name, uvm_component parent);
extern task main_phase(uvm_phase phase);
endclass
function mfetch_scoreboard::new(string name, uvm_component parent);
super.new(name, parent);
gp_mpu_stop_agt = new("gp_mpu_stop_agt", this);
gp_mpu_stop_mdl = new("gp_mpu_stop_mdl", this);
endfunction
task mfetch_scoreboard::main_phase(uvm_phase phase);
actual_mpu_stop_item = mpu_stop_item::type_id::create("actual_mpu_stop_item", this);
fork
forever begin
gp_mpu_stop_agt.get(actual_mpu_stop_item);
if(actual_mpu_stop_item.a == 1) begin
`uvm_info(get_type_name(), "MFetch Simulation End Due to Stop Instruction.", UVM_LOW)
$stop;
end
end
forever begin
end
join
endtask
`endif