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