| //----------------------------------------------------------------------------- |
| // Copyright 2018 Qualcomm, Inc. |
| // Copyright 2018 Synopsys, Inc. |
| // Copyright 2018 Cadence Design Systems, Inc. |
| // Copyright 2018 NVIDIA 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 -- NODOCS -- uvm_copier |
| // |
| // The uvm_copier class provides a policy object for doing comparisons. The |
| // policies determine how miscompares are treated and counted. Results of a |
| // comparison are stored in the copier object. The <uvm_object::compare> |
| // and <uvm_object::do_compare> methods are passed a uvm_copier policy |
| // object. |
| // |
| //------------------------------------------------------------------------------ |
| |
| // Class: uvm_copier |
| // Implementation of the uvm_copier class, as defined in section |
| // 16.6.1 of 1800.2-2017 |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.1 |
| class uvm_copier extends uvm_policy; |
| // @uvm-ieee 1800.2-2017 auto 16.6.2.2 |
| `uvm_object_utils(uvm_copier) |
| // Variable -- NODOCS -- policy |
| // |
| // Determines whether comparison is UVM_DEEP, UVM_REFERENCE, or UVM_SHALLOW. |
| |
| uvm_recursion_policy_enum policy = UVM_DEFAULT_POLICY; |
| |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.2.1 |
| function new(string name="uvm_copier") ; |
| super.new(name); |
| endfunction |
| |
| // Implementation only. |
| |
| // Implementation only. Not present in the LRM. |
| //recursion_state_e m_saved_state[uvm_object /*LHS*/][uvm_object /*RHS*/][uvm_recursion_policy_enum /*recursion*/]; |
| |
| recursion_state_e m_recur_states[uvm_object /*RHS*/][uvm_object /*LHS*/][uvm_recursion_policy_enum /*recursion*/]; |
| |
| // Function -- copy_object |
| // |
| // Copies two class objects using the <policy> knob to determine whether the |
| // comparison should be deep, shallow, or reference. |
| // |
| // The name input is used for purposes of storing and printing a miscompare. |
| // |
| // The ~lhs~ and ~rhs~ objects are the two objects used for comparison. |
| // |
| // The ~check_type~ determines whether or not to verify the object |
| // types match (the return from ~lhs.get_type_name()~ matches |
| // ~rhs.get_type_name()~). |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.4.1 |
| virtual function void copy_object ( |
| uvm_object lhs, |
| uvm_object rhs); |
| |
| uvm_field_op field_op; |
| if (get_recursion_policy() == UVM_REFERENCE) begin |
| `uvm_error("UVM_COPY_POLICY","Attempting to make a copy of a object which is a reference") |
| return; |
| end |
| |
| if (rhs == null || lhs == null) begin |
| `uvm_error("UVM_COPY_NULL_OBJ","Attempting to make a copy of a object with null src/target") |
| return; |
| end |
| |
| push_active_object(lhs); |
| m_recur_states[rhs][lhs][get_recursion_policy()] = uvm_policy::STARTED; |
| field_op = uvm_field_op::m_get_available_op() ; |
| field_op.set(UVM_COPY,this,rhs); |
| lhs.do_execute_op(field_op); |
| if (field_op.user_hook_enabled()) begin |
| lhs.do_copy(rhs); |
| end |
| field_op.m_recycle(); |
| m_recur_states[rhs][lhs][get_recursion_policy()] = uvm_policy::FINISHED; |
| void'(pop_active_object()); |
| endfunction |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.4.2 |
| virtual function recursion_state_e object_copied( |
| uvm_object lhs, |
| uvm_object rhs, |
| uvm_recursion_policy_enum recursion |
| ); |
| if (!m_recur_states.exists(rhs)) return NEVER ; |
| else if (!m_recur_states[rhs].exists(lhs)) return NEVER ; |
| else if (!m_recur_states[rhs][lhs].exists(recursion)) return NEVER ; |
| else begin |
| return m_recur_states[rhs][lhs][recursion]; |
| end |
| |
| |
| |
| endfunction |
| |
| |
| function void flush(); |
| m_recur_states.delete(); |
| endfunction |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.3 |
| virtual function void set_recursion_policy (uvm_recursion_policy_enum policy); |
| this.policy = policy; |
| endfunction |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.3 |
| virtual function uvm_recursion_policy_enum get_recursion_policy(); |
| return policy; |
| endfunction |
| |
| // Function: get_num_copies |
| // |
| // Returns the number of times the ~rhs~ has been copied to a unique ~lhs~ |
| // |
| // @uvm-contrib This API is being considered for potential contribution to 1800.2 |
| function int unsigned get_num_copies(uvm_object rhs); |
| if (m_recur_states.exists(rhs)) |
| return m_recur_states[rhs].size(); |
| return 0; |
| endfunction : get_num_copies |
| |
| // Function: get_first_copy |
| // |
| //| function int get_first_copy(uvm_object rhs, ref uvm_object lhs) |
| // |
| // assigns to the ~lhs~ the value of the first (smallest) object that |
| // was copied from the ~rhs~. It returns 0 if the ~rhs~ hasn't been copied; |
| // otherwise, it returns 1. |
| // |
| // @uvm-contrib This API is being considered for potential contribution to 1800.2 |
| `uvm_copier_get_function(first) |
| |
| |
| // Function: get_next_copy |
| // |
| //| function int get_next_copy(uvm_object rhs, ref uvm_object lhs) |
| // |
| // finds the smallest object that was copied from the ~rhs~ whose value is |
| // greater than the given ~lhs~ object argument. If there is a next entry, |
| // the ~lhs~ is assigned the value of the next object, and the function returns 1. |
| // Otherwise, the ~lhs~ is unchanged, and the function returns 0. |
| // |
| // @uvm-contrib This API is being considered for potential contribution to 1800.2 |
| `uvm_copier_get_function(next) |
| |
| // Function: get_last_copy |
| // |
| //| function int get_last_copy(uvm_object rhs, ref uvm_object lhs) |
| // |
| // assigns to the ~lhs~ the value of the last (largest) object that |
| // was copied from the ~rhs~. It returns 0 if the ~rhs~ hasn't been copied; |
| // otherwise, it returns 1. |
| // |
| // @uvm-contrib This API is being considered for potential contribution to 1800.2 |
| `uvm_copier_get_function(last) |
| |
| // Function: get_prev_copy |
| // |
| //| function int get_prev_copy(uvm_object rhs, ref uvm_object lhs) |
| // |
| // finds the largest object that was copied from the ~rhs~ whose value is |
| // smaller than the given ~lhs~ object argument. If there is a previous entry, |
| // the ~lhs~ is assigned the value of the previous object, and the function returns 1. |
| // Otherwise, the ~lhs~ is unchanged, and the function returns 0. |
| // |
| // @uvm-contrib This API is being considered for potential contribution to 1800.2 |
| `uvm_copier_get_function(prev) |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.2.3 |
| static function void set_default (uvm_copier copier) ; |
| uvm_coreservice_t coreservice ; |
| coreservice = uvm_coreservice_t::get() ; |
| coreservice.set_default_copier(copier) ; |
| endfunction |
| |
| // @uvm-ieee 1800.2-2017 auto 16.6.2.4 |
| static function uvm_copier get_default () ; |
| uvm_coreservice_t coreservice ; |
| coreservice = uvm_coreservice_t::get() ; |
| return coreservice.get_default_copier() ; |
| endfunction |
| |
| endclass |