source: sources/src/sc_signal.h @ 60

Last change on this file since 60 was 60, checked in by meunier, 7 years ago
  • Intégration des modifications de Clément, qui a intégré la version parallélisée de systemcass faite par Manuel.
File size: 9.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
14#ifndef __SC_SIGNAL_H__
15#define __SC_SIGNAL_H__
16
17// Define registers writing method
18#include <iostream>
19#include <cstdlib>
20#include <cstring>
21#include <typeinfo> // for typeid
22
23#include "sc_fwd.h"
24#include "sc_nbdefs.h"
25#include "sc_time.h" // SC_ZERO_TIME
26#include "sc_object.h"
27#include "sc_interface.h"
28#include "internal_ext.h"
29
30namespace sc_core {
31
32//
33#if ((__GNUC__ < 3) || (__GNUC_MINOR__ < 4))
34    #define INLINE __attribute__((always_inline))
35#else
36    /* gcc3.4 doesn't support */ 
37    #define INLINE
38#endif
39
40
41#define READ_SIGNAL(value_type_,pointer_) \
42    ((value_type_ &) (*((value_type_ *) (pointer_))))
43
44///////////////////// DEPRECATED
45// C ANSI-only since it is needed to link with extern "C"
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);
51
52typedef tab_t base_type;
53
54struct pending_write_t {
55    base_type * pointer;
56    base_type value;
57   
58    friend std::ostream & operator << (std::ostream & o, const pending_write_t & p) {
59        return o << "(pointer = " << p.pointer << "; value = " << p.value << ")\n";
60    }
61};
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 "C" int32_t * pending_write_vector_nb;
71extern "C" unsigned long long int total_assig;
72#pragma omp threadprivate(pending_write_vector_nb, total_assig)
73extern unsigned int pending_write_vector_capacity;
74
75extern pending_write_vector_t pending_write_vector;
76#pragma omp threadprivate(pending_write_vector)
77
78template < typename T >
79inline void post_write(base_type * const pointer_, const T & value_) /*INLINE*/;
80
81template < typename T >
82inline void post_multiwrite(base_type * const pointer_, const T & value_) {
83    size_t size = (sizeof(T) - 1) / sizeof(base_type);
84    size_t i = 0;
85    const base_type * pvalue = (const base_type *) (void *) (&value_);
86    do {
87        post_write(pointer_ + i, pvalue[i]);
88    } while (i++ < size);
89}
90
91template < typename T >
92inline void post_write(base_type * const pointer_, const T & value_) {
93    if (sizeof(T) > sizeof(base_type)) {
94        post_multiwrite(pointer_, value_);
95    }
96    else {
97#if defined(CONFIG_DEBUG)
98        if (*pending_write_vector_nb >= pending_write_vector_capacity) {
99            std::cerr << "Error : The array for posted writing on register is too small.\n";
100            std::cerr << "Up to 1 writing per register is allowed during a cycle.\n";
101            std::cerr << "Please check the hardware description.\n";
102            exit(-1);
103        }
104#endif
105        pending_write_vector[*pending_write_vector_nb].pointer = pointer_;
106        // pending_write_vector[(*pending_write_vector_nb)++].value = *(reinterpret_cast<const base_type*const>(&value_)); => bug !
107        pending_write_vector[(*pending_write_vector_nb)++].value = value_; // => bug avec blues !
108
109        // -> fix to use user-defined struct in sc_signal/sc_in/sc_out/sc_inout
110        // pending_write_vector[(*pending_write_vector_nb)++].value = *((base_type*)&value_); => bug !
111#if 0
112        std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n";
113#endif
114#if 0 
115        // introduce bug on using trace functions
116        if (value_ == READ_SIGNAL(T,pointer_)) {
117            return;
118        }
119#endif
120    }
121}
122
123
124inline bool is_posted_write() {
125    return *pending_write_vector_nb > 0;
126}
127
128
129extern "C" void update(void);
130
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
148    public: 
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   
155
156    public:
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};
163
164
165template < typename T >
166class sc_signal : public sc_signal_base {
167
168    private:
169
170    T val;
171    T new_val;
172    typedef T data_type;
173    typedef sc_signal < T > this_type;
174
175
176    ///////////
177    // Internal
178    public:
179    void init();
180    ///////////
181
182    void check_writer();
183
184    public:
185    // constructors, destructor
186    sc_signal() {
187        if (typeid(data_type) == typeid(double) || typeid(data_type) == typeid(float)) {
188            std::cerr << "Error: SystemCASS does not support sc_signal<T> with T of type " << typeid(data_type).name() << std::endl;
189            exit(1);
190        }
191        init();
192    }
193
194    explicit sc_signal(const char * name_) : sc_signal_base(name_) {
195        init();
196    }
197
198    /*virtual*/ ~sc_signal() {}
199    /*virtual*/ inline const data_type & read() const INLINE;
200    /*virtual*/ inline void write(const data_type &) /*INLINE*/;
201
202    inline operator const data_type & () const { return this->read(); }
203
204    inline this_type & operator = (const data_type & a) {
205        sc_signal< T >::write(a);
206        return *this;
207    }
208
209    inline this_type & operator = (const sc_signal < T > & a) {
210        sc_signal< T >::write(a.read());
211        return *this;
212    }
213
214    inline this_type & operator += (const data_type & a) {
215        sc_signal< T >::write(read() + a);
216        return *this;
217    }
218
219    inline this_type & operator += (const sc_signal < T > & a) {
220        sc_signal< T >::write(read() + a.read());
221        return *this;
222    }
223
224    inline void * operator new (size_t size, size_t align) {
225        void * p;
226        const size_t nsize = (size + align - 1) & ~(align - 1);
227        if (nsize < size) {
228            std::cerr << "sc_signal new() alignement doesn't work (" <<
229                nsize << " < " << size << ")" << std::endl;
230            abort();
231        }
232
233        if (posix_memalign(&p, align, nsize) == 0) {
234            return p;
235        }
236        else {
237            return NULL;
238        }
239    }
240
241    inline void * operator new (size_t size) {
242        return malloc(size);
243    }
244
245    inline void * operator new (size_t size, void * p) {
246        return p;
247    }
248
249    const data_type & get_new_value() const {
250        // Warning: untested and doesn't support variable size
251        unsigned int i = 0;
252        for (i = 0; i < pending_write_vector_capacity; i++) {
253            if (pending_write_vector[i].pointer == get_pointer()) {
254                return pending_write_vector[i].value;
255            }
256        }
257        return val;
258    }
259
260    //  void trace (sc_trace_file * tf) const;
261    /*
262    virtual void print(std::ostream & o) const { o << *this; }
263    virtual void dump(std::ostream & o) const { o << *this; }
264    */
265
266    private:
267    // disabled
268    sc_signal(const sc_signal < T > &);
269
270};
271
272
273template < typename T >
274void sc_signal< T >::init() {
275    set_pointer((tab_t *) (void *) &val);
276    set_kind(kind_string);
277    sc_interface::init(sizeof(data_type)); 
278#if 0
279    val = (T) 0; /* The simulator initializes the signal/register to 0.    */
280                 /* However, hardware initialization still has to be done. */
281                 /* This kind of initialization is for trace diffing.      */
282#else
283    memset(&val, 0, sizeof(val));
284#endif
285}
286
287
288// read the value
289template < typename T >
290/*virtual*/ inline const T & sc_signal< T >::read() const {
291#ifdef DUMP_READ
292    std::cerr << "read " << READ_SIGNAL(const data_type, get_pointer()) << " on signal " << name() << "\n";
293#endif
294    // QM
295    return READ_SIGNAL(T, get_pointer());
296}
297
298
299// write the new value
300template < typename T >
301inline void sc_signal< T >::write(const data_type & value_) {
302    if (sc_signal< T >::val == value_ && sc_signal< T >::new_val == value_) {
303        return;
304    }
305#ifdef CONFIG_DEBUG
306    if (get_pointer() == NULL) {
307        std::cerr << "Error : Unable to write into '" << name() << "'.";
308        exit(24032005);
309    }
310#endif
311#ifdef DUMP_WRITE
312    if (sc_signal< T >::read() == value_) {
313        return;
314    }
315    std::cerr << "write (posted) " << value_ << " on sc_signal (writing into register) '" << name() << "'\n";
316#endif
317    sc_signal<T>::new_val = value_;
318    post_write(/*(tab_t*)&val*/ get_pointer(), value_);
319}
320
321#undef INLINE
322#undef READ_SIGNAL
323
324
325} // end of namespace sc_core
326
327#endif /* __SC_SIGNAL_H__ */
328
329/*
330# Local Variables:
331# tab-width: 4;
332# c-basic-offset: 4;
333# c-file-offsets:((innamespace . 0)(inline-open . 0));
334# indent-tabs-mode: nil;
335# End:
336#
337# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
338*/
339
Note: See TracBrowser for help on using the repository browser.