source: sources/src/sc_signal.h @ 8

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

Initial import from CVS repository

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