source: sources/src/sc_signal.h @ 59

Last change on this file since 59 was 59, checked in by meunier, 8 years ago
  • Fixed memory leaks
  • Fixed indentation in some files
File size: 8.3 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
14#ifndef __SC_SIGNAL_H__
15#define __SC_SIGNAL_H__
16
17// Define registers writing method
18#include <iostream>
19#include <cstdlib>
20#include <typeinfo> // for typeid
21
22#include "sc_fwd.h"
23#include "sc_nbdefs.h"
24#include "sc_time.h" // SC_ZERO_TIME
25#include "sc_object.h"
26#include "sc_interface.h"
27#include "internal_ext.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
40#define READ_SIGNAL(value_type_,pointer_) \
41    ((value_type_ &) (*((value_type_ *) (pointer_))))
42
43///////////////////// DEPRECATED
44// C ANSI-only since it is needed to link with extern "C"
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);
50
51typedef tab_t base_type;
52
53struct pending_write_t {
54    base_type * pointer;
55    base_type value;
56   
57    friend std::ostream & operator << (std::ostream & o, const pending_write_t & p) {
58        return o << "(pointer = " << p.pointer << "; value = " << p.value << ")\n";
59    }
60};
61
62
63// Check pending_writing to register
64extern void pending_writing2register_clear();
65extern void pending_writing2register_record_and_check(const tab_t *);
66
67// Pending write to register (simple stack)
68typedef pending_write_t * pending_write_vector_t;
69extern pending_write_vector_t pending_write_vector;
70extern "C" unsigned int pending_write_vector_nb;
71extern unsigned int pending_write_vector_capacity;
72
73
74template < typename T >
75inline void post_write(base_type * const pointer_, const T & value_) /*INLINE*/;
76
77template < typename T >
78inline void post_multiwrite(base_type * const pointer_, const T & value_) {
79    size_t size = (sizeof(T) - 1) / sizeof(base_type);
80    size_t i = 0;
81    const base_type * pvalue = (const base_type *) (void *) (&value_);
82    do {
83        post_write(pointer_ + i, pvalue[i]);
84    } while (i++ < size);
85}
86
87template < typename T >
88inline void post_write(base_type * const pointer_, const T & value_) {
89    if (sizeof(T) > sizeof(base_type)) {
90        post_multiwrite(pointer_, value_);
91    }
92    else {
93#if defined(CONFIG_DEBUG)
94        if (pending_write_vector_nb >= pending_write_vector_capacity) {
95            std::cerr << "Error : The array for posted writing on register is too small.\n";
96            std::cerr << "Up to 1 writing per register is allowed during a cycle.\n";
97            std::cerr << "Please check the hardware description.\n";
98            exit(-1);
99        }
100#endif
101        pending_write_vector[pending_write_vector_nb].pointer = pointer_;
102        // pending_write_vector[pending_write_vector_nb++].value = *(reinterpret_cast<const base_type*const>(&value_)); => bug !
103        pending_write_vector[pending_write_vector_nb++].value = value_; // => bug avec blues !
104
105        // -> fix to use user-defined struct in sc_signal/sc_in/sc_out/sc_inout
106        // pending_write_vector[pending_write_vector_nb++].value = *((base_type*)&value_); => bug !
107#if 0
108        std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n";
109#endif
110#if 0 
111        // introduce bug on using trace functions
112        if (value_ == READ_SIGNAL(T,pointer_)) {
113            return;
114        }
115#endif
116    }
117}
118
119
120inline bool is_posted_write() {
121    return pending_write_vector_nb > 0;
122}
123
124
125extern "C" void update(void);
126
127
128// ----------------------------------------------------------------------------
129//  CLASS : sc_signal_base
130//
131//  The sc_signal_base<T> primitive channel class.
132// ----------------------------------------------------------------------------
133
134class sc_signal_base : public sc_object, public sc_interface {
135
136    //////
137    // Internal
138    friend class sc_clock;
139    friend class sc_port_base;
140    void init();
141    //////
142
143
144    public: 
145    // LRM (?)
146    //virtual const sc_event /*&*/ default_event() const;
147    static const char * const kind_string;
148    //virtual const char * kind() const;
149
150   
151
152    public:
153    sc_signal_base();
154    sc_signal_base(const char * name_);
155    sc_signal_base(const char * name_, void *);
156    ~sc_signal_base();
157
158};
159
160
161template < typename T >
162class sc_signal : public sc_signal_base {
163
164    private:
165
166    T val;
167
168    typedef T data_type;
169    typedef sc_signal < T > this_type;
170
171
172    ///////////
173    // Internal
174    public:
175    void init();
176    ///////////
177
178    void check_writer();
179
180    public:
181    // constructors, destructor
182    sc_signal() {
183        if (typeid(data_type) == typeid(double) || typeid(data_type) == typeid(float)) {
184            std::cerr << "Error: SystemCASS does not support sc_signal<T> with T of type " << typeid(data_type).name() << std::endl;
185            exit(1);
186        }
187        init();
188    }
189
190    explicit sc_signal(const char * name_) : sc_signal_base(name_) {
191        init();
192    }
193
194    /*virtual*/ ~sc_signal() {}
195    /*virtual*/ inline const data_type & read() const INLINE;
196    /*virtual*/ inline void write(const data_type &) /*INLINE*/;
197
198    inline operator const data_type & () const { return this->read(); }
199
200    inline this_type & operator = (const data_type & a) {
201        sc_signal< T >::write(a);
202        return *this;
203    }
204
205    inline this_type & operator = (const sc_signal < T > & a) {
206        sc_signal< T >::write(a.read());
207        return *this;
208    }
209
210    inline this_type & operator += (const data_type & a) {
211        sc_signal< T >::write(read() + a);
212        return *this;
213    }
214
215    inline this_type & operator += (const sc_signal < T > & a) {
216        sc_signal< T >::write(read() + a.read());
217        return *this;
218    }
219
220    const data_type & get_new_value() const {
221        // Warning: untested and doesn't support variable size
222        unsigned int i = 0;
223        for (i = 0; i < pending_write_vector_capacity; i++) {
224            if (pending_write_vector[i].pointer == get_pointer()) {
225                return pending_write_vector[i].value;
226            }
227        }
228        return val;
229    }
230
231    //  void trace (sc_trace_file * tf) const;
232    /*
233    virtual void print(std::ostream & o) const { o << *this; }
234    virtual void dump(std::ostream & o) const { o << *this; }
235    */
236
237    private:
238    // disabled
239    sc_signal(const sc_signal < T > &);
240
241};
242
243
244template < typename T >
245void sc_signal< T >::init() {
246    set_pointer((tab_t *) (void *) &val);
247    set_kind(kind_string);
248    sc_interface::init(sizeof(data_type)); 
249    val = (T) 0; /* The simulator initializes the signal/register to 0.    */
250    /* However, hardware initialization still has to be done. */
251    /* This kind of initialization is for trace diffing.      */
252}
253
254
255// read the value
256template < typename T >
257/*virtual*/ inline const T & sc_signal< T >::read() const {
258#ifdef DUMP_READ
259    std::cerr << "read " << READ_SIGNAL(const data_type, get_pointer()) << " on signal " << name() << "\n";
260#endif
261    // QM
262    return READ_SIGNAL(T, get_pointer());
263}
264
265
266// write the new value
267template < typename T >
268inline void sc_signal< T >::write(const data_type & value_) {
269#ifdef CONFIG_DEBUG
270    if (get_pointer() == NULL) {
271        std::cerr << "Error : Unable to write into '" << name() << "'.";
272        exit(24032005);
273    }
274#endif
275#ifdef DUMP_WRITE
276    if (sc_signal< T >::read() == value_) {
277        return;
278    }
279    std::cerr << "write (posted) " << value_ << " on sc_signal (writing into register) '" << name() << "'\n";
280#endif
281   
282    post_write(/*(tab_t*)&val*/ get_pointer(), value_);
283}
284
285#undef INLINE
286#undef READ_SIGNAL
287
288
289} // end of namespace sc_core
290
291#endif /* __SC_SIGNAL_H__ */
292
293/*
294# Local Variables:
295# tab-width: 4;
296# c-basic-offset: 4;
297# c-file-offsets:((innamespace . 0)(inline-open . 0));
298# indent-tabs-mode: nil;
299# End:
300#
301# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
302*/
303
Note: See TracBrowser for help on using the repository browser.