SystemC 3.0.0
Accellera SystemC proof-of-concept library
sc_signal.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_signal.h -- The sc_signal<T> primitive channel class.
23
24 Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
25
26 CHANGE LOG IS AT THE END OF THE FILE
27 *****************************************************************************/
28
29#ifndef SC_SIGNAL_H
30#define SC_SIGNAL_H
31
41#include <typeinfo>
42
43namespace sc_core {
44
45inline
46bool
47sc_writer_policy_check_write::check_write( sc_object* target, bool /*value_changed*/ )
48{
50 if( SC_UNLIKELY_( !m_writer_p.valid() ) ) {
51 // always store first writer
52 sc_process_handle( writer_p ).swap( m_writer_p );
53 } else if( SC_UNLIKELY_(m_writer_p != writer_p && writer_p != 0) ) {
54 // Alternative option: only flag error, if either
55 // - we enforce conflicts across multiple evaluation phases, or
56 // - the new value is different from the previous write
57 //if( !m_delta_only || value_changed )
58 {
60 // error has been suppressed, accept check as well,
61 // but update current writer to the last "successful" one
62 sc_process_handle( writer_p ).swap( m_writer_p );
63 }
64 }
65 return true;
66}
67
68
69inline void
71{
72 if( m_delta_only ) // reset, if we're only checking for delta conflicts
74}
75
76
77// ----------------------------------------------------------------------------
78// CLASS : sc_signal_channel
79//
80// The sc_signal type-agnostic primitive channel base class.
81// ----------------------------------------------------------------------------
82
84 : public sc_prim_channel
85{
86protected:
87
88 sc_signal_channel( const char* name_ )
89 : sc_prim_channel( name_ )
90 , m_change_event_p( 0 )
91 , m_change_stamp( ~sc_dt::UINT64_ONE )
92 {}
93
94public:
95
97
98 // interface methods
99
100 virtual const char* kind() const
101 { return "sc_signal_channel"; }
102
103 // get the default event
104 const sc_event& default_event() const
105 { return value_changed_event(); }
106
107 // get the value changed event
109
110 // was there an event?
111 bool event() const
112 { return simcontext()->event_occurred(m_change_stamp); }
113
114protected:
115 void do_update();
116
117 // reporting to avoid code bloat in sc_signal_t
118
121 void deprecated_trace() const;
122
123 sc_event* lazy_kernel_event( sc_event**, const char* ) const;
124 void notify_next_delta( sc_event* ev ) const
125 { if( ev ) ev->notify_next_delta(); }
126
127protected:
128 mutable sc_event* m_change_event_p; // value change event if present.
129 sc_dt::uint64 m_change_stamp; // delta of last event
130
131private:
132 // disabled
133 sc_signal_channel( const sc_signal_channel& ) /* = delete */;
134 sc_signal_channel& operator=( const sc_signal_channel& ) /* = delete */;
135};
136
137
138inline
139::std::ostream&
140operator << ( ::std::ostream& os, const sc_signal_channel& a )
141{
142 a.print( os );
143 return os;
144}
145
146
147// ----------------------------------------------------------------------------
148// CLASS : sc_signal_t<T, POL> (implementation-defined)
149//
150// The generic sc_signal<T,POL> primitive channel base class
151// (to reduce complexity of specialisations for bool and sc_logic)
152// ----------------------------------------------------------------------------
153
154template< class T, sc_writer_policy POL >
156 : public sc_signal_inout_if<T>
157 , public sc_signal_channel
158 , protected sc_writer_policy_check<POL>
159{
160protected:
165
166protected:
167
168 // constructor and destructor
169
170 sc_signal_t( const char* name_, const T& initial_value_ )
171 : base_type( name_ )
172 , m_cur_val( initial_value_ )
173 , m_new_val( initial_value_ )
174 {}
175
176 virtual ~sc_signal_t() {} /* = default; */
177
178public:
179
180 // interface methods
181
182 virtual const char* kind() const
183 { return "sc_signal"; }
184
185 virtual void register_port( sc_port_base&, const char* );
186
188 { return POL; }
189
190 // get the default event
191 virtual const sc_event& default_event() const
192 { return value_changed_event(); }
193
194 // get the value changed event
195 virtual const sc_event& value_changed_event() const
197
198 // read the current value
199 virtual const T& read() const
200 { return m_cur_val; }
201
202 // get a reference to the current value (for tracing)
203 virtual const T& get_data_ref() const
204 {
206 return m_cur_val;
207 }
208
209 // was there an event?
210 virtual bool event() const
211 { return base_type::event(); }
212
213 // write the new value
214 virtual void write( const T& );
215
216
217 // other methods
218
219 operator const T& () const
220 { return read(); }
221
222
223 // assignment
224 this_type& operator = ( const T& a )
225 { write( a ); return *this; }
226
228 { write( a.read() ); return *this; }
229
231 { write( a.read() ); return *this; }
232
233
234 const T& get_new_value() const
235 {
237 return m_new_val;
238 }
239
240
241 void trace( sc_trace_file* tf ) const
242 {
244# ifdef DEBUG_SYSTEMC
245 sc_trace( tf, read(), name() );
246# else
247 if ( tf ) {}
248# endif
249 }
250
251
252 virtual void print( ::std::ostream& = ::std::cout ) const;
253 virtual void dump( ::std::ostream& = ::std::cout ) const;
254
255
256protected:
257
258 virtual void update();
259 void do_update();
260
261protected:
262 T m_cur_val; // current value of object.
263 T m_new_val; // next value of object.
264
265private:
266 // disabled
267 sc_signal_t( const sc_signal_t& ) /* = delete */;
268};
269
270// ----------------------------------------------------------------------------
271
272template< class T, sc_writer_policy POL >
273inline
274void
276 , const char* if_typename_ )
277{
278 bool is_output = std::string( if_typename_ ) == typeid(if_type).name();
279 if( !policy_type::check_port( this, &port_, is_output ) )
280 ((void)0); // fallback? error has been suppressed ...
281}
282
283
284// write the new value
285
286template< class T, sc_writer_policy POL >
287inline
288void
290{
291 // first write per eval phase: m_new_val == m_cur_val
292 bool value_changed = !( m_new_val == value_ );
293 if ( !policy_type::check_write(this, value_changed) )
294 return;
295
296 m_new_val = value_;
297 if( value_changed || policy_type::needs_update() ) {
298 request_update();
299 }
300}
301
302
303template< class T, sc_writer_policy POL >
304inline
305void
306sc_signal_t<T,POL>::print( ::std::ostream& os ) const
307{
308 os << m_cur_val;
309}
310
311template< class T, sc_writer_policy POL >
312void
313sc_signal_t<T,POL>::dump( ::std::ostream& os ) const
314{
315 os << " name = " << name() << ::std::endl;
316 os << " value = " << m_cur_val << ::std::endl;
317 os << "new value = " << m_new_val << ::std::endl;
318}
319
320
321template< class T, sc_writer_policy POL >
322void
324{
325 policy_type::update();
326 if( !( m_new_val == m_cur_val ) ) {
327 do_update();
328 }
329}
330
331template< class T, sc_writer_policy POL >
332inline void
334{
335 base_type::do_update();
336 m_cur_val = m_new_val;
337}
338
339// ----------------------------------------------------------------------------
340// CLASS : sc_signal<T, POL>
341//
342// The sc_signal<T,POL> primitive channel class
343// ----------------------------------------------------------------------------
344
345template< class T, sc_writer_policy POL = SC_DEFAULT_WRITER_POLICY >
347 : public sc_signal_t<T,POL>
348{
349public:
353 typedef T value_type;
355
356 // constructors and destructor
357
359 : base_type( sc_gen_unique_name( "signal" ), value_type() )
360 {}
361
362 explicit
363 sc_signal( const char* name_ )
364 : base_type( name_, value_type() )
365 {}
366
367 sc_signal( const char* name_, const value_type& initial_value_ )
368 : base_type( name_, initial_value_ )
369 {}
370
371 virtual ~sc_signal() {} /* = default; */
372
373 // assignment
374 using base_type::operator=;
376 { base_type::operator=(a); return *this; }
377
378private:
379 // disabled
380 sc_signal( const sc_signal& ) /* = delete */;
381};
382
383
384// ----------------------------------------------------------------------------
385// CLASS : sc_signal<bool>
386//
387// Specialization of sc_signal<T> for type bool.
388// ----------------------------------------------------------------------------
389
391
395
396template< sc_writer_policy POL >
397class SC_API sc_signal<bool,POL>
398 : public sc_signal_t<bool,POL>
399{
400protected:
403 typedef bool value_type;
405
406public:
407
408 // constructors and destructor
409
411 : base_type( sc_gen_unique_name( "signal" ), value_type() )
412 , m_negedge_event_p( 0 ) , m_posedge_event_p( 0 ) , m_reset_p( 0 )
413 {}
414
415 explicit
416 sc_signal( const char* name_ )
417 : base_type( name_, value_type() )
418 , m_negedge_event_p( 0 ) , m_posedge_event_p( 0 ) , m_reset_p( 0 )
419 {}
420
421 sc_signal( const char* name_, const value_type& initial_value_ )
422 : base_type( name_, initial_value_ )
423 , m_negedge_event_p( 0 ) , m_posedge_event_p( 0 ) , m_reset_p( 0 )
424 {}
425
426 virtual ~sc_signal();
427
428 // get the positive edge event
429 virtual const sc_event& posedge_event() const;
430
431 // get the negative edge event
432 virtual const sc_event& negedge_event() const;
433
434 // was there a positive edge event?
435 virtual bool posedge() const
436 { return ( this->event() && this->m_cur_val ); }
437
438 // was there a negative edge event?
439 virtual bool negedge() const
440 { return ( this->event() && ! this->m_cur_val ); }
441
442
443 // assignment
444 using base_type::operator=;
445 this_type& operator = ( const this_type& a )
446 { base_type::operator=(a); return *this; }
447
448protected:
449
450 virtual void update();
451 void do_update();
452
453 virtual bool is_clock() const { return false; }
454
455protected:
456 mutable sc_event* m_negedge_event_p; // negative edge event if present.
457 mutable sc_event* m_posedge_event_p; // positive edge event if present.
458 mutable sc_reset* m_reset_p; // reset mechanism if present.
459
460private:
461 // reset creation
462 virtual sc_reset* is_reset() const;
463
464 // disabled
465 sc_signal( const this_type& ) /* = delete */;
466};
467
468
469// ----------------------------------------------------------------------------
470// CLASS : sc_signal<sc_dt::sc_logic>
471//
472// Specialization of sc_signal<T> for type sc_dt::sc_logic.
473// ----------------------------------------------------------------------------
474
478
479template< sc_writer_policy POL >
481 : public sc_signal_t<sc_dt::sc_logic,POL>
482{
483protected:
488
489public:
490
492 : base_type( sc_gen_unique_name( "signal" ), value_type() )
493 , m_negedge_event_p( 0 ) , m_posedge_event_p( 0 )
494 {}
495
496 explicit
497 sc_signal( const char* name_ )
498 : base_type( name_, value_type() )
499 , m_negedge_event_p( 0 ) , m_posedge_event_p( 0 )
500 {}
501
502 sc_signal( const char* name_, const value_type& initial_value_ )
503 : base_type( name_, initial_value_ )
504 , m_negedge_event_p( 0 ) , m_posedge_event_p( 0 )
505 {}
506
507 virtual ~sc_signal();
508
509 // get the positive edge event
510 virtual const sc_event& posedge_event() const;
511
512 // get the negative edge event
513 virtual const sc_event& negedge_event() const;
514
515
516 // was there a positive edge event?
517 virtual bool posedge() const
518 { return ( this->event() && this->m_cur_val == sc_dt::SC_LOGIC_1 ); }
519
520 // was there a negative edge event?
521 virtual bool negedge() const
522 { return ( this->event() && this->m_cur_val == sc_dt::SC_LOGIC_0 ); }
523
524
525 // assignment
526 using base_type::operator=;
527 this_type& operator = ( const this_type& a )
528 { base_type::operator=(a); return *this; }
529
530protected:
531
532 virtual void update();
533 void do_update();
534
535protected:
536 mutable sc_event* m_negedge_event_p; // negative edge event if present.
537 mutable sc_event* m_posedge_event_p; // positive edge event if present.
538
539private:
540 // disabled
541 sc_signal( const this_type& ) /* = delete */;
542};
543
544} // namespace sc_core
545
546/*****************************************************************************
547
548 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
549 changes you are making here.
550
551 Name, Affiliation, Date:
552 Description of Modification:
553
554 *****************************************************************************/
555//$Log: sc_signal.h,v $
556//Revision 1.16 2011/08/26 20:45:42 acg
557// Andy Goodrich: moved the modification log to the end of the file to
558// eliminate source line number skew when check-ins are done.
559//
560//Revision 1.15 2011/08/15 16:43:24 acg
561// Torsten Maehne: changes to remove unused argument warnings.
562//
563//Revision 1.14 2011/06/25 17:08:38 acg
564// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
565// library.
566//
567//Revision 1.13 2011/04/13 02:59:09 acg
568// Andy Goodrich: made events internal to signals into kernel events.
569//
570//Revision 1.12 2011/04/08 18:22:46 acg
571// Philipp A. Hartmann: use the context of the primitive channel to get
572// the change stamp value.
573//
574//Revision 1.11 2011/04/05 20:48:09 acg
575// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
576// only return true if the clock has not moved.
577//
578//Revision 1.10 2011/04/05 07:10:55 acg
579// Andy Goodrich: added line that I dropped in sc_signal<sc_dt::sc_logic>.
580//
581//Revision 1.9 2011/04/05 06:15:18 acg
582// Philipp A. Hartmann: sc_writer_policy: ignore no-ops in delta check.
583//
584//Revision 1.8 2011/03/23 16:17:22 acg
585// Andy Goodrich: hide the sc_events that are kernel related.
586//
587//Revision 1.7 2011/03/06 15:55:08 acg
588// Andy Goodrich: Changes for named events.
589//
590//Revision 1.6 2011/02/18 20:23:45 acg
591// Andy Goodrich: Copyright update.
592//
593//Revision 1.5 2011/02/07 19:16:50 acg
594// Andy Goodrich: changes for handling multiple writers.
595//
596//Revision 1.4 2011/01/25 20:50:37 acg
597// Andy Goodrich: changes for IEEE 1666 2011.
598//
599//Revision 1.3 2010/12/07 19:50:37 acg
600// Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
601//
602//Revision 1.1.1.1 2006/12/15 20:20:04 acg
603//SystemC 2.3
604//
605//Revision 1.14 2006/05/08 17:52:47 acg
606// Andy Goodrich:
607// (1) added David Long's forward declarations for friend functions,
608// methods, and operators to keep the Microsoft compiler happy.
609// (2) Added delta_count() method to sc_prim_channel for use by
610// sc_signal so that the friend declaration in sc_simcontext.h
611// can be for a non-templated class (i.e., sc_prim_channel.)
612//
613//Revision 1.12 2006/04/11 23:11:57 acg
614// Andy Goodrich: Changes for reset support that only includes
615// sc_cthread_process instances.
616//
617//Revision 1.11 2006/03/13 20:19:44 acg
618// Andy Goodrich: changed sc_event instances into pointers to sc_event instances
619// that are allocated as needed. This saves considerable storage for large
620// numbers of signals, etc.
621//
622//Revision 1.10 2006/01/26 21:00:50 acg
623// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
624// sc_event::notify_delayed()
625//
626//Revision 1.9 2006/01/24 20:45:41 acg
627//Andy Goodrich: converted notify_delayed() calls into notify_next_delta() calls
628//to eliminate deprecation warnings. notify_next_delta() is an implemenation-
629//dependent method of sc_event. It is simpler than notify_delayed(), and should
630//speed up simulation speeds.
631//
632//Revision 1.8 2006/01/19 19:18:25 acg
633//Andy Goodrich: eliminated check_writer in favor of inline code within the
634//write() method since we always execute the check_writer code even when
635//check writing is turned off.
636//
637//Revision 1.7 2006/01/19 00:30:57 acg
638//Andy Goodrich: Yet another implementation for disabling write checks on
639//signals. This version uses an environment variable, SC_SIGNAL_WRITE_CHECK,
640//that when set to DISABLE will turn off write checking.
641//
642//Revision 1.6 2006/01/18 21:42:26 acg
643//Andy Goodrich: Changes for check writer support, and tightening up sc_clock
644//port usage.
645//
646//Revision 1.5 2006/01/13 20:41:59 acg
647//Andy Goodrich: Changes to add port registration to the things that are
648//checked when SC_NO_WRITE_CHECK is not defined.
649//
650//Revision 1.4 2006/01/13 18:47:20 acg
651//Reversed sense of multiwriter signal check. It now defaults to ON unless the
652//user defines SC_NO_WRITE_CHEK before inclusion of the file.
653//
654//Revision 1.3 2006/01/03 23:18:26 acg
655//Changed copyright to include 2006.
656//
657//Revision 1.2 2005/12/20 21:58:18 acg
658//Removed Makefile.in, changed the event() methods to use sc_simcontext::event_occurred.
659//
660//Revision 1.1.1.1 2005/12/19 23:16:43 acg
661//First check in of SystemC 2.1 into its own archive.
662//
663//Revision 1.19 2005/09/15 23:01:51 acg
664//Added std:: prefix to appropriate methods and types to get around
665//issues with the Edison Front End.
666//
667//Revision 1.18 2005/06/10 22:43:55 acg
668//Added CVS change log annotation.
669//
670
671#endif
672
673// Taf!
#define SC_UNLIKELY_(x)
Definition: sc_cmnhdr.h:87
#define SC_API_TEMPLATE_DECL_
Definition: sc_cmnhdr.h:157
#define SC_API
Definition: sc_cmnhdr.h:148
SC_API void sc_signal_invalid_writer(sc_object *target, sc_object *first_writer, sc_object *second_writer, bool check_delta)
inline::std::ostream & operator<<(::std::ostream &os, const sc_fifo< T > &a)
Definition: sc_fifo.h:428
SC_API const char * sc_gen_unique_name(const char *, bool preserve_first)
void sc_trace(sc_trace_file *tf, const sc_in< T > &port, const std::string &name)
sc_simcontext * sc_get_curr_simcontext()
SC_API const sc_logic SC_LOGIC_0
unsigned long long uint64
Definition: sc_nbdefs.h:216
class SC_API sc_logic
Definition: sc_signal_ifs.h:39
SC_API const sc_logic SC_LOGIC_1
constexpr uint64 UINT64_ONE
Definition: sc_nbdefs.h:219
const sc_event & value_changed_event() const
const sc_event & default_event() const
Definition: sc_signal.h:104
sc_event * lazy_kernel_event(sc_event **, const char *) const
void notify_next_delta(sc_event *ev) const
Definition: sc_signal.h:124
virtual const char * kind() const
Definition: sc_signal.h:100
sc_signal_channel(const char *name_)
Definition: sc_signal.h:88
sc_dt::uint64 m_change_stamp
Definition: sc_signal.h:129
void deprecated_get_new_value() const
void deprecated_get_data_ref() const
virtual void print(::std::ostream &=::std::cout) const
Definition: sc_signal.h:306
virtual sc_writer_policy get_writer_policy() const
Definition: sc_signal.h:187
virtual void update()
Definition: sc_signal.h:323
sc_signal_t(const char *name_, const T &initial_value_)
Definition: sc_signal.h:170
const T & get_new_value() const
Definition: sc_signal.h:234
virtual const T & get_data_ref() const
Definition: sc_signal.h:203
virtual const char * kind() const
Definition: sc_signal.h:182
virtual void write(const T &)
Definition: sc_signal.h:289
virtual const sc_event & default_event() const
Definition: sc_signal.h:191
virtual const T & read() const
Definition: sc_signal.h:199
sc_signal_inout_if< T > if_type
Definition: sc_signal.h:161
sc_signal_channel base_type
Definition: sc_signal.h:162
void trace(sc_trace_file *tf) const
Definition: sc_signal.h:241
virtual ~sc_signal_t()
Definition: sc_signal.h:176
this_type & operator=(const T &a)
Definition: sc_signal.h:224
sc_signal_t< T, POL > this_type
Definition: sc_signal.h:163
virtual void register_port(sc_port_base &, const char *)
Definition: sc_signal.h:275
virtual const sc_event & value_changed_event() const
Definition: sc_signal.h:195
virtual bool event() const
Definition: sc_signal.h:210
sc_writer_policy_check< POL > policy_type
Definition: sc_signal.h:164
virtual void dump(::std::ostream &=::std::cout) const
Definition: sc_signal.h:313
sc_signal_t< T, POL > base_type
Definition: sc_signal.h:351
virtual ~sc_signal()
Definition: sc_signal.h:371
sc_signal_inout_if< T > if_type
Definition: sc_signal.h:350
sc_signal(const char *name_, const value_type &initial_value_)
Definition: sc_signal.h:367
this_type & operator=(const this_type &a)
Definition: sc_signal.h:375
sc_writer_policy_check< POL > policy_type
Definition: sc_signal.h:354
sc_signal< T, POL > this_type
Definition: sc_signal.h:352
sc_signal(const char *name_)
Definition: sc_signal.h:363
virtual const sc_event & negedge_event() const
virtual bool posedge() const
Definition: sc_signal.h:435
sc_signal< bool, POL > this_type
Definition: sc_signal.h:402
virtual const sc_event & posedge_event() const
sc_signal(const char *name_)
Definition: sc_signal.h:416
sc_writer_policy_check< POL > policy_type
Definition: sc_signal.h:404
sc_signal(const char *name_, const value_type &initial_value_)
Definition: sc_signal.h:421
virtual bool negedge() const
Definition: sc_signal.h:439
sc_signal_t< bool, POL > base_type
Definition: sc_signal.h:401
virtual bool is_clock() const
Definition: sc_signal.h:453
virtual const sc_event & negedge_event() const
virtual const sc_event & posedge_event() const
sc_signal(const char *name_, const value_type &initial_value_)
Definition: sc_signal.h:502
sc_signal< sc_dt::sc_logic, POL > this_type
Definition: sc_signal.h:485
sc_signal_t< sc_dt::sc_logic, POL > base_type
Definition: sc_signal.h:484
sc_writer_policy_check< POL > policy_type
Definition: sc_signal.h:487
virtual const T & read() const =0
bool check_write(sc_object *target, bool value_changed)
Definition: sc_signal.h:47
const char * name() const
Definition: sc_object.h:122
virtual void print(::std::ostream &os=::std::cout) const
void swap(sc_process_handle &other)
sc_process_b * get_current_writer() const