ovm_object.sv

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

Intelligent Design Verification
Intelligent Design Verification
Project: OVM, Revision: 1.1.0
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.4.6
Mon Sep 29 14:20:12 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV