sc_object.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2006 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_object.cpp -- Abstract base class of all SystemC objects.
00021 
00022   Original Author: Stan Y. Liao, Synopsys, Inc.
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
00032                                25 August, 2003
00033   Description of Modification: if module name hierarchy is empty, sc_object 
00034                                ctor assumes the currently executing process 
00035                                as the parent object to support dynamic process
00036                                creation similar to other sc_objects
00037 
00038       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
00039                                5 September 2003
00040   Description of Modification: - Made creation of attributes structure
00041                                  conditional on its being used. This eliminates
00042                                  100 bytes of storage for each normal sc_object.
00043 
00044  *****************************************************************************/
00045 
00046 
00047 // $Log: sc_object.cpp,v $
00048 // Revision 1.1.1.1  2006/12/15 20:31:37  acg
00049 // SystemC 2.2
00050 //
00051 // Revision 1.4  2006/03/21 00:00:34  acg
00052 //   Andy Goodrich: changed name of sc_get_current_process_base() to be
00053 //   sc_get_current_process_b() since its returning an sc_process_b instance.
00054 //
00055 // Revision 1.3  2006/01/13 18:44:30  acg
00056 // Added $Log to record CVS changes into the source.
00057 //
00058 
00059 #include <stdio.h>
00060 #include <cstdlib>
00061 #include <cassert>
00062 #include <ctype.h>
00063 
00064 #include "sysc/kernel/sc_externs.h"
00065 #include "sysc/kernel/sc_kernel_ids.h"
00066 #include "sysc/kernel/sc_module.h"
00067 #include "sysc/kernel/sc_object.h"
00068 #include "sysc/kernel/sc_object_manager.h"
00069 #include "sysc/kernel/sc_process_handle.h"
00070 #include "sysc/kernel/sc_simcontext.h"
00071 #include "sysc/utils/sc_hash.h"
00072 #include "sysc/utils/sc_iostream.h"
00073 #include "sysc/utils/sc_list.h"
00074 #include "sysc/utils/sc_mempool.h"
00075 
00076 namespace sc_core {
00077 
00078 typedef int (*STRCMP)(const void*, const void*);
00079 
00080 const char SC_HIERARCHY_CHAR = '.';
00081 
00082 /* This will be gotten rid after multiple-processes
00083    are implemented.  This is to fix some regression
00084    problems. */
00085 bool sc_enable_name_checking = true;
00086 
00087 
00088 // ----------------------------------------------------------------------------
00089 //  CLASS : sc_object
00090 //
00091 //  Abstract base class of all SystemC `simulation' objects.
00092 // ----------------------------------------------------------------------------
00093 
00094 const char*
00095 sc_object::basename() const
00096 {
00097     const char* p = strrchr( m_name, SC_HIERARCHY_CHAR );
00098     return p ? (p + 1) : m_name;
00099 }
00100 
00101 void
00102 sc_object::print(::std::ostream& os) const
00103 {
00104     os << name();
00105 }
00106 
00107 void
00108 sc_object::dump(::std::ostream& os) const
00109 {
00110     os << "name = " << name() << "\n";
00111     os << "kind = " << kind() << "\n";
00112 }
00113 
00114 static int sc_object_num = 0;
00115 
00116 static char*
00117 sc_object_newname(char* name)
00118 {
00119     std::sprintf(name, "{%d}", sc_object_num);
00120     sc_object_num++;
00121     return name;
00122 }
00123 
00124 void 
00125 sc_object::sc_object_init(const char* nm) 
00126 { 
00127     bool        clash;                  // True if path name exists in obj table
00128     const char* leafname_p;             // Leaf name (this object) 
00129     char        pathname[BUFSIZ];       // Path name 
00130     char        pathname_orig[BUFSIZ];  // Original path name which may clash 
00131     const char* parentname_p;           // Parent path name 
00132     bool        put_in_table;           // True if should put in object table 
00133  
00134     // SET UP POINTERS TO OBJECT MANAGER, PARENT, AND SIMULATION CONTEXT: 
00135     //
00136     // Make the current simcontext the simcontext for this object 
00137 
00138     m_simc = sc_get_curr_simcontext(); 
00139     m_attr_cltn_p = 0; 
00140     sc_object_manager* object_manager = m_simc->get_object_manager(); 
00141     sc_object*         parent_p = object_manager->hierarchy_curr(); 
00142     if (!parent_p) { 
00143         sc_object* proc = (sc_object*)sc_get_current_process_b();
00144         parent_p = proc; 
00145     } 
00146     m_parent = parent_p; 
00147 
00148 
00149     // CONSTRUCT PATHNAME TO OBJECT BEING CREATED: 
00150     // 
00151     // If there is not a leaf name generate one. 
00152 
00153     parentname_p = parent_p ? parent_p->name() : ""; 
00154     if (nm && nm[0] ) 
00155     { 
00156         leafname_p = nm; 
00157         put_in_table = true; 
00158     } 
00159     else 
00160     { 
00161         leafname_p = sc_object_newname(pathname_orig); 
00162         put_in_table = false; 
00163     } 
00164     if (parent_p) { 
00165         std::sprintf(pathname, "%s%c%s", parentname_p, 
00166                 SC_HIERARCHY_CHAR, leafname_p 
00167         ); 
00168     } else { 
00169         strcpy(pathname, leafname_p); 
00170     } 
00171 
00172     // SAVE the original path name 
00173     // 
00174     strcpy(pathname_orig, pathname); 
00175 
00176     // MAKE SURE THE OBJECT NAME IS UNIQUE 
00177     // 
00178     // If not use unique name generator to make it unique. 
00179 
00180     clash = false; 
00181     while (object_manager->find_object(pathname)) { 
00182         clash = true; 
00183         leafname_p = sc_gen_unique_name(leafname_p); 
00184         if (parent_p) { 
00185             std::sprintf(pathname, "%s%c%s", parentname_p, 
00186                     SC_HIERARCHY_CHAR, leafname_p 
00187             ); 
00188         } else { 
00189             strcpy(pathname, leafname_p); 
00190         } 
00191     } 
00192     if (clash) { 
00193     std::string message = pathname_orig;
00194     message += ". Latter declaration will be renamed to ";
00195     message += pathname;
00196         SC_REPORT_WARNING( SC_ID_OBJECT_EXISTS_, message.c_str());
00197     } 
00198 
00199 
00200     // MOVE OBJECT NAME TO PERMANENT STORAGE 
00201     // 
00202     // Note here we pull a little trick -- use the first byte to store 
00203     // information about whether to put the object in the object table in the 
00204     // object manager 
00205 
00206     char* ptr = new char[strlen( pathname ) + 2]; 
00207     ptr[0] = put_in_table; 
00208     m_name = ptr + 1; 
00209     strcpy(m_name, pathname); 
00210 
00211     if (put_in_table) { 
00212         object_manager->insert_object(m_name, this); 
00213         sc_module* curr_module = m_simc->hierarchy_curr(); 
00214         if( curr_module != 0 ) { 
00215             curr_module->add_child_object( this ); 
00216         } else { 
00217             sc_process_b* curr_proc = sc_get_current_process_b();
00218             if (curr_proc) { 
00219                 curr_proc->add_child_object( this ); 
00220             } else { 
00221                 m_simc->add_child_object( this ); 
00222             } 
00223         } 
00224     } 
00225 } 
00226 
00227 sc_object::sc_object() : m_parent(0)
00228 {
00229     sc_object_init( sc_gen_unique_name("object") );
00230 }
00231 
00232 static bool
00233 object_name_illegal_char(char ch)
00234 {
00235     return (ch == SC_HIERARCHY_CHAR) || isspace(ch);
00236 }
00237 
00238 sc_object::sc_object(const char* nm) : m_parent(0)
00239 {
00240     int namebuf_alloc = 0;
00241     char* namebuf = 0;
00242     const char* p;
00243 
00244     // null name or "" uses machine generated name.
00245     if ( !nm || strlen(nm) == 0 )
00246     nm = sc_gen_unique_name("object");
00247     p = nm;
00248 
00249     if (nm && sc_enable_name_checking) {
00250         namebuf_alloc = 1 + strlen(nm);
00251         namebuf = (char*) sc_mempool::allocate(namebuf_alloc);
00252         char* q = namebuf;
00253         const char* r = nm;
00254         bool has_illegal_char = false;
00255         while (*r) {
00256             if (object_name_illegal_char(*r)) {
00257                 has_illegal_char = true;
00258                 *q = '_';
00259             } else {
00260                 *q = *r;
00261             }
00262             r++;
00263             q++;
00264         }
00265         *q = '\0';
00266         p = namebuf;
00267         if (has_illegal_char)
00268     {
00269         std::string message = nm;
00270         message += " substituted by ";
00271         message += namebuf;
00272             SC_REPORT_WARNING( SC_ID_ILLEGAL_CHARACTERS_, message.c_str());
00273     }
00274     }
00275     sc_object_init(p);
00276     sc_mempool::release( namebuf, namebuf_alloc );
00277 }
00278 
00279 sc_object::~sc_object()
00280 {
00281     if (m_name[-1] && m_simc) {
00282         sc_object_manager* object_manager = m_simc->get_object_manager();
00283         object_manager->remove_object(m_name);
00284 
00285         sc_module* parent_mod = DCAST<sc_module*>(m_parent);
00286         if (parent_mod) {
00287             parent_mod->remove_child_object( this );
00288         } else {
00289             sc_process_b* parent_proc = DCAST<sc_process_b*>(m_parent);
00290             if (parent_proc) {
00291                 parent_proc->remove_child_object( this );
00292             } else {
00293                 m_simc->remove_child_object( this );
00294             }
00295         }
00296     }
00297     delete [] (m_name-1);
00298     if ( m_attr_cltn_p ) delete m_attr_cltn_p;
00299 }
00300 
00301 void
00302 sc_object::trace( sc_trace_file * /* unused */) const
00303 {
00304     /* This space is intentionally left blank */
00305 }
00306 
00307 
00308 // add attribute
00309 
00310 bool
00311 sc_object::add_attribute( sc_attr_base& attribute_ )
00312 {
00313     if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00314     return ( m_attr_cltn_p->push_back( &attribute_ ) );
00315 }
00316 
00317 
00318 // get attribute by name
00319 
00320 sc_attr_base*
00321 sc_object::get_attribute( const std::string& name_ )
00322 {
00323     if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00324     return ( (*m_attr_cltn_p)[name_] );
00325 }
00326 
00327 const sc_attr_base*
00328 sc_object::get_attribute( const std::string& name_ ) const
00329 {
00330     if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00331     return ( (*m_attr_cltn_p)[name_] );
00332 }
00333 
00334 
00335 // remove attribute by name
00336 
00337 sc_attr_base*
00338 sc_object::remove_attribute( const std::string& name_ )
00339 {
00340     if ( m_attr_cltn_p )
00341     return ( m_attr_cltn_p->remove( name_ ) );
00342     else
00343     return 0;
00344 }
00345 
00346 
00347 // remove all attributes
00348 
00349 void
00350 sc_object::remove_all_attributes()
00351 {
00352     if ( m_attr_cltn_p )
00353     m_attr_cltn_p->remove_all();
00354 }
00355 
00356 
00357 // get the number of attributes
00358 
00359 int
00360 sc_object::num_attributes() const
00361 {
00362     if ( m_attr_cltn_p )
00363     return ( m_attr_cltn_p->size() );
00364     else
00365     return 0;
00366 }
00367 
00368 
00369 // get the attribute collection
00370 
00371 sc_attr_cltn&
00372 sc_object::attr_cltn()
00373 {
00374     if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00375     return *m_attr_cltn_p;
00376 }
00377 
00378 const sc_attr_cltn&
00379 sc_object::attr_cltn() const
00380 {
00381     if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00382     return *m_attr_cltn_p;
00383 }
00384 
00385 } // namespace sc_core

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5