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_process.cpp -- Base process implementation. 23 24 Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003 25 Stuart Swan, Cadence 26 Bishnupriya Bhattacharya, Cadence Design Systems, 27 25 August, 2003 28 29 CHANGE LOG AT THE END OF THE FILE 30 *****************************************************************************/ 31 32#include "sysc/kernel/sc_name_gen.h" 33#include "sysc/kernel/sc_cthread_process.h" 34#include "sysc/kernel/sc_method_process.h" 35#include "sysc/kernel/sc_thread_process.h" 36#include "sysc/kernel/sc_sensitive.h" 37#include "sysc/kernel/sc_process_handle.h" 38#include "sysc/kernel/sc_event.h" 39#include <sstream> 40 41namespace sc_core { 42 43// sc_process_handle entities that are returned for null pointer instances: 44// 45// Note the special name for 'non_event' - this makes sure it does not 46// appear as a named event. 47 48std::vector<sc_event*> sc_process_handle::empty_event_vector; 49std::vector<sc_object*> sc_process_handle::empty_object_vector; 50sc_event sc_process_handle::non_event(SC_KERNEL_EVENT_PREFIX); 51 52// Last process that was created: 53 54sc_process_b* sc_process_b::m_last_created_process_p = 0; 55 56//------------------------------------------------------------------------------ 57//"sc_process_b::add_static_event" 58// 59// This method adds an event to the list of static events, and sets the 60// event up to call back this process when it fires. 61//------------------------------------------------------------------------------ 62void sc_process_b::add_static_event( const sc_event& e ) 63{ 64 sc_method_handle method_h; // This process as a method. 65 sc_thread_handle thread_h; // This process as a thread. 66 67 68 // CHECK TO SEE IF WE ARE ALREADY REGISTERED WITH THE EVENT: 69 70 for( int i = m_static_events.size() - 1; i >= 0; -- i ) { 71 if( &e == m_static_events[i] ) { 72 return; 73 } 74 } 75 76 // REMEMBER THE EVENT AND THEN REGISTER OUR OBJECT INSTANCE WITH IT: 77 78 m_static_events.push_back( &e ); 79 80 switch ( m_process_kind ) 81 { 82 case SC_THREAD_PROC_: 83 case SC_CTHREAD_PROC_: 84 thread_h = SCAST<sc_thread_handle>( this ); 85 e.add_static( thread_h ); 86 break; 87 case SC_METHOD_PROC_: 88 method_h = SCAST<sc_method_handle>( this ); 89 e.add_static( method_h ); 90 break; 91 default: 92 assert( false ); 93 break; 94 } 95} 96 97//------------------------------------------------------------------------------ 98//"sc_process_b::disconnect_process" 99// 100// This method removes this object instance from use. It will be called by 101// the kill_process() methods of classes derived from it. This object instance 102// will be removed from any data structures it resides, other than existence. 103//------------------------------------------------------------------------------ 104void sc_process_b::disconnect_process() 105{ 106 int mon_n; // monitor queue size. 107 sc_thread_handle thread_h; // This process as a thread. 108 109 // IF THIS OBJECT IS PINING FOR THE FJORDS WE ARE DONE: 110 111 if ( m_state & ps_bit_zombie ) return; 112 113 // IF THIS IS A THREAD SIGNAL ANY MONITORS WAITING FOR IT TO EXIT: 114 115 switch ( m_process_kind ) 116 { 117 case SC_THREAD_PROC_: 118 case SC_CTHREAD_PROC_: 119 thread_h = SCAST<sc_thread_handle>(this); 120 mon_n = thread_h->m_monitor_q.size(); 121 if ( mon_n ) 122 { 123 for ( int mon_i = 0; mon_i < mon_n; mon_i++ ) 124 { 125 thread_h->m_monitor_q[mon_i]->signal( thread_h, 126 sc_process_monitor::spm_exit); 127 } 128 } 129 break; 130 default: 131 break; 132 } 133 134 // REMOVE EVENT WAITS, AND REMOVE THE PROCESS FROM ITS SC_RESET: 135 136 remove_dynamic_events(); 137 remove_static_events(); 138 139 for ( std::vector<sc_reset*>::size_type rst_i = 0; rst_i < m_resets.size(); rst_i++ ) 140 { 141 m_resets[rst_i]->remove_process( this ); 142 } 143 m_resets.resize(0); 144 145 146 // FIRE THE TERMINATION EVENT, MARK AS TERMINATED, AND DECREMENT THE COUNT: 147 // 148 // (1) We wait to set the process kind until after doing the removals 149 // above. 150 // (2) Decrementing the reference count will result in actual object 151 // deletion if we hit zero. 152 153 m_state = ps_bit_zombie; 154 if ( m_term_event_p ) m_term_event_p->notify(); 155 reference_decrement(); 156} 157 158//------------------------------------------------------------------------------ 159//"sc_process_b::delete_process" 160// 161// This method deletes the current instance, if it is not the running 162// process. Otherwise, it is put in the simcontext's process deletion 163// queue. 164// 165// The reason for the two step deletion process is that the process from which 166// reference_decrement() is called may be the running process, so we may need 167// to wait until it goes idle. 168//------------------------------------------------------------------------------ 169void sc_process_b::delete_process() 170{ 171 assert( m_references_n == 0 ); 172 173 // Immediate deletion: 174 175 if ( this != sc_get_current_process_b() ) 176 { 177 delete this; 178 } 179 180 // Deferred deletion: note we set the reference count to one for the call 181 // to reference_decrement that occurs in sc_simcontext::crunch(). 182 183 else 184 { 185 m_references_n = 1; 186 detach(); 187 simcontext()->mark_to_collect_process( this ); 188 } 189} 190 191 192//------------------------------------------------------------------------------ 193//"sc_process_b::dont_initialize" 194// 195// This virtual method sets the initialization switch for this object instance. 196//------------------------------------------------------------------------------ 197void sc_process_b::dont_initialize( bool dont ) 198{ 199 m_dont_init = dont; 200} 201 202//------------------------------------------------------------------------------ 203//"sc_process_b::dump_state" 204// 205// This method returns the process state as a string. 206//------------------------------------------------------------------------------ 207std::string sc_process_b::dump_state() const 208{ 209 std::string result; 210 result = "["; 211 if ( m_state == ps_normal ) 212 { 213 result += " normal"; 214 } 215 else 216 { 217 if ( m_state & ps_bit_disabled ) 218 result += "disabled "; 219 if ( m_state & ps_bit_suspended ) 220 result += "suspended "; 221 if ( m_state & ps_bit_ready_to_run ) 222 result += "ready_to_run "; 223 if ( m_state & ps_bit_zombie ) 224 result += "zombie "; 225 } 226 result += "]"; 227 return result; 228} 229 230 231//------------------------------------------------------------------------------ 232//"sc_process_b::gen_unique_name" 233// 234// This method generates a unique name within this object instance's namespace. 235//------------------------------------------------------------------------------ 236const char* sc_process_b::gen_unique_name( const char* basename_, 237 bool preserve_first ) 238{ 239 if ( ! m_name_gen_p ) m_name_gen_p = new sc_name_gen; 240 return m_name_gen_p->gen_unique_name( basename_, preserve_first ); 241} 242 243//------------------------------------------------------------------------------ 244//"sc_process_b::remove_dynamic_events" 245// 246// This method removes this object instance from the events in its dynamic 247// event lists. 248// 249// Arguments: 250// skip_timeout = skip cleaning up the timeout event, it will be done 251// by sc_event_notify(). 252//------------------------------------------------------------------------------ 253void 254sc_process_b::remove_dynamic_events( bool skip_timeout ) 255{ 256 sc_method_handle method_h; // This process as a method. 257 sc_thread_handle thread_h; // This process as a thread. 258 259 m_trigger_type = STATIC; 260 switch ( m_process_kind ) 261 { 262 case SC_THREAD_PROC_: 263 case SC_CTHREAD_PROC_: 264 thread_h = SCAST<sc_thread_handle>(this); 265 if ( thread_h->m_timeout_event_p && !skip_timeout ) { 266 thread_h->m_timeout_event_p->remove_dynamic(thread_h); 267 thread_h->m_timeout_event_p->cancel(); 268 } 269 if ( m_event_p ) m_event_p->remove_dynamic( thread_h ); 270 if ( m_event_list_p ) 271 { 272 m_event_list_p->remove_dynamic( thread_h, 0 ); 273 m_event_list_p->auto_delete(); 274 m_event_list_p = 0; 275 } 276 break; 277 case SC_METHOD_PROC_: 278 method_h = SCAST<sc_method_handle>(this); 279 if ( method_h->m_timeout_event_p && !skip_timeout ) { 280 method_h->m_timeout_event_p->remove_dynamic(method_h); 281 method_h->m_timeout_event_p->cancel(); 282 } 283 if ( m_event_p ) m_event_p->remove_dynamic( method_h ); 284 if ( m_event_list_p ) 285 { 286 m_event_list_p->remove_dynamic( method_h, 0 ); 287 m_event_list_p->auto_delete(); 288 m_event_list_p = 0; 289 } 290 break; 291 default: // Some other type, it needs to clean up itself. 292 // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl; 293 break; 294 } 295} 296 297//------------------------------------------------------------------------------ 298//"sc_process_b::remove_static_events" 299// 300// This method removes this object instance from the events in its static 301// event list. 302//------------------------------------------------------------------------------ 303void 304sc_process_b::remove_static_events() 305{ 306 sc_method_handle method_h; // This process as a method. 307 sc_thread_handle thread_h; // This process as a thread. 308 309 switch ( m_process_kind ) 310 { 311 case SC_THREAD_PROC_: 312 case SC_CTHREAD_PROC_: 313 thread_h = SCAST<sc_thread_handle>( this ); 314 for( int i = m_static_events.size() - 1; i >= 0; -- i ) { 315 m_static_events[i]->remove_static( thread_h ); 316 } 317 m_static_events.resize(0); 318 break; 319 case SC_METHOD_PROC_: 320 method_h = DCAST<sc_method_handle>( this ); 321 assert( method_h != 0 ); 322 for( int i = m_static_events.size() - 1; i >= 0; -- i ) { 323 m_static_events[i]->remove_static( method_h ); 324 } 325 m_static_events.resize(0); 326 break; 327 default: // Some other type, it needs to clean up itself. 328 // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl; 329 break; 330 } 331} 332 333//------------------------------------------------------------------------------ 334// "sc_process_b::report_error" 335// 336// This method can be used to issue a report from within a process. 337// The error of the given ID is reported with the given message and 338// the process' name() appended to the report. 339//------------------------------------------------------------------------------ 340void 341sc_process_b::report_error( const char* msgid, const char* msg ) const 342{ 343 std::stringstream sstr; 344 if( msg && msg[0] ) 345 sstr << msg << ": "; 346 sstr << name(); 347 SC_REPORT_ERROR( msgid, sstr.str().c_str() ); 348} 349 350 351//------------------------------------------------------------------------------ 352// "sc_process_b::report_immediate_self_notification" 353// 354// This method is used to report an immediate self-notification 355// that used to trigger the process before the clarification in 1666-2011. 356// The warning is only reported once. 357//------------------------------------------------------------------------------ 358void 359sc_process_b::report_immediate_self_notification() const 360{ 361 static bool once = false; 362 if( !once ) { 363 SC_REPORT_WARNING( SC_ID_IMMEDIATE_SELF_NOTIFICATION_, name() ); 364 once = true; 365 } 366} 367 368//------------------------------------------------------------------------------ 369//"sc_process_b::reset_changed" 370// 371// This method is called when there is a change in the value of the 372// signal that was specified via reset_signal_is, or the value of the 373// m_sticky_reset field. We get called any time m_sticky_reset changes 374// or a signal value changes since, since we may need to throw an exception 375// or clear one. Note that this method may be called when there is no 376// active process, but rather the main simulator is executing so we must 377// check for that case. 378// 379// Arguments: 380// async = true if this is an asynchronous reset. 381// asserted = true if reset being asserted, false if being deasserted. 382//------------------------------------------------------------------------------ 383void sc_process_b::reset_changed( bool async, bool asserted ) 384{ 385 386 // Error out on the corner case: 387 388 if ( !sc_allow_process_control_corners && !async && 389 (m_state & ps_bit_suspended) ) 390 { 391 report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_, 392 "synchronous reset changed on a suspended process" ); 393 } 394 395 // IF THIS OBJECT IS PUSHING UP DAISIES WE ARE DONE: 396 397 if ( m_state & ps_bit_zombie ) return; 398 399 // Reset is being asserted: 400 401 if ( asserted ) 402 { 403 // if ( m_reset_event_p ) m_reset_event_p->notify(); 404 if ( async ) 405 { 406 m_active_areset_n++; 407 if ( sc_is_running() ) throw_reset(true); 408 } 409 else 410 { 411 m_active_reset_n++; 412 if ( sc_is_running() ) throw_reset(false); 413 } 414 } 415 416 // Reset is being deasserted: 417 418 else 419 { 420 if ( async ) 421 { 422 m_active_areset_n--; 423 } 424 else 425 { 426 m_active_reset_n--; 427 } 428 } 429 430 // Clear the throw type if there are no active resets. 431 432 if ( (m_throw_status == THROW_SYNC_RESET || 433 m_throw_status == THROW_ASYNC_RESET) && 434 m_active_areset_n == 0 && m_active_reset_n == 0 && !m_sticky_reset ) 435 { 436 m_throw_status = THROW_NONE; 437 } 438} 439 440//------------------------------------------------------------------------------ 441//"sc_process_b::reset_event" 442// 443// This method returns a reference to the reset event for this object 444// instance. If no event exists one is allocated. 445//------------------------------------------------------------------------------ 446sc_event& sc_process_b::reset_event() 447{ 448 if ( !m_reset_event_p ) 449 { 450 m_reset_event_p = new sc_event( 451 (std::string(SC_KERNEL_EVENT_PREFIX)+"_reset_event").c_str() ); 452 } 453 return *m_reset_event_p; 454} 455 456//------------------------------------------------------------------------------ 457//"sc_process_b::reset_process" 458// 459// This inline method changes the reset state of this object instance and 460// conditionally its descendants. 461// 462// Notes: 463// (1) It is called for sync_reset_on() and sync_reset_off(). It is not used 464// for signal sensitive resets, though all reset flow ends up in 465// reset_changed(). 466// 467// Arguments: 468// rt = source of the reset: 469// * reset_asynchronous - sc_process_handle::reset() 470// * reset_synchronous_off - sc_process_handle::sync_reset_off() 471// * reset_synchronous_on - sc_process_handle::sync_reset_on() 472// descendants = indication of how to process descendants. 473//------------------------------------------------------------------------------ 474void sc_process_b::reset_process( reset_type rt, 475 sc_descendant_inclusion_info descendants ) 476{ 477 478 // PROCESS THIS OBJECT INSTANCE'S DESCENDANTS IF REQUESTED TO: 479 480 if ( descendants == SC_INCLUDE_DESCENDANTS ) 481 { 482 const std::vector<sc_object*> children = get_child_objects(); 483 int child_n = children.size(); 484 485 for ( int child_i = 0; child_i < child_n; child_i++ ) 486 { 487 sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 488 if ( child_p ) child_p->reset_process(rt, descendants); 489 } 490 } 491 492 // PROCESS THIS OBJECT INSTANCE: 493 494 switch (rt) 495 { 496 // One-shot asynchronous reset: remove dynamic sensitivity and throw: 497 // 498 // If this is an sc_method only throw if it is active. 499 500 case reset_asynchronous: 501 if ( sc_get_status() != SC_RUNNING ) 502 { 503 report_error(SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_); 504 } 505 else 506 { 507 remove_dynamic_events(); 508 throw_reset(true); 509 } 510 break; 511 512 // Turn on sticky synchronous reset: use standard reset mechanism. 513 514 case reset_synchronous_on: 515 if ( m_sticky_reset == false ) 516 { 517 m_sticky_reset = true; 518 reset_changed( false, true ); 519 } 520 break; 521 522 // Turn off sticky synchronous reset: use standard reset mechanism. 523 524 default: 525 if ( m_sticky_reset == true ) 526 { 527 m_sticky_reset = false; 528 reset_changed( false, false ); 529 } 530 break; 531 } 532} 533 534//------------------------------------------------------------------------------ 535//"sc_process_b::sc_process_b" 536// 537// This is the object instance constructor for this class. 538//------------------------------------------------------------------------------ 539sc_process_b::sc_process_b( const char* name_p, bool is_thread, bool free_host, 540 SC_ENTRY_FUNC method_p, sc_process_host* host_p, 541 const sc_spawn_options* /* opt_p */ 542) : 543 sc_object( name_p ), 544 file(0), 545 lineno(0), 546 proc_id( simcontext()->next_proc_id()), 547 m_active_areset_n(0), 548 m_active_reset_n(0), 549 m_dont_init( false ), 550 m_dynamic_proc( simcontext()->elaboration_done() ), 551 m_event_p(0), 552 m_event_count(0), 553 m_event_list_p(0), 554 m_exist_p(0), 555 m_free_host( free_host ), 556 m_has_reset_signal( false ), 557 m_has_stack(false), 558 m_is_thread(is_thread), 559 m_last_report_p(0), 560 m_name_gen_p(0), 561 m_process_kind(SC_NO_PROC_), 562 m_references_n(1), 563 m_resets(), 564 m_reset_event_p(0), 565 m_resume_event_p(0), 566 m_runnable_p(0), 567 m_semantics_host_p( host_p ), 568 m_semantics_method_p ( method_p ), 569 m_state(ps_normal), 570 m_static_events(), 571 m_sticky_reset(false), 572 m_term_event_p(0), 573 m_throw_helper_p(0), 574 m_throw_status( THROW_NONE ), 575 m_timed_out(false), 576 m_timeout_event_p(0), 577 m_trigger_type(STATIC), 578 m_unwinding(false) 579{ 580 581 // THIS OBJECT INSTANCE IS NOW THE LAST CREATED PROCESS: 582 583 m_last_created_process_p = this; 584 m_timeout_event_p = new sc_event( 585 (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() ); 586} 587 588//------------------------------------------------------------------------------ 589//"sc_process_b::~sc_process_b" 590// 591// This is the object instance destructor for this class. 592//------------------------------------------------------------------------------ 593sc_process_b::~sc_process_b() 594{ 595 596 // REDIRECT ANY CHILDREN AS CHILDREN OF THE SIMULATION CONTEXT: 597 598 orphan_child_objects(); 599 600 601 // DELETE SEMANTICS OBJECTS IF NEED BE: 602 603 if ( m_free_host ) delete m_semantics_host_p; 604# if !defined(SC_USE_MEMBER_FUNC_PTR) // Remove invocation object. 605 delete m_semantics_method_p; 606# endif 607 608 609 // REMOVE ANY STRUCTURES THAT MAY HAVE BEEN BUILT: 610 611 delete m_last_report_p; 612 delete m_name_gen_p; 613 delete m_reset_event_p; 614 delete m_resume_event_p; 615 delete m_term_event_p; 616 delete m_throw_helper_p; 617 delete m_timeout_event_p; 618 619} 620 621//------------------------------------------------------------------------------ 622//"sc_process_b::terminated_event" 623// 624// This method returns a reference to the terminated event for this object 625// instance. If no event exists one is allocated. 626//------------------------------------------------------------------------------ 627sc_event& sc_process_b::terminated_event() 628{ 629 if ( !m_term_event_p ) 630 { 631 m_term_event_p = new sc_event( 632 (std::string(SC_KERNEL_EVENT_PREFIX)+"_term_event").c_str() ); 633 } 634 return *m_term_event_p; 635} 636 637// +---------------------------------------------------------------------------- 638// |"sc_process_b::trigger_reset_event" 639// | 640// | This method triggers the notify event. It exists because we can't get 641// | sc_event context in sc_process.h because the includes would be 642// | circular... sigh... 643// +---------------------------------------------------------------------------- 644void sc_process_b::trigger_reset_event() 645{ 646 if ( m_reset_event_p ) m_reset_event_p->notify(); 647} 648 649//------------------------------------------------------------------------------ 650//"sc_process_handle::operator sc_cthread_handle" 651// 652//------------------------------------------------------------------------------ 653sc_process_handle::operator sc_cthread_handle() 654{ 655 return DCAST<sc_cthread_handle>(m_target_p); 656} 657 658//------------------------------------------------------------------------------ 659//"sc_process_handle::sc_method_handle" 660// 661//------------------------------------------------------------------------------ 662sc_process_handle::operator sc_method_handle() 663{ 664 return DCAST<sc_method_handle>(m_target_p); 665} 666 667//------------------------------------------------------------------------------ 668//"sc_process_handle::sc_thread_handle" 669// 670//------------------------------------------------------------------------------ 671sc_process_handle::operator sc_thread_handle() 672{ 673 return DCAST<sc_thread_handle>(m_target_p); 674} 675 676} // namespace sc_core 677 678 679/***************************************************************************** 680 681 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 682 changes you are making here. 683 684 Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05 685 Description of Modification: This is the rewrite of process support. It 686 contains some code from the now-defunct 687 sc_process_b.cpp, as well as the former 688 version of sc_process_b.cpp. 689 690 Name, Affiliation, Date: 691 Description of Modification: 692 693 *****************************************************************************/ 694 695// $Log: sc_process.cpp,v $ 696// Revision 1.37 2011/08/24 22:05:51 acg 697// Torsten Maehne: initialization changes to remove warnings. 698// 699// Revision 1.36 2011/08/15 16:43:24 acg 700// Torsten Maehne: changes to remove unused argument warnings. 701// 702// Revision 1.35 2011/08/07 19:08:04 acg 703// Andy Goodrich: moved logs to end of file so line number synching works 704// better between versions. 705// 706// Revision 1.34 2011/07/29 22:55:01 acg 707// Philipp A. Hartmann: add missing include. 708// 709// Revision 1.33 2011/07/29 22:43:41 acg 710// Philipp A. Hartmann: changes to handle case where a process control 711// invocation on a child process causes the list of child processes to change. 712// 713// Revision 1.32 2011/07/24 11:20:03 acg 714// Philipp A. Hartmann: process control error message improvements: 715// (1) Downgrade error to warning for re-kills of processes. 716// (2) Add process name to process messages. 717// (3) drop some superfluous colons in messages. 718// 719// Revision 1.31 2011/04/19 15:04:27 acg 720// Philipp A. Hartmann: clean up SC_ID messages. 721// 722// Revision 1.30 2011/04/14 22:33:43 acg 723// Andy Goodrich: added missing checks for a process being a zombie. 724// 725// Revision 1.29 2011/04/13 05:00:43 acg 726// Andy Goodrich: removed check for method process in termination_event() 727// since with the new IEEE 1666 2011 its legal. 728// 729// Revision 1.28 2011/04/13 02:44:26 acg 730// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the 731// throw status will be set back to THROW_*_RESET if reset is active and 732// the check for an unwind being complete was expecting THROW_NONE as the 733// clearing of THROW_NOW. 734// 735// Revision 1.27 2011/04/10 22:17:35 acg 736// Andy Goodrich: added trigger_reset_event() to allow sc_process.h to 737// contain the run_process() inline method. sc_process.h cannot have 738// sc_simcontext information because of recursive includes. 739// 740// Revision 1.26 2011/04/08 22:33:08 acg 741// Andy Goodrich: moved the semantics() method to the header file and made 742// it an inline method. 743// 744// Revision 1.25 2011/04/08 18:24:48 acg 745// Andy Goodrich: moved reset_changed() to .cpp since it needs visibility 746// to sc_simcontext. 747// 748// Revision 1.24 2011/04/05 20:50:57 acg 749// Andy Goodrich: 750// (1) changes to make sure that event(), posedge() and negedge() only 751// return true if the clock has not moved. 752// (2) fixes for method self-resumes. 753// (3) added SC_PRERELEASE_VERSION 754// (4) removed kernel events from the object hierarchy, added 755// sc_hierarchy_name_exists(). 756// 757// Revision 1.23 2011/04/05 06:25:38 acg 758// Andy Goodrich: new checks for simulation running in reset_process(). 759// 760// Revision 1.22 2011/03/20 13:43:23 acg 761// Andy Goodrich: added async_signal_is() plus suspend() as a corner case. 762// 763// Revision 1.21 2011/03/12 21:07:51 acg 764// Andy Goodrich: changes to kernel generated event support. 765// 766// Revision 1.20 2011/03/07 17:38:43 acg 767// Andy Goodrich: tightening up of checks for undefined interaction between 768// synchronous reset and suspend. 769// 770// Revision 1.19 2011/03/06 23:30:13 acg 771// Andy Goodrich: refining suspend - sync reset corner case checking so that 772// the following are error situations: 773// (1) Calling suspend on a process with a reset_signal_is() specification 774// or sync_reset_on() is active. 775// (2) Calling sync_reset_on() on a suspended process. 776// 777// Revision 1.18 2011/03/06 19:57:11 acg 778// Andy Goodrich: refinements for the illegal suspend - synchronous reset 779// interaction. 780// 781// Revision 1.17 2011/03/06 16:47:09 acg 782// Andy Goodrich: changes for testing sync_reset - suspend corner cases. 783// 784// Revision 1.16 2011/03/06 15:57:57 acg 785// Andy Goodrich: added process control corner case checks. Changes for 786// named events. 787// 788// Revision 1.15 2011/02/18 20:27:14 acg 789// Andy Goodrich: Updated Copyrights. 790// 791// Revision 1.14 2011/02/17 19:52:13 acg 792// Andy Goodrich: 793// (1) Simplfied process control usage. 794// (2) Changed dump_status() to dump_state with new signature. 795// 796// Revision 1.13 2011/02/13 21:47:37 acg 797// Andy Goodrich: update copyright notice. 798// 799// Revision 1.12 2011/02/13 21:41:34 acg 800// Andy Goodrich: get the log messages for the previous check in correct. 801// 802// Revision 1.11 2011/02/13 21:32:24 acg 803// Andy Goodrich: moved sc_process_b::reset_process() from header file 804// to cpp file. Added dump_status() to print out the status of a 805// process. 806// 807// Revision 1.10 2011/02/04 15:27:36 acg 808// Andy Goodrich: changes for suspend-resume semantics. 809// 810// Revision 1.9 2011/02/01 21:06:12 acg 811// Andy Goodrich: new layout for the process_state enum. 812// 813// Revision 1.8 2011/01/25 20:50:37 acg 814// Andy Goodrich: changes for IEEE 1666 2011. 815// 816// Revision 1.7 2011/01/19 23:21:50 acg 817// Andy Goodrich: changes for IEEE 1666 2011 818// 819// Revision 1.6 2011/01/18 20:10:45 acg 820// Andy Goodrich: changes for IEEE1666_2011 semantics. 821// 822// Revision 1.5 2010/07/22 20:02:33 acg 823// Andy Goodrich: bug fixes. 824// 825// Revision 1.4 2009/05/22 16:06:29 acg 826// Andy Goodrich: process control updates. 827// 828// Revision 1.3 2008/05/22 17:06:26 acg 829// Andy Goodrich: updated copyright notice to include 2008. 830// 831// Revision 1.2 2007/09/20 20:32:35 acg 832// Andy Goodrich: changes to the semantics of throw_it() to match the 833// specification. A call to throw_it() will immediately suspend the calling 834// thread until all the throwees have executed. At that point the calling 835// thread will be restarted before the execution of any other threads. 836// 837// Revision 1.1.1.1 2006/12/15 20:20:05 acg 838// SystemC 2.3 839// 840// Revision 1.6 2006/04/20 17:08:17 acg 841// Andy Goodrich: 3.0 style process changes. 842// 843// Revision 1.5 2006/04/11 23:13:21 acg 844// Andy Goodrich: Changes for reduced reset support that only includes 845// sc_cthread, but has preliminary hooks for expanding to method and thread 846// processes also. 847// 848// Revision 1.4 2006/01/24 20:49:05 acg 849// Andy Goodrich: changes to remove the use of deprecated features within the 850// simulator, and to issue warning messages when deprecated features are used. 851// 852// Revision 1.3 2006/01/13 18:44:30 acg 853// Added $Log to record CVS changes into the source. 854// 855