1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_export.cpp --
23
24  Original Author: Bishnupriya Bhattachary, Cadence, Design Systems,
25                   25 August, 2003
26
27  CHANGE LOG IS AT THE END OF THE FILE
28 *****************************************************************************/
29
30#include "sysc/communication/sc_export.h"
31#include "sysc/kernel/sc_simcontext.h"
32#include "sysc/kernel/sc_module.h"
33#include "sysc/kernel/sc_object_int.h"
34
35namespace sc_core {
36
37// ----------------------------------------------------------------------------
38//  CLASS : sc_export_base
39//
40// ----------------------------------------------------------------------------
41
42sc_export_base::sc_export_base() : sc_object(sc_gen_unique_name("export"))
43{
44    simcontext()->get_export_registry()->insert(this);
45}
46
47sc_export_base::sc_export_base(const char* name_) : sc_object(name_)
48{
49    simcontext()->get_export_registry()->insert(this);
50}
51
52sc_export_base::~sc_export_base()
53{
54    simcontext()->get_export_registry()->remove(this);
55}
56
57// called by construction_done() (does nothing by default)
58
59void
60sc_export_base::before_end_of_elaboration()
61{
62}
63
64// called when construction is done
65
66void
67sc_export_base::construction_done()
68{
69    if ( get_interface() == 0 )
70    {
71      report_error( SC_ID_SC_EXPORT_NOT_BOUND_AFTER_CONSTRUCTION_, 0);
72    }
73
74    sc_module* parent = static_cast<sc_module*>( get_parent_object() );
75    sc_object::hierarchy_scope scope( parent );
76    before_end_of_elaboration();
77}
78
79// called by elaboration_done() (does nothing by default)
80
81void
82sc_export_base::end_of_elaboration()
83{}
84
85// called when elaboration is done
86
87void
88sc_export_base::elaboration_done()
89{
90    sc_module* parent = static_cast<sc_module*>( get_parent_object() );
91    sc_object::hierarchy_scope scope( parent );
92    end_of_elaboration();
93}
94
95// called by start_simulation (does nothing)
96
97void
98sc_export_base::start_of_simulation()
99{}
100
101// called before simulation starts
102
103void
104sc_export_base::start_simulation()
105{
106    sc_module* parent = static_cast<sc_module*>( get_parent_object() );
107    sc_object::hierarchy_scope scope( parent );
108    start_of_simulation();
109}
110
111// called by simulation_done (does nothing)
112
113void
114sc_export_base::end_of_simulation()
115{}
116
117// called after simulation ends
118
119void
120sc_export_base::simulation_done()
121{
122    sc_module* parent = static_cast<sc_module*>( get_parent_object() );
123    sc_object::hierarchy_scope scope( parent );
124    end_of_simulation();
125}
126
127void
128sc_export_base::report_error( const char* id, const char* add_msg ) const
129{
130    char msg[BUFSIZ];
131    if( add_msg != 0 ) {
132        std::sprintf( msg, "%s: export '%s' (%s)", add_msg, name(), kind() );
133    } else {
134        std::sprintf( msg, "export '%s' (%s)", name(), kind() );
135    }
136    SC_REPORT_ERROR( id, msg );
137}
138
139
140// ----------------------------------------------------------------------------
141//  CLASS : sc_export_registry
142//
143//  Registry for all exports.
144//  FOR INTERNAL USE ONLY!
145// ----------------------------------------------------------------------------
146
147void
148sc_export_registry::insert( sc_export_base* export_ )
149{
150    if( sc_is_running() ) {
151	export_->report_error(SC_ID_INSERT_EXPORT_, "simulation running");
152    }
153
154    if( m_simc->elaboration_done()  ) {
155       export_->report_error(SC_ID_INSERT_EXPORT_, "elaboration done");
156    }
157
158
159#ifdef DEBUG_SYSTEMC
160    // check if port_ is already inserted
161    for( int i = size() - 1; i >= 0; -- i ) {
162	if( export_ == m_export_vec[i] ) {
163	    export_->report_error( SC_ID_INSERT_EXPORT_,
164	                           "export already inserted ");
165	}
166    }
167#endif
168
169/*
170    //TBD:  maybe we want to do this stuf for later
171
172    // append the port to the current module's vector of ports
173    sc_module* curr_module = m_simc->hierarchy_curr();
174    if( curr_module == 0 ) {
175	port_->report_error( SC_ID_PORT_OUTSIDE_MODULE_ );
176    }
177    curr_module->append_port( port_ );
178*/
179
180    // insert
181    m_export_vec.push_back( export_ );
182}
183
184void
185sc_export_registry::remove( sc_export_base* export_ )
186{
187    if (size()==0) return;
188    int i;
189    for( i = size() - 1; i >= 0; -- i ) {
190	if( export_ == m_export_vec[i] ) {
191	    break;
192	}
193    }
194    if( i == -1 ) {
195	export_->report_error( SC_ID_SC_EXPORT_NOT_REGISTERED_ );
196    }
197
198    // remove
199    m_export_vec[i] = m_export_vec[size() - 1];
200    m_export_vec.resize(size()-1);
201}
202
203// constructor
204
205sc_export_registry::sc_export_registry( sc_simcontext& simc_ )
206: m_construction_done(0),
207  m_export_vec(),
208  m_simc( &simc_ )
209{
210}
211
212
213// destructor
214
215sc_export_registry::~sc_export_registry()
216{
217}
218
219// called when construction is done
220
221bool
222sc_export_registry::construction_done()
223{
224    if( m_construction_done == size() )
225      // nothing has been updated
226      return true;
227
228    for( int i = size()-1; i >= m_construction_done; --i ) {
229	m_export_vec[i]->construction_done();
230    }
231
232    m_construction_done = size();
233    return false;
234}
235
236// called when elaboration is done
237
238void
239sc_export_registry::elaboration_done()
240{
241    for( int i = size() - 1; i >= 0; -- i ) {
242	m_export_vec[i]->elaboration_done();
243    }
244}
245
246// called before simulation begins
247
248void
249sc_export_registry::start_simulation()
250{
251    for( int i = size() - 1; i >= 0; -- i ) {
252	m_export_vec[i]->start_simulation();
253    }
254}
255
256void
257sc_export_registry::simulation_done()
258{
259    for( int i = size() - 1; i >= 0; -- i ) {
260	m_export_vec[i]->simulation_done();
261    }
262}
263
264} // namespace sc_core
265
266// $Log: sc_export.cpp,v $
267// Revision 1.8  2011/08/26 20:45:40  acg
268//  Andy Goodrich: moved the modification log to the end of the file to
269//  eliminate source line number skew when check-ins are done.
270//
271// Revision 1.7  2011/08/24 22:05:36  acg
272//  Torsten Maehne: initialization changes to remove warnings.
273//
274// Revision 1.6  2011/05/09 04:07:37  acg
275//  Philipp A. Hartmann:
276//    (1) Restore hierarchy in all phase callbacks.
277//    (2) Ensure calls to before_end_of_elaboration.
278//
279// Revision 1.5  2011/02/18 20:31:05  acg
280//  Philipp A. Hartmann: added error messages for calls that cannot be done
281//  after elaboration.
282//
283// Revision 1.4  2011/02/18 20:23:45  acg
284//  Andy Goodrich: Copyright update.
285//
286// Revision 1.3  2011/02/18 20:07:04  acg
287//  Philipp A. Hartmann: Patch to revert to sprintf from snprintf to keep
288//  some versions of MSVC happy.
289//
290// Revision 1.2  2011/02/14 17:50:16  acg
291//  Andy Goodrich: testing for sc_port and sc_export instantiations during
292//  end of elaboration and issuing appropriate error messages.
293//
294// Revision 1.1.1.1  2006/12/15 20:20:04  acg
295// SystemC 2.3
296//
297// Revision 1.4  2006/01/26 21:00:50  acg
298//  Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
299//  sc_event::notify_delayed()
300//
301// Revision 1.3  2006/01/13 18:47:42  acg
302// Added $Log command so that CVS comments are reproduced in the source.
303//
304
305// Taf!
306