sc_prim_channel.h revision 12027:1eb7dc7aa10b
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_prim_channel.h -- Abstract base class of all primitive channel classes.
23
24  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
25
26 CHANGE LOG AT THE END OF THE FILE
27 *****************************************************************************/
28
29#ifndef SC_PRIM_CHANNEL_H
30#define SC_PRIM_CHANNEL_H
31
32#include "sysc/kernel/sc_object.h"
33#include "sysc/kernel/sc_wait.h"
34#include "sysc/kernel/sc_wait_cthread.h"
35
36namespace sc_core {
37
38// ----------------------------------------------------------------------------
39//  CLASS : sc_prim_channel
40//
41//  Abstract base class of all primitive channel classes.
42// ----------------------------------------------------------------------------
43
44class sc_prim_channel
45: public sc_object
46{
47    friend class sc_prim_channel_registry;
48
49public:
50    enum { list_end = 0xdb };
51public:
52    virtual const char* kind() const
53        { return "sc_prim_channel"; }
54
55    inline bool update_requested()
56	{ return m_update_next_p != (sc_prim_channel*)list_end; }
57
58    // request the update method to be executed during the update phase
59    inline void request_update();
60
61    // request the update method to be executed during the update phase
62    // from a process external to the simulator.
63    void async_request_update();
64
65protected:
66
67    // constructors
68    sc_prim_channel();
69    explicit sc_prim_channel( const char* );
70
71    // destructor
72    virtual ~sc_prim_channel();
73
74    // the update method (does nothing by default)
75    virtual void update();
76
77    // called by construction_done (does nothing by default)
78    virtual void before_end_of_elaboration();
79
80    // called by elaboration_done (does nothing by default)
81    virtual void end_of_elaboration();
82
83    // called by start_simulation (does nothing by default)
84    virtual void start_of_simulation();
85
86    // called by simulation_done (does nothing by default)
87    virtual void end_of_simulation();
88
89protected:
90
91    // to avoid calling sc_get_curr_simcontext()
92
93    // static sensitivity for SC_THREADs and SC_CTHREADs
94
95    void wait()
96        { sc_core::wait( simcontext() ); }
97
98
99    // dynamic sensitivity for SC_THREADs and SC_CTHREADs
100
101    void wait( const sc_event& e )
102        { sc_core::wait( e, simcontext() ); }
103
104    void wait( const sc_event_or_list& el )
105	{ sc_core::wait( el, simcontext() ); }
106
107    void wait( const sc_event_and_list& el )
108	{ sc_core::wait( el, simcontext() ); }
109
110    void wait( const sc_time& t )
111        { sc_core::wait( t, simcontext() ); }
112
113    void wait( double v, sc_time_unit tu )
114        { sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
115
116    void wait( const sc_time& t, const sc_event& e )
117        { sc_core::wait( t, e, simcontext() ); }
118
119    void wait( double v, sc_time_unit tu, const sc_event& e )
120        { sc_core::wait( sc_time( v, tu, simcontext() ), e, simcontext() ); }
121
122    void wait( const sc_time& t, const sc_event_or_list& el )
123        { sc_core::wait( t, el, simcontext() ); }
124
125    void wait( double v, sc_time_unit tu, const sc_event_or_list& el )
126        { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
127
128    void wait( const sc_time& t, const sc_event_and_list& el )
129        { sc_core::wait( t, el, simcontext() ); }
130
131    void wait( double v, sc_time_unit tu, const sc_event_and_list& el )
132        { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
133
134    void wait( int n )
135        { sc_core::wait( n, simcontext() ); }
136
137
138    // static sensitivity for SC_METHODs
139
140    void next_trigger()
141	{ sc_core::next_trigger( simcontext() ); }
142
143
144    // dynamic sensitivity for SC_METHODs
145
146    void next_trigger( const sc_event& e )
147        { sc_core::next_trigger( e, simcontext() ); }
148
149    void next_trigger( const sc_event_or_list& el )
150        { sc_core::next_trigger( el, simcontext() ); }
151
152    void next_trigger( const sc_event_and_list& el )
153        { sc_core::next_trigger( el, simcontext() ); }
154
155    void next_trigger( const sc_time& t )
156        { sc_core::next_trigger( t, simcontext() ); }
157
158    void next_trigger( double v, sc_time_unit tu )
159        {sc_core::next_trigger( sc_time( v, tu, simcontext() ), simcontext() );}
160
161    void next_trigger( const sc_time& t, const sc_event& e )
162        { sc_core::next_trigger( t, e, simcontext() ); }
163
164    void next_trigger( double v, sc_time_unit tu, const sc_event& e )
165        { sc_core::next_trigger(
166	    sc_time( v, tu, simcontext() ), e, simcontext() ); }
167
168    void next_trigger( const sc_time& t, const sc_event_or_list& el )
169        { sc_core::next_trigger( t, el, simcontext() ); }
170
171    void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
172        { sc_core::next_trigger(
173	    sc_time( v, tu, simcontext() ), el, simcontext() ); }
174
175    void next_trigger( const sc_time& t, const sc_event_and_list& el )
176        { sc_core::next_trigger( t, el, simcontext() ); }
177
178    void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
179        { sc_core::next_trigger(
180	    sc_time( v, tu, simcontext() ), el, simcontext() ); }
181
182
183    // for SC_METHODs and SC_THREADs and SC_CTHREADs
184
185    bool timed_out()
186	{ return sc_core::timed_out( simcontext() ); }
187
188
189#if 0 // @@@@####
190    // delta count maintenance
191    sc_dt::uint64 delta_count()
192	{ return simcontext()->m_delta_count; }
193#endif
194
195private:
196
197    // called during the update phase of a delta cycle (if requested)
198    void perform_update();
199
200    // called when construction is done
201    void construction_done();
202
203    // called when elaboration is done
204    void elaboration_done();
205
206    // called before simulation starts
207    void start_simulation();
208
209    // called after simulation ends
210    void simulation_done();
211
212    // disabled
213    sc_prim_channel( const sc_prim_channel& );
214    sc_prim_channel& operator = ( const sc_prim_channel& );
215
216private:
217
218    sc_prim_channel_registry* m_registry;          // Update list manager.
219    sc_prim_channel*          m_update_next_p;     // Next entry in update list.
220};
221
222
223// ----------------------------------------------------------------------------
224//  CLASS : sc_prim_channel_registry
225//
226//  Registry for all primitive channels.
227//  FOR INTERNAL USE ONLY!
228// ----------------------------------------------------------------------------
229
230class sc_prim_channel_registry
231{
232    friend class sc_simcontext;
233
234public:
235
236    void insert( sc_prim_channel& );
237    void remove( sc_prim_channel& );
238
239
240    int size() const
241        { return m_prim_channel_vec.size(); }
242
243    inline void request_update( sc_prim_channel& );
244    void async_request_update( sc_prim_channel& );
245
246    bool pending_updates() const
247    {
248        return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end
249               || pending_async_updates();
250    }
251
252    bool pending_async_updates() const;
253
254private:
255
256    // constructor
257    explicit sc_prim_channel_registry( sc_simcontext& simc_ );
258
259    // destructor
260    ~sc_prim_channel_registry();
261
262    // called during the update phase of a delta cycle
263    void perform_update();
264
265    // called when construction is done
266    bool construction_done();
267
268    // called when elaboration is done
269    void elaboration_done();
270
271    // called before simulation starts
272    void start_simulation();
273
274    // called after simulation ends
275    void simulation_done();
276
277    // disabled
278    sc_prim_channel_registry();
279    sc_prim_channel_registry( const sc_prim_channel_registry& );
280    sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& );
281
282private:
283    class async_update_list;
284
285    async_update_list*            m_async_update_list_p; // external updates.
286    int                           m_construction_done;   // # of constructs.
287    std::vector<sc_prim_channel*> m_prim_channel_vec;    // existing channels.
288    sc_simcontext*                m_simc;                // simulator context.
289    sc_prim_channel*              m_update_list_p;       // internal updates.
290};
291
292
293// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
294
295// ----------------------------------------------------------------------------
296//  CLASS : sc_prim_channel_registry
297//
298//  Registry for all primitive channels.
299//  FOR INTERNAL USE ONLY!
300// ----------------------------------------------------------------------------
301
302inline
303void
304sc_prim_channel_registry::request_update( sc_prim_channel& prim_channel_ )
305{
306    prim_channel_.m_update_next_p = m_update_list_p;
307    m_update_list_p = &prim_channel_;
308}
309
310// ----------------------------------------------------------------------------
311//  CLASS : sc_prim_channel
312//
313//  Abstract base class of all primitive channel classes.
314// ----------------------------------------------------------------------------
315
316// request the update method (to be executed during the update phase)
317
318inline
319void
320sc_prim_channel::request_update()
321{
322    if( ! m_update_next_p ) {
323	m_registry->request_update( *this );
324    }
325}
326
327// request the update method from external to the simulator (to be executed
328// during the update phase)
329
330inline
331void
332sc_prim_channel::async_request_update()
333{
334    m_registry->async_request_update(*this);
335}
336
337
338// called during the update phase of a delta cycle (if requested)
339
340inline
341void
342sc_prim_channel::perform_update()
343{
344    update();
345    m_update_next_p = 0;
346}
347
348
349} // namespace sc_core
350
351
352/*****************************************************************************
353
354  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
355  changes you are making here.
356
357      Name, Affiliation, Date: Andy Goodrich, Forte,
358                               Bishnupriya Bhattacharya, Cadence Design Systems,
359                               25 August, 2003
360  Description of Modification: phase callbacks
361
362 *****************************************************************************/
363//$Log: sc_prim_channel.h,v $
364//Revision 1.10  2011/08/26 21:38:32  acg
365// Philipp A. Hartmann: removed unused switch m_construction_done.
366//
367//Revision 1.9  2011/08/07 19:08:01  acg
368// Andy Goodrich: moved logs to end of file so line number synching works
369// better between versions.
370//
371//Revision 1.8  2011/05/09 04:07:37  acg
372// Philipp A. Hartmann:
373//   (1) Restore hierarchy in all phase callbacks.
374//   (2) Ensure calls to before_end_of_elaboration.
375//
376//Revision 1.7  2011/05/05 17:44:01  acg
377// Philip A. Hartmann: change in the name of pending_async_updates.
378//
379//Revision 1.6  2011/04/19 15:03:48  acg
380// Philipp A. Hartmann: remove ASYNC_UPDATE preprocessor check from header.
381//
382//Revision 1.5  2011/04/19 02:36:26  acg
383// Philipp A. Hartmann: new aysnc_update and mutex support.
384//
385//Revision 1.4  2011/04/05 20:48:09  acg
386// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
387// only return true if the clock has not moved.
388//
389//Revision 1.3  2011/02/18 20:23:45  acg
390// Andy Goodrich: Copyright update.
391//
392//Revision 1.2  2011/01/20 16:52:15  acg
393// Andy Goodrich: changes for IEEE 1666 2011.
394//
395//Revision 1.1.1.1  2006/12/15 20:20:04  acg
396//SystemC 2.3
397//
398//Revision 1.3  2006/05/08 17:52:47  acg
399// Andy Goodrich:
400//   (1) added David Long's forward declarations for friend functions,
401//       methods, and operators to keep the Microsoft compiler happy.
402//   (2) Added delta_count() method to sc_prim_channel for use by
403//       sc_signal so that the friend declaration in sc_simcontext.h
404//	   can be for a non-templated class (i.e., sc_prim_channel.)
405//
406//Revision 1.2  2006/01/03 23:18:26  acg
407//Changed copyright to include 2006.
408//
409//Revision 1.1.1.1  2005/12/19 23:16:43  acg
410//First check in of SystemC 2.1 into its own archive.
411//
412//Revision 1.10  2005/07/30 03:44:11  acg
413//Changes from 2.1.
414//
415//Revision 1.9  2005/06/10 22:43:55  acg
416//Added CVS change log annotation.
417
418#endif
419
420// Taf!
421