ovm_object.sv

Go to the documentation of this file.
00001 // $Id: a00245.html,v 1.1 2009/01/07 19:30:01 alex.marin Exp $
00002 //----------------------------------------------------------------------
00003 //   Copyright 2007-2008 Mentor Graphics Corporation
00004 //   Copyright 2007-2008 Cadence Design Systems, Inc.
00005 //   All Rights Reserved Worldwide
00006 //
00007 //   Licensed under the Apache License, Version 2.0 (the
00008 //   "License"); you may not use this file except in
00009 //   compliance with the License.  You may obtain a copy of
00010 //   the License at
00011 //
00012 //       http://www.apache.org/licenses/LICENSE-2.0
00013 //
00014 //   Unless required by applicable law or agreed to in
00015 //   writing, software distributed under the License is
00016 //   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00017 //   CONDITIONS OF ANY KIND, either express or implied.  See
00018 //   the License for the specific language governing
00019 //   permissions and limitations under the License.
00020 //----------------------------------------------------------------------
00021 
00022 `include "base/ovm_misc.svh"
00023 `include "base/ovm_object.svh"
00024 `include "base/ovm_object_globals.svh"
00025 `include "base/ovm_printer.svh"
00026 `include "base/ovm_packer.svh"
00027 typedef class ovm_component;
00028 
00029 //----------------------------------------------------------------------------
00030 //
00031 // CLASS: ovm_object
00032 //
00033 //----------------------------------------------------------------------------
00034 
00035 
00036 // new
00037 // ---
00038 
00039 function ovm_object::new (string name="");
00040 
00041   m_inst_id = m_inst_count++;
00042   m_leaf_name = name;
00043   m_field_automation (null, OVM_CHECK_FIELDS, "");
00044 endfunction
00045 
00046 
00047 // reseed
00048 // ------
00049 
00050 function void ovm_object::reseed ();
00051   if(use_ovm_seeding)
00052     this.srandom(ovm_create_random_seed(get_type_name(), get_full_name()));
00053 endfunction
00054 
00055 
00056 // get type
00057 // --------
00058 
00059 function ovm_object_wrapper ovm_object::get_type();
00060   ovm_report_error("NOTYPID", "get_type not implemented in derived class.");
00061   return null;
00062 endfunction
00063 
00064 
00065 // get inst_id
00066 // -----------
00067 
00068 function int ovm_object::get_inst_id();
00069   return m_inst_id;
00070 endfunction
00071 
00072 
00073 // get inst_count
00074 // --------------
00075 
00076 function int ovm_object::get_inst_count();
00077   return m_inst_count;
00078 endfunction
00079 
00080 
00081 // get_name
00082 // --------
00083 
00084 function string ovm_object::get_name ();
00085   return m_leaf_name;
00086 endfunction
00087 
00088 
00089 // get_full_name
00090 // -------------
00091 
00092 function string ovm_object::get_full_name ();
00093   return get_name();
00094 endfunction
00095 
00096 
00097 // set_name
00098 // --------
00099 
00100 function void ovm_object::set_name (string name);
00101   m_leaf_name = name;
00102 endfunction
00103 
00104 
00105 // print 
00106 // -----
00107  
00108 function void ovm_object::print(ovm_printer printer=null);
00109   if(printer==null)
00110     printer = ovm_default_printer;
00111 
00112   if(printer.istop()) begin
00113     printer.print_object(get_name(), this);
00114   end
00115   else begin
00116     //do m_field_automation here so user doesn't need to call anything to get
00117     //automation.
00118     ovm_auto_options_object.printer = printer;
00119     m_field_automation(null, OVM_PRINT, "");
00120     //call user override
00121     do_print(printer);
00122   end
00123 endfunction
00124 
00125 
00126 // sprint
00127 // ------
00128 
00129 function string ovm_object::sprint(ovm_printer printer=null);
00130   bit p;
00131 
00132   if(printer==null)
00133     printer = ovm_default_printer;
00134 
00135   p = printer.knobs.sprint;
00136   printer.knobs.sprint = 1;
00137 
00138   print(printer);
00139 
00140   printer.knobs.sprint = p;  //revert back to regular printing
00141   return printer.m_string;
00142 endfunction
00143 
00144 
00145 // do_sprint (virtual)
00146 // ---------
00147 
00148 function string ovm_object::do_sprint(ovm_printer printer);
00149   if(!printer.knobs.sprint) begin
00150     ovm_report_error("SPNSTR", "do_sprint called without string option set for printer");
00151     return "";
00152   end
00153   do_print(printer);
00154   return printer.m_string; 
00155 endfunction
00156 
00157 // print_field_match (static)
00158 // -----------------
00159 
00160 function void ovm_object::print_field_match(string fnc, string match);
00161   string scratch;
00162 
00163   if(m_sc.save_last_field)
00164     m_sc.last_field = m_sc.get_full_scope_arg();
00165 
00166   if(print_matches) begin
00167     int style;
00168     scratch = {
00169       fnc, ": Matched string ", match, " to field ", m_sc.get_full_scope_arg()
00170     };
00171     ovm_report_info("STRMTC", scratch, OVM_LOW);
00172   end
00173 endfunction
00174 
00175 // set
00176 // ---
00177 
00178 function void  ovm_object::set_int_local (string      field_name,
00179                                           ovm_bitstream_t value,
00180                                           bit         recurse=1);
00181   if(m_sc.scope.in_hierarchy(this)) return;
00182 
00183   this.m_sc.status = 0;
00184   this.m_sc.bitstream = value;
00185 
00186   m_field_automation(null, OVM_SETINT, field_name);
00187 
00188   if(m_sc.warning && !this.m_sc.status) begin
00189     ovm_report_error("NOMTC", $psprintf("did not find a match for field %s", field_name));
00190   end
00191 
00192 endfunction
00193 
00194 
00195 // set_object_local
00196 // ----------------
00197 
00198 function void  ovm_object::set_object_local (string     field_name,
00199                                              ovm_object value,
00200                                              bit        clone=1,
00201                                              bit        recurse=1);
00202   ovm_object cc;
00203   if(m_sc.scope.in_hierarchy(this)) return;
00204 
00205   if(clone && (value!=null)) begin 
00206     cc = value.clone();
00207     if(cc != null) cc.set_name(field_name); 
00208     value = cc; 
00209   end 
00210 
00211   this.m_sc.status = 0;
00212   this.m_sc.object = value;
00213   ovm_auto_options_object.clone = clone;
00214 
00215   m_field_automation(null, OVM_SETOBJ, field_name);
00216 
00217   if(m_sc.warning && !this.m_sc.status) begin
00218     ovm_report_error("NOMTC", $psprintf("did not find a match for field %s", field_name));
00219   end
00220 
00221 endfunction
00222 
00223 
00224 // set_string_local
00225 // ----------------
00226 function void  ovm_object::set_string_local (string field_name,
00227                                              string value,
00228                                              bit    recurse=1);
00229   if(m_sc.scope.in_hierarchy(this)) return;
00230   this.m_sc.status = 0;
00231   this.m_sc.stringv = value;
00232 
00233   m_field_automation(null, OVM_SETSTR, field_name);
00234 
00235   if(m_sc.warning && !this.m_sc.status) begin
00236 `ifdef INCA
00237     ovm_report_error("NOMTC", $psprintf("did not find a match for field %s (@%0d)", field_name, this));
00238 `else
00239     ovm_report_error("NOMTC", $psprintf("did not find a match for field %s", field_name));
00240 `endif
00241   end
00242 endfunction
00243 
00244 
00245 // m_do_set (static)
00246 // ------------
00247 
00248 // function m_do_set (match, arg, lhs, what, flag)
00249 //   Precondition:
00250 //     match     -- a match string to test against arg to do the set
00251 //     arg       -- the name of the short name of the lhs object
00252 //     lhs       -- the lhs to do on (left hand side)
00253 //     what      -- integer, what to do
00254 //     flag      -- object flags
00255 //
00256 //     ovm_object::m_sc.bitstream -- rhs object used for set/get
00257 //     ovm_object::m_sc.status        -- return status for set/get calls
00258 //
00259 
00260 
00261 function int ovm_object::m_do_set (string match,
00262                                        string arg,
00263                                        inout ovm_bitstream_t lhs, 
00264                                        input int what,
00265                                        int flag);
00266 
00267   bit matched;
00268 
00269   if (what < OVM_START_FUNCS || what > OVM_END_FUNCS)
00270      return 0;
00271 
00272   matched = ovm_is_match(match, m_sc.scope.get_arg());
00273 
00274   case (what)
00275     OVM_SETINT:
00276       begin
00277         if(matched) begin
00278           if(flag &OVM_READONLY) begin
00279             ovm_report_warning("RDONLY", $psprintf("Readonly argument match %s is ignored", 
00280                m_sc.get_full_scope_arg()));
00281             return 0;
00282           end
00283           print_field_match("set_int()", match);
00284           lhs = ovm_object::m_sc.bitstream;
00285           ovm_object::m_sc.status = 1;
00286           return 1;
00287         end
00288       end
00289     default:
00290       begin
00291         if(matched) begin
00292           ovm_report_warning("MTCTYP", $psprintf("matched integral field %s, ", 
00293           m_sc.get_full_scope_arg(),
00294           "but expected a non-integral type"));
00295         end
00296       end
00297   endcase
00298   return 0;
00299 endfunction
00300 
00301 
00302 // m_do_set_string (static)
00303 // -------------------
00304 
00305 // function m_do_set_string (match, arg, lhs, what, flag)
00306 //   Precondition:
00307 //     match     -- a match string to test against arg to do the set
00308 //     arg       -- the name of the short name of the lhs object
00309 //     lhs       -- the lhs to do get or set on (left hand side)
00310 //     what      -- integer, what to do
00311 //     flag      -- object flags
00312 //
00313 //     ovm_object::m_sc.stringv    -- rhs object used for set/get
00314 //     ovm_object::m_sc.status        -- return status for set/get calls
00315 //
00316 
00317 function int ovm_object::m_do_set_string(string match,
00318                                              string arg,
00319                                              inout string lhs, 
00320                                              input int what,
00321                                              int flag);
00322 
00323   bit matched;
00324   string s;
00325 
00326   if (what < OVM_START_FUNCS || what > OVM_END_FUNCS)
00327      return 0;
00328 
00329   matched = ovm_is_match(match, m_sc.scope.get_arg());
00330 
00331   case (what)
00332     OVM_SETSTR:
00333       begin
00334         if(matched) begin
00335           if(flag &OVM_READONLY) begin
00336             ovm_report_warning("RDONLY", $psprintf("Readonly argument match %s is ignored", 
00337                m_sc.get_full_scope_arg()));
00338             return 0;
00339           end
00340           print_field_match("set_string()", match);
00341           lhs = ovm_object::m_sc.stringv;
00342           ovm_object::m_sc.status = 1;
00343           return 1;
00344         end
00345       end
00346     default:
00347       begin
00348         if(matched) begin
00349           ovm_report_warning("MTCTYP", $psprintf("matched string field %s, ", 
00350           m_sc.get_full_scope_arg(),
00351           "but expected a non-string type"));
00352         end
00353       end
00354   endcase
00355   return 0;
00356 endfunction
00357 
00358 
00359 // m_do_set_object (static)
00360 // -----------------
00361 
00362 // function m_do_set_object (match, arg, lhsobj, what, flag)
00363 //   Precondition:
00364 //     match     -- a match string to test against arg to do the set
00365 //     arg       -- the name of the short name of the lhs object
00366 //     lhsobj    -- the object to do set_object on (left hand side)
00367 //     what      -- integer, what to do
00368 //     flag      -- object flags
00369 //
00370 //     ovm_object::m_sc.object -- rhs object used for set
00371 //     ovm_object::m_sc.status     -- return status for set/get calls. set
00372 //       always returns 0.
00373 //
00374 //   Postcondition:
00375 //     Performs the set or get operation on an object. If the object doesn't
00376 //     match then the object is recursed. The get* operations return true if
00377 //     an index was returned. The set* always return 0.
00378 
00379 function int ovm_object::m_do_set_object (string match,
00380                                             string arg,
00381                                             inout ovm_object lhsobj, 
00382                                             input int what,
00383                                                   int flag);
00384 
00385   bit matched;
00386   bit prev;
00387 
00388   if (what < OVM_START_FUNCS || what > OVM_END_FUNCS)
00389      return 0;
00390 
00391   matched = ovm_is_match(match, m_sc.scope.get_arg());
00392 
00393   case (what)
00394     OVM_SETOBJ:
00395       begin
00396         if(matched) begin
00397           if(flag &OVM_READONLY) begin
00398             ovm_report_warning("RDONLY", $psprintf("Readonly argument match %s is ignored", 
00399                m_sc.get_full_scope_arg()));
00400             return 0;
00401           end
00402           print_field_match("set_object()", match);
00403           lhsobj = ovm_object::m_sc.object;
00404           ovm_object::m_sc.status = 1;
00405         end
00406         else if(lhsobj==null) return 0;
00407         if(flag &OVM_READONLY) 
00408           return 0; 
00409         lhsobj.m_field_automation(null, OVM_SETOBJ, match);
00410         return ovm_object::m_sc.status;
00411       end
00412   endcase
00413 
00414   if(matched) begin
00415     ovm_report_warning("MTCTYP", $psprintf("matched object field %s, ", 
00416           m_sc.get_full_scope_arg(),
00417           "but expected a non-object type"));
00418   end
00419   if(lhsobj==null) return 0;
00420   lhsobj.m_field_automation(null, what, match);
00421 
00422   return ovm_object::m_sc.status;
00423 
00424 endfunction
00425 
00426 // clone
00427 // -----
00428 
00429 function ovm_object ovm_object::clone();
00430   ovm_object tmp;
00431   tmp = this.create(get_name());
00432   if(tmp == null) begin
00433 //    ovm_report_warning("CRFLD", $psprintf("The create method failed for %s,  object will be copied using shallow copy", get_name()));
00434 //    tmp = new this;
00435     ovm_report_warning("CRFLD", $psprintf("The create method failed for %s,  object cannot be cloned", get_name()));
00436   end
00437   else begin
00438     tmp.copy(this);
00439   end
00440 
00441   return(tmp);
00442 endfunction
00443 
00444 
00445 // copy
00446 // ----
00447 
00448 ovm_copy_map ovm_global_copy_map = new;
00449 function void ovm_object::copy (ovm_object rhs);
00450   //For cycle checking
00451   static int depth;
00452   if((rhs !=null)  && (ovm_global_copy_map.get(rhs) != null)) begin
00453     return;
00454   end
00455 
00456   if(rhs==null) begin
00457     ovm_report_warning("NULLCP", "A null object was supplied to copy; copy is ignored");
00458     return;
00459   end
00460 
00461   ovm_global_copy_map.set(rhs, this); 
00462   ++depth;
00463 
00464   do_copy(rhs);
00465   m_field_automation(rhs, OVM_COPY, "");
00466 
00467   --depth;
00468   if(depth==0) begin
00469     ovm_global_copy_map.clear();
00470   end
00471 endfunction
00472 
00473 
00474 // do_copy
00475 // -------
00476 
00477 function void ovm_object::do_copy (ovm_object rhs);
00478   return;
00479 endfunction
00480 
00481 
00482 // compare
00483 // -------
00484 
00485 function void ovm_comparer::print_msg(string msg);
00486   result++;
00487   if(result <= show_max) begin
00488      msg = {"Miscompare for ", scope.get_arg(), ": ", msg};
00489      ovm_report_info("MISCMP", msg, OVM_LOW);
00490   end
00491   miscompares = { miscompares, scope.get_arg(), ": ", msg, "\n" };
00492 endfunction
00493 
00494 //Need this funciton because sformat doesn't support objects
00495 function void ovm_comparer::print_rollup(ovm_object rhs, ovm_object lhs);
00496   string msg;
00497   if(scope.depth() == 0) begin
00498     if(result && (show_max || (sev != OVM_INFO))) begin
00499       if(show_max < result) 
00500          $swrite(msg, "%0d Miscompare(s) (%0d shown) for object ",
00501            result, show_max);
00502       else
00503          $swrite(msg, "%0d Miscompare(s) for object ", result);
00504 
00505       case (sev)
00506 `ifdef INCA
00507         OVM_WARNING: begin 
00508                    ovm_report_warning("MISCMP", $psprintf("%s%s@%0d vs. %s@%0d", msg,
00509                       lhs.get_name(), lhs, rhs.get_name(), rhs));
00510                  end
00511         OVM_ERROR: begin 
00512                    ovm_report_error("MISCMP", $psprintf("%s%s@%0d vs. %s@%0d", msg,
00513                       lhs.get_name(), lhs, rhs.get_name(), rhs));
00514                  end
00515         default: begin 
00516                    ovm_report_info("MISCMP", $psprintf("%s%s@%0d vs. %s@%0d", msg,
00517                       lhs.get_name(), lhs, rhs.get_name(), rhs), OVM_LOW);
00518                  end
00519 `else
00520         OVM_WARNING: begin 
00521                    ovm_report_warning("MISCMP", $psprintf("%s%s vs. %s", msg,
00522                       lhs.get_name(), rhs.get_name()));
00523                  end
00524         OVM_ERROR: begin 
00525                    ovm_report_error("MISCMP", $psprintf("%s%s vs. %s", msg,
00526                       lhs.get_name(), rhs.get_name()));
00527                  end
00528         default: begin 
00529                    ovm_report_info("MISCMP", $psprintf("%s%s vs. %s", msg,
00530                       lhs.get_name(), rhs.get_name()), OVM_LOW);
00531                  end
00532 `endif
00533       endcase
00534     end
00535   end
00536 endfunction
00537 
00538 function void ovm_comparer::print_msg_object(ovm_object lhs, ovm_object rhs);
00539   result++;
00540 `ifdef INCA
00541   if(result <= show_max) begin
00542     ovm_report_info("MISCMP", 
00543       $psprintf("Miscompare for %0s: lhs = @%0d : rhs = @%0d", 
00544       scope.get_arg(), lhs, rhs), verbosity);
00545   end
00546   $swrite(miscompares, "%s%s: lhs = @%0d : rhs = @%0d",
00547       miscompares, scope.get_arg(), lhs, rhs);
00548 `else
00549   if(result <= show_max) begin
00550     ovm_report_info("MISCMP", 
00551       $psprintf("Miscompare for %0s",
00552       scope.get_arg()), verbosity);
00553   end
00554   $swrite(miscompares, "%s%s:",
00555       miscompares, scope.get_arg());
00556 `endif
00557 endfunction
00558 
00559 function ovm_status_container ovm_object::init_status();
00560   if(m_sc==null) m_sc=new;
00561   return m_sc;
00562 endfunction
00563 
00564 function bit  ovm_object::compare (ovm_object rhs,
00565                                    ovm_comparer comparer=null);
00566   bit t, dc;
00567   static int style;
00568   bit done;
00569   done = 0;
00570   if(comparer != null) 
00571     ovm_auto_options_object.comparer = comparer;
00572   else 
00573     ovm_auto_options_object.comparer = ovm_default_comparer;
00574   comparer = ovm_auto_options_object.comparer;
00575 
00576   if(!m_sc.scope.depth()) begin
00577     comparer.compare_map.clear();
00578     comparer.result = 0;
00579     comparer.miscompares = "";
00580     comparer.scope = m_sc.scope;
00581     if(get_name() == "") begin
00582       m_sc.scope.down("<object>", this);
00583     end
00584     else
00585       m_sc.scope.down(this.get_name(), this);
00586   end
00587   if(!done && (rhs == null)) begin
00588     if(m_sc.scope.depth()) begin
00589       comparer.print_msg_object(this, rhs);
00590     end
00591     else begin
00592       comparer.print_msg_object(this, rhs);
00593 `ifdef INCA
00594       ovm_report_info("MISCMP",
00595            $psprintf("%0d Miscompare(s) for object %s@%0d vs. @%0d", 
00596            comparer.result, get_name(), this, rhs), ovm_auto_options_object.comparer.verbosity);
00597 `else
00598       ovm_report_info("MISCMP",
00599            $psprintf("%0d Miscompare(s) for object %s", 
00600            comparer.result, get_name()), ovm_auto_options_object.comparer.verbosity);
00601 `endif
00602       done = 1;
00603     end
00604   end
00605 
00606   if(!done && (comparer.compare_map.get(rhs) != null)) begin
00607     if(comparer.compare_map.get(rhs) != this) begin
00608       comparer.print_msg_object(this, comparer.compare_map.get(rhs));
00609     end 
00610     done = 1;  //don't do any more work after this case, but do cleanup
00611   end
00612 
00613   if(!done && comparer.check_type && get_type_name() != rhs.get_type_name()) begin
00614     m_sc.stringv = { "lhs type = \"", get_type_name(), 
00615                      "\" : rhs type = \"", rhs.get_type_name(), "\""};
00616     comparer.print_msg(m_sc.stringv);
00617   end
00618 
00619   if(!done) begin
00620     comparer.compare_map.set(rhs, this);
00621     m_field_automation(rhs, OVM_COMPARE, "");
00622     dc = do_compare(rhs, comparer);
00623   end
00624 
00625   if(m_sc.scope.depth() == 1)  begin
00626     m_sc.scope.up(this);
00627   end
00628 
00629   comparer.print_rollup(this, rhs);
00630   return (comparer.result == 0 && dc == 1);
00631 endfunction
00632 
00633 
00634 // do_compare
00635 // ----------
00636 
00637 function bit  ovm_object::do_compare (ovm_object rhs,
00638                                       ovm_comparer comparer);
00639   return 1;
00640 endfunction
00641 
00642 
00643 // m_field_automation
00644 // --------------
00645 
00646 function void ovm_object::m_field_automation ( ovm_object tmp_data__,
00647                                              int        what__,
00648                                              string     str__ );
00649   return;
00650 endfunction
00651 
00652 
00653 // check_fields
00654 // ------------
00655 
00656 function void ovm_object::m_do_field_check(string field);
00657   if(m_field_array.exists(field) && (m_field_array[field] == 1)) begin
00658     ovm_report_error("MLTFLD", $psprintf("Field %s is defined multiple times in type %s",
00659        field, get_type_name()));
00660   end
00661   m_field_array[field]++; 
00662 endfunction
00663 
00664 
00665 // do_print (virtual override)
00666 // ------------
00667 
00668 function void ovm_object::do_print(ovm_printer printer);
00669   return;
00670 endfunction
00671 
00672 
00673 // m_pack
00674 // ------
00675 
00676 function void ovm_object::m_pack (inout ovm_packer packer);
00677 
00678   if(packer!=null) 
00679     ovm_auto_options_object.packer = packer;
00680   else  
00681     ovm_auto_options_object.packer = ovm_default_packer;
00682   packer = ovm_auto_options_object.packer;
00683 
00684   packer.reset();
00685   packer.scope.down(get_name(), this);
00686 
00687   m_field_automation(null, OVM_PACK, "");
00688   do_pack(packer);
00689 
00690   packer.set_packed_size();
00691 
00692   packer.scope.up(this); 
00693 
00694 endfunction
00695   
00696 
00697 // pack
00698 // ---- 
00699   
00700 function int ovm_object::pack (ref bit bitstream [],
00701                                input ovm_packer packer =null );
00702   m_pack(packer);
00703   packer.get_bits(bitstream);
00704   return packer.get_packed_size();
00705 endfunction
00706 
00707 // pack_bytes
00708 // ----------
00709 
00710 function int ovm_object::pack_bytes (ref byte unsigned bytestream [],
00711                                      input ovm_packer packer=null );
00712   m_pack(packer);
00713   packer.get_bytes(bytestream);
00714   return packer.get_packed_size();
00715 endfunction
00716 
00717 
00718 // pack_ints
00719 // ---------
00720 
00721 function int ovm_object::pack_ints (ref int unsigned intstream [],
00722                                     input ovm_packer packer=null );
00723   m_pack(packer);
00724   packer.get_ints(intstream);
00725   return packer.get_packed_size();
00726 endfunction
00727 
00728 
00729 // do_pack
00730 // -------
00731 
00732 function void ovm_object::do_pack (ovm_packer packer );
00733   return;
00734 endfunction
00735 
00736 
00737 // m_unpack_pre
00738 // ------------
00739   
00740 function void ovm_object::m_unpack_pre (inout ovm_packer packer);
00741   if(packer!=null)
00742     ovm_auto_options_object.packer = packer;
00743   else
00744     ovm_auto_options_object.packer = ovm_default_packer;
00745   packer = ovm_auto_options_object.packer;
00746   packer.reset();
00747 endfunction
00748   
00749 
00750 // m_unpack_post
00751 // -------------
00752 
00753 function void ovm_object::m_unpack_post (ovm_packer packer);
00754 
00755   int provided_size; 
00756 
00757   provided_size = packer.get_packed_size();
00758 
00759   //Put this object into the hierarchy
00760   packer.scope.down(get_name(), this);
00761 
00762   m_field_automation(null, OVM_UNPACK, "");
00763 
00764   do_unpack(packer);
00765 
00766   //Scope back up before leaving
00767   packer.scope.up(this);
00768 
00769   if(packer.get_packed_size() != provided_size) begin
00770     ovm_report_warning("BDUNPK", $psprintf("Unpack operation unsuccessful: unpacked %0d bits from a total of %0d bits", packer.get_packed_size(), provided_size));
00771   end
00772 
00773 endfunction
00774 
00775 
00776 // unpack
00777 // ------
00778 
00779 function int ovm_object::unpack (ref    bit        bitstream [],
00780                                  input  ovm_packer packer=null);
00781   m_unpack_pre(packer);
00782   packer.put_bits(bitstream);
00783   m_unpack_post(packer);
00784   return packer.get_packed_size();
00785 endfunction
00786 
00787 // unpack_bytes
00788 // ------------
00789 
00790 function int ovm_object::unpack_bytes (ref    byte unsigned bytestream [],
00791                                        input  ovm_packer packer=null);
00792   m_unpack_pre(packer);
00793   packer.put_bytes(bytestream);
00794   m_unpack_post(packer);
00795   return packer.get_packed_size();
00796 endfunction
00797 
00798 
00799 // unpack_ints
00800 // -----------
00801   
00802 function int ovm_object::unpack_ints (ref    int unsigned intstream [],
00803                                       input  ovm_packer packer=null);
00804   m_unpack_pre(packer);
00805   packer.put_ints(intstream);
00806   m_unpack_post(packer);
00807   return packer.get_packed_size();
00808 endfunction
00809 
00810 
00811 // do_unpack
00812 // ---------
00813 
00814 function void ovm_object::do_unpack (ovm_packer packer);
00815   return;
00816 endfunction
00817 
00818 
00819 // record
00820 // ------
00821 
00822 function void ovm_object::record (ovm_recorder recorder=null);
00823 //mxg  if(!recorder) 
00824   if(recorder == null) 
00825     recorder = ovm_default_recorder;
00826 
00827   if(!recorder.tr_handle) return;
00828 
00829   ovm_auto_options_object.recorder = recorder;
00830   recorder.recording_depth++;
00831 
00832   m_field_automation(null, OVM_RECORD, "");
00833   do_record(recorder);
00834 
00835   recorder.recording_depth--;
00836 
00837   if(recorder.recording_depth==0) begin
00838     recorder.tr_handle = 0;
00839   end
00840 endfunction
00841 
00842 
00843 // do_record (virtual)
00844 // ---------
00845 
00846 function void ovm_object::do_record (ovm_recorder recorder);
00847   return;
00848 endfunction
00849 
00850 
00851 // m_get_function_type (static)
00852 // -------------------
00853 
00854 function string ovm_object::m_get_function_type (int what);
00855   case (what)
00856     OVM_COPY:              return "copy";
00857     OVM_COMPARE:           return "compare";
00858     OVM_PRINT:             return "print";
00859     OVM_RECORD:            return "record";
00860     OVM_PACK:              return "pack";
00861     OVM_UNPACK:            return "unpack";
00862     OVM_FLAGS:             return "get_flags";
00863     OVM_SETINT:            return "set";
00864     OVM_SETOBJ:            return "set_object";
00865     OVM_SETSTR:            return "set_string";
00866     default:           return "unknown";
00867   endcase
00868 endfunction
00869 
00870 
00871 // m_get_report_object
00872 // -------------------
00873 
00874 function ovm_report_object ovm_object::m_get_report_object();
00875   return null;
00876 endfunction
00877 
00878 
00879 // m_record_field_object (static)
00880 // ---------------------
00881 
00882 function void ovm_object::m_record_field_object (string arg,
00883                                                ovm_object value,
00884                                                ovm_recorder recorder =null,
00885                                                int flag = OVM_DEFAULT);
00886   begin
00887     if(!recorder)
00888       recorder=ovm_auto_options_object.recorder;
00889 
00890     if((flag&OVM_NORECORD) != 0) return;
00891 
00892     recorder.record_object(arg, value);
00893 
00894   end
00895 endfunction
00896 
00897 
00898 // m_do_data (static)
00899 // ---------
00900 
00901 // function m_do_data (arg, lhs, rhs, what, flag)
00902 //   Precondition:
00903 //     arg       -- the name of the short name of the lhs object
00904 //     lhs       -- the lhs to do work on (left hand side)
00905 //     lhs       -- the rhs to do work from (right hand side)
00906 //     what      -- integer, what to do
00907 //     flag      -- object flags
00908 
00909 function int ovm_object::m_do_data (string arg,
00910                                   inout ovm_bitstream_t lhs,
00911                                   input ovm_bitstream_t rhs,
00912                                         int what,
00913                                         int bits,
00914                                         int flag);
00915 
00916 
00917   if (what > OVM_END_DATA_EXTRA)
00918      return 0;
00919 
00920   if(bits > OVM_STREAMBITS) begin
00921     ovm_report_warning("FLDTNC",$psprintf("%s is %0d bits; maximum field size is %0d, truncating",
00922                  arg, bits, OVM_STREAMBITS));
00923   end
00924   case (what)
00925     OVM_COPY:
00926       begin
00927         if(((flag)&OVM_NOCOPY) == 0) begin
00928           ovm_bitstream_t mask;
00929           mask = -1;
00930           mask >>= (OVM_STREAMBITS-bits);
00931           lhs = rhs & mask;
00932         end
00933         return 0;
00934       end
00935     OVM_COMPARE:
00936       begin
00937         if(((flag)&OVM_NOCOMPARE) == 0) begin
00938           bit r;
00939           if(bits <= 64)
00940             r = ovm_auto_options_object.comparer.compare_field_int(arg, lhs, rhs, bits, ovm_radix_enum'(flag&OVM_RADIX));
00941           else
00942             r = ovm_auto_options_object.comparer.compare_field(arg, lhs, rhs, bits, ovm_radix_enum'(flag&OVM_RADIX));
00943         end
00944         return 0;
00945       end
00946     OVM_PACK:
00947       begin
00948         if(((flag)&OVM_NOPACK) == 0) begin
00949           if(((flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.abstract) ||
00950              (!(flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.physical)) begin
00951             if(bits<=64)
00952               ovm_auto_options_object.packer.pack_field_int(lhs, bits);
00953             else
00954               ovm_auto_options_object.packer.pack_field(lhs, bits);
00955           end
00956         end
00957         return 0;
00958       end
00959     OVM_UNPACK:
00960       begin
00961         if(((flag)&OVM_NOPACK) == 0) begin
00962           if(((flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.abstract) ||
00963              (!(flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.physical)) begin
00964             if(bits<=64)
00965               lhs=ovm_auto_options_object.packer.unpack_field_int(bits);
00966             else
00967               lhs=ovm_auto_options_object.packer.unpack_field(bits);
00968           end
00969         end
00970         return 0;
00971       end
00972     OVM_PRINT:
00973       begin
00974         if(((flag)&OVM_NOPRINT) == 0) 
00975         begin  
00976           ovm_printer printer; 
00977           ovm_radix_enum radix;
00978           radix = ovm_radix_enum'(flag&OVM_RADIX);
00979           printer = ovm_auto_options_object.printer; 
00980           printer.print_field(arg, lhs, bits, radix);
00981         end
00982       end
00983     OVM_RECORD:
00984       begin
00985         if(((flag)&OVM_NORECORD) == 0) 
00986         begin 
00987           integer h;
00988           ovm_radix_enum radix;
00989 
00990           if(m_sc.scope.depth()) arg = m_sc.scope.get_arg();
00991           radix = ovm_radix_enum'(flag&OVM_RADIX);
00992           ovm_auto_options_object.recorder.record_field(arg, lhs, bits, radix);
00993         end 
00994       end
00995   endcase
00996   return 0;
00997 endfunction
00998 
00999 
01000 // m_do_data_object (static)
01001 // ----------------
01002 
01003 // function m_do_data_object (arg, lhs, rhs, what, flag)
01004 //   Precondition:
01005 //     arg       -- the name of the short name of the lhs object
01006 //     lhs       -- the lhs to do work on (left hand side)
01007 //     lhs       -- the rhs to do work from (right hand side)
01008 //     what      -- integer, what to do
01009 //     flag      -- object flags
01010 
01011 function int ovm_object::m_do_data_object (string arg,
01012                                        inout ovm_object lhs,
01013                                        input ovm_object rhs,
01014                                              int what,
01015                                              int flag);
01016 
01017   ovm_object lhs_obj;
01018 
01019   if (what > OVM_END_DATA_EXTRA)
01020      return 0;
01021 
01022   case (what)
01023     OVM_COPY:
01024       begin
01025         int rval;
01026         if(((flag)&OVM_NOCOPY) != 0) begin
01027           return 0;
01028         end
01029         if(rhs == null) begin
01030           lhs = null;
01031           return OVM_REFERENCE;
01032         end
01033 
01034         if(flag & OVM_SHALLOW) begin
01035           rval = OVM_SHALLOW;
01036         end
01037         else if(flag & OVM_REFERENCE) begin
01038           lhs = rhs;
01039           rval = OVM_REFERENCE;
01040         end
01041         else  //deepcopy
01042         begin
01043           ovm_object v;
01044           v = ovm_global_copy_map.get(rhs);
01045           if(v) begin
01046             lhs = v;
01047             rval = OVM_REFERENCE;
01048           end
01049           else if(lhs==null) begin
01050             lhs = rhs.clone();
01051             lhs.set_name(arg);
01052             rval = OVM_REFERENCE;
01053           end
01054           else if(rhs == null) begin
01055             rval = OVM_REFERENCE;
01056           end
01057           else begin
01058             //lhs doesn't change for this case, so don't need to copy back
01059             lhs.copy(rhs);
01060              rval = 0;
01061           end
01062         end
01063         return rval;
01064       end
01065     OVM_COMPARE:
01066       begin
01067         bit refcmp;
01068 
01069         if(((flag)&OVM_NOCOMPARE) != 0) begin
01070           return 0;
01071         end
01072 
01073         //if the object are the same then don't need to do a deep compare
01074         if(rhs == lhs) return 0;
01075 
01076         refcmp = (flag & OVM_SHALLOW) && !(ovm_auto_options_object.comparer.policy == OVM_DEEP);
01077 
01078         //do a deep compare here 
01079         if(!refcmp && !(ovm_auto_options_object.comparer.policy == OVM_REFERENCE))
01080         begin
01081           if(((rhs == null) && (lhs != null)) || ((lhs==null) && (rhs!=null))) begin
01082             ovm_auto_options_object.comparer.print_msg_object(lhs, rhs);
01083             return 1;  //miscompare
01084           end
01085           if((rhs == null) && (lhs==null))
01086             return 0;
01087           else begin
01088             bit r;
01089             r = lhs.compare(rhs, ovm_auto_options_object.comparer);
01090             if(r == 0) begin
01091               return 1;
01092             end
01093             else begin
01094               return 0;
01095             end
01096           end
01097         end
01098         else begin //reference compare
01099           if(lhs != rhs) begin
01100             ovm_auto_options_object.comparer.print_msg_object(lhs, rhs);
01101             return 1;
01102           end
01103         end
01104       end
01105     OVM_PACK:
01106       begin
01107         if(((flag&OVM_NOPACK) == 0) && ((flag&OVM_REFERENCE)==0)) begin
01108           if(((flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.abstract) ||
01109              (!(flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.physical)) begin
01110             ovm_auto_options_object.packer.pack_object(lhs);
01111           end
01112         end
01113         return 0;
01114       end
01115     OVM_UNPACK:
01116       begin
01117         if(((flag&OVM_NOPACK) == 0) && ((flag&OVM_REFERENCE)==0)) begin
01118           if(((flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.abstract) ||
01119              (!(flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.physical)) begin
01120           ovm_auto_options_object.packer.unpack_object_ext(lhs);
01121           end
01122         end
01123         return 0;
01124       end
01125     OVM_PRINT:
01126       begin
01127         if(((flag)&OVM_NOPRINT) == 0) 
01128         begin  
01129           if(((flag)&OVM_REFERENCE) || (lhs == null)) begin
01130             int d;
01131             d = ovm_auto_options_object.printer.knobs.depth;
01132             ovm_auto_options_object.printer.knobs.depth = 0;
01133             ovm_auto_options_object.printer.print_object(arg, lhs);
01134             ovm_auto_options_object.printer.knobs.depth = d;
01135           end
01136           else begin
01137             ovm_component obj;
01138             if(lhs != null) begin
01139               if($cast(obj,lhs)) begin 
01140                 if(ovm_auto_options_object.printer.m_scope.current() == obj.get_parent() )
01141                   ovm_auto_options_object.printer.print_object(arg, lhs);
01142                 else
01143                   ovm_auto_options_object.printer.print_object_header(arg, lhs);
01144               end
01145               else begin
01146                 ovm_auto_options_object.printer.print_object(arg, lhs);
01147               end
01148             end
01149           end
01150         end
01151       end
01152     OVM_RECORD:
01153       begin
01154         if(((flag)&OVM_NORECORD) == 0) 
01155         begin 
01156           //If refernce is on then don't want to do cycle check since only
01157           //recording the reference.
01158           if((flag)&OVM_REFERENCE != 0) 
01159             m_record_field_object(arg, lhs, ovm_auto_options_object.recorder,flag);
01160           else begin
01161             if(m_sc.scope.in_hierarchy(lhs)) return 0;
01162             m_record_field_object(arg, lhs, ovm_auto_options_object.recorder,flag);
01163           end
01164         end 
01165       end
01166   endcase
01167   return 0;
01168 endfunction
01169 
01170 
01171 // m_do_data_string (static)
01172 // ----------------
01173 
01174 // function m_do_data_string (arg, lhs, rhs, what, flag)
01175 //   Precondition:
01176 //     arg       -- the name of the short name of the lhs object
01177 //     lhs       -- the lhs to do work on (left hand side)
01178 //     lhs       -- the rhs to do work from (right hand side)
01179 //     what      -- integer, what to do
01180 //     flag      -- object flags
01181 //
01182 
01183 function int ovm_object::m_do_data_string(string arg,
01184                                       inout string lhs,
01185                                       input string rhs,
01186                                             int what,
01187                                             int flag);
01188 
01189 
01190   if (what > OVM_END_DATA_EXTRA)
01191      return 0;
01192 
01193   case (what)
01194     OVM_COPY:
01195       begin
01196         if(((flag)&OVM_NOCOPY) == 0) begin
01197           lhs = rhs;
01198         end
01199         return 0;
01200       end
01201     OVM_COMPARE:
01202       begin
01203         if(((flag)&OVM_NOCOMPARE) == 0) begin
01204           if(lhs != rhs) begin
01205             m_sc.stringv = { "lhs = \"", lhs, "\" : rhs = \"", rhs, "\""};
01206             ovm_auto_options_object.comparer.print_msg(m_sc.stringv);
01207             return 1;
01208           end
01209         end
01210         return 0;
01211       end
01212     OVM_PACK:
01213       begin 
01214         if(((flag)&OVM_NOPACK) == 0) begin
01215           if(((flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.abstract) ||
01216              (!(flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.physical)) begin
01217           ovm_auto_options_object.packer.pack_string(lhs);
01218           end
01219         end
01220         return 0;
01221       end
01222     OVM_UNPACK:
01223       begin
01224         if(((flag)&OVM_NOPACK) == 0) begin
01225           if(((flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.abstract) ||
01226              (!(flag&OVM_ABSTRACT) && ovm_auto_options_object.packer.physical)) begin
01227           lhs = ovm_auto_options_object.packer.unpack_string();
01228           end
01229         end
01230         return 0;
01231       end
01232     OVM_PRINT:
01233       begin
01234         if(((flag)&OVM_NOPRINT) == 0) 
01235         begin  
01236           ovm_auto_options_object.printer.print_string(arg, lhs);
01237         end
01238       end
01239     OVM_RECORD:
01240       begin
01241         if(((flag)&OVM_NORECORD) == 0) 
01242         begin 
01243           ovm_auto_options_object.recorder.record_string(arg, lhs);
01244         end 
01245       end
01246   endcase
01247   return 0;
01248 
01249 endfunction
01250 
01251 
01252 //-----------------------------------------------------------------------------
01253 //
01254 // ovm_status_container
01255 //
01256 //-----------------------------------------------------------------------------
01257 
01258 function string ovm_status_container::get_full_scope_arg ();
01259   get_full_scope_arg = scope.get_arg();
01260 endfunction
01261 
01262 function ovm_scope_stack ovm_status_container::init_scope();
01263   if(scope==null) scope=new;
01264   return scope;
01265 endfunction
01266 
01267 //-----------------------------------------------------------------------------
01268 //
01269 // ovm_options_container
01270 //
01271 //-----------------------------------------------------------------------------
01272 
01273 ovm_options_container ovm_auto_options_object = ovm_options_container::init();
01274 
01275 function ovm_options_container::new();
01276   comparer = ovm_default_comparer;
01277   packer   = ovm_default_packer;
01278   recorder = ovm_default_recorder;
01279   printer  = ovm_default_printer;
01280 endfunction
01281 
01282 function ovm_options_container ovm_options_container::init();
01283   if(ovm_auto_options_object==null) ovm_auto_options_object=new;
01284   return ovm_auto_options_object;
01285 endfunction
01286 
01287 //-----------------------------------------------------------------------------
01288 //
01289 // ovm_recorder
01290 //
01291 //-----------------------------------------------------------------------------
01292 
01293 function void ovm_recorder::record_field   (string      name, 
01294                                             ovm_bitstream_t value, 
01295                                             int         size, 
01296                                             ovm_radix_enum  radix=OVM_NORADIX);
01297   if(tr_handle==0) return;
01298   scope.set_arg(name);
01299 
01300   if(!radix)
01301     radix = default_radix;
01302 
01303   case(radix)
01304     OVM_BIN:     ovm_set_attribute_by_name(tr_handle, scope.get_arg(), value, "'b",size);
01305     OVM_OCT:     ovm_set_attribute_by_name(tr_handle, scope.get_arg(), value, "'o",size);
01306     OVM_DEC:     ovm_set_attribute_by_name(tr_handle, scope.get_arg(), value, "'s",size);
01307     OVM_TIME:    ovm_set_attribute_by_name(tr_handle, scope.get_arg(), value, "'u",size);
01308     OVM_STRING:  ovm_set_attribute_by_name(tr_handle, scope.get_arg(), value, "'a",size);
01309     default: ovm_set_attribute_by_name(tr_handle, scope.get_arg(), value, "'x",size);
01310   endcase
01311 endfunction
01312 
01313 function void ovm_recorder::record_object  (string      name,
01314                                             ovm_object  value);
01315   int v;
01316   string str; 
01317 
01318   if(scope.in_hierarchy(value)) return;
01319 
01320   if(identifier) begin 
01321 `ifdef INCA
01322     $swrite(str, "%0d", value);
01323 `else
01324     str = "";
01325 `endif
01326     v = str.atoi(); 
01327     scope.set_arg(name);
01328     ovm_set_attribute_by_name(tr_handle, scope.get_arg(), v, "'s");
01329   end
01330   
01331   if(policy != OVM_REFERENCE) begin
01332     if(value!=null) begin
01333       scope.down(name, value);
01334       value.record(this);
01335       scope.up(value);
01336     end
01337   end
01338 endfunction
01339 
01340 function void ovm_recorder::record_string  (string      name,
01341                                             string      value);
01342   scope.set_arg(name);
01343   ovm_set_attribute_by_name(tr_handle, scope.get_arg(), ovm_string_to_bits(value), "'a");
01344 endfunction
01345 
01346 function void ovm_recorder::record_time    (string      name,
01347                                             time        value); 
01348   record_field(name, value, 64, OVM_TIME); 
01349 endfunction
01350 
01351 function void ovm_recorder::record_generic (string      name, 
01352                                             string      value);
01353   record_string(name, value);
01354 endfunction
01355 
01356 
01357 //-----------------------------------------------------------------------------
01358 //
01359 // ovm_comparer
01360 //
01361 //-----------------------------------------------------------------------------
01362 
01363 function bit  ovm_comparer::compare_field  (string      name, 
01364                                             ovm_bitstream_t lhs, 
01365                                             ovm_bitstream_t rhs, 
01366                                             int         size,
01367                                             ovm_radix_enum  radix=OVM_NORADIX); 
01368   ovm_bitstream_t mask;
01369   string msg;
01370 
01371   if(size <= 64)
01372     return compare_field_int(name, lhs, rhs, size, radix);
01373 
01374   mask = -1;
01375   mask >>= (OVM_STREAMBITS-size);
01376   if((lhs & mask) !== (rhs & mask)) begin
01377     scope.set_arg(name);
01378     case (radix)
01379       OVM_BIN: begin
01380             $swrite(msg, "lhs = 'b%0b : rhs = 'b%0b", 
01381                      lhs&mask, rhs&mask);
01382            end
01383       OVM_OCT: begin
01384             $swrite(msg, "lhs = 'o%0o : rhs = 'o%0o", 
01385                      lhs&mask, rhs&mask);
01386            end
01387       OVM_DEC: begin
01388             $swrite(msg, "lhs = %0d : rhs = %0d", 
01389                      lhs&mask, rhs&mask);
01390            end
01391       OVM_TIME: begin
01392           $swrite(msg, "lhs = %0t : rhs = %0t", 
01393              lhs&mask, rhs&mask);
01394       end
01395       OVM_STRING: begin
01396             $swrite(msg, "lhs = %0s : rhs = %0s", 
01397                      lhs&mask, rhs&mask);
01398            end
01399       OVM_ENUM: begin
01400             //Printed as decimal, user should cuse compare string for enum val
01401             $swrite(msg, "lhs = %0d : rhs = %0d", 
01402                      lhs&mask, rhs&mask);
01403             end
01404       default: begin
01405             $swrite(msg, "lhs = 'h%0x : rhs = 'h%0x", 
01406                      lhs&mask, rhs&mask);
01407            end
01408     endcase
01409     print_msg(msg);
01410     return 0;
01411   end
01412   return 1;
01413 endfunction
01414 
01415 function bit  ovm_comparer::compare_field_int  (string      name, 
01416                                             logic [63:0] lhs, 
01417                                             logic [63:0] rhs, 
01418                                             int         size,
01419                                             ovm_radix_enum  radix=OVM_NORADIX); 
01420   logic [63:0] mask;
01421   string msg;
01422 
01423   mask = -1;
01424   mask >>= (64-size);
01425   if((lhs & mask) !== (rhs & mask)) begin
01426     scope.set_arg(name);
01427     case (radix)
01428       OVM_BIN: begin
01429             $swrite(msg, "lhs = 'b%0b : rhs = 'b%0b", 
01430                      lhs&mask, rhs&mask);
01431            end
01432       OVM_OCT: begin
01433             $swrite(msg, "lhs = 'o%0o : rhs = 'o%0o", 
01434                      lhs&mask, rhs&mask);
01435            end
01436       OVM_DEC: begin
01437             $swrite(msg, "lhs = %0d : rhs = %0d", 
01438                      lhs&mask, rhs&mask);
01439            end
01440       OVM_TIME: begin
01441           $swrite(msg, "lhs = %0t : rhs = %0t", 
01442              lhs&mask, rhs&mask);
01443       end
01444       OVM_STRING: begin
01445             $swrite(msg, "lhs = %0s : rhs = %0s", 
01446                      lhs&mask, rhs&mask);
01447            end
01448       OVM_ENUM: begin
01449             //Printed as decimal, user should cuse compare string for enum val
01450             $swrite(msg, "lhs = %0d : rhs = %0d", 
01451                      lhs&mask, rhs&mask);
01452             end
01453       default: begin
01454             $swrite(msg, "lhs = 'h%0x : rhs = 'h%0x", 
01455                      lhs&mask, rhs&mask);
01456            end
01457     endcase
01458     print_msg(msg);
01459     return 0;
01460   end
01461   return 1;
01462 endfunction
01463 
01464 
01465 function bit  ovm_comparer::compare_object (string      name,
01466                                             ovm_object  lhs,
01467                                             ovm_object  rhs);
01468 
01469   if (rhs == lhs)
01470     return 1;
01471 
01472   if (policy == OVM_REFERENCE && lhs != rhs) begin
01473     scope.set_arg(name);
01474     print_msg_object(lhs, rhs);
01475     return 0;
01476   end
01477 
01478   if (rhs == null || lhs == null) begin
01479     scope.set_arg(name);
01480     print_msg_object(lhs, rhs);
01481     return 0;  //miscompare
01482   end
01483 
01484   scope.down(name, null);
01485   compare_object = lhs.compare(rhs, this);
01486   scope.up(null);
01487 
01488 endfunction
01489 
01490 function bit  ovm_comparer::compare_string (string      name,
01491                                             string      lhs,
01492                                             string      rhs);
01493   string msg;
01494   if(lhs != rhs) begin
01495     scope.set_arg(name);
01496     msg = { "lhs = \"", lhs, "\" : rhs = \"", rhs, "\""};
01497     print_msg(msg);
01498     return 0;
01499   end
01500   return 1;
01501 endfunction
01502 
01503 function ovm_comparer ovm_comparer::init();
01504   if(ovm_default_comparer==null) ovm_default_comparer=new;
01505   return ovm_default_comparer;
01506 endfunction

Intelligent Design Verification
Intelligent Design Verification
Project: OVM, Revision: 2.0.1
Copyright (c) 2008 Intelligent Design Verification.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included here:
http://www.intelligentdv.com/licenses/fdl.txt
doxygen
Doxygen Version: 1.5.5
Wed Jan 7 19:27:18 2009
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV