sc_method_process.h revision 12027
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_method_process.h -- Method process declarations 23 24 Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005 25 26 27 CHANGE LOG AT THE END OF THE FILE 28 *****************************************************************************/ 29 30// $Log: sc_method_process.h,v $ 31// Revision 1.23 2011/09/05 21:20:22 acg 32// Andy Goodrich: result of automake invocation. 33// 34// Revision 1.22 2011/08/29 18:04:32 acg 35// Philipp A. Hartmann: miscellaneous clean ups. 36// 37// Revision 1.21 2011/08/26 20:46:10 acg 38// Andy Goodrich: moved the modification log to the end of the file to 39// eliminate source line number skew when check-ins are done. 40// 41 42#if !defined(sc_method_process_h_INCLUDED) 43#define sc_method_process_h_INCLUDED 44 45#include "sysc/kernel/sc_process.h" 46#include "sysc/kernel/sc_spawn_options.h" 47#include "sysc/kernel/sc_cor.h" 48#include "sysc/kernel/sc_event.h" 49#include "sysc/kernel/sc_except.h" 50 51 52// DEBUGGING MACROS: 53// 54// DEBUG_MSG(NAME,P,MSG) 55// MSG = message to print 56// NAME = name that must match the process for the message to print, or 57// null if the message should be printed unconditionally. 58// P = pointer to process message is for, or NULL in which case the 59// message will not print. 60#if 0 61# define DEBUG_NAME "" 62# define DEBUG_MSG(NAME,P,MSG) \ 63 { \ 64 if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \ 65 std::cout << "**** " << sc_time_stamp() << " (" \ 66 << sc_get_current_process_name() << "): " << MSG \ 67 << " - " << P->name() << std::endl; \ 68 } 69#else 70# define DEBUG_MSG(NAME,P,MSG) 71#endif 72 73 74namespace sc_core { 75 76// forward function and class declarations: 77 78void sc_method_cor_fn( void* ); 79void sc_cmethod_cor_fn( void* ); 80void sc_set_stack_size( sc_method_handle, std::size_t ); 81class sc_event; 82class sc_module; 83class sc_process_table; 84class sc_process_handle; 85class sc_simcontext; 86class sc_runnable; 87 88void next_trigger( sc_simcontext* ); 89void next_trigger( const sc_event&, sc_simcontext* ); 90void next_trigger( const sc_event_or_list&, sc_simcontext* ); 91void next_trigger( const sc_event_and_list&, sc_simcontext* ); 92void next_trigger( const sc_time&, sc_simcontext* ); 93void next_trigger( const sc_time&, const sc_event&, sc_simcontext* ); 94void next_trigger( const sc_time&, const sc_event_or_list&, sc_simcontext* ); 95void next_trigger( const sc_time&, const sc_event_and_list&, sc_simcontext* ); 96 97struct sc_invoke_method; 98//============================================================================== 99// sc_method_process - 100// 101//============================================================================== 102class sc_method_process : public sc_process_b { 103 friend struct sc_invoke_method; 104 friend void sc_method_cor_fn( void* ); 105 friend void sc_cmethod_cor_fn( void* ); 106 friend void sc_set_stack_size( sc_method_handle, std::size_t ); 107 friend class sc_event; 108 friend class sc_module; 109 friend class sc_process_table; 110 friend class sc_process_handle; 111 friend class sc_simcontext; 112 friend class sc_runnable; 113 114 friend void next_trigger( sc_simcontext* ); 115 friend void next_trigger( const sc_event&, 116 sc_simcontext* ); 117 friend void next_trigger( const sc_event_or_list&, 118 sc_simcontext* ); 119 friend void next_trigger( const sc_event_and_list&, 120 sc_simcontext* ); 121 friend void next_trigger( const sc_time&, 122 sc_simcontext* ); 123 friend void next_trigger( const sc_time&, const sc_event&, 124 sc_simcontext* ); 125 friend void next_trigger( const sc_time&, const sc_event_or_list&, 126 sc_simcontext* ); 127 friend void next_trigger( const sc_time&, const sc_event_and_list&, 128 sc_simcontext* ); 129 130 public: 131 sc_method_process( const char* name_p, bool free_host, 132 SC_ENTRY_FUNC method_p, sc_process_host* host_p, 133 const sc_spawn_options* opt_p ); 134 135 virtual const char* kind() const 136 { return "sc_method_process"; } 137 138 protected: 139 void check_for_throws(); 140 virtual void disable_process( 141 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ); 142 virtual void enable_process( 143 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ); 144 inline bool run_process(); 145 virtual void kill_process( 146 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ); 147 sc_method_handle next_exist(); 148 sc_method_handle next_runnable(); 149 void clear_trigger(); 150 void next_trigger( const sc_event& ); 151 void next_trigger( const sc_event_or_list& ); 152 void next_trigger( const sc_event_and_list& ); 153 void next_trigger( const sc_time& ); 154 void next_trigger( const sc_time&, const sc_event& ); 155 void next_trigger( const sc_time&, const sc_event_or_list& ); 156 void next_trigger( const sc_time&, const sc_event_and_list& ); 157 virtual void resume_process( 158 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ); 159 void set_next_exist( sc_method_handle next_p ); 160 void set_next_runnable( sc_method_handle next_p ); 161 void set_stack_size( std::size_t size ); 162 virtual void suspend_process( 163 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ); 164 virtual void throw_reset( bool async ); 165 virtual void throw_user( const sc_throw_it_helper& helper, 166 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ); 167 bool trigger_dynamic( sc_event* ); 168 inline void trigger_static(); 169 170 protected: 171 sc_cor* m_cor; // Thread's coroutine. 172 std::size_t m_stack_size; // Thread stack size. 173 std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors. 174 175 private: 176 // may not be deleted manually (called from sc_process_b) 177 virtual ~sc_method_process(); 178 179 private: // disabled 180 sc_method_process( const sc_method_process& ); 181 const sc_method_process& operator = ( const sc_method_process& ); 182 183}; 184 185inline 186void 187sc_method_process::next_trigger( const sc_event& e ) 188{ 189 clear_trigger(); 190 e.add_dynamic( this ); 191 m_event_p = &e; 192 m_trigger_type = EVENT; 193} 194 195inline 196void 197sc_method_process::next_trigger( const sc_event_or_list& el ) 198{ 199 clear_trigger(); 200 el.add_dynamic( this ); 201 m_event_list_p = ⪙ 202 m_trigger_type = OR_LIST; 203} 204 205inline 206void 207sc_method_process::next_trigger( const sc_event_and_list& el ) 208{ 209 clear_trigger(); 210 el.add_dynamic( this ); 211 m_event_list_p = ⪙ 212 m_event_count = el.size(); 213 m_trigger_type = AND_LIST; 214} 215 216inline 217void 218sc_method_process::next_trigger( const sc_time& t ) 219{ 220 clear_trigger(); 221 m_timeout_event_p->notify_internal( t ); 222 m_timeout_event_p->add_dynamic( this ); 223 m_trigger_type = TIMEOUT; 224} 225 226inline 227void 228sc_method_process::next_trigger( const sc_time& t, const sc_event& e ) 229{ 230 clear_trigger(); 231 m_timeout_event_p->notify_internal( t ); 232 m_timeout_event_p->add_dynamic( this ); 233 e.add_dynamic( this ); 234 m_event_p = &e; 235 m_trigger_type = EVENT_TIMEOUT; 236} 237 238inline 239void 240sc_method_process::next_trigger( const sc_time& t, const sc_event_or_list& el ) 241{ 242 clear_trigger(); 243 m_timeout_event_p->notify_internal( t ); 244 m_timeout_event_p->add_dynamic( this ); 245 el.add_dynamic( this ); 246 m_event_list_p = ⪙ 247 m_trigger_type = OR_LIST_TIMEOUT; 248} 249 250inline 251void 252sc_method_process::next_trigger( const sc_time& t, const sc_event_and_list& el ) 253{ 254 clear_trigger(); 255 m_timeout_event_p->notify_internal( t ); 256 m_timeout_event_p->add_dynamic( this ); 257 el.add_dynamic( this ); 258 m_event_list_p = ⪙ 259 m_event_count = el.size(); 260 m_trigger_type = AND_LIST_TIMEOUT; 261} 262 263inline 264void sc_method_process::set_next_exist(sc_method_handle next_p) 265{ 266 m_exist_p = next_p; 267} 268 269inline 270sc_method_handle sc_method_process::next_exist() 271{ 272 return (sc_method_handle)m_exist_p; 273} 274 275 276inline 277void sc_method_process::set_next_runnable(sc_method_handle next_p) 278{ 279 m_runnable_p = next_p; 280} 281 282inline 283sc_method_handle sc_method_process::next_runnable() 284{ 285 return (sc_method_handle)m_runnable_p; 286} 287 288// +---------------------------------------------------------------------------- 289// |"sc_method_process::run_process" 290// | 291// | This method executes this object instance, including fielding exceptions. 292// | 293// | Result is false if an unfielded exception occurred, true if not. 294// +---------------------------------------------------------------------------- 295inline bool sc_method_process::run_process() 296{ 297 // Execute this object instance's semantics and catch any exceptions that 298 // are generated: 299 300 bool restart = false; 301 do { 302 try { 303 DEBUG_MSG(DEBUG_NAME,this,"executing method semantics"); 304 semantics(); 305 restart = false; 306 } 307 catch( sc_unwind_exception& ex ) { 308 DEBUG_MSG(DEBUG_NAME,this,"caught unwind exception"); 309 ex.clear(); 310 restart = ex.is_reset(); 311 } 312 catch( ... ) { 313 sc_report* err_p = sc_handle_exception(); 314 simcontext()->set_error( err_p ); 315 return false; 316 } 317 } while( restart ); 318 319 return true; 320} 321 322//------------------------------------------------------------------------------ 323//"sc_method_process::trigger_static" 324// 325// This inline method adds the current method to the queue of runnable 326// processes, if required. This is the case if the following criteria 327// are met: 328// (1) The process is in a runnable state. 329// (2) The process is not already on the run queue. 330// (3) The process is expecting a static trigger, 331// dynamic event waits take priority. 332// 333// 334// If the triggering process is the same process, the trigger is 335// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS 336// is defined. 337//------------------------------------------------------------------------------ 338inline 339void 340sc_method_process::trigger_static() 341{ 342 if ( (m_state & ps_bit_disabled) || is_runnable() || 343 m_trigger_type != STATIC ) 344 return; 345 346#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS ) 347 if( SC_UNLIKELY_( sc_get_current_process_b() == this ) ) 348 { 349 report_immediate_self_notification(); 350 return; 351 } 352#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS 353 354 // If we get here then the method is has satisfied its wait, if its 355 // suspended mark its state as ready to run. If its not suspended then 356 // push it onto the runnable queue. 357 358 if ( m_state & ps_bit_suspended ) 359 { 360 m_state = m_state | ps_bit_ready_to_run; 361 } 362 else 363 { 364 simcontext()->push_runnable_method(this); 365 } 366} 367 368#undef DEBUG_MSG 369 370} // namespace sc_core 371 372// Revision 1.20 2011/08/24 22:05:50 acg 373// Torsten Maehne: initialization changes to remove warnings. 374// 375// Revision 1.19 2011/07/29 22:43:15 acg 376// Andy Goodrich: addition of check_for_throws() method. 377// 378// Revision 1.18 2011/07/24 11:18:09 acg 379// Philipp A. Hartmann: add code to restart a method process after a 380// self-reset. 381// 382// Revision 1.17 2011/05/09 04:07:48 acg 383// Philipp A. Hartmann: 384// (1) Restore hierarchy in all phase callbacks. 385// (2) Ensure calls to before_end_of_elaboration. 386// 387// Revision 1.16 2011/04/13 02:41:34 acg 388// Andy Goodrich: eliminate warning messages generated when the DEBUG_MSG 389// macro is used. 390// 391// Revision 1.15 2011/04/10 22:12:32 acg 392// Andy Goodrich: adding debugging macros. 393// 394// Revision 1.14 2011/04/08 22:31:21 acg 395// Andy Goodrich: added new inline method run_process() to hide the process 396// implementation for sc_simcontext. 397// 398// Revision 1.13 2011/04/05 20:50:56 acg 399// Andy Goodrich: 400// (1) changes to make sure that event(), posedge() and negedge() only 401// return true if the clock has not moved. 402// (2) fixes for method self-resumes. 403// (3) added SC_PRERELEASE_VERSION 404// (4) removed kernel events from the object hierarchy, added 405// sc_hierarchy_name_exists(). 406// 407// Revision 1.12 2011/04/01 21:24:57 acg 408// Andy Goodrich: removed unused code. 409// 410// Revision 1.11 2011/02/19 08:30:53 acg 411// Andy Goodrich: Moved process queueing into trigger_static from 412// sc_event::notify. 413// 414// Revision 1.10 2011/02/18 20:27:14 acg 415// Andy Goodrich: Updated Copyrights. 416// 417// Revision 1.9 2011/02/17 19:51:34 acg 418// Andy Goodrich: 419// (1) Changed the signature of trigger_dynamic back to a bool. 420// (2) Removed ready_to_run(). 421// (3) Simplified process control usage. 422// 423// Revision 1.8 2011/02/16 22:37:30 acg 424// Andy Goodrich: clean up to remove need for ps_disable_pending. 425// 426// Revision 1.7 2011/02/13 21:47:37 acg 427// Andy Goodrich: update copyright notice. 428// 429// Revision 1.6 2011/02/01 21:05:05 acg 430// Andy Goodrich: Changes in trigger_dynamic methods to handle new 431// process control rules about event sensitivity. 432// 433// Revision 1.5 2011/01/18 20:10:44 acg 434// Andy Goodrich: changes for IEEE1666_2011 semantics. 435// 436// Revision 1.4 2009/07/28 01:10:53 acg 437// Andy Goodrich: updates for 2.3 release candidate. 438// 439// Revision 1.3 2009/05/22 16:06:29 acg 440// Andy Goodrich: process control updates. 441// 442// Revision 1.2 2008/05/22 17:06:25 acg 443// Andy Goodrich: updated copyright notice to include 2008. 444// 445// Revision 1.1.1.1 2006/12/15 20:20:05 acg 446// SystemC 2.3 447// 448// Revision 1.7 2006/05/08 17:57:13 acg 449// Andy Goodrich: Added David Long's forward declarations for friend functions 450// to keep the Microsoft C++ compiler happy. 451// 452// Revision 1.6 2006/04/20 17:08:17 acg 453// Andy Goodrich: 3.0 style process changes. 454// 455// Revision 1.5 2006/04/11 23:13:21 acg 456// Andy Goodrich: Changes for reduced reset support that only includes 457// sc_cthread, but has preliminary hooks for expanding to method and thread 458// processes also. 459// 460// Revision 1.4 2006/01/24 20:49:05 acg 461// Andy Goodrich: changes to remove the use of deprecated features within the 462// simulator, and to issue warning messages when deprecated features are used. 463// 464// Revision 1.3 2006/01/13 18:44:29 acg 465// Added $Log to record CVS changes into the source. 466 467#endif // !defined(sc_method_process_h_INCLUDED) 468