ovm_object.sv

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

Intelligent Design Verification
Intelligent Design Verification
Project: OVM, Revision: 1.0.0
Copyright (c) 2008-2010 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.6.3
IDV SV Filter Version: 2.6.3
Sat Jun 19 11:08:58 2010
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV