SystemC 3.0.0
Accellera SystemC proof-of-concept library
sc_event.h
Go to the documentation of this file.
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_event.h --
23
24 Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
25
26 CHANGE LOG AT THE END OF THE FILE
27 *****************************************************************************/
28
29
30#ifndef SC_EVENT_H
31#define SC_EVENT_H
32
38
39#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
40#pragma warning(push)
41#pragma warning(disable: 4251) // DLL import for std::string
42#endif
43
44namespace sc_core {
45
46// forward declarations
47class sc_event;
48class sc_event_timed;
49class sc_event_list;
50class sc_event_or_list;
51class sc_event_and_list;
52class sc_object;
53class sc_object_host;
54class sc_signal_channel;
55
56// friend function declarations
57SC_API int sc_notify_time_compare( const void*, const void* );
58
59// ----------------------------------------------------------------------------
60// CLASS : sc_event_expr
61//
62// The event expression class.
63// ----------------------------------------------------------------------------
64
65template< typename T >
67{
68 friend class sc_event;
69 friend class sc_event_and_list;
70 friend class sc_event_or_list;
71
72 typedef T type;
73
74 inline sc_event_expr()
75 : m_expr( new T(true) )
76 {}
77
78public:
79
80 inline sc_event_expr( sc_event_expr const & e) // move semantics
81 : m_expr(e.m_expr)
82 {
83 e.m_expr = 0;
84 }
85
86 T const & release() const
87 {
88 sc_assert( m_expr );
89 T* expr = m_expr;
90 m_expr=0;
91 return *expr;
92 }
93
94 void push_back( sc_event const & e) const
95 {
96 sc_assert( m_expr );
97 m_expr->push_back(e);
98 }
99
100 void push_back( type const & el) const
101 {
102 sc_assert( m_expr );
103 m_expr->push_back(el);
104 }
105 operator T const &() const
106 {
107 return release();
108 }
109
111 {
112 delete m_expr;
113 }
114
115private:
116 mutable type * m_expr;
117
118 // disabled
119 void operator=( sc_event_expr const & );
120};
121
122// ----------------------------------------------------------------------------
123// CLASS : sc_event_list
124//
125// Base class for lists of events.
126// ----------------------------------------------------------------------------
127
129{
130 friend class sc_process_b;
131 friend class sc_method_process;
132 friend class sc_thread_process;
133 friend void sc_thread_cor_fn( void* arg );
134
135public:
137 sc_event_list& operator = ( const sc_event_list& );
138
139 int size() const;
140 bool empty() const
141 { return size() == 0; }
142
143protected:
144
145 void push_back( const sc_event& );
146 void push_back( const sc_event_list& );
147
148 explicit
149 sc_event_list( bool and_list_, bool auto_delete_ = false );
150
151 sc_event_list( const sc_event&,
152 bool and_list_,
153 bool auto_delete_ = false );
154
156
157 void swap( sc_event_list& );
158 void move_from( const sc_event_list& );
159
160 bool and_list() const;
161
166
167 bool busy() const;
168 bool temporary() const;
169 void auto_delete() const;
170
173
174private:
175
176 std::vector<const sc_event*> m_events;
177 bool m_and_list;
178 bool m_auto_delete;
179 mutable unsigned m_busy;
180};
181
182
183// ----------------------------------------------------------------------------
184// CLASS : sc_event_and_list
185//
186// AND list of events.
187// ----------------------------------------------------------------------------
188
190: public sc_event_list
191{
192 friend class sc_event;
193 friend class sc_event_expr<sc_event_and_list>;
194 friend class sc_process_b;
195 friend class sc_method_process;
196 friend class sc_thread_process;
197
198protected:
199
200 explicit
201 sc_event_and_list( bool auto_delete_ );
202
203public:
204
206 sc_event_and_list( const sc_event& );
207
208 void swap( sc_event_and_list& );
211
214};
215
217
218// ----------------------------------------------------------------------------
219// CLASS : sc_event_or_list
220//
221// OR list of events.
222// ----------------------------------------------------------------------------
223
225: public sc_event_list
226{
227 friend class sc_event;
228 friend class sc_event_expr<sc_event_or_list>;
229 friend class sc_process_b;
230 friend class sc_method_process;
231 friend class sc_thread_process;
232
233protected:
234
235 explicit
236 sc_event_or_list( bool auto_delete_ );
237
238public:
240 sc_event_or_list( const sc_event& );
241 void swap( sc_event_or_list& );
246};
247
249
250// ----------------------------------------------------------------------------
251// CLASS : sc_event
252//
253// The event class.
254// ----------------------------------------------------------------------------
255
257{
258 friend class sc_event_list;
259 friend class sc_event_timed;
260 friend class sc_simcontext;
261 friend class sc_object_host;
262 friend class sc_process_b;
263 friend class sc_process_handle;
264 friend class sc_method_process;
265 friend class sc_thread_process;
266 friend void sc_thread_cor_fn( void* arg );
267 friend class sc_clock;
268 friend class sc_event_queue;
269 friend class sc_signal_channel;
270 template<typename IF> friend class sc_fifo;
271 friend class sc_semaphore;
272 friend class sc_mutex;
273 friend class sc_join;
274 friend class sc_trace_file;
275
276public:
277
279 explicit sc_event( const char* name );
281
282 void cancel();
283
284 const char* basename() const;
285 const char* name() const
286 { return m_name.c_str(); }
288 { return m_parent_with_hierarchy_flag; }
289 bool in_hierarchy() const
290 { return m_parent_with_hierarchy_flag.get_flag() == true; }
291
292 void notify();
293 void notify( const sc_time& );
294 void notify( double, sc_time_unit );
295
297 void notify_delayed( const sc_time& );
298 void notify_delayed( double, sc_time_unit );
299
300 sc_event_or_expr operator | ( const sc_event& ) const;
302 sc_event_and_expr operator & ( const sc_event& ) const;
304
305 // has this event been triggered in the current delta cycle?
306 bool triggered() const;
307
308 // never notified event
309 static const sc_event& none() { return sc_get_curr_simcontext()->null_event(); }
310
311private:
312
313 void add_static( sc_method_handle ) const;
314 void add_static( sc_thread_handle ) const;
315 void add_dynamic( sc_method_handle ) const;
316 void add_dynamic( sc_thread_handle ) const;
317
318 void notify_internal( const sc_time& );
319 void notify_next_delta();
320
321 bool remove_static( sc_method_handle ) const;
322 bool remove_static( sc_thread_handle ) const;
323 bool remove_dynamic( sc_method_handle ) const;
324 bool remove_dynamic( sc_thread_handle ) const;
325
326 void register_event( const char* name, bool is_kernel_event = false );
327 void reset();
328
329 void trigger();
330
331private:
332
333 enum notify_t { NONE, DELTA, TIMED };
334
335 sc_simcontext* m_simc;
336 sc_dt::uint64 m_trigger_stamp; // delta of last trigger
337 notify_t m_notify_type;
338 int m_delta_event_index;
339 sc_event_timed* m_timed;
340
341 mutable std::vector<sc_method_handle> m_methods_static;
342 mutable std::vector<sc_method_handle> m_methods_dynamic;
343 mutable std::vector<sc_thread_handle> m_threads_static;
344 mutable std::vector<sc_thread_handle> m_threads_dynamic;
345
346 std::string m_name; // name of the event
347 sc_ptr_flag<sc_object_host> m_parent_with_hierarchy_flag; // parent object of
348 // the event, extra flag is set to true, if event is registered in hierarchy
349
350private:
351 static struct kernel_tag {} kernel_event;
352 explicit sc_event( kernel_tag, const char* name = NULL );
353
354 // disabled
355 sc_event( const sc_event& );
356 sc_event& operator = ( const sc_event& );
357};
358
359// ----------------------------------------------------------------------------
360// CLASS : sc_event_timed
361//
362// Class for storing the time to notify a timed event.
363// ----------------------------------------------------------------------------
364
366{
367 friend class sc_event;
368 friend class sc_simcontext;
369
370 friend SC_API int sc_notify_time_compare( const void*, const void* );
371
372private:
373
374 sc_event_timed( sc_event* e, const sc_time& t )
375 : m_event( e ), m_notify_time( t )
376 {}
377
379 { if( m_event != 0 ) { m_event->m_timed = 0; } }
380
381 sc_event* event() const
382 { return m_event; }
383
384 const sc_time& notify_time() const
385 { return m_notify_time; }
386
387 static void* operator new( std::size_t )
388 { return allocate(); }
389
390 static void operator delete( void* p, std::size_t )
391 { deallocate( p ); }
392
393private:
394
395 // dedicated memory management
396 static void* allocate();
397 static void deallocate( void* );
398
399private:
400
401 sc_event* m_event;
402 sc_time m_notify_time;
403
404private:
405
406 // disabled
407 sc_event_timed();
408 sc_event_timed( const sc_event_timed& );
409 sc_event_timed& operator = ( const sc_event_timed& );
410};
411
412
413// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
414
415inline
416void
418{
419 notify( sc_time( v, tu, m_simc ) );
420}
421
422
423inline
424void
425sc_event::notify_internal( const sc_time& t )
426{
427 if( t == SC_ZERO_TIME ) {
428 // add this event to the delta events set
429 m_delta_event_index = m_simc->add_delta_event( this );
430 m_notify_type = DELTA;
431 } else {
432 sc_event_timed* et =
433 new sc_event_timed( this, m_simc->time_stamp() + t );
434 m_simc->add_timed_event( et );
435 m_timed = et;
436 m_notify_type = TIMED;
437 }
438}
439
440inline
441void
442sc_event::notify_next_delta()
443{
444 if( m_notify_type != NONE ) {
446 }
447 // add this event to the delta events set
448 m_delta_event_index = m_simc->add_delta_event( this );
449 m_notify_type = DELTA;
450}
451
452inline
453void
455{
456 notify_delayed( sc_time( v, tu, m_simc ) );
457}
458
459
460inline
461void
462sc_event::add_static( sc_method_handle method_h ) const
463{
464 m_methods_static.push_back( method_h );
465}
466
467inline
468void
469sc_event::add_static( sc_thread_handle thread_h ) const
470{
471 m_threads_static.push_back( thread_h );
472}
473
474inline
475void
476sc_event::add_dynamic( sc_method_handle method_h ) const
477{
478 m_methods_dynamic.push_back( method_h );
479}
480
481inline
482void
483sc_event::add_dynamic( sc_thread_handle thread_h ) const
484{
485 m_threads_dynamic.push_back( thread_h );
486}
487
488
489// ----------------------------------------------------------------------------
490// Deprecated functional notation for notifying events.
491// ----------------------------------------------------------------------------
492
493extern void notify( sc_event& e );
494extern void notify( const sc_time& t, sc_event& e );
495extern void notify( double v, sc_time_unit tu, sc_event& e );
496
497
498// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
499
500inline
501sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ )
502 : m_events()
503 , m_and_list( and_list_ )
504 , m_auto_delete( auto_delete_ )
505 , m_busy( 0 )
506{
507}
508
509inline
511 bool and_list_,
512 bool auto_delete_ )
513 : m_events()
514 , m_and_list( and_list_ )
515 , m_auto_delete( auto_delete_ )
516 , m_busy(0)
517{
518 m_events.push_back( &e );
519}
520
521inline
523 : m_events()
524 , m_and_list( that.m_and_list )
525 , m_auto_delete( false )
526 , m_busy( 0 )
527{
528 move_from( that );
529 that.auto_delete(); // free automatic lists
530}
531
532inline
535{
536 if( m_busy )
538
539 if( SC_LIKELY_(this != &that) ) {
540 move_from( that );
541 that.auto_delete(); // free automatic lists
542 }
543
544 return *this;
545}
546
547inline
549{
550 if( m_busy )
552}
553
554inline
555void
557{
558 if( busy() || that.busy() )
560 m_events.swap( that.m_events );
561}
562
563inline
564void
566{
567 if( that.temporary() ) {
568 swap( const_cast<sc_event_list&>(that) ); // move from source
569 } else {
570 m_events = that.m_events; // copy from source
571 }
572}
573
574inline
575int
577{
578 return static_cast<int>(m_events.size());
579}
580
581inline
582bool
584{
585 return m_and_list;
586}
587
588
589inline
590bool
592{
593 return m_busy != 0;
594}
595
596
597inline
598bool
600{
601 return m_auto_delete && ! m_busy;
602}
603
604#if defined(__GNUC__) && (__GNUC__ >= 11)
605// Ignore overly strict -Wfree-nonheap-object warning on GCC 11.0 and later
606// -- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54202
607#pragma GCC diagnostic push
608#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
609#endif
610
611inline
612void
614{
615 if( m_busy ) {
616 --m_busy;
617 }
618 if( ! m_busy && m_auto_delete ) {
619 delete this;
620 }
621}
622
623#if defined(__GNUC__) && (__GNUC__ >= 11)
624#pragma GCC diagnostic pop
625#endif
626
627
628// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
629
630inline
632 : sc_event_list( false )
633{}
634
635inline
637: sc_event_list( false )
638{
639 push_back( e );
640}
641
642inline
644: sc_event_list( false, auto_delete_ )
645{}
646
647inline
650{
651 if( busy() )
653
654 push_back( e );
655 return *this;
656}
657
658inline
661{
662 if( busy() )
664
665 push_back( el );
666 return *this;
667}
668
669inline
672{
673 sc_event_or_expr expr;
674 expr.push_back( *this );
675 expr.push_back( e2 );
676 return expr;
677}
678
679inline
682{
683 sc_event_or_expr expr;
684 expr.push_back( *this );
685 expr.push_back( e2 );
686 return expr;
687}
688
689
690// sc_event
691
692inline
695{
696 sc_event_or_expr expr;
697 expr.push_back( *this );
698 expr.push_back( e2 );
699 return expr;
700}
701
702inline
705{
706 sc_event_or_expr expr;
707 expr.push_back( *this );
708 expr.push_back( e2 );
709 return expr;
710}
711
712// sc_event_expr
713
714inline
717{
718 expr.push_back( e );
719 return expr;
720}
721
722inline
725{
726 expr.push_back( el );
727 return expr;
728}
729
730inline
731void
733{
734 sc_event_list::swap( that );
735}
736
737
738
739// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
740
741inline
743 : sc_event_list( true )
744{}
745
746inline
748: sc_event_list( true )
749{
750 push_back( e );
751}
752
753inline
755: sc_event_list( true, auto_delete_ )
756{}
757
758inline
759void
761{
762 sc_event_list::swap( that );
763}
764
765
766inline
769{
770 if( busy() )
772
773 push_back( e );
774 return *this;
775}
776
777inline
780{
781 if( busy() )
783
784 push_back( el );
785 return *this;
786}
787
788inline
791{
793 expr.push_back( *this );
794 expr.push_back( e );
795 return expr;
796}
797
798inline
801{
803 expr.push_back( *this );
804 expr.push_back( el );
805 return expr;
806}
807
808// sc_event
809
810inline
813{
815 expr.push_back( *this );
816 expr.push_back( e2 );
817 return expr;
818}
819
820inline
823{
825 expr.push_back( *this );
826 expr.push_back( e2 );
827 return expr;
828}
829
830// sc_event_expr
831
832inline
835{
836 expr.push_back( e );
837 return expr;
838}
839
840inline
843{
844 expr.push_back( el );
845 return expr;
846}
847
848} // namespace sc_core
849
850#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
851#pragma warning(pop)
852#endif
853
854// $Log: sc_event.h,v $
855// Revision 1.14 2011/08/29 18:04:32 acg
856// Philipp A. Hartmann: miscellaneous clean ups.
857//
858// Revision 1.13 2011/08/26 20:46:09 acg
859// Andy Goodrich: moved the modification log to the end of the file to
860// eliminate source line number skew when check-ins are done.
861//
862// Revision 1.12 2011/08/24 22:05:50 acg
863// Torsten Maehne: initialization changes to remove warnings.
864//
865// Revision 1.11 2011/03/12 21:07:51 acg
866// Andy Goodrich: changes to kernel generated event support.
867//
868// Revision 1.10 2011/03/06 15:55:11 acg
869// Andy Goodrich: Changes for named events.
870//
871// Revision 1.9 2011/03/05 01:39:21 acg
872// Andy Goodrich: changes for named events.
873//
874// Revision 1.8 2011/02/18 20:27:14 acg
875// Andy Goodrich: Updated Copyrights.
876//
877// Revision 1.7 2011/02/13 21:47:37 acg
878// Andy Goodrich: update copyright notice.
879//
880// Revision 1.6 2011/02/01 21:03:23 acg
881// Andy Goodrich: new return codes for trigger_dynamic calls.
882//
883// Revision 1.5 2011/01/18 20:10:44 acg
884// Andy Goodrich: changes for IEEE1666_2011 semantics.
885//
886// Revision 1.4 2010/12/07 20:09:11 acg
887// Andy Goodrich: writer policy fix.
888//
889// Revision 1.3 2009/05/22 16:06:29 acg
890// Andy Goodrich: process control updates.
891//
892// Revision 1.2 2008/05/22 17:06:25 acg
893// Andy Goodrich: updated copyright notice to include 2008.
894//
895// Revision 1.1.1.1 2006/12/15 20:20:05 acg
896// SystemC 2.3
897//
898// Revision 1.8 2006/05/26 20:33:16 acg
899// Andy Goodrich: changes required by additional platform compilers (i.e.,
900// Microsoft VC++, Sun Forte, HP aCC).
901//
902// Revision 1.7 2006/05/08 17:57:51 acg
903// Andy Goodrich: added David Long's forward declarations for friend
904// functions, methods, and operators to keep the Microsoft compiler happy.
905//
906// Revision 1.6 2006/04/11 23:13:20 acg
907// Andy Goodrich: Changes for reduced reset support that only includes
908// sc_cthread, but has preliminary hooks for expanding to method and thread
909// processes also.
910//
911// Revision 1.5 2006/01/24 20:56:00 acg
912// Andy Goodrich: fixed up CVS comment.
913//
914// Revision 1.4 2006/01/24 20:48:14 acg
915// Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
916// new implementation-dependent methods, notify_next_delta() & notify_internal()
917// to replace calls to notify_delayed() from within the simulator. These two
918// new methods are simpler than notify_delayed() and should speed up simulations
919//
920// Revision 1.3 2006/01/13 18:44:29 acg
921// Added $Log to record CVS changes into the source.
922//
923
924#endif
925
926// Taf!
#define SC_LIKELY_(x)
Definition: sc_cmnhdr.h:86
#define SC_API
Definition: sc_cmnhdr.h:148
#define sc_assert(expr)
Definition: sc_report.h:248
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:217
sc_event_or_expr operator|(sc_event_or_expr expr, sc_event const &e)
Definition: sc_event.h:716
class SC_API sc_simcontext
Definition: sc_object.h:50
class sc_method_process * sc_method_handle
Definition: sc_process.h:61
class SC_API sc_event
Definition: sc_interface.h:36
const char SC_ID_NOTIFY_DELAYED_[]
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:62
SC_API int sc_notify_time_compare(const void *, const void *)
void notify(sc_event &e)
sc_simcontext * sc_get_curr_simcontext()
class SC_API sc_object
Definition: sc_object.h:46
SC_API const sc_time SC_ZERO_TIME
sc_time_unit
Definition: sc_time.h:82
sc_event_expr< sc_event_or_list > sc_event_or_expr
Definition: sc_event.h:248
class SC_API sc_object_host
Definition: sc_object.h:47
sc_event_expr< sc_event_and_list > sc_event_and_expr
Definition: sc_event.h:216
sc_event_and_expr operator&(sc_event_and_expr expr, sc_event const &e)
Definition: sc_event.h:834
X & operator|=(sc_proxy< X > &px, const sc_proxy< Y > &py)
Definition: sc_lv_base.h:474
unsigned long long uint64
Definition: sc_nbdefs.h:216
X & operator&=(sc_proxy< X > &px, const sc_proxy< Y > &py)
Definition: sc_lv_base.h:340
void push_back(type const &el) const
Definition: sc_event.h:100
T const & release() const
Definition: sc_event.h:86
sc_event_expr(sc_event_expr const &e)
Definition: sc_event.h:80
void push_back(sc_event const &e) const
Definition: sc_event.h:94
void push_back(const sc_event &)
bool temporary() const
Definition: sc_event.h:599
void add_dynamic(sc_thread_handle) const
bool and_list() const
Definition: sc_event.h:583
friend void sc_thread_cor_fn(void *arg)
void remove_dynamic(sc_thread_handle, const sc_event *) const
void report_invalid_modification() const
sc_event_list(const sc_event_list &)
Definition: sc_event.h:522
void auto_delete() const
Definition: sc_event.h:613
bool empty() const
Definition: sc_event.h:140
bool busy() const
Definition: sc_event.h:591
void remove_dynamic(sc_method_handle, const sc_event *) const
sc_event_list & operator=(const sc_event_list &)
Definition: sc_event.h:534
void move_from(const sc_event_list &)
Definition: sc_event.h:565
void push_back(const sc_event_list &)
void report_premature_destruction() const
int size() const
Definition: sc_event.h:576
void add_dynamic(sc_method_handle) const
void swap(sc_event_list &)
Definition: sc_event.h:556
void swap(sc_event_and_list &)
Definition: sc_event.h:760
sc_event_and_list & operator&=(const sc_event &)
Definition: sc_event.h:768
sc_event_expr< sc_event_and_list > operator&(const sc_event &)
Definition: sc_event.h:790
sc_event_expr< sc_event_or_list > operator|(const sc_event &) const
Definition: sc_event.h:671
sc_event_or_list & operator|=(const sc_event &)
Definition: sc_event.h:649
void swap(sc_event_or_list &)
Definition: sc_event.h:732
sc_event(const char *name)
friend void sc_thread_cor_fn(void *arg)
bool triggered() const
const char * basename() const
void notify_delayed(const sc_time &)
static const sc_event & none()
Definition: sc_event.h:309
const char * name() const
Definition: sc_event.h:285
bool in_hierarchy() const
Definition: sc_event.h:289
sc_object * get_parent_object() const
Definition: sc_event.h:287
friend class sc_event_timed
Definition: sc_event.h:259
void notify(const sc_time &)
sc_event_or_expr operator|(const sc_event &) const
Definition: sc_event.h:694
sc_event_and_expr operator&(const sc_event &) const
Definition: sc_event.h:812
friend SC_API int sc_notify_time_compare(const void *, const void *)
sc_event & null_event()
const sc_time & time_stamp() const