/**************************************************************************** +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+ |F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e| +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+ FILE reset_driver.sv DESCRIPTION drives reset ****************************************************************************/ `ifndef RESET_DRIVER_SV `define RESET_DRIVER_SV /** * Class: reset_driver */ class reset_driver extends uvm_driver #(reset_transaction); // reset virtual interface virtual reset_if vif; // configuration reset_config cfg; // UVM factory registration `uvm_component_utils_begin(reset_driver) `uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE) `uvm_component_utils_end // new - constructor function new (string name = "reset_driver", uvm_component parent = null); super.new(name, parent); endfunction : new // UVM build_phase virtual function void build_phase(uvm_phase phase); super.build_phase(phase); // get configuration object from db if(!uvm_config_db#(reset_config)::get(this, "*", "reset_config", cfg)) `uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"}) endfunction: build_phase // UVM connect_phase virtual function void connect_phase(uvm_phase phase); super.connect_phase(phase); // get interface from db if(!uvm_config_db#(virtual reset_if)::get(this, "", "reset_if", vif)) `uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"}) endfunction : connect_phase // additional class methods extern virtual task run_phase(uvm_phase phase); extern virtual function void start_of_simulation_phase(uvm_phase phase); extern virtual task drive_tr (reset_transaction tr); endclass : reset_driver // UVM start_of_simulation_phase function void reset_driver::start_of_simulation_phase(uvm_phase phase); super.start_of_simulation_phase(phase); vif.reset <= cfg.value_at_0; // init reset endfunction // UVM run_phase task reset_driver::run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); drive_tr(req); seq_item_port.item_done(); end endtask : run_phase // Drives a transfer when an item is ready to be sent. task reset_driver::drive_tr (reset_transaction tr); `uvm_info( get_type_name(), $sformatf("Driving reset: delay %0d clocks duration of %0d clocks", tr.transmit_delay, tr.duration), UVM_LOW) // delay if (tr.transmit_delay > 0) begin repeat(tr.transmit_delay) @(posedge vif.clk); end // start reset vif.reset <= cfg.active_high; // duration repeat(tr.duration) @(posedge vif.clk); // drop reset vif.reset <= ~cfg.active_high; endtask : drive_tr `endif