source: sources/src/sc_signal.h @ 32

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

Changes:

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