ovm_factory.sv

Go to the documentation of this file.
00001 // $Id: ovm_factory.sv 3 2008-03-05 03:07:32Z 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_factory.svh"
00023 `include "base/ovm_object.svh"
00024 
00025 
00026 // create
00027 // ------
00028 
00029 function ovm_object ovm_factory::create (string name="");
00030   ovm_factory f; f=new(name);
00031   return f; 
00032 endfunction
00033 
00034 // new
00035 // ---
00036 
00037 function ovm_factory::new (string name="");
00038     super.new (name);
00039     if(inst==null)
00040       inst = this;
00041 endfunction
00042 
00043 
00044 // auto_register (static)
00045 // -------------
00046 
00047 function void ovm_factory::auto_register (ovm_object_wrapper obj);
00048 
00049   if (inst==null) begin
00050     inst = new ("ovm_factory_inst");
00051   end
00052   inst.auto_register_type(obj);
00053 
00054 endfunction
00055 
00056 
00057 // auto_register_type
00058 // ------------------
00059 
00060 function void ovm_factory::auto_register_type (ovm_object_wrapper obj);
00061 
00062   if (types.exists(obj.get_type_name())) begin
00063     ovm_report_warning("TPRGED", $psprintf("Type ''%0s", obj.get_type_name(),
00064                  "' already registered with factory. Support for same ",
00065                  "type names in different scopes not implemented."));
00066     return;
00067   end
00068 
00069   types[obj.get_type_name()] = obj;
00070   
00071 endfunction
00072 
00073 // print_all_overrides
00074 // -------------------
00075 
00076 function void  ovm_factory::print_all_overrides (bit all_types=0);
00077   if(inst==null) inst = new;
00078   inst.m_print_all_overrides(all_types);
00079 endfunction
00080 
00081 function void  ovm_factory::m_print_all_overrides (bit all_types=0);
00082   ovm_factory_override t_ov[$];
00083   string no_ov[$];
00084   string key;
00085 
00086   if(type_overrides.first(key)) begin
00087     do begin
00088       t_ov.push_back(type_overrides[key]);
00089     end while(type_overrides.next(key));
00090   end
00091   if(all_types && types.first(key)) begin
00092     do begin
00093       if(!type_overrides.exists(key) && 
00094          !ovm_is_match("ovm_*", types[key].get_type_name()) )
00095       begin
00096         no_ov.push_back(types[key].get_type_name());
00097       end
00098     end while(types.next(key));
00099   end
00100 
00101   $display("#### Factory Overrides");
00102 
00103   if(!t_ov.size() && !inst_overrides.size()) begin
00104     $display("  No overrides exist in the factory");
00105   end
00106 
00107   if(inst_overrides.size()) begin
00108     string s;
00109     $display("Instance Overrides");
00110     $display("  Requested Type Name       Instance Path                       Override Type");
00111     $display("  -------------------------------------------------------------------------------------");
00112     for(int i=0; i<inst_overrides.size(); ++i) begin
00113       s = {"  ",inst_overrides[i].req_type_name};
00114       if(s.len() > 25) begin 
00115         s = s.substr(0,24);
00116         s[24] = "+";
00117       end
00118       else 
00119         for(int i=s.len(); i<=25; ++i) 
00120           s = {s," "};
00121       $write(s);
00122       s = {"  ",inst_overrides[i].inst_path};
00123       if(s.len() > 35) begin 
00124         s = s.substr(0,34);
00125         s[34] = "+";
00126       end
00127       else 
00128         for(int i=s.len(); i<=35; ++i) 
00129           s = {s," "};
00130       $write(s);
00131       s = {"  ", inst_overrides[i].type_name};
00132       if(s.len() > 25) begin 
00133         s = s.substr(0,24);
00134         s[24] = "+";
00135       end
00136       else 
00137         for(int i=s.len(); i<=25; ++i) 
00138           s = {s," "};
00139       $display(s);
00140     end
00141   end
00142   else if(t_ov.size()) begin
00143     $display("No Instance Overrides");
00144   end
00145   $display("");
00146   if(t_ov.size()) begin
00147     string s;
00148     $display("Type Overrides");
00149     $display("  Requested Type Name       Override Type");
00150     $display("  --------------------------------------------------");
00151     for(int i=0; i<t_ov.size(); ++i) begin
00152       s = {"  ",t_ov[i].req_type_name};
00153       if(s.len() > 25) begin 
00154         s = s.substr(0,24);
00155         s[24] = "+";
00156       end
00157       else 
00158         for(int i=s.len(); i<=25; ++i) 
00159           s = {s," "};
00160       $write(s);
00161       s = {"  ", t_ov[i].type_name};
00162       if(s.len() > 25) begin 
00163         s = s.substr(0,24);
00164         s[24] = "+";
00165       end
00166       else 
00167         for(int i=s.len(); i<=25; ++i) 
00168           s = {s," "};
00169       $display(s);
00170     end
00171   end
00172   if(no_ov.size()) begin
00173     $display("Additional Types in the factory (no type override)");
00174     $display("  Type Name");
00175     $display("  -------------------------");
00176     for(int i=0; i<no_ov.size(); ++i) begin
00177       $display("  ", no_ov[i]);
00178     end
00179   end
00180   $display("####");
00181 endfunction
00182 
00183 // print_override_info
00184 // -------------------
00185 
00186 function void  ovm_factory::print_override_info (string lookup_str,
00187                                                  string inst_path="",
00188                                                  string inst_name="");
00189   if(inst==null) inst = new;
00190   inst.m_print_override_info(lookup_str, inst_path, inst_name);
00191 endfunction
00192 
00193 function void  ovm_factory::m_print_override_info (string lookup_str,
00194                                                  string inst_path,
00195                                                  string inst_name);
00196  
00197   ovm_factory_override i_ov[$];
00198   ovm_factory_override t_ov;
00199   bit match;
00200   bit first_inst;
00201   
00202   for (int index=0; index < inst_overrides.size(); index++) begin
00203     if (inst_name != "") begin
00204       if (ovm_is_match(inst_overrides[index].inst_path,
00205                    {inst_path,".",inst_name}))
00206         i_ov.push_back(inst_overrides[index]);
00207     end
00208     else if (ovm_is_match(inst_overrides[index].inst_path, {inst_path})) begin
00209         i_ov.push_back(inst_overrides[index]);
00210     end
00211   end 
00212 
00213   t_ov = type_overrides[type_overrides[lookup_str].type_name];
00214 
00215   first_inst = 0;
00216 
00217   $display("#### Factory creation information");
00218   $display("   Type name (lookup string): ", lookup_str);
00219   $display("   Instance path            : ", inst_path);
00220   $display("   Instance name            : ", inst_name);
00221   for(int i=0; i<i_ov.size(); ++i) begin
00222     if (ovm_is_match(i_ov[i].req_type_name, lookup_str)) 
00223       match = 1; 
00224     else
00225       match = 0;
00226     $write("   Instance override");
00227     if(match==0) $write(" (ignored because required type does ",
00228                         "not match requested type for the instance path)\n");
00229     else if(first_inst==1) $write(" (disabled do to previous instance override)\n");
00230     else $write(" (enabled)\n");
00231     $display("      Required type   -- ", i_ov[i].req_type_name);
00232     $display("      Override inst   -- ", i_ov[i].inst_path);
00233     $display("      Override type   -- ", i_ov[i].type_name);
00234     if(match)
00235       first_inst = 1;
00236   end
00237   if(type_overrides[lookup_str].type_name != lookup_str) begin
00238     $write("   Type override");
00239     if(first_inst) $write(" (disabled do to instance override)\n");
00240     else $write(" (enabled)\n");
00241     $display("      Required type -- ", lookup_str);
00242     $display("      Override type -- ", type_overrides[lookup_str].type_name);
00243   end
00244   $write("   Base type requested: ", lookup_str);
00245   if(i_ov.size()) $write(" (disabled do to instance override)\n");
00246   else if(type_overrides[lookup_str].type_name != lookup_str)
00247     $write(" (disabled do to type override)\n");
00248   $display("####");
00249 endfunction
00250 
00251 
00252 // override_type
00253 // -------------
00254 
00255 function void ovm_factory::override_type (string lookup_str,
00256                                           string type_name,
00257                                           string inst_path,
00258                                           bit replace=1);
00259   
00260   ovm_factory_override tmp;
00261 
00262   // check that type is registered with the factory
00263   if (!types.exists(type_name)) begin
00264     if (inst_path == "")
00265       ovm_report_fatal("TYPNTF", $psprintf("Cannot register type override '%0s' because the type it's supposed to produce, '%0s', is not registered with the factory.", lookup_str, type_name));
00266     else
00267       ovm_report_fatal("TYPNTF", $psprintf("Cannot register instance override '%0s' for instance '%s' because the type it's supposed to produce, '%0s', is not registered with the factory.", lookup_str, inst_path, type_name));
00268     return;
00269   end
00270 
00271   // check if an instance override
00272   if (inst_path != "") begin
00273     tmp = new(inst_path, lookup_str, type_name);
00274     inst_overrides.push_back(tmp);
00275     return;
00276   end
00277 
00278   // check if the lookup string already exists
00279   if (type_overrides.exists(lookup_str)) begin
00280 
00281     if (replace==1) begin
00282       m_sc.scratch1 = type_overrides[lookup_str].type_name;
00283     end
00284     else if (replace==0) begin
00285       m_sc.scratch1 = type_overrides[lookup_str].type_name;
00286       ovm_report_warning("TPREGD", $psprintf("Lookup string '%0s' already registered to produce '%0s'.  Set replace argument to replace existing entry.", lookup_str, m_sc.scratch1));
00287       return;
00288     end
00289   end
00290   else begin
00291   end
00292 
00293   tmp = new("", lookup_str, type_name);
00294 
00295   type_overrides[lookup_str] = tmp;
00296 
00297 endfunction
00298 
00299 
00300 // find_override
00301 // -------------
00302 
00303 function ovm_object_wrapper ovm_factory::find_override(string lookup_str,
00304                                                        string inst_path,
00305                                                        string inst_name);
00306 
00307   // First see if any instance-specific override; return first match
00308   for (int index=0; index < inst_overrides.size(); index++) begin
00309 
00310     if (ovm_is_match(inst_overrides[index].req_type_name, lookup_str)) begin
00311 
00312       if (inst_name != "") begin
00313 
00314         if (ovm_is_match(inst_overrides[index].inst_path,
00315                      {inst_path,".",inst_name}))
00316           return types[inst_overrides[index].type_name];
00317 
00318       end
00319       else if (ovm_is_match(inst_overrides[index].inst_path, {inst_path})) begin
00320 
00321         return types[inst_overrides[index].type_name];
00322 
00323       end
00324     end
00325   end 
00326 
00327   // Next, lookup simple overrides queue
00328   if (type_overrides.exists(lookup_str)) begin
00329     return types[type_overrides[lookup_str].type_name];
00330   end
00331 
00332   // No override found
00333   return null;
00334 
00335 endfunction
00336 
00337 
00338 // create_type
00339 // -----------
00340 
00341 function ovm_object ovm_factory::create_type (string     lookup_str,  
00342                                               string     inst_path="",  
00343                                               string     name=""); 
00344 
00345   ovm_object_wrapper wrapper;
00346 
00347   wrapper = find_override(lookup_str, inst_path, name);
00348 
00349   // no override exists, so use lookup_str directly
00350   if (wrapper==null) begin
00351     if(!types.exists(lookup_str)) begin
00352       ovm_report_warning("BDTYP",$psprintf("Cannot create an object based on lookup string '%0s'.  This type is not registered with the factory.", lookup_str));
00353       return null;
00354     end
00355     wrapper = types[lookup_str];
00356   end
00357 
00358   return wrapper.create_object(name);
00359 
00360 endfunction
00361 
00362 
00363 // create_component_type
00364 // ---------------------
00365 
00366 function ovm_component ovm_factory::create_component_type (string     lookup_str,  
00367                                               string     inst_path="",  
00368                                               string     name, 
00369                                               ovm_component   parent);
00370 
00371   ovm_object_wrapper wrapper;
00372 
00373   // no override exists, so use lookup_str directly
00374   wrapper = find_override(lookup_str, inst_path, name);
00375   if (wrapper == null) begin
00376     if(!types.exists(lookup_str)) begin 
00377       ovm_report_warning("BDTYP", $psprintf("Cannot create an object based on lookup string '%0s'.  This type is not registered with the factory.", lookup_str));
00378       return null;
00379     end
00380     else begin
00381       wrapper = types[lookup_str];
00382     end
00383   end
00384 
00385   return wrapper.create_component(name, parent);
00386 
00387 endfunction
00388 
00389 
00390 // create_object (static)
00391 // -------------
00392 
00393 function ovm_object ovm_factory::create_object (string     lookup_str,  
00394                                                 string     inst_path="", 
00395                                                 string     name="");
00396 
00397   if (inst==null)
00398     inst = new ("ovm_factory_inst");
00399 
00400   return inst.create_type(lookup_str, inst_path, name);
00401 
00402 endfunction
00403 
00404 
00405 // create_component (static)
00406 // ----------------
00407 
00408 function ovm_component ovm_factory::create_component (string lookup_str,  
00409                                             string   inst_path="", 
00410                                             string   name, 
00411                                             ovm_component parent);
00412 
00413   if (inst==null)
00414     inst = new ("ovm_factory_inst");
00415 
00416   create_component = inst.create_component_type(lookup_str, inst_path, name, parent);
00417 
00418 endfunction
00419 
00420 
00421 // set_type_override (static)
00422 // -----------------
00423 
00424 function void ovm_factory::set_type_override (string lookup_str,
00425                                               string type_name,
00426                                               bit replace=1);
00427   if (inst==null)
00428     inst = new ("ovm_factory_inst");
00429 
00430   inst.override_type (lookup_str, type_name, "", replace);
00431 
00432 endfunction
00433 
00434 
00435 // set_inst_override (static)
00436 // -----------------
00437 
00438 function void ovm_factory::set_inst_override (string inst_path,
00439                                               string lookup_str,
00440                                               string type_name);
00441 
00442   if (inst==null)
00443     inst = new ("ovm_factory_inst");
00444 
00445   inst.override_type (lookup_str, type_name, inst_path, 0);
00446 
00447 endfunction
00448 

Intelligent Design Verification
Intelligent Design Verification
Project: OVM, Revision: 1.0.1
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:16:37 2010
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV