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