URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [uvm_reg_fifo.svh] - Rev 16
Compare with Previous | Blame | View Log
//// -------------------------------------------------------------// Copyright 2010-2011 Mentor Graphics Corporation// 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.// -------------------------------------------------------------////------------------------------------------------------------------------------// Class: uvm_reg_fifo//// This special register models a DUT FIFO accessed via write/read,// where writes push to the FIFO and reads pop from it.//// Backdoor access is not enabled, as it is not yet possible to force// complete FIFO state, i.e. the write and read indexes used to access// the FIFO data.////------------------------------------------------------------------------------class uvm_reg_fifo extends uvm_reg;local uvm_reg_field value;local int m_set_cnt;local int unsigned m_size;// Variable: fifo//// The abstract representation of the FIFO. Constrained// to be no larger than the size parameter. It is public// to enable subtypes to add constraints on it and randomize.//rand uvm_reg_data_t fifo[$];constraint valid_fifo_size {fifo.size() <= m_size;}//----------------------// Group: Initialization//----------------------// Function: new//// Creates an instance of a FIFO register having ~size~ elements of// ~n_bits~ each.//function new(string name = "reg_fifo",int unsigned size,int unsigned n_bits,int has_cover);super.new(name,n_bits,has_cover);m_size = size;endfunction// Funtion: build//// Builds the abstract FIFO register object. Called by// the instantiating block, a <uvm_reg_block> subtype.//virtual function void build();value = uvm_reg_field::type_id::create("value");value.configure(this, get_n_bits(), 0, "RW", 0, 32'h0, 1, 0, 1);endfunction// Function: set_compare//// Sets the compare policy during a mirror (read) of the DUT FIFO.// The DUT read value is checked against its mirror only when both the// ~check~ argument in the <mirror()> call and the compare policy// for the field is <UVM_CHECK>.//function void set_compare(uvm_check_e check=UVM_CHECK);value.set_compare(check);endfunction//---------------------// Group: Introspection//---------------------// Function: size//// The number of entries currently in the FIFO.//function int unsigned size();return fifo.size();endfunction// Function: capacity//// The maximum number of entries, or depth, of the FIFO.function int unsigned capacity();return m_size;endfunction//--------------// Group: Access//--------------// Function: write//// Pushes the given value to the DUT FIFO. If auto-prediction is enabled,// the written value is also pushed to the abstract FIFO before the// call returns. If auto-prediction is not enabled (via// <uvm_reg_map::set_auto_predict>), the value is pushed to abstract// FIFO only when the write operation is observed on the target bus.// This mode requires using the <uvm_reg_predictor> class.// If the write is via an <update()> operation, the abstract FIFO// already contains the written value and is thus not affected by// either prediction mode.// Function: read//// Reads the next value out of the DUT FIFO. If auto-prediction is// enabled, the frontmost value in abstract FIFO is popped.// Function: set//// Pushes the given value to the abstract FIFO. You may call this// method several times before an <update()> as a means of preloading// the DUT FIFO. Calls to ~set()~ to a full FIFO are ignored. You// must call <update()> to update the DUT FIFO with your set values.//virtual function void set(uvm_reg_data_t value,string fname = "",int lineno = 0);// emulate write, with intention of updatevalue &= ((1 << get_n_bits())-1);if (fifo.size() == m_size) beginreturn;endsuper.set(value,fname,lineno);m_set_cnt++;fifo.push_back(this.value.value);endfunction// Function: update//// Pushes (writes) all values preloaded using <set()> to the DUT.// You must ~update~ after ~set~ before any blocking statements,// else other reads/writes to the DUT FIFO may cause the mirror to// become out of sync with the DUT.//virtual task update(output uvm_status_e status,input uvm_path_e path = UVM_DEFAULT_PATH,input uvm_reg_map map = null,input uvm_sequence_base parent = null,input int prior = -1,input uvm_object extension = null,input string fname = "",input int lineno = 0);uvm_reg_data_t upd;if (!m_set_cnt || fifo.size() == 0)return;m_update_in_progress = 1;for (int i=fifo.size()-m_set_cnt; m_set_cnt > 0; i++, m_set_cnt--) beginif (i >= 0) begin//uvm_reg_data_t val = get();//super.update(status,path,map,parent,prior,extension,fname,lineno);write(status,fifo[i],path,map,parent,prior,extension,fname,lineno);endendm_update_in_progress = 0;endtask// Function: mirror//// Reads the next value out of the DUT FIFO. If auto-prediction is// enabled, the frontmost value in abstract FIFO is popped. If// the ~check~ argument is set and comparison is enabled with// <set_compare()>.// Function: get//// Returns the next value from the abstract FIFO, but does not pop it.// Used to get the expected value in a <mirror()> operation.//virtual function uvm_reg_data_t get(string fname="", int lineno=0);//return fifo.pop_front();return fifo[0];endfunction// Function: do_predict//// Updates the abstract (mirror) FIFO based on <write()> and// <read()> operations. When auto-prediction is on, this method// is called before each read, write, peek, or poke operation returns.// When auto-prediction is off, this method is called by a// <uvm_reg_predictor> upon receipt and conversion of an observed bus// operation to this register.//// If a write prediction, the observed// write value is pushed to the abstract FIFO as long as it is// not full and the operation did not originate from an <update()>.// If a read prediction, the observed read value is compared// with the frontmost value in the abstract FIFO if <set_compare()>// enabled comparison and the FIFO is not empty.//virtual function void do_predict(uvm_reg_item rw,uvm_predict_e kind = UVM_PREDICT_DIRECT,uvm_reg_byte_en_t be = -1);super.do_predict(rw,kind,be);if (rw.status == UVM_NOT_OK)return;case (kind)UVM_PREDICT_WRITE,UVM_PREDICT_DIRECT:beginif (fifo.size() != m_size && !m_update_in_progress)fifo.push_back(this.value.value);endUVM_PREDICT_READ:beginuvm_reg_data_t value = rw.value[0] & ((1 << get_n_bits())-1);uvm_reg_data_t mirror_val;if (fifo.size() == 0) beginreturn;endmirror_val = fifo.pop_front();if (this.value.get_compare() == UVM_CHECK && mirror_val != value) begin`uvm_warning("MIRROR_MISMATCH",$sformatf("Observed DUT read value 'h%0h != mirror value 'h%0h",value,mirror_val))endendendcaseendfunction// Group: Special Overrides// Task: pre_write//// Special pre-processing for a <write()> or <update()>.// Called as a result of a <write()> or <update()>. It is an error to// attempt a write to a full FIFO or a write while an update is still// pending. An update is pending after one or more calls to <set()>.// If in your application the DUT allows writes to a full FIFO, you// must override ~pre_write~ as appropriate.//virtual task pre_write(uvm_reg_item rw);if (m_set_cnt && !m_update_in_progress) begin`uvm_error("Needs Update","Must call update() after set() and before write()")rw.status = UVM_NOT_OK;return;endif (fifo.size() >= m_size && !m_update_in_progress) begin`uvm_error("FIFO Full","Write to full FIFO ignored")rw.status = UVM_NOT_OK;return;endendtask// Task: pre_read//// Special post-processing for a <write()> or <update()>.// Aborts the operation if the internal FIFO is empty. If in your application// the DUT does not behave this way, you must override ~pre_write~ as// appropriate.////virtual task pre_read(uvm_reg_item rw);// abort if fifo emptyif (fifo.size() == 0) beginrw.status = UVM_NOT_OK;return;endendtaskfunction void post_randomize();m_set_cnt = 0;endfunctionendclass
