sample_uvm_tb/agent_reset.sv

162 lines
5.8 KiB
Systemverilog
Raw Permalink Normal View History

2024-12-26 22:15:54 -08:00
// -----
//
// Copyright (c) 2024 Mahesh Asolkar
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----
2024-08-11 21:48:11 -07:00
class sequencer_reset extends uvm_sequencer;
`uvm_component_utils(sequencer_reset)
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
2024-12-26 22:15:54 -08:00
// ----------------------------------------------------------------------
2024-08-11 21:48:11 -07:00
class driver_reset extends uvm_driver;
virtual testbench_if tb_if;
`uvm_component_utils(driver_reset)
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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
2024-12-26 22:15:54 -08:00
// ----------------------------------------------------------------------
2024-08-11 21:48:11 -07:00
class monitor_reset extends uvm_monitor;
virtual testbench_if tb_if;
`uvm_component_utils(monitor_reset)
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
virtual task run_phase(uvm_phase phase);
fork
do_monitor();
join
endtask
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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
2024-12-26 22:15:54 -08:00
// ----------------------------------------------------------------------
2024-08-11 21:48:11 -07:00
class agent_reset extends uvm_agent;
sequencer_reset sequencer;
driver_reset driver;
monitor_reset monitor;
`uvm_component_utils(agent_reset)
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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
2024-12-26 22:15:54 -08:00
// ------------------------------------------------------------
2024-08-11 21:48:11 -07:00
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