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