📄 sc_module.cpp
字号:
/***************************************************************************** The following code is derived, directly or indirectly, from the SystemC source code Copyright (c) 1996-2006 by all Contributors. All Rights reserved. The contents of this file are subject to the restrictions and limitations set forth in the SystemC Open Source License Version 2.4 (the "License"); You may not use this file except in compliance with such restrictions and limitations. You may obtain instructions on how to receive a copy of the License at http://www.systemc.org/. Software distributed by Contributors under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. *****************************************************************************//***************************************************************************** sc_module.cpp -- Base class of all sequential and combinational processes. Original Author: Stan Y. Liao, Synopsys, Inc. *****************************************************************************//***************************************************************************** MODIFICATION LOG - modifiers, enter your name, affiliation, date and changes you are making here. Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. Description of Modification: - Implementation of operator() and operator, positional connection method. - Implementation of error checking in operator<<'s. - Implementation of the function test_module_prm. - Implementation of set_stack_size(). Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003 Description of Modification: Inherit from sc_process_host Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems, 25 August, 2003 Description of Modification: dont_initialize() uses sc_get_last_created_process_handle() instead of sc_get_current_process_b() Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 25 Mar 2003 Description of Modification: Fixed bug in SC_NEW, see comments on ~sc_module_dynalloc_list below. *****************************************************************************/// $Log: sc_module.cpp,v $// Revision 1.1.1.1 2006/12/15 20:31:37 acg// SystemC 2.2//// Revision 1.8 2006/03/21 00:00:34 acg// Andy Goodrich: changed name of sc_get_current_process_base() to be// sc_get_current_process_b() since its returning an sc_process_b instance.//// Revision 1.7 2006/03/14 23:56:58 acg// Andy Goodrich: This fixes a bug when an exception is thrown in// sc_module::sc_module() for a dynamically allocated sc_module// object. We are calling sc_module::end_module() on a module that has// already been deleted. The scenario runs like this://// a) the sc_module constructor is entered// b) the exception is thrown// c) the exception processor deletes the storage for the sc_module// d) the stack is unrolled causing the sc_module_name instance to be deleted// e) ~sc_module_name() calls end_module() with its pointer to the sc_module// f) because the sc_module has been deleted its storage is corrupted,// either by linking it to a free space chain, or by reuse of some sort// g) the m_simc field is garbage// h) the m_object_manager field is also garbage// i) an exception occurs//// This does not happen for automatic sc_module instances since the// storage for the module is not reclaimed its just part of the stack.//// I am fixing this by having the destructor for sc_module clear the// module pointer in its sc_module_name instance. That cuts things at// step (e) above, since the pointer will be null if the module has// already been deleted. To make sure the module stack is okay, I call// end-module() in ~sc_module in the case where there is an// sc_module_name pointer lying around.//// Revision 1.6 2006/01/26 21:04:54 acg// Andy Goodrich: deprecation message changes and additional messages.//// Revision 1.5 2006/01/25 00:31:19 acg// Andy Goodrich: Changed over to use a standard message id of// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.//// Revision 1.4 2006/01/24 20:49:05 acg// Andy Goodrich: changes to remove the use of deprecated features within the// simulator, and to issue warning messages when deprecated features are used.//// Revision 1.3 2006/01/13 18:44:29 acg// Added $Log to record CVS changes into the source.//#include <cassert>#include <math.h>#include <stdio.h>#include "sysc/kernel/sc_event.h"#include "sysc/kernel/sc_kernel_ids.h"#include "sysc/kernel/sc_macros_int.h"#include "sysc/kernel/sc_module.h"#include "sysc/kernel/sc_module_registry.h"#include "sysc/kernel/sc_name_gen.h"#include "sysc/kernel/sc_object_manager.h"#include "sysc/kernel/sc_process.h"#include "sysc/kernel/sc_process_handle.h"#include "sysc/kernel/sc_simcontext.h"#include "sysc/kernel/sc_simcontext_int.h"#include "sysc/kernel/sc_reset.h"#include "sysc/communication/sc_communication_ids.h"#include "sysc/communication/sc_interface.h"#include "sysc/communication/sc_port.h"#include "sysc/communication/sc_signal.h"#include "sysc/communication/sc_signal_ports.h"#include "sysc/utils/sc_utils_ids.h"#include "sysc/utils/sc_iostream.h"namespace sc_core {// ----------------------------------------------------------------------------// CLASS : sc_module_dynalloc_list//// Garbage collection for modules dynamically allocated with SC_NEW.// ----------------------------------------------------------------------------class sc_module_dynalloc_list{public: sc_module_dynalloc_list() {} ~sc_module_dynalloc_list(); void add( sc_module* p ) { m_list.push_back( p ); }private: sc_plist<sc_module*> m_list;};//------------------------------------------------------------------------------//"~sc_module_dynalloc_list"//// Note we clear the m_parent field for the module being deleted. This because// we process the list front to back so the parent has already been deleted, // and we don't want ~sc_object() to try to access the parent which may // contain garbage.//------------------------------------------------------------------------------sc_module_dynalloc_list::~sc_module_dynalloc_list(){ sc_plist<sc_module*>::iterator it( m_list ); while( ! it.empty() ) { (*it)->m_parent = 0; delete *it; it ++; }}// ----------------------------------------------------------------------------sc_module*sc_module_dynalloc( sc_module* module_ ){ static sc_module_dynalloc_list dynalloc_list; dynalloc_list.add( module_ ); return module_;}// ----------------------------------------------------------------------------// STRUCT : sc_bind_proxy//// Struct for temporarily storing a pointer to an interface or port.// Used for positional binding.// ---------------------------------------------------------------------------- sc_bind_proxy::sc_bind_proxy(): iface( 0 ), port( 0 ){}sc_bind_proxy::sc_bind_proxy( sc_interface& iface_ ): iface( &iface_ ), port( 0 ){}sc_bind_proxy::sc_bind_proxy( sc_port_base& port_ ): iface( 0 ), port( &port_ ){}const sc_bind_proxy SC_BIND_PROXY_NIL;// ----------------------------------------------------------------------------// CLASS : sc_module//// Base class for all structural entities.// ----------------------------------------------------------------------------voidsc_module::sc_module_init(){ simcontext()->hierarchy_push( this ); m_end_module_called = false; m_module_name_p = 0; m_port_vec = new std::vector<sc_port_base*>; m_port_index = 0; m_name_gen = new sc_name_gen; simcontext()->get_module_registry()->insert( *this );}sc_module::sc_module( const char* nm ): sc_object(nm), sensitive(this), sensitive_pos(this), sensitive_neg(this){ sc_module_init();}/* * This form of the constructor assumes that the user has * used an sc_module_name parameter for his/her constructor. * That parameter object has been pushed onto the stack, * and can be looked up by calling the * top_of_module_name_stack() function of the object manager. * This technique has two advantages: * * 1) The user no longer has to write sc_module(name) in the * constructor initializer. * 2) The user no longer has to call end_module() at the end * of the constructor -- a common negligence. * * But it is important to note that sc_module_name may be used * in the user's constructor's parameter. If it is used anywhere * else, unexpected things will happen. The error-checking * mechanism builtin here cannot hope to catch all misuses. * */sc_module::sc_module(): sc_object(::sc_core::sc_get_curr_simcontext() ->get_object_manager() ->top_of_module_name_stack() ->operator const char*()), sensitive(this), sensitive_pos(this), sensitive_neg(this){ /* When this form is used, we better have a fresh sc_module_name on the top of the stack */ sc_module_name* mod_name = simcontext()->get_object_manager()->top_of_module_name_stack(); if (0 == mod_name || 0 != mod_name->m_module_p) SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 ); sc_module_init(); mod_name->set_module( this ); m_module_name_p = mod_name; // must come after sc_module_init call.}sc_module::sc_module( const sc_module_name& ): sc_object(::sc_core::sc_get_curr_simcontext() ->get_object_manager() ->top_of_module_name_stack() ->operator const char*()), sensitive(this), sensitive_pos(this), sensitive_neg(this){ /* For those used to the old style of passing a name to sc_module, this constructor will reduce the chance of making a mistake */ /* When this form is used, we better have a fresh sc_module_name on the top of the stack */ sc_module_name* mod_name = simcontext()->get_object_manager()->top_of_module_name_stack(); if (0 == mod_name || 0 != mod_name->m_module_p) SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 ); sc_module_init(); mod_name->set_module( this ); m_module_name_p = mod_name; // must come after sc_module_init call.}sc_module::sc_module( const std::string& s ): sc_object( s.c_str() ), sensitive(this), sensitive_pos(this), sensitive_neg(this){ sc_module_init();}sc_module::~sc_module(){ delete m_port_vec; delete m_name_gen; if ( m_module_name_p ) { m_module_name_p->clear_module( this ); // must be before end_module() end_module(); } simcontext()->get_module_registry()->remove( *this );}const ::std::vector<sc_object*>&sc_module::get_child_objects() const{ return m_child_objects;}voidsc_module::add_child_object( sc_object* object_ ){ // no check if object_ is already in the set m_child_objects.push_back( object_ );}voidsc_module::remove_child_object( sc_object* object_ ){ int size = m_child_objects.size(); for( int i = 0; i < size; ++ i ) { if( object_ == m_child_objects[i] ) { m_child_objects[i] = m_child_objects[size - 1]; m_child_objects.resize(size-1); return; } } // no check if object_ is really in the set}voidsc_module::end_module(){ if( ! m_end_module_called ) { /* TBD: Can check here to alert the user that end_module was not called for a previous module. */ (void)sc_get_curr_simcontext()->hierarchy_pop(); sc_get_curr_simcontext()->reset_curr_proc(); sensitive.reset(); sensitive_pos.reset(); sensitive_neg.reset(); m_end_module_called = true; m_module_name_p = 0; // make sure we are not called in ~sc_module(). }}// to prevent initialization for SC_METHODs and SC_THREADsvoidsc_module::dont_initialize(){ sc_process_handle last_proc = sc_get_last_created_process_handle(); last_proc.dont_initialize( true );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -