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_module.h -- Base class of all hierarchical modules and channels.
23
24  Original Author: Stan Y. Liao, Synopsys, Inc.
25                   Martin Janssen, Synopsys, Inc.
26
27  CHANGE LOG AT THE END OF THE FILE
28 *****************************************************************************/
29
30
31#ifndef SC_MODULE_H
32#define SC_MODULE_H
33
34#include "sysc/kernel/sc_kernel_ids.h"
35#include "sysc/kernel/sc_process.h"
36#include "sysc/kernel/sc_module_name.h"
37#include "sysc/kernel/sc_sensitive.h"
38#include "sysc/kernel/sc_time.h"
39#include "sysc/kernel/sc_wait.h"
40#include "sysc/kernel/sc_wait_cthread.h"
41#include "sysc/kernel/sc_process.h"
42#include "sysc/kernel/sc_process_handle.h"
43#include "sysc/utils/sc_list.h"
44
45namespace sc_core {
46
47class sc_name_gen;
48template<class T> class sc_in;
49template<class T> class sc_inout;
50template<class T> class sc_out;
51
52// ----------------------------------------------------------------------------
53//  STRUCT : sc_bind_proxy
54//
55//  Struct for temporarily storing a pointer to an interface or port.
56//  Used for positional binding.
57// ----------------------------------------------------------------------------
58
59struct sc_bind_proxy
60{
61    sc_interface* iface;
62    sc_port_base* port;
63
64    sc_bind_proxy();
65    sc_bind_proxy( sc_interface& );
66    sc_bind_proxy( sc_port_base& );
67};
68
69
70extern const sc_bind_proxy SC_BIND_PROXY_NIL;
71
72
73// ----------------------------------------------------------------------------
74//  CLASS : sc_module
75//
76//  Base class for all structural entities.
77// ----------------------------------------------------------------------------
78
79class sc_module
80: public sc_object, public sc_process_host
81{
82    friend class sc_module_name;
83    friend class sc_module_registry;
84    friend class sc_object;
85    friend class sc_port_registry;
86	friend class sc_process_b;
87    friend class sc_simcontext;
88
89public:
90
91    sc_simcontext* sc_get_curr_simcontext()
92	{ return simcontext(); }
93
94    // to generate unique names for objects in an MT-Safe way
95    const char* gen_unique_name( const char* basename_, bool preserve_first );
96
97    virtual const char* kind() const
98        { return "sc_module"; }
99
100protected:
101
102    // called by construction_done
103    virtual void before_end_of_elaboration();
104
105    void construction_done();
106
107    // called by elaboration_done (does nothing by default)
108    virtual void end_of_elaboration();
109
110    void elaboration_done( bool& );
111
112    // called by start_simulation (does nothing by default)
113    virtual void start_of_simulation();
114
115    void start_simulation();
116
117    // called by simulation_done (does nothing by default)
118    virtual void end_of_simulation();
119
120    void simulation_done();
121
122    void sc_module_init();
123
124    // constructor
125    sc_module();
126    sc_module( const sc_module_name& nm ); /* for those used to old style */
127
128    /* DEPRECATED */ sc_module( const char* nm );
129    /* DEPRECATED */ sc_module( const std::string& nm );
130
131public:
132
133    // destructor
134    virtual ~sc_module();
135
136    // positional binding methods
137
138    sc_module& operator << ( sc_interface& );
139    sc_module& operator << ( sc_port_base& );
140
141    sc_module& operator , ( sc_interface& interface_ )
142        { return operator << ( interface_ ); }
143
144    sc_module& operator , ( sc_port_base& port_ )
145        { return operator << ( port_ ); }
146
147    // operator() is declared at the end of the class.
148
149    const ::std::vector<sc_object*>& get_child_objects() const;
150
151protected:
152
153    // this must be called by user-defined modules
154    void end_module();
155
156
157    // to prevent initialization for SC_METHODs and SC_THREADs
158    void dont_initialize();
159
160    // positional binding code - used by operator ()
161
162    void positional_bind( sc_interface& );
163    void positional_bind( sc_port_base& );
164
165    // set reset sensitivity for SC_xTHREADs
166    void async_reset_signal_is( const sc_in<bool>& port, bool level );
167    void async_reset_signal_is( const sc_inout<bool>& port, bool level );
168    void async_reset_signal_is( const sc_out<bool>& port, bool level );
169    void async_reset_signal_is( const sc_signal_in_if<bool>& iface, bool level);
170    void reset_signal_is( const sc_in<bool>& port, bool level );
171    void reset_signal_is( const sc_inout<bool>& port, bool level );
172    void reset_signal_is( const sc_out<bool>& port, bool level );
173    void reset_signal_is( const sc_signal_in_if<bool>& iface, bool level );
174
175    // static sensitivity for SC_THREADs and SC_CTHREADs
176
177    void wait()
178        { ::sc_core::wait( simcontext() ); }
179
180    // dynamic sensitivity for SC_THREADs and SC_CTHREADs
181
182    void wait( const sc_event& e )
183        { ::sc_core::wait( e, simcontext() ); }
184
185    void wait( const sc_event_or_list& el )
186	{ ::sc_core::wait( el, simcontext() ); }
187
188    void wait( const sc_event_and_list& el )
189	{ ::sc_core::wait( el, simcontext() ); }
190
191    void wait( const sc_time& t )
192        { ::sc_core::wait( t, simcontext() ); }
193
194    void wait( double v, sc_time_unit tu )
195        { ::sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
196
197    void wait( const sc_time& t, const sc_event& e )
198        { ::sc_core::wait( t, e, simcontext() ); }
199
200    void wait( double v, sc_time_unit tu, const sc_event& e )
201        { ::sc_core::wait(
202		sc_time( v, tu, simcontext() ), e, simcontext() ); }
203
204    void wait( const sc_time& t, const sc_event_or_list& el )
205        { ::sc_core::wait( t, el, simcontext() ); }
206
207    void wait( double v, sc_time_unit tu, const sc_event_or_list& el )
208        { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
209
210    void wait( const sc_time& t, const sc_event_and_list& el )
211        { ::sc_core::wait( t, el, simcontext() ); }
212
213    void wait( double v, sc_time_unit tu, const sc_event_and_list& el )
214        { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
215
216
217    // static sensitivity for SC_METHODs
218
219    void next_trigger()
220	{ ::sc_core::next_trigger( simcontext() ); }
221
222
223    // dynamic sensitivty for SC_METHODs
224
225    void next_trigger( const sc_event& e )
226        { ::sc_core::next_trigger( e, simcontext() ); }
227
228    void next_trigger( const sc_event_or_list& el )
229        { ::sc_core::next_trigger( el, simcontext() ); }
230
231    void next_trigger( const sc_event_and_list& el )
232        { ::sc_core::next_trigger( el, simcontext() ); }
233
234    void next_trigger( const sc_time& t )
235        { ::sc_core::next_trigger( t, simcontext() ); }
236
237    void next_trigger( double v, sc_time_unit tu )
238        { ::sc_core::next_trigger(
239	    sc_time( v, tu, simcontext() ), simcontext() ); }
240
241    void next_trigger( const sc_time& t, const sc_event& e )
242        { ::sc_core::next_trigger( t, e, simcontext() ); }
243
244    void next_trigger( double v, sc_time_unit tu, const sc_event& e )
245        { ::sc_core::next_trigger(
246		sc_time( v, tu, simcontext() ), e, simcontext() ); }
247
248    void next_trigger( const sc_time& t, const sc_event_or_list& el )
249        { ::sc_core::next_trigger( t, el, simcontext() ); }
250
251    void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
252        { ::sc_core::next_trigger(
253	    sc_time( v, tu, simcontext() ), el, simcontext() ); }
254
255    void next_trigger( const sc_time& t, const sc_event_and_list& el )
256        { ::sc_core::next_trigger( t, el, simcontext() ); }
257
258    void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
259        { ::sc_core::next_trigger(
260	    sc_time( v, tu, simcontext() ), el, simcontext() ); }
261
262
263    // for SC_METHODs and SC_THREADs and SC_CTHREADs
264
265    bool timed_out()
266        { return ::sc_core::timed_out(); }
267
268
269    // for SC_CTHREADs
270
271    void halt()
272        { ::sc_core::halt( simcontext() ); }
273
274    void wait( int n )
275        { ::sc_core::wait( n, simcontext() ); }
276
277    void at_posedge( const sc_signal_in_if<bool>& s )
278	{ ::sc_core::at_posedge( s, simcontext() ); }
279
280    void at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
281	{ ::sc_core::at_posedge( s, simcontext() ); }
282
283    void at_negedge( const sc_signal_in_if<bool>& s )
284	{ ::sc_core::at_negedge( s, simcontext() ); }
285
286    void at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
287	{ ::sc_core::at_negedge( s, simcontext() ); }
288
289    // Catch uses of watching:
290    void watching( bool /* expr */ )
291        { SC_REPORT_ERROR(SC_ID_WATCHING_NOT_ALLOWED_,""); }
292
293    // These are protected so that user derived classes can refer to them.
294    sc_sensitive     sensitive;
295    sc_sensitive_pos sensitive_pos;
296    sc_sensitive_neg sensitive_neg;
297
298    // Function to set the stack size of the current (c)thread process.
299    void set_stack_size( std::size_t );
300
301    int append_port( sc_port_base* );
302
303private:
304    sc_module( const sc_module& );
305    const sc_module& operator = ( const sc_module& );
306
307private:
308
309    bool                        m_end_module_called;
310    std::vector<sc_port_base*>* m_port_vec;
311    int                         m_port_index;
312    sc_name_gen*                m_name_gen;
313    sc_module_name*             m_module_name_p;
314
315public:
316
317    void defunct() { }
318
319    // positional binding methods (cont'd)
320
321    void operator () ( const sc_bind_proxy& p001,
322		       const sc_bind_proxy& p002 = SC_BIND_PROXY_NIL,
323		       const sc_bind_proxy& p003 = SC_BIND_PROXY_NIL,
324		       const sc_bind_proxy& p004 = SC_BIND_PROXY_NIL,
325		       const sc_bind_proxy& p005 = SC_BIND_PROXY_NIL,
326		       const sc_bind_proxy& p006 = SC_BIND_PROXY_NIL,
327		       const sc_bind_proxy& p007 = SC_BIND_PROXY_NIL,
328		       const sc_bind_proxy& p008 = SC_BIND_PROXY_NIL,
329		       const sc_bind_proxy& p009 = SC_BIND_PROXY_NIL,
330		       const sc_bind_proxy& p010 = SC_BIND_PROXY_NIL,
331		       const sc_bind_proxy& p011 = SC_BIND_PROXY_NIL,
332		       const sc_bind_proxy& p012 = SC_BIND_PROXY_NIL,
333		       const sc_bind_proxy& p013 = SC_BIND_PROXY_NIL,
334		       const sc_bind_proxy& p014 = SC_BIND_PROXY_NIL,
335		       const sc_bind_proxy& p015 = SC_BIND_PROXY_NIL,
336		       const sc_bind_proxy& p016 = SC_BIND_PROXY_NIL,
337		       const sc_bind_proxy& p017 = SC_BIND_PROXY_NIL,
338		       const sc_bind_proxy& p018 = SC_BIND_PROXY_NIL,
339		       const sc_bind_proxy& p019 = SC_BIND_PROXY_NIL,
340		       const sc_bind_proxy& p020 = SC_BIND_PROXY_NIL,
341		       const sc_bind_proxy& p021 = SC_BIND_PROXY_NIL,
342		       const sc_bind_proxy& p022 = SC_BIND_PROXY_NIL,
343		       const sc_bind_proxy& p023 = SC_BIND_PROXY_NIL,
344		       const sc_bind_proxy& p024 = SC_BIND_PROXY_NIL,
345		       const sc_bind_proxy& p025 = SC_BIND_PROXY_NIL,
346		       const sc_bind_proxy& p026 = SC_BIND_PROXY_NIL,
347		       const sc_bind_proxy& p027 = SC_BIND_PROXY_NIL,
348		       const sc_bind_proxy& p028 = SC_BIND_PROXY_NIL,
349		       const sc_bind_proxy& p029 = SC_BIND_PROXY_NIL,
350		       const sc_bind_proxy& p030 = SC_BIND_PROXY_NIL,
351		       const sc_bind_proxy& p031 = SC_BIND_PROXY_NIL,
352		       const sc_bind_proxy& p032 = SC_BIND_PROXY_NIL,
353		       const sc_bind_proxy& p033 = SC_BIND_PROXY_NIL,
354		       const sc_bind_proxy& p034 = SC_BIND_PROXY_NIL,
355		       const sc_bind_proxy& p035 = SC_BIND_PROXY_NIL,
356		       const sc_bind_proxy& p036 = SC_BIND_PROXY_NIL,
357		       const sc_bind_proxy& p037 = SC_BIND_PROXY_NIL,
358		       const sc_bind_proxy& p038 = SC_BIND_PROXY_NIL,
359		       const sc_bind_proxy& p039 = SC_BIND_PROXY_NIL,
360		       const sc_bind_proxy& p040 = SC_BIND_PROXY_NIL,
361		       const sc_bind_proxy& p041 = SC_BIND_PROXY_NIL,
362		       const sc_bind_proxy& p042 = SC_BIND_PROXY_NIL,
363		       const sc_bind_proxy& p043 = SC_BIND_PROXY_NIL,
364		       const sc_bind_proxy& p044 = SC_BIND_PROXY_NIL,
365		       const sc_bind_proxy& p045 = SC_BIND_PROXY_NIL,
366		       const sc_bind_proxy& p046 = SC_BIND_PROXY_NIL,
367		       const sc_bind_proxy& p047 = SC_BIND_PROXY_NIL,
368		       const sc_bind_proxy& p048 = SC_BIND_PROXY_NIL,
369		       const sc_bind_proxy& p049 = SC_BIND_PROXY_NIL,
370		       const sc_bind_proxy& p050 = SC_BIND_PROXY_NIL,
371		       const sc_bind_proxy& p051 = SC_BIND_PROXY_NIL,
372		       const sc_bind_proxy& p052 = SC_BIND_PROXY_NIL,
373		       const sc_bind_proxy& p053 = SC_BIND_PROXY_NIL,
374		       const sc_bind_proxy& p054 = SC_BIND_PROXY_NIL,
375		       const sc_bind_proxy& p055 = SC_BIND_PROXY_NIL,
376		       const sc_bind_proxy& p056 = SC_BIND_PROXY_NIL,
377		       const sc_bind_proxy& p057 = SC_BIND_PROXY_NIL,
378		       const sc_bind_proxy& p058 = SC_BIND_PROXY_NIL,
379		       const sc_bind_proxy& p059 = SC_BIND_PROXY_NIL,
380		       const sc_bind_proxy& p060 = SC_BIND_PROXY_NIL,
381		       const sc_bind_proxy& p061 = SC_BIND_PROXY_NIL,
382		       const sc_bind_proxy& p062 = SC_BIND_PROXY_NIL,
383		       const sc_bind_proxy& p063 = SC_BIND_PROXY_NIL,
384		       const sc_bind_proxy& p064 = SC_BIND_PROXY_NIL );
385
386};
387
388extern sc_module* sc_module_dynalloc(sc_module*);
389#define SC_NEW(x)  ::sc_core::sc_module_dynalloc(new x);
390
391
392// -----------------------------------------------------------------------------
393// SOME MACROS TO SIMPLIFY SYNTAX:
394// -----------------------------------------------------------------------------
395
396#define SC_MODULE(user_module_name)                                           \
397    struct user_module_name : ::sc_core::sc_module
398
399#define SC_CTOR(user_module_name)                                             \
400    typedef user_module_name SC_CURRENT_USER_MODULE;                          \
401    user_module_name( ::sc_core::sc_module_name )
402
403// the SC_HAS_PROCESS macro call must be followed by a ;
404#define SC_HAS_PROCESS(user_module_name)                                      \
405    typedef user_module_name SC_CURRENT_USER_MODULE
406
407// The this-> construct on sensitive operators in the macros below is
408// required for gcc 4.x when a templated class has a templated parent that is
409// derived from sc_module:
410//
411// template<typename X>
412// class B : public sc_module;
413// template<typename X>
414// class A : public B<X>
415
416#define declare_method_process(handle, name, host_tag, func)        \
417    {		                                                    \
418        ::sc_core::sc_process_handle handle =                      \
419	    sc_core::sc_get_curr_simcontext()->create_method_process( \
420		name,  false, SC_MAKE_FUNC_PTR( host_tag, func ), \
421		this, 0 ); \
422        this->sensitive << handle;                                        \
423        this->sensitive_pos << handle;                                    \
424        this->sensitive_neg << handle;                                    \
425    }
426
427#define declare_thread_process(handle, name, host_tag, func)        \
428    {                                                               \
429        ::sc_core::sc_process_handle handle =                      \
430	     sc_core::sc_get_curr_simcontext()->create_thread_process( \
431                 name,  false,           \
432                 SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
433        this->sensitive << handle;                                        \
434        this->sensitive_pos << handle;                                    \
435        this->sensitive_neg << handle;                                    \
436    }
437
438#define declare_cthread_process(handle, name, host_tag, func, edge) \
439    {                                                               \
440        ::sc_core::sc_process_handle handle =                     \
441	     sc_core::sc_get_curr_simcontext()->create_cthread_process( \
442            name,  false,          \
443                     SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
444        this->sensitive.operator() ( handle, edge );\
445    }
446
447#define SC_CTHREAD(func, edge)                                                \
448    declare_cthread_process( func ## _handle,                                 \
449                             #func,                                           \
450                             SC_CURRENT_USER_MODULE,                          \
451                             func,                                            \
452                             edge )
453
454#define SC_METHOD(func)                                                       \
455    declare_method_process( func ## _handle,                                  \
456                            #func,                                            \
457                            SC_CURRENT_USER_MODULE,                           \
458                            func )
459
460#define SC_THREAD(func)                                                       \
461    declare_thread_process( func ## _handle,                                  \
462                            #func,                                            \
463                            SC_CURRENT_USER_MODULE,                           \
464                            func )
465
466
467
468// ----------------------------------------------------------------------------
469//  TYPEDEFS
470// ----------------------------------------------------------------------------
471
472typedef sc_module sc_channel;
473typedef sc_module sc_behavior;
474
475} // namespace sc_core
476
477/*****************************************************************************
478
479  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
480  changes you are making here.
481
482      Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
483  Description of Modification: - Implementation of operator() and operator,
484                                 positional connection method.
485                               - Implementation of error checking in
486                                 operator<<'s.
487                               - Implementation of the function test_module_prm.
488                               - Implementation of set_stack_size().
489
490      Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc.
491  Description of Modification: - Change implementation for VC6.
492
493      Name, Affiliation, Date: Andy Godorich, Forte
494                               Bishnupriya Bhattacharya, Cadence Design Systems,
495                               25 August, 2003
496  Description of Modification: inherit from sc_process_host as a part of
497                               implementing dynamic processes
498
499 *****************************************************************************/
500
501// $Log: sc_module.h,v $
502// Revision 1.11  2011/08/26 20:46:10  acg
503//  Andy Goodrich: moved the modification log to the end of the file to
504//  eliminate source line number skew when check-ins are done.
505//
506// Revision 1.10  2011/08/15 16:43:24  acg
507//  Torsten Maehne: changes to remove unused argument warnings.
508//
509// Revision 1.9  2011/03/05 19:44:20  acg
510//  Andy Goodrich: changes for object and event naming and structures.
511//
512// Revision 1.8  2011/02/18 20:27:14  acg
513//  Andy Goodrich: Updated Copyrights.
514//
515// Revision 1.7  2011/02/13 21:47:37  acg
516//  Andy Goodrich: update copyright notice.
517//
518// Revision 1.6  2011/01/18 20:10:44  acg
519//  Andy Goodrich: changes for IEEE1666_2011 semantics.
520//
521// Revision 1.5  2010/12/07 20:09:12  acg
522// Andy Goodrich: remove unused signal declaration
523//
524// Revision 1.4  2009/05/22 16:06:29  acg
525//  Andy Goodrich: process control updates.
526//
527// Revision 1.3  2008/05/22 17:06:25  acg
528//  Andy Goodrich: updated copyright notice to include 2008.
529//
530// Revision 1.2  2007/01/24 20:14:40  acg
531//  Andy Goodrich: improved comments about the use of this-> in the macros
532//  that access sensitive.
533//
534// Revision 1.1.1.1  2006/12/15 20:20:05  acg
535// SystemC 2.3
536//
537// Revision 1.10  2006/12/02 20:58:18  acg
538//  Andy Goodrich: updates from 2.2 for IEEE 1666 support.
539//
540// Revision 1.7  2006/04/11 23:13:21  acg
541//   Andy Goodrich: Changes for reduced reset support that only includes
542//   sc_cthread, but has preliminary hooks for expanding to method and thread
543//   processes also.
544//
545// Revision 1.6  2006/03/15 17:53:34  acg
546//  Andy Goodrich, Forte Design
547//  Reordered includes to pick up <cassert> for use by sc_process_name.h
548//
549// Revision 1.5  2006/03/14 23:56:58  acg
550//   Andy Goodrich: This fixes a bug when an exception is thrown in
551//   sc_module::sc_module() for a dynamically allocated sc_module
552//   object. We are calling sc_module::end_module() on a module that has
553//   already been deleted. The scenario runs like this:
554//
555//   a) the sc_module constructor is entered
556//   b) the exception is thrown
557//   c) the exception processor deletes the storage for the sc_module
558//   d) the stack is unrolled causing the sc_module_name instance to be deleted
559//   e) ~sc_module_name() calls end_module() with its pointer to the sc_module
560//   f) because the sc_module has been deleted its storage is corrupted,
561//      either by linking it to a free space chain, or by reuse of some sort
562//   g) the m_simc field is garbage
563//   h) the m_object_manager field is also garbage
564//   i) an exception occurs
565//
566//   This does not happen for automatic sc_module instances since the
567//   storage for the module is not reclaimed its just part of the stack.
568//
569//   I am fixing this by having the destructor for sc_module clear the
570//   module pointer in its sc_module_name instance. That cuts things at
571//   step (e) above, since the pointer will be null if the module has
572//   already been deleted. To make sure the module stack is okay, I call
573//   end-module() in ~sc_module in the case where there is an
574//   sc_module_name pointer lying around.
575//
576// Revision 1.4  2006/01/24 20:49:05  acg
577// Andy Goodrich: changes to remove the use of deprecated features within the
578// simulator, and to issue warning messages when deprecated features are used.
579//
580// Revision 1.3  2006/01/13 18:44:30  acg
581// Added $Log to record CVS changes into the source.
582
583#endif
584