source: sources/src/sc_signal.h @ 60

Last change on this file since 60 was 60, checked in by meunier, 8 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
RevLine 
[1]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\------------------------------------------------------------*/
[52]13
[1]14#ifndef __SC_SIGNAL_H__
15#define __SC_SIGNAL_H__
16
17// Define registers writing method
[27]18#include <iostream>
19#include <cstdlib>
[60]20#include <cstring>
[59]21#include <typeinfo> // for typeid
[52]22
[27]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
[1]30namespace sc_core {
31
32//
33#if ((__GNUC__ < 3) || (__GNUC_MINOR__ < 4))
[52]34    #define INLINE __attribute__((always_inline))
[1]35#else
[52]36    /* gcc3.4 doesn't support */ 
37    #define INLINE
[1]38#endif
39
[52]40
[1]41#define READ_SIGNAL(value_type_,pointer_) \
[52]42    ((value_type_ &) (*((value_type_ *) (pointer_))))
[1]43
[52]44///////////////////// DEPRECATED
[1]45// C ANSI-only since it is needed to link with extern "C"
46
[52]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
[1]52typedef tab_t base_type;
[52]53
[32]54struct pending_write_t {
[52]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    }
[1]61};
62
[52]63
[1]64// Check pending_writing to register
[52]65extern void pending_writing2register_clear();
66extern void pending_writing2register_record_and_check(const tab_t *);
[1]67
68// Pending write to register (simple stack)
[52]69typedef pending_write_t * pending_write_vector_t;
[60]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)
[1]73extern unsigned int pending_write_vector_capacity;
74
[60]75extern pending_write_vector_t pending_write_vector;
76#pragma omp threadprivate(pending_write_vector)
[1]77
[52]78template < typename T >
[59]79inline void post_write(base_type * const pointer_, const T & value_) /*INLINE*/;
[52]80
81template < typename T >
[59]82inline void post_multiwrite(base_type * const pointer_, const T & value_) {
[52]83    size_t size = (sizeof(T) - 1) / sizeof(base_type);
84    size_t i = 0;
[59]85    const base_type * pvalue = (const base_type *) (void *) (&value_);
[52]86    do {
87        post_write(pointer_ + i, pvalue[i]);
88    } while (i++ < size);
[1]89}
[52]90
91template < typename T >
[59]92inline void post_write(base_type * const pointer_, const T & value_) {
[52]93    if (sizeof(T) > sizeof(base_type)) {
[59]94        post_multiwrite(pointer_, value_);
[52]95    }
96    else {
97#if defined(CONFIG_DEBUG)
[60]98        if (*pending_write_vector_nb >= pending_write_vector_capacity) {
[52]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        }
[1]104#endif
[60]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 !
[1]108
[52]109        // -> fix to use user-defined struct in sc_signal/sc_in/sc_out/sc_inout
[60]110        // pending_write_vector[(*pending_write_vector_nb)++].value = *((base_type*)&value_); => bug !
[1]111#if 0
[52]112        std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n";
[1]113#endif
114#if 0 
[52]115        // introduce bug on using trace functions
116        if (value_ == READ_SIGNAL(T,pointer_)) {
117            return;
118        }
[1]119#endif
[52]120    }
[1]121}
122
[52]123
124inline bool is_posted_write() {
[60]125    return *pending_write_vector_nb > 0;
[1]126}
127
128
[52]129extern "C" void update(void);
130
131
[1]132// ----------------------------------------------------------------------------
133//  CLASS : sc_signal_base
134//
135//  The sc_signal_base<T> primitive channel class.
136// ----------------------------------------------------------------------------
137
[52]138class sc_signal_base : public sc_object, public sc_interface {
[1]139
[52]140    //////
141    // Internal
142    friend class sc_clock;
143    friend class sc_port_base;
144    void init();
145    //////
[1]146
[52]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
[1]162};
163
[22]164
[52]165template < typename T >
166class sc_signal : public sc_signal_base {
[22]167
[52]168    private:
[59]169
[52]170    T val;
[60]171    T new_val;
[52]172    typedef T data_type;
173    typedef sc_signal < T > this_type;
[1]174
[52]175
176    ///////////
177    // Internal
178    public:
179    void init();
180    ///////////
181
182    void check_writer();
183
184    public:
185    // constructors, destructor
186    sc_signal() {
[59]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        }
[52]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
[60]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
[59]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    }
[52]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
[1]270};
271
[52]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)); 
[60]278#if 0
[59]279    val = (T) 0; /* The simulator initializes the signal/register to 0.    */
[60]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
[1]285}
[52]286
287
[1]288// read the value
[52]289template < typename T >
290/*virtual*/ inline const T & sc_signal< T >::read() const {
[1]291#ifdef DUMP_READ
[59]292    std::cerr << "read " << READ_SIGNAL(const data_type, get_pointer()) << " on signal " << name() << "\n";
[1]293#endif
[59]294    // QM
295    return READ_SIGNAL(T, get_pointer());
[1]296}
297
[52]298
[1]299// write the new value
[52]300template < typename T >
301inline void sc_signal< T >::write(const data_type & value_) {
[60]302    if (sc_signal< T >::val == value_ && sc_signal< T >::new_val == value_) {
303        return;
304    }
[27]305#ifdef CONFIG_DEBUG
[52]306    if (get_pointer() == NULL) {
307        std::cerr << "Error : Unable to write into '" << name() << "'.";
308        exit(24032005);
309    }
[1]310#endif
311#ifdef DUMP_WRITE
[52]312    if (sc_signal< T >::read() == value_) {
313        return;
314    }
315    std::cerr << "write (posted) " << value_ << " on sc_signal (writing into register) '" << name() << "'\n";
[1]316#endif
[60]317    sc_signal<T>::new_val = value_;
[52]318    post_write(/*(tab_t*)&val*/ get_pointer(), value_);
[1]319}
320
321#undef INLINE
322#undef READ_SIGNAL
323
[52]324
[1]325} // end of namespace sc_core
326
327#endif /* __SC_SIGNAL_H__ */
328
[52]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.