124 lines
3.7 KiB
Systemverilog
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
|