//-----------------------------------------------------------------------------
//   Copyright 2007-2010 Mentor Graphics Corporation
//   Copyright 2007-2011 Cadence Design Systems, Inc.
//   Copyright 2010 Synopsys, 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.
//-----------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
// CLASS: uvm_comparer
//
// The uvm_comparer 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 comparer object. The <uvm_object::compare>
// and <uvm_object::do_compare> methods are passed an uvm_comparer policy
// object.
//
//------------------------------------------------------------------------------

class uvm_comparer;

  // Variable: policy
  //
  // Determines whether comparison is UVM_DEEP, UVM_REFERENCE, or UVM_SHALLOW.

  uvm_recursion_policy_enum policy = UVM_DEFAULT_POLICY;


  // Variable: show_max
  //
  // Sets the maximum number of messages to send to the messager for miscompares
  // of an object. 

  int unsigned show_max = 1;


  // Variable: verbosity
  //
  // Sets the verbosity for printed messages. 
  //
  // The verbosity setting is used by the messaging mechanism to determine
  // whether messages should be suppressed or shown.

  int unsigned verbosity = UVM_LOW;


  // Variable: sev
  //
  // Sets the severity for printed messages. 
  //
  // The severity setting is used by the messaging mechanism for printing and
  // filtering messages.

  uvm_severity sev = UVM_INFO;


  // Variable: miscompares
  //
  // This string is reset to an empty string when a comparison is started. 
  //
  // The string holds the last set of miscompares that occurred during a
  // comparison.

  string miscompares = "";


  // Variable: physical
  //
  // This bit provides a filtering mechanism for fields. 
  //
  // The abstract and physical settings allow an object to distinguish between
  // two different classes of fields.
  //
  // It is up to you, in the <uvm_object::do_compare> method, to test the
  // setting of this field if you want to use the physical trait as a filter.

  bit physical = 1;


  // Variable: abstract
  //
  // This bit provides a filtering mechanism for fields. 
  //
  // The abstract and physical settings allow an object to distinguish between
  // two different classes of fields.
  //
  // It is up to you, in the <uvm_object::do_compare> method, to test the
  // setting of this field if you want to use the abstract trait as a filter.

  bit abstract = 1;


  // Variable: check_type
  //
  // This bit determines whether the type, given by <uvm_object::get_type_name>,
  // is used to verify that the types of two objects are the same. 
  //
  // This bit is used by the <compare_object> method. In some cases it is useful
  // to set this to 0 when the two operands are related by inheritance but are
  // different types.

  bit check_type = 1;


  // Variable: result
  // 
  // This bit stores the number of miscompares for a given compare operation.
  // You can use the result to determine the number of miscompares that
  // were found.

  int unsigned result = 0;


  // Function: compare_field
  //
  // Compares two integral values. 
  //
  // The ~name~ input is used for purposes of storing and printing a miscompare.
  //
  // The left-hand-side ~lhs~ and right-hand-side ~rhs~ objects are the two
  // objects used for comparison. 
  //
  // The size variable indicates the number of bits to compare; size must be
  // less than or equal to 4096. 
  //
  // The radix is used for reporting purposes, the default radix is hex.

  virtual function bit compare_field (string name, 
                                      uvm_bitstream_t lhs, 
                                      uvm_bitstream_t rhs, 
                                      int size,
                                      uvm_radix_enum radix=UVM_NORADIX); 
    uvm_bitstream_t mask;
    string msg;
  
    if(size <= 64)
      return compare_field_int(name, lhs, rhs, size, radix);
  
    mask = -1;
    mask >>= (UVM_STREAMBITS-size);
    if((lhs & mask) !== (rhs & mask)) begin
      uvm_object::__m_uvm_status_container.scope.set_arg(name);
      case (radix)
        UVM_BIN: begin
              $swrite(msg, "lhs = 'b%0b : rhs = 'b%0b", 
                       lhs&mask, rhs&mask);
             end
        UVM_OCT: begin
              $swrite(msg, "lhs = 'o%0o : rhs = 'o%0o", 
                       lhs&mask, rhs&mask);
             end
        UVM_DEC: begin
              $swrite(msg, "lhs = %0d : rhs = %0d", 
                       lhs&mask, rhs&mask);
             end
        UVM_TIME: begin
            $swrite(msg, "lhs = %0t : rhs = %0t", 
               lhs&mask, rhs&mask);
        end
        UVM_STRING: begin
              $swrite(msg, "lhs = %0s : rhs = %0s", 
                       lhs&mask, rhs&mask);
             end
        UVM_ENUM: begin
              //Printed as decimal, user should cuse compare string for enum val
              $swrite(msg, "lhs = %0d : rhs = %0d", 
                       lhs&mask, rhs&mask);
              end
        default: begin
              $swrite(msg, "lhs = 'h%0x : rhs = 'h%0x", 
                       lhs&mask, rhs&mask);
             end
      endcase
      print_msg(msg);
      return 0;
    end
    return 1;
  endfunction

  
  
  // Function: compare_field_int
  //
  // This method is the same as <compare_field> except that the arguments are
  // small integers, less than or equal to 64 bits. It is automatically called
  // by <compare_field> if the operand size is less than or equal to 64.

  virtual function bit compare_field_int (string name, 
                                          logic[63:0] lhs, 
                                          logic[63:0] rhs, 
                                          int size,
                                          uvm_radix_enum radix=UVM_NORADIX); 
    logic [63:0] mask;
    string msg;
  
    mask = -1;
    mask >>= (64-size);
    if((lhs & mask) !== (rhs & mask)) begin
      uvm_object::__m_uvm_status_container.scope.set_arg(name);
      case (radix)
        UVM_BIN: begin
              $swrite(msg, "lhs = 'b%0b : rhs = 'b%0b", 
                       lhs&mask, rhs&mask);
             end
        UVM_OCT: begin
              $swrite(msg, "lhs = 'o%0o : rhs = 'o%0o", 
                       lhs&mask, rhs&mask);
             end
        UVM_DEC: begin
              $swrite(msg, "lhs = %0d : rhs = %0d", 
                       lhs&mask, rhs&mask);
             end
        UVM_TIME: begin
            $swrite(msg, "lhs = %0t : rhs = %0t", 
               lhs&mask, rhs&mask);
        end
        UVM_STRING: begin
              $swrite(msg, "lhs = %0s : rhs = %0s", 
                       lhs&mask, rhs&mask);
             end
        UVM_ENUM: begin
              //Printed as decimal, user should cuse compare string for enum val
              $swrite(msg, "lhs = %0d : rhs = %0d", 
                       lhs&mask, rhs&mask);
              end
        default: begin
              $swrite(msg, "lhs = 'h%0x : rhs = 'h%0x", 
                       lhs&mask, rhs&mask);
             end
      endcase
      print_msg(msg);
      return 0;
    end
    return 1;
  endfunction


  // Function: compare_field_real
  //
  // This method is the same as <compare_field> except that the arguments are
  // real numbers.

  virtual function bit compare_field_real (string name, 
                                          real lhs, 
                                          real rhs);
    string msg;
  
    if(lhs != rhs) begin
      uvm_object::__m_uvm_status_container.scope.set_arg(name);
      $swrite(msg, "lhs = ", lhs, " : rhs = ", rhs);
      print_msg(msg);
      return 0;
    end
    return 1;
  endfunction


  // Function: compare_object
  //
  // Compares 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()~).

  virtual function bit compare_object (string name,
                                       uvm_object lhs,
                                       uvm_object rhs);
    if (rhs == lhs)
      return 1;

    if (policy == UVM_REFERENCE && lhs != rhs) begin
      uvm_object::__m_uvm_status_container.scope.set_arg(name);
      print_msg_object(lhs, rhs);
      return 0;
    end

    if (rhs == null || lhs == null) begin
      uvm_object::__m_uvm_status_container.scope.set_arg(name);
      print_msg_object(lhs, rhs);
      return 0;  //miscompare
    end

    uvm_object::__m_uvm_status_container.scope.down(name);
    compare_object = lhs.compare(rhs, this);
    uvm_object::__m_uvm_status_container.scope.up();

  endfunction
  
  
  // Function: compare_string
  //
  // Compares two string variables. 
  //
  // 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.

  virtual function bit compare_string (string name,
                                       string lhs,
                                       string rhs);
    string msg;
    if(lhs != rhs) begin
      uvm_object::__m_uvm_status_container.scope.set_arg(name);
      msg = { "lhs = \"", lhs, "\" : rhs = \"", rhs, "\""};
      print_msg(msg);
      return 0;
    end
    return 1;
  endfunction


  // Function: print_msg
  //
  // Causes the error count to be incremented and the message, ~msg~, to be
  // appended to the <miscompares> string (a newline is used to separate
  // messages). 
  //
  // If the message count is less than the <show_max> setting, then the message
  // is printed to standard-out using the current verbosity and severity
  // settings. See the <verbosity> and <sev> variables for more information.

  function void print_msg (string msg);
    result++;
    if(result <= show_max) begin
       msg = {"Miscompare for ", uvm_object::__m_uvm_status_container.scope.get(), ": ", msg};
       uvm_report_info("MISCMP", msg, UVM_LOW);
    end
    miscompares = { miscompares, uvm_object::__m_uvm_status_container.scope.get(), ": ", msg, "\n" };
  endfunction



  // Internal methods - do not call directly

  // print_rollup
  // ------------

  //Need this function because sformat doesn't support objects
  function void print_rollup(uvm_object rhs, uvm_object lhs);
    string msg;
    if(uvm_object::__m_uvm_status_container.scope.depth() == 0) begin
      if(result && (show_max || (uvm_severity_type'(sev) != UVM_INFO))) begin
        if(show_max < result) 
           $swrite(msg, "%0d Miscompare(s) (%0d shown) for object ",
             result, show_max);
        else begin
           $swrite(msg, "%0d Miscompare(s) for object ", result);
        end

        case (sev)
          UVM_WARNING: begin 
                     uvm_report_warning("MISCMP", $sformatf("%s%s@%0d vs. %s@%0d", msg,
                        lhs.get_name(), lhs.get_inst_id(), rhs.get_name(), rhs.get_inst_id()), UVM_NONE);
                   end
          UVM_ERROR: begin 
                     uvm_report_error("MISCMP", $sformatf("%s%s@%0d vs. %s@%0d", msg,
                        lhs.get_name(), lhs.get_inst_id(), rhs.get_name(), rhs.get_inst_id()), UVM_NONE);
                   end
          default: begin 
                     uvm_report_info("MISCMP", $sformatf("%s%s@%0d vs. %s@%0d", msg,
                        lhs.get_name(), lhs.get_inst_id(), rhs.get_name(), rhs.get_inst_id()), UVM_LOW);
                   end
        endcase
      end
    end
  endfunction


  // print_msg_object
  // ----------------

  function void print_msg_object(uvm_object lhs, uvm_object rhs);
    result++;
    if(result <= show_max) begin
      uvm_report_info("MISCMP", 
        $sformatf("Miscompare for %0s: lhs = @%0d : rhs = @%0d", 
        uvm_object::__m_uvm_status_container.scope.get(), (lhs!=null ? lhs.get_inst_id() : 0), (rhs != null ? rhs.get_inst_id() : 0)), verbosity);
    end
    $swrite(miscompares, "%s%s: lhs = @%0d : rhs = @%0d",
        miscompares, uvm_object::__m_uvm_status_container.scope.get(), (lhs != null ? lhs.get_inst_id() : 0), (rhs != null ? rhs.get_inst_id() : 0));
  endfunction



  // init ??

  static function uvm_comparer init();
    if(uvm_default_comparer==null) uvm_default_comparer=new;
    return uvm_default_comparer;
  endfunction

 
  int depth;                      //current depth of objects
  uvm_copy_map compare_map = new; //mapping of rhs to lhs objects
  uvm_scope_stack scope    = new;

endclass

