/**************************************************************************** +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+ |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_monitor.sv DESCRIPTION monitors interface for reset; collects coverage ****************************************************************************/ `ifndef RESET_MONITOR_SV `define RESET_MONITOR_SV /** * Class: reset_monitor */ class reset_monitor extends uvm_monitor; // reset virtual interface virtual reset_if vif; // configuration reset_config cfg; // TLM - from monitor to other components uvm_analysis_port #(reset_transaction) item_collected_port; // keep track of number of transactions int unsigned num_transactions = 0; // current transaction reset_transaction tr_collected; // UVM factory registration `uvm_component_utils_begin(reset_monitor) `uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE) `uvm_component_utils_end // coverage covergroup cg_reset; // reset duration cp_duration : coverpoint tr_collected.duration { bins one_clk = {1}; bins other = default; } endgroup : cg_reset; // new - constructor function new(string name = "reset_monitor", uvm_component parent = null); super.new(name, parent); item_collected_port = new("item_collected_port", this); cg_reset = new(); endfunction : new // UVM build_phase 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 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 report_phase(uvm_phase phase); endclass : reset_monitor // UVM run_phase task reset_monitor::run_phase(uvm_phase phase); forever begin tr_collected = reset_transaction::type_id::create("tr_collected"); // monitor reset if(cfg.active_high) begin @(posedge vif.reset); end else begin @(negedge vif.reset); end `uvm_info(get_type_name(), "Reset observed", UVM_MEDIUM) tr_collected.duration = 1; fork // get duration forever begin @(posedge vif.clk) tr_collected.duration++; end // monitor reset dropped begin if(cfg.active_high) begin @(negedge vif.reset); end else begin @(posedge vif.reset); end end join_any disable fork; item_collected_port.write(tr_collected); // TLM // collect coverage if enabled if(cfg.has_coverage == 1) begin cg_reset.sample(); end num_transactions++; end // forever begin endtask : run_phase // UVM report_phase function void reset_monitor::report_phase(uvm_phase phase); // final report `uvm_info(get_type_name(), $sformatf("Report: reset monitor collected %0d transfers", num_transactions), UVM_LOW); endfunction : report_phase `endif