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

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:23:30 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV