sample_uvm_tb/agent_reset.sv
2024-08-11 21:48:11 -07:00

124 lines
3.7 KiB
Systemverilog

class sequencer_reset extends uvm_sequencer;
`uvm_component_utils(sequencer_reset)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
class driver_reset extends uvm_driver;
virtual testbench_if tb_if;
`uvm_component_utils(driver_reset)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual testbench_if)::get(this, "", "tb_vif", tb_if)) begin
`uvm_fatal("CFG_DB_FAIL", $sformatf("Failed to fetch interface for %0s", get_full_name()))
end
endfunction
virtual task run_phase(uvm_phase phase);
forever begin
@(posedge tb_if.rst_n);
while (tb_if.rst_n != 0) begin
seq_item_port.get_next_item(req);
drive_item(req);
seq_item_port.item_done();
end
end
endtask
task drive_item(uvm_sequence_item req);
`uvm_info("drive_item", $sformatf("Initiating reset..."), UVM_LOW)
tb_if.rst_n = 0;
repeat(10) @(posedge tb_if.clk);
tb_if.rst_n = 1;
`uvm_info("drive_item", $sformatf("Reset done."), UVM_LOW)
endtask
endclass
class monitor_reset extends uvm_monitor;
virtual testbench_if tb_if;
`uvm_component_utils(monitor_reset)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual testbench_if)::get(this, "", "tb_vif", tb_if)) begin
`uvm_fatal("CFG_DB_FAIL", $sformatf("Failed to fetch interface for %0s", get_full_name()))
end
endfunction
virtual task run_phase(uvm_phase phase);
fork
do_monitor();
join
endtask
task do_monitor();
bit prev_val;
if (tb_if.rst_n === 1'b0) begin
`uvm_info("do_monitor", $sformatf("Starting with reset asserted"), UVM_LOW)
end else if (tb_if.rst_n === 1'b1) begin
`uvm_info("do_monitor", $sformatf("Starting with reset de-asserted"), UVM_LOW)
end else begin
`uvm_info("do_monitor", $sformatf("Starting with reset unknown"), UVM_LOW)
end
forever begin
prev_val = tb_if.rst_n;
@(tb_if.rst_n);
if ((prev_val !== 1'b1) && (tb_if.rst_n !== 1'b1)) begin
`uvm_info("drive_item", $sformatf("Reset de-asserted"), UVM_LOW)
end
if ((prev_val !== 1'b0) && (tb_if.rst_n !== 1'b0)) begin
`uvm_info("drive_item", $sformatf("Reset asserted"), UVM_LOW)
end
end
endtask
endclass
class agent_reset extends uvm_agent;
sequencer_reset sequencer;
driver_reset driver;
monitor_reset monitor;
`uvm_component_utils(agent_reset)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
sequencer = sequencer_reset::type_id::create("sequencer", this);
driver = driver_reset::type_id::create("driver", this);
monitor = monitor_reset::type_id::create("monitor", this);
`uvm_info("build_phase", $sformatf("Building done"), UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
driver.seq_item_port.connect(sequencer.seq_item_export);
`uvm_info("connect_phase", $sformatf("Connecting done"), UVM_LOW)
endfunction
endclass