source: sources/src/sc_signal.h @ 17

Last change on this file since 17 was 17, checked in by buchmann, 15 years ago

Fix :

  • add missing system header includes
File size: 8.4 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                   sc_signal.h                     |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                           Taktak Sami                       |
9|                                                             |
10| Date    :                   09_07_2004                      |
11|                                                             |
12\------------------------------------------------------------*/
13#ifndef __SC_SIGNAL_H__
14#define __SC_SIGNAL_H__
15
16// Define registers writing method
17#include<iostream>
18#include<cstdlib>
19#include"sc_fwd.h"
20#include"sc_nbdefs.h"
21//#include"sc_event_finder.h"
22//#include"sc_event.h"
23#include"sc_time.h" // SC_ZERO_TIME
24#include"sc_object.h"
25#include"sc_interface.h"
26#include"internal_ext.h"
27#include "fsm_rules.h"
28
29namespace sc_core {
30
31//
32#if ((__GNUC__ < 3) || (__GNUC_MINOR__ < 4))
33#define INLINE __attribute__((always_inline))
34#else
35/* gcc3.4 doesn't support */ 
36#define INLINE
37#endif
38
39#define READ_SIGNAL(value_type_,pointer_) \
40        ((value_type_&) (*((value_type_*) (pointer_))))
41
42        ///////////////////// DEPRECATED
43// C ANSI-only since it is needed to link with extern "C"
44// this declaration is not in casc.h since the CHECK_FSM_RULES macro
45// is not defined.
46
47extern void bind (sc_port_base&,sc_port_base&);
48extern void bind (sc_port_base&,sc_signal_base&);
49extern void bind (sc_signal_base &x);
50extern void bind (sc_port_base   &x);
51typedef tab_t base_type;
52struct pending_write {
53        base_type   *pointer;
54        base_type    value;
55        //pending_write (base_type *const pointer_, const base_type value_)
56        //{     pointer = pointer_; value = value_; }
57        friend std::ostream& operator << (std::ostream &o, const pending_write &p)
58        { return o << "(pointer = " << p.pointer << "; value = " << p.value << ")\n"; }
59};
60
61// Check pending_writing to register
62extern void pending_writing2register_clear  ();
63extern void pending_writing2register_record_and_check (const tab_t *);
64
65// Pending write to register (simple stack)
66typedef pending_write *pending_write_vector_t;
67extern pending_write_vector_t pending_write_vector;
68extern "C" unsigned int pending_write_vector_nb;
69extern unsigned int pending_write_vector_capacity;
70
71
72template <typename T>
73inline void post_write (base_type *const pointer_,
74                        const T          value_) /*INLINE*/;
75template <typename T>
76inline void post_multiwrite (base_type *const pointer_,
77                             const T          value_)
78{
79        size_t size = (sizeof (T)-1) / sizeof (base_type);
80        size_t i = 0;
81        const base_type *pvalue = (const base_type*)(&value_);
82        do {
83#if 0
84    cout << "post_multiwrite 0x" << hex << pvalue[i] << " @" << (pointer_ + i) << "\n";
85#endif
86                post_write (pointer_ + i, pvalue[i]);
87        } while (i++ < size);
88}
89template <typename T>
90inline void post_write (base_type *const pointer_, 
91                        const T          value_)
92{
93        if (sizeof (T) > sizeof (base_type)) {
94#if 0
95    cout << "sizeof (T) = " << sizeof (T) << " (base_type = " << sizeof
96(base_type) << "\n";
97#endif
98                post_multiwrite (pointer_,value_);
99        } else {
100#if defined(DEBUG)
101        if (pending_write_vector_nb >= pending_write_vector_capacity) {
102        //if (pending_write_vector_nb >= pending_write_vector_capacity * sizeof(pending_write)) {
103                std::cerr << "Error : The array for posted writing on register is too small.\n";
104                std::cerr << "Up to 1 writing per register is allowed during a cycle.\n";
105                std::cerr << "Please check the hardware description.\n";
106                exit (-1);
107        }
108#endif // DEBUG
109  pending_write_vector[pending_write_vector_nb].pointer = pointer_;
110//      pending_write_vector[pending_write_vector_nb++].value = *(reinterpret_cast<const base_type*const>(&value_)); => bug !
111  pending_write_vector[pending_write_vector_nb++].value = value_; // => bug avec blues !
112
113        // -> fix to use user-defined struct in sc_signal/sc_in/sc_out/sc_inout
114        // pending_write_vector[pending_write_vector_nb++].value = *((base_type*)&value_); => bug !
115#if 0
116        std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n";
117#endif
118#if 0 
119        // introduce bug on using trace functions
120        if (value_ == READ_SIGNAL(T,pointer_))
121                return;
122#endif
123        };
124}
125
126inline bool is_posted_write ()
127{
128                return pending_write_vector_nb > 0;
129}
130
131extern "C" void update (void);
132
133// ----------------------------------------------------------------------------
134//  CLASS : sc_signal_base
135//
136//  The sc_signal_base<T> primitive channel class.
137// ----------------------------------------------------------------------------
138
139class sc_signal_base : public sc_object, public sc_interface
140{
141        //////
142        // Internal
143  friend class sc_clock;
144  friend class sc_port_base;
145  void init ();
146        //////                           
147 
148
149public: 
150  // LRM (?)
151  //virtual const sc_event /*&*/ default_event () const;
152  static const char* const kind_string;
153  //virtual const char *kind () const;
154
155  //
156public:
157  sc_signal_base();
158  sc_signal_base(const char* name_);
159  sc_signal_base(const char* name_, void*);
160        ~sc_signal_base();
161};
162
163template <typename T>
164class sc_signal : public sc_signal_base
165{
166private:
167        T val;
168  typedef T  data_type;
169  typedef sc_signal < T >  this_type;
170        ///////////
171        // Internal
172        public: void init ();
173        ///////////
174//  virtual void update ();
175  void check_writer ();
176public:
177  // constructors, destructor
178  sc_signal () 
179        { init (); }
180  explicit sc_signal (const char *name_): sc_signal_base(name_)
181        { init (); }
182  /*virtual */~ sc_signal () 
183  {}
184  // methods
185  /*
186  virtual void register_port (sc_port_base &, const char *)
187  {}
188  virtual const sc_event & default_event () const
189  {}
190  virtual const sc_event & value_changed_event () const
191  {}
192  */
193  /*virtual*/ inline const data_type & read () const INLINE;
194/*
195  virtual const T & get_data_ref () const
196  {}
197  virtual bool event () const
198  {}
199  */
200  /*virtual*/ inline void write (const data_type &) /*INLINE*/;
201  inline operator const data_type & () const
202  { return this->read(); }
203  inline this_type& operator = (const data_type & a)
204  { sc_signal<T>::write (a); return *this; }
205  inline this_type& operator = (const sc_signal < T > &a)
206  { sc_signal<T>::write (a.read()); return *this; }
207  inline this_type& operator += (const data_type & a)
208  { sc_signal<T>::write (read() + a); return *this; }
209  inline this_type& operator += (const sc_signal < T > &a)
210  { sc_signal<T>::write (read()+a.read()); return *this; }
211  const data_type & get_new_value () const;
212//  void trace (sc_trace_file * tf) const;
213  /*
214        virtual void print (std::ostream &o) const
215  { o << *this; }
216  virtual void dump (std::ostream &o) const
217  { o << *this; }
218        */
219private:
220  // disabled
221  sc_signal (const sc_signal < T > &);
222
223};
224
225template <typename T>
226void
227sc_signal<T>::init()
228{
229  set_pointer ((tab_t*)&val);
230  set_kind    (kind_string);
231        sc_interface::init (sizeof (data_type)); 
232  val = 0; /* The simulator initializes the signal/register to 0.    */
233           /* However, hardware initialization still has to be done. */
234           /* This kind of initialization is for trace diffing.      */
235}
236// read the value
237template <typename T>
238/*virtual*/ 
239inline 
240const T & 
241sc_signal<T>::read() const
242{
243#ifdef DUMP_READ
244  std::cerr << "read " << READ_SIGNAL(const T, get_pointer())
245                << " on signal " << name () << "\n";
246#endif
247#ifdef CHECK_FSM_RULES
248        // we can read value from sc_signal type (used like a register) at any time
249#endif 
250    return READ_SIGNAL(const T, get_pointer());
251}
252
253// write the new value
254template <typename T>
255inline
256void
257sc_signal<T>::write( const data_type& value_ )
258{
259#ifdef CHECK_FSM_RULES
260        if ((casc_fsm_step != TRANSITION) 
261                        && ( casc_fsm_step != STIMULI)) {
262                std::cerr << "FSM rules error : trying to write on signal " 
263                          << name () 
264                          << " from " << get_step_name () << " function.\n";
265                exit (-1);
266        }               
267#endif
268#ifdef DEBUG
269  if (get_pointer() == NULL)
270  {
271    std::cerr << "Error : Unable to write into '" << name () << "'.";
272    exit (24032005);
273  }
274#endif
275#ifdef CHECK_MULTIWRITING2REGISTER
276  pending_writing2register_record_and_check (get_pointer ());
277#endif
278#ifdef DUMP_WRITE
279  if (sc_signal<T>::read() == value_)
280    return;
281  std::cerr << "write (posted) " << value_
282                << " on sc_signal (writing into register) '" << name () << "'\n";
283#endif
284  post_write (/*(tab_t*)&val*/ get_pointer(), value_);
285}
286
287#undef INLINE
288
289#undef READ_SIGNAL
290
291} // end of namespace sc_core
292
293#endif /* __SC_SIGNAL_H__ */
294
Note: See TracBrowser for help on using the repository browser.