Changeset 52 for sources/src/sc_signal.h
- Timestamp:
- Jan 22, 2013, 4:23:22 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sources/src/sc_signal.h
r47 r52 11 11 | | 12 12 \------------------------------------------------------------*/ 13 13 14 #ifndef __SC_SIGNAL_H__ 14 15 #define __SC_SIGNAL_H__ … … 17 18 #include <iostream> 18 19 #include <cstdlib> 20 19 21 #include "sc_fwd.h" 20 22 #include "sc_nbdefs.h" 21 //#include "sc_event_finder.h"22 //#include "sc_event.h"23 23 #include "sc_time.h" // SC_ZERO_TIME 24 24 #include "sc_object.h" … … 30 30 // 31 31 #if ((__GNUC__ < 3) || (__GNUC_MINOR__ < 4)) 32 #define INLINE __attribute__((always_inline))32 #define INLINE __attribute__((always_inline)) 33 33 #else 34 /* gcc3.4 doesn't support */ 35 #define INLINE 36 #endif 34 /* gcc3.4 doesn't support */ 35 #define INLINE 36 #endif 37 37 38 38 39 #define READ_SIGNAL(value_type_,pointer_) \ 39 ((value_type_&) (*((value_type_*) (pointer_))))40 41 40 ((value_type_ &) (*((value_type_ *) (pointer_)))) 41 42 ///////////////////// DEPRECATED 42 43 // C ANSI-only since it is needed to link with extern "C" 43 44 44 extern void bind (sc_port_base&,sc_port_base&); 45 extern void bind (sc_port_base&,sc_signal_base&); 46 extern void bind (sc_signal_base &x); 47 extern void bind (sc_port_base &x); 45 extern void bind(sc_port_base &, sc_port_base &); 46 extern void bind(sc_port_base &, sc_signal_base &); 47 extern void bind(sc_signal_base & x); 48 extern void bind(sc_port_base & x); 49 48 50 typedef tab_t base_type; 51 49 52 struct pending_write_t { 50 base_type *pointer; 51 base_type value; 52 //pending_write_t (base_type *const pointer_, const base_type value_) 53 //{ pointer = pointer_; value = value_; } 54 friend std::ostream& operator << (std::ostream &o, const pending_write_t &p) 55 { return o << "(pointer = " << p.pointer << "; value = " << p.value << ")\n"; } 53 base_type * pointer; 54 base_type value; 55 //pending_write_t(base_type * const pointer_, const base_type value_) { 56 // pointer = pointer_; 57 // value = value_; 58 //} 59 60 friend std::ostream & operator << (std::ostream & o, const pending_write_t & p) { 61 return o << "(pointer = " << p.pointer << "; value = " << p.value << ")\n"; 62 } 56 63 }; 57 64 65 58 66 // Check pending_writing to register 59 extern void pending_writing2register_clear 60 extern void pending_writing2register_record_and_check 67 extern void pending_writing2register_clear(); 68 extern void pending_writing2register_record_and_check(const tab_t *); 61 69 62 70 // Pending write to register (simple stack) 63 typedef pending_write_t * pending_write_vector_t;71 typedef pending_write_t * pending_write_vector_t; 64 72 extern pending_write_vector_t pending_write_vector; 65 73 extern "C" unsigned int pending_write_vector_nb; … … 67 75 68 76 69 template <typename T> 70 inline void post_write (base_type *const pointer_, 71 const T value_) /*INLINE*/; 72 template <typename T> 73 inline void post_multiwrite (base_type *const pointer_, 74 const T value_) 75 { 76 size_t size = (sizeof (T)-1) / sizeof (base_type); 77 size_t i = 0; 78 const base_type *pvalue = (const base_type*)(void*)(&value_); 79 do { 77 template < typename T > 78 inline void post_write(base_type * const pointer_, const T value_) /*INLINE*/; 79 80 template < typename T > 81 inline void post_multiwrite(base_type * const pointer_, const T value_) { 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 post_write(pointer_ + i, pvalue[i]); 87 } while (i++ < size); 88 } 89 90 template < typename T > 91 inline void post_write(base_type * const pointer_, const T value_) { 92 if (sizeof(T) > sizeof(base_type)) { 93 post_multiwrite(pointer_,value_); 94 } 95 else { 96 #if defined(CONFIG_DEBUG) 97 if (pending_write_vector_nb >= pending_write_vector_capacity) { 98 std::cerr << "Error : The array for posted writing on register is too small.\n"; 99 std::cerr << "Up to 1 writing per register is allowed during a cycle.\n"; 100 std::cerr << "Please check the hardware description.\n"; 101 exit(-1); 102 } 103 #endif 104 pending_write_vector[pending_write_vector_nb].pointer = pointer_; 105 // pending_write_vector[pending_write_vector_nb++].value = *(reinterpret_cast<const base_type*const>(&value_)); => bug ! 106 pending_write_vector[pending_write_vector_nb++].value = value_; // => bug avec blues ! 107 108 // -> fix to use user-defined struct in sc_signal/sc_in/sc_out/sc_inout 109 // pending_write_vector[pending_write_vector_nb++].value = *((base_type*)&value_); => bug ! 80 110 #if 0 81 cout << "post_multiwrite 0x" << hex << pvalue[i] << " @" << (pointer_ + i) << "\n"; 82 #endif 83 post_write (pointer_ + i, pvalue[i]); 84 } while (i++ < size); 85 } 86 template <typename T> 87 inline void post_write (base_type *const pointer_, 88 const T value_) 89 { 90 if (sizeof (T) > sizeof (base_type)) { 91 #if 0 92 std::cout << "sizeof (T) = " << sizeof (T) 93 << " (base_type = " << sizeof (base_type) << "\n"; 94 #endif 95 post_multiwrite (pointer_,value_); 96 } else { 97 #if defined(CONFIG_DEBUG) 98 if (pending_write_vector_nb >= pending_write_vector_capacity) { 99 //if (pending_write_vector_nb >= pending_write_vector_capacity * sizeof(pending_write_t)) { 100 std::cerr << "Error : The array for posted writing on register is too small.\n"; 101 std::cerr << "Up to 1 writing per register is allowed during a cycle.\n"; 102 std::cerr << "Please check the hardware description.\n"; 103 exit (-1); 104 } 105 #endif // CONFIG_DEBUG 106 pending_write_vector[pending_write_vector_nb].pointer = pointer_; 107 // pending_write_vector[pending_write_vector_nb++].value = *(reinterpret_cast<const base_type*const>(&value_)); => bug ! 108 pending_write_vector[pending_write_vector_nb++].value = value_; // => bug avec blues ! 109 110 // -> fix to use user-defined struct in sc_signal/sc_in/sc_out/sc_inout 111 // pending_write_vector[pending_write_vector_nb++].value = *((base_type*)&value_); => bug ! 112 #if 0 113 std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n"; 111 std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n"; 114 112 #endif 115 113 #if 0 116 // introduce bug on using trace functions 117 if (value_ == READ_SIGNAL(T,pointer_)) 118 return; 119 #endif 120 }; 121 } 122 123 inline bool is_posted_write () 124 { 125 return pending_write_vector_nb > 0; 126 } 127 128 extern "C" void update (void); 114 // introduce bug on using trace functions 115 if (value_ == READ_SIGNAL(T,pointer_)) { 116 return; 117 } 118 #endif 119 } 120 } 121 122 123 inline bool is_posted_write() { 124 return pending_write_vector_nb > 0; 125 } 126 127 128 extern "C" void update(void); 129 129 130 130 131 // ---------------------------------------------------------------------------- … … 134 135 // ---------------------------------------------------------------------------- 135 136 136 class sc_signal_base : public sc_object, public sc_interface 137 { 138 ////// 139 // Internal 140 friend class sc_clock; 141 friend class sc_port_base; 142 void init (); 143 ////// 144 145 146 public: 147 // LRM (?) 148 //virtual const sc_event /*&*/ default_event () const; 149 static const char* const kind_string; 150 //virtual const char *kind () const; 151 152 // 153 public: 154 sc_signal_base(); 155 sc_signal_base(const char* name_); 156 sc_signal_base(const char* name_, void*); 157 ~sc_signal_base(); 137 class sc_signal_base : public sc_object, public sc_interface { 138 139 ////// 140 // Internal 141 friend class sc_clock; 142 friend class sc_port_base; 143 void init(); 144 ////// 145 146 147 public: 148 // LRM (?) 149 //virtual const sc_event /*&*/ default_event() const; 150 static const char * const kind_string; 151 //virtual const char * kind() const; 152 153 154 155 public: 156 sc_signal_base(); 157 sc_signal_base(const char * name_); 158 sc_signal_base(const char * name_, void *); 159 ~sc_signal_base(); 160 158 161 }; 159 162 160 template <typename T> 161 class sc_signal : public sc_signal_base 162 { 163 private: 164 T val; 165 typedef T data_type; 166 typedef sc_signal < T > this_type; 167 168 /////////// 169 // Internal 170 public: void init (); 171 /////////// 172 173 // virtual void update (); 174 void check_writer (); 175 public: 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; 163 164 template < typename T > 165 class sc_signal : public sc_signal_base { 166 167 private: 168 T val; 169 typedef T data_type; 170 typedef sc_signal < T > this_type; 171 172 173 /////////// 174 // Internal 175 public: 176 void init(); 177 /////////// 178 179 void check_writer(); 180 181 public: 182 // constructors, destructor 183 sc_signal() { 184 init(); 185 } 186 187 explicit sc_signal(const char * name_) : sc_signal_base(name_) { 188 init(); 189 } 190 191 /*virtual*/ ~sc_signal() {} 192 /*virtual*/ inline const data_type & read() const INLINE; 193 /*virtual*/ inline void write(const data_type &) /*INLINE*/; 194 195 inline operator const data_type & () const { return this->read(); } 196 197 inline this_type & operator = (const data_type & a) { 198 sc_signal< T >::write(a); 199 return *this; 200 } 201 202 inline this_type & operator = (const sc_signal < T > & a) { 203 sc_signal< T >::write(a.read()); 204 return *this; 205 } 206 207 inline this_type & operator += (const data_type & a) { 208 sc_signal< T >::write(read() + a); 209 return *this; 210 } 211 212 inline this_type & operator += (const sc_signal < T > & a) { 213 sc_signal< T >::write(read() + a.read()); 214 return *this; 215 } 216 217 const data_type & get_new_value() const; 218 219 // void trace (sc_trace_file * tf) const; 220 /* 221 virtual void print(std::ostream & o) const { o << *this; } 222 virtual void dump(std::ostream & o) const { o << *this; } 223 */ 224 225 private: 226 // disabled 227 sc_signal(const sc_signal < T > &); 228 229 }; 230 231 232 template < typename T > 233 void sc_signal< T >::init() { 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 242 243 // read the value 244 template < typename T > 245 /*virtual*/ inline const T & sc_signal< T >::read() const { 246 #ifdef DUMP_READ 247 std::cerr << "read " << READ_SIGNAL(const T, get_pointer()) << " on signal " << name() << "\n"; 248 #endif 249 return READ_SIGNAL(const T, get_pointer()); 250 } 251 252 253 // write the new value 254 template < typename T > 255 inline void sc_signal< T >::write(const data_type & value_) { 256 #ifdef CONFIG_DEBUG 257 if (get_pointer() == NULL) { 258 std::cerr << "Error : Unable to write into '" << name() << "'."; 259 exit(24032005); 260 } 261 #endif 262 #ifdef DUMP_WRITE 263 if (sc_signal< T >::read() == value_) { 264 return; 265 } 266 std::cerr << "write (posted) " << value_ << " on sc_signal (writing into register) '" << name() << "'\n"; 267 #endif 268 post_write(/*(tab_t*)&val*/ get_pointer(), value_); 269 } 270 271 #undef INLINE 272 #undef READ_SIGNAL 273 274 275 } // end of namespace sc_core 276 277 #endif /* __SC_SIGNAL_H__ */ 278 193 279 /* 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 */ 218 private: 219 // disabled 220 sc_signal (const sc_signal < T > &); 221 222 }; 223 224 template <typename T> 225 void 226 sc_signal<T>::init() 227 { 228 set_pointer ((tab_t*)(void*)&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 236 template <typename T> 237 /*virtual*/ 238 inline 239 const T & 240 sc_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 return READ_SIGNAL(const T, get_pointer()); 247 } 248 249 // write the new value 250 template <typename T> 251 inline 252 void 253 sc_signal<T>::write( const data_type& value_ ) 254 { 255 #ifdef CONFIG_DEBUG 256 if (get_pointer() == NULL) 257 { 258 std::cerr << "Error : Unable to write into '" << name () << "'."; 259 exit (24032005); 260 } 261 #endif 262 #ifdef DUMP_WRITE 263 if (sc_signal<T>::read() == value_) 264 return; 265 std::cerr << "write (posted) " << value_ 266 << " on sc_signal (writing into register) '" << name () << "'\n"; 267 #endif 268 post_write (/*(tab_t*)&val*/ get_pointer(), value_); 269 } 270 271 #undef INLINE 272 273 #undef READ_SIGNAL 274 275 } // end of namespace sc_core 276 277 #endif /* __SC_SIGNAL_H__ */ 278 280 # Local Variables: 281 # tab-width: 4; 282 # c-basic-offset: 4; 283 # c-file-offsets:((innamespace . 0)(inline-open . 0)); 284 # indent-tabs-mode: nil; 285 # End: 286 # 287 # vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 288 */ 289
Note: See TracChangeset
for help on using the changeset viewer.