source: sources/src/sc_signal.h @ 52

Last change on this file since 52 was 52, checked in by meunier, 11 years ago

Code formatting in all source files.

File size: 7.9 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
21#include "sc_fwd.h"
22#include "sc_nbdefs.h"
23#include "sc_time.h" // SC_ZERO_TIME
24#include "sc_object.h"
25#include "sc_interface.h"
26#include "internal_ext.h"
27
28namespace sc_core {
29
30//
31#if ((__GNUC__ < 3) || (__GNUC_MINOR__ < 4))
32    #define INLINE __attribute__((always_inline))
33#else
34    /* gcc3.4 doesn't support */ 
35    #define INLINE
36#endif
37
38
39#define READ_SIGNAL(value_type_,pointer_) \
40    ((value_type_ &) (*((value_type_ *) (pointer_))))
41
42///////////////////// DEPRECATED
43// C ANSI-only since it is needed to link with extern "C"
44
45extern void bind(sc_port_base &, sc_port_base &);
46extern void bind(sc_port_base &, sc_signal_base &);
47extern void bind(sc_signal_base & x);
48extern void bind(sc_port_base & x);
49
50typedef tab_t base_type;
51
52struct pending_write_t {
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    }
63};
64
65
66// Check pending_writing to register
67extern void pending_writing2register_clear();
68extern void pending_writing2register_record_and_check(const tab_t *);
69
70// Pending write to register (simple stack)
71typedef pending_write_t * pending_write_vector_t;
72extern pending_write_vector_t pending_write_vector;
73extern "C" unsigned int pending_write_vector_nb;
74extern unsigned int pending_write_vector_capacity;
75
76
77template < typename T >
78inline void post_write(base_type * const pointer_, const T value_) /*INLINE*/;
79
80template < typename T >
81inline 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
90template < typename T >
91inline 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 !
110#if 0
111        std::cerr << "posted write : ptr = " << pointer_ << ", val = " << value_ << "\n";
112#endif
113#if 0 
114        // introduce bug on using trace functions
115        if (value_ == READ_SIGNAL(T,pointer_)) {
116            return;
117        }
118#endif
119    }
120}
121
122
123inline bool is_posted_write() {
124    return pending_write_vector_nb > 0;
125}
126
127
128extern "C" void update(void);
129
130
131// ----------------------------------------------------------------------------
132//  CLASS : sc_signal_base
133//
134//  The sc_signal_base<T> primitive channel class.
135// ----------------------------------------------------------------------------
136
137class 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
161};
162
163
164template < typename T >
165class 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
232template < typename T >
233void 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
244template < 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
254template < typename T >
255inline 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
279/*
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 TracBrowser for help on using the repository browser.