⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xbus_bus_monitor.sv

📁 Open Verification Methodology
💻 SV
字号:
// $Id: //dvt/vtech/dev/main/ovm/examples/xbus/sv/xbus_bus_monitor.sv#7 $//----------------------------------------------------------------------//   Copyright 2007-2008 Mentor Graphics Corporation//   Copyright 2007-2008 Cadence Design Systems, Inc.//   All Rights Reserved Worldwide////   Licensed under the Apache License, Version 2.0 (the//   "License"); you may not use this file except in//   compliance with the License.  You may obtain a copy of//   the License at////       http://www.apache.org/licenses/LICENSE-2.0////   Unless required by applicable law or agreed to in//   writing, software distributed under the License is//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR//   CONDITIONS OF ANY KIND, either express or implied.  See//   the License for the specific language governing//   permissions and limitations under the License.//----------------------------------------------------------------------`ifndef XBUS_BUS_MONITOR_SV`define XBUS_BUS_MONITOR_SV//------------------------------------------------------------------------------//// CLASS: slave_address_map_info//// The following class is used to determine which slave should respond // to a transfer on the bus//------------------------------------------------------------------------------class slave_address_map_info extends ovm_object;  int min_addr;  int max_addr;   `ovm_object_utils_begin(slave_address_map_info)    `ovm_field_int(min_addr, OVM_ALL_ON)    `ovm_field_int(max_addr, OVM_ALL_ON)  `ovm_object_utils_end  function void set_address_map (int min_addr , int max_addr);     this.min_addr = min_addr;    this.max_addr = max_addr;  endfunction : set_address_mapendclass : slave_address_map_info//------------------------------------------------------------------------------//// CLASS: xbus_bus_monitor////------------------------------------------------------------------------------class xbus_bus_monitor extends ovm_monitor;  // The virtual interface used to view HDL signals.  virtual xbus_if xbmi;  // Property indicating the number of transactions occuring on the xbus.  protected int unsigned num_transactions = 0;  // The following two bits are used to control whether checks and coverage are  // done both in the bus monitor class and the interface.  bit xbus_checks_enable = 1;   bit xbus_coverage_enable = 1;  // Analysis ports for the item_collected, reset end notifier, and phase change  // notifier.  ovm_analysis_port #(xbus_transfer) item_collected_port;  ovm_analysis_port #(int) reset_end_port;  ovm_analysis_port #(string) phase_change_port;  // The following property is used to store slave address map  protected slave_address_map_info slave_addr_map[string];  // The following property holds the transaction information currently  // being captured (by the collect_address_phase and data_phase methods).   protected xbus_transfer trans_collected;  // Events needed to trigger covergroups  event cov_transaction;  event cov_transaction_beat;  // Fields to hold trans data and wait_state.  No coverage of dynamic arrays.  protected bit [15:0] addr;  protected bit [7:0] data;  protected int unsigned wait_state;  // Transfer collected covergroup  covergroup cov_trans @cov_transaction;    option.per_instance = 1;    trans_start_addr : coverpoint trans_collected.addr {      option.auto_bin_max = 16; }    trans_dir : coverpoint trans_collected.read_write;    trans_size : coverpoint trans_collected.size {      bins sizes[] = {1, 2, 4, 8};      illegal_bins invalid_sizes = default; }    trans_addrXdir : cross trans_start_addr, trans_dir;    trans_dirXsize : cross trans_dir, trans_size;  endgroup : cov_trans  // Transfer collected data covergroup  covergroup cov_trans_beat @cov_transaction_beat;    option.per_instance = 1;    beat_addr : coverpoint addr {      option.auto_bin_max = 16; }    beat_dir : coverpoint trans_collected.read_write;    beat_data : coverpoint data {      option.auto_bin_max = 8; }    beat_wait : coverpoint wait_state {      bins waits[] = { [0:9] };      bins others = { [10:$] }; }    beat_addrXdir : cross beat_addr, beat_dir;    beat_addrXdata : cross beat_addr, beat_data;  endgroup : cov_trans_beat  // Provide implementations of virtual methods such as get_type_name and create  `ovm_component_utils_begin(xbus_bus_monitor)    `ovm_field_int(xbus_checks_enable, OVM_ALL_ON)    `ovm_field_int(xbus_coverage_enable, OVM_ALL_ON)    `ovm_field_int(num_transactions, OVM_ALL_ON)    `ovm_field_aa_object_string(slave_addr_map, OVM_ALL_ON)  `ovm_component_utils_end  // new - constructor  function new (string name, ovm_component parent);    super.new(name, parent);    cov_trans = new();    cov_trans.set_inst_name({get_full_name(), ".cov_trans"});    cov_trans_beat = new();    cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"});    trans_collected = new();    item_collected_port = new("item_collected_port", this);    reset_end_port = new("reset_end_port", this);    phase_change_port = new("phase_change_port", this);  endfunction : new  // set_slave_configs  function void set_slave_configs(string slave_name,    int min_addr, int max_addr);    slave_addr_map[slave_name] = new();    slave_addr_map[slave_name].set_address_map(min_addr, max_addr);  endfunction : set_slave_configs  // run phase  task run();    fork      observe_reset();      collect_transactions();    join  endtask : run  // observe_reset  task observe_reset();    forever begin      @(negedge xbmi.sig_reset);      reset_end_port.write(0);    end  endtask : observe_reset  // collect_transactions  virtual protected task collect_transactions();    forever begin      collect_arbitration_phase();      collect_address_phase();      collect_data_phase();      if(m_rh.get_verbosity_level() > OVM_MEDIUM) begin        `message(OVM_HIGH,("Transfer collected :"))        trans_collected.print();      end      if (xbus_checks_enable)        perform_xbus_transfer_checks();      if (xbus_coverage_enable)        perform_xbus_transfer_coverage();       item_collected_port.write(trans_collected);    end  endtask : collect_transactions  // collect_arbitration_phase  task collect_arbitration_phase();    string tmpStr;    @(posedge xbmi.sig_clock iff (xbmi.sig_grant != 0));    phase_change_port.write("arbitration");    void'(this.begin_tr(trans_collected));    // Check which grant is asserted to determine which master is performing    // the transfer on the bus.    for (int j = 0; j <= 15; j++) begin      if (xbmi.sig_grant[j] === 1) begin        $sformat(tmpStr,"masters[%0d]", j);        trans_collected.master = tmpStr;        break;         end     end  endtask : collect_arbitration_phase  // collect_address_phase  task collect_address_phase();    @(posedge xbmi.sig_clock);    trans_collected.addr = xbmi.sig_addr;    case (xbmi.sig_size)      2'b00 : trans_collected.size = 1;      2'b01 : trans_collected.size = 2;      2'b10 : trans_collected.size = 4;      2'b11 : trans_collected.size = 8;    endcase    trans_collected.data = new[trans_collected.size];    case ({xbmi.sig_read,xbmi.sig_write})      2'b00 : begin        trans_collected.read_write = NOP;        phase_change_port.write("nop_cycle");      end      2'b10 : begin        trans_collected.read_write = READ;        phase_change_port.write("normal_address_phase");      end      2'b01 : begin        trans_collected.read_write = WRITE;        phase_change_port.write("normal_address_phase");      end      2'b11 : begin        if (xbus_checks_enable)          `dut_error(("Read and Write true at the same time"))      end                endcase  endtask : collect_address_phase  // collect_data_phase  task collect_data_phase();    int i;    if (trans_collected.read_write != NOP) begin      check_which_slave();      for (i = 0; i < trans_collected.size; i++) begin        phase_change_port.write("data_phase");        @(posedge xbmi.sig_clock iff xbmi.sig_wait === 0);        trans_collected.data[i] = xbmi.sig_data;      end      num_transactions++;      this.end_tr(trans_collected);    end  endtask : collect_data_phase  // check_which_slave  function void check_which_slave();    string slave_name;    bit slave_found;    slave_found = 1'b0;    if(slave_addr_map.first(slave_name))      do begin        if (slave_addr_map[slave_name].min_addr <= trans_collected.addr          && trans_collected.addr <= slave_addr_map[slave_name].max_addr)         begin          trans_collected.slave = slave_name;          slave_found = 1'b1;        end        if (slave_found == 1'b1)          break;      end    while (slave_addr_map.next(slave_name));      assert(slave_found) else begin        `dut_error(("Master attempted a transfer at illegal address 16'h%0h",          trans_collected.addr))      end  endfunction : check_which_slave  // perform_xbus_transfer_checks  function void perform_xbus_transfer_checks();    check_xbus_transfer_size();    check_xbus_transfer_data_size();  endfunction : perform_xbus_transfer_checks  // check_xbus_transfer_size  function void check_xbus_transfer_size();   if (trans_collected.read_write != NOP) begin    check_xbus_transfer_size : assert(trans_collected.size == 1 ||       trans_collected.size == 2 || trans_collected.size == 4 ||       trans_collected.size == 8) else begin      `dut_error(("Invalid transfer size!"))    end   end  endfunction : check_xbus_transfer_size  // check_xbus_transfer_data_size  function void check_xbus_transfer_data_size();    if (trans_collected.size != trans_collected.data.size())      `dut_error(("Transfer size field / data size mistmatch."))  endfunction : check_xbus_transfer_data_size  // perform_xbus_transfer_coverage  function void perform_xbus_transfer_coverage();    if (trans_collected.read_write != NOP) begin      -> cov_transaction;      for (int unsigned i = 0; i < trans_collected.size; i++) begin        addr = trans_collected.addr + i;        data = trans_collected.data[i];        wait_state = trans_collected.wait_state[i];        -> cov_transaction_beat;      end    end  endfunction : perform_xbus_transfer_coverageendclass : xbus_bus_monitor`endif // XBUS_BUS_MONITOR_SV

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -