source: sources/src/sc_signal.h @ 59

Last change on this file since 59 was 59, checked in by meunier, 7 years ago
  • Fixed memory leaks
  • Fixed indentation in some files
File size: 8.3 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>
[59]20#include <typeinfo> // for typeid
[52]21
[27]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
[1]29namespace sc_core {
30
31//
32#if ((__GNUC__ < 3) || (__GNUC_MINOR__ < 4))
[52]33    #define INLINE __attribute__((always_inline))
[1]34#else
[52]35    /* gcc3.4 doesn't support */ 
36    #define INLINE
[1]37#endif
38
[52]39
[1]40#define READ_SIGNAL(value_type_,pointer_) \
[52]41    ((value_type_ &) (*((value_type_ *) (pointer_))))
[1]42
[52]43///////////////////// DEPRECATED
[1]44// C ANSI-only since it is needed to link with extern "C"
45
[52]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
[1]51typedef tab_t base_type;
[52]52
[32]53struct pending_write_t {
[52]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    }
[1]60};
61
[52]62
[1]63// Check pending_writing to register
[52]64extern void pending_writing2register_clear();
65extern void pending_writing2register_record_and_check(const tab_t *);
[1]66
67// Pending write to register (simple stack)
[52]68typedef pending_write_t * pending_write_vector_t;
[1]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
[52]74template < typename T >
[59]75inline void post_write(base_type * const pointer_, const T & value_) /*INLINE*/;
[52]76
77template < typename T >
[59]78inline void post_multiwrite(base_type * const pointer_, const T & value_) {
[52]79    size_t size = (sizeof(T) - 1) / sizeof(base_type);
80    size_t i = 0;
[59]81    const base_type * pvalue = (const base_type *) (void *) (&value_);
[52]82    do {
83        post_write(pointer_ + i, pvalue[i]);
84    } while (i++ < size);
[1]85}
[52]86
87template < typename T >
[59]88inline void post_write(base_type * const pointer_, const T & value_) {
[52]89    if (sizeof(T) > sizeof(base_type)) {
[59]90        post_multiwrite(pointer_, value_);
[52]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        }
[1]100#endif
[52]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 !
[1]104
[52]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 !
[1]107#if 0
[52]108        std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n";
[1]109#endif
110#if 0 
[52]111        // introduce bug on using trace functions
112        if (value_ == READ_SIGNAL(T,pointer_)) {
113            return;
114        }
[1]115#endif
[52]116    }
[1]117}
118
[52]119
120inline bool is_posted_write() {
121    return pending_write_vector_nb > 0;
[1]122}
123
124
[52]125extern "C" void update(void);
126
127
[1]128// ----------------------------------------------------------------------------
129//  CLASS : sc_signal_base
130//
131//  The sc_signal_base<T> primitive channel class.
132// ----------------------------------------------------------------------------
133
[52]134class sc_signal_base : public sc_object, public sc_interface {
[1]135
[52]136    //////
137    // Internal
138    friend class sc_clock;
139    friend class sc_port_base;
140    void init();
141    //////
[1]142
[52]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
[1]158};
159
[22]160
[52]161template < typename T >
162class sc_signal : public sc_signal_base {
[22]163
[52]164    private:
[59]165
[52]166    T val;
[59]167
[52]168    typedef T data_type;
169    typedef sc_signal < T > this_type;
[1]170
[52]171
172    ///////////
173    // Internal
174    public:
175    void init();
176    ///////////
177
178    void check_writer();
179
180    public:
181    // constructors, destructor
182    sc_signal() {
[59]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        }
[52]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
[59]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    }
[52]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
[1]241};
242
[52]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)); 
[59]249    val = (T) 0; /* The simulator initializes the signal/register to 0.    */
[52]250    /* However, hardware initialization still has to be done. */
251    /* This kind of initialization is for trace diffing.      */
[1]252}
[52]253
254
[1]255// read the value
[52]256template < typename T >
257/*virtual*/ inline const T & sc_signal< T >::read() const {
[1]258#ifdef DUMP_READ
[59]259    std::cerr << "read " << READ_SIGNAL(const data_type, get_pointer()) << " on signal " << name() << "\n";
[1]260#endif
[59]261    // QM
262    return READ_SIGNAL(T, get_pointer());
[1]263}
264
[52]265
[1]266// write the new value
[52]267template < typename T >
268inline void sc_signal< T >::write(const data_type & value_) {
[27]269#ifdef CONFIG_DEBUG
[52]270    if (get_pointer() == NULL) {
271        std::cerr << "Error : Unable to write into '" << name() << "'.";
272        exit(24032005);
273    }
[1]274#endif
275#ifdef DUMP_WRITE
[52]276    if (sc_signal< T >::read() == value_) {
277        return;
278    }
279    std::cerr << "write (posted) " << value_ << " on sc_signal (writing into register) '" << name() << "'\n";
[1]280#endif
[59]281   
[52]282    post_write(/*(tab_t*)&val*/ get_pointer(), value_);
[1]283}
284
285#undef INLINE
286#undef READ_SIGNAL
287
[52]288
[1]289} // end of namespace sc_core
290
291#endif /* __SC_SIGNAL_H__ */
292
[52]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.