sc_in.hh revision 13383:2a8fdb1a805c
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_EXT_CHANNEL_SC_IN_HH__
31#define __SYSTEMC_EXT_CHANNEL_SC_IN_HH__
32
33#include <string>
34
35#include "../core/sc_event.hh"
36#include "../core/sc_main.hh"
37#include "../core/sc_port.hh"
38#include "../utils/sc_trace_file.hh"
39#include "sc_signal_in_if.hh"
40#include "sc_signal_inout_if.hh"
41
42namespace sc_core
43{
44
45class sc_event;
46class sc_trace_file;
47
48template <class T>
49class sc_in : public sc_port<sc_signal_in_if<T>, 1>
50{
51  public:
52    sc_in() : sc_port<sc_signal_in_if<T>, 1>(),
53        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
54    {}
55    explicit sc_in(const char *name) : sc_port<sc_signal_in_if<T>, 1>(name),
56        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
57    {}
58    virtual ~sc_in() {}
59
60    // Deprecated binding constructors.
61    explicit sc_in(const sc_signal_in_if<T> &interface) :
62        sc_port<sc_signal_in_if<T>, 1>(interface),
63        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
64    {}
65    sc_in(const char *name, const sc_signal_in_if<T> &interface) :
66        sc_port<sc_signal_in_if<T>, 1>(name, interface),
67        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
68    {}
69    explicit sc_in(sc_port_b<sc_signal_in_if<T> > &parent) :
70        sc_port<sc_signal_in_if<T>, 1>(parent),
71        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
72    {}
73    sc_in(const char *name, sc_port_b<sc_signal_in_if<T> > &parent) :
74        sc_port<sc_signal_in_if<T>, 1>(name, parent),
75        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
76    {}
77    explicit sc_in(sc_port<sc_signal_in_if<T>, 1> &parent) :
78        sc_port<sc_signal_in_if<T>, 1>(parent),
79        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
80    {}
81    sc_in(const char *name, sc_port<sc_signal_in_if<T>, 1> &parent) :
82        sc_port<sc_signal_in_if<T>, 1>(name, parent),
83        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
84    {}
85
86    virtual void
87    bind(const sc_signal_in_if<T> &i)
88    {
89        sc_port<sc_signal_in_if<T>, 1>::bind(
90                const_cast<sc_signal_in_if<T> &>(i));
91    }
92    void operator () (const sc_signal_in_if<T> &i) { bind(i); }
93
94    virtual void
95    bind(sc_port<sc_signal_in_if<T>, 1> &i)
96    {
97        sc_port<sc_signal_in_if<T>, 1>::bind(i);
98    }
99    void
100    operator () (sc_port<sc_signal_in_if<T>, 1> &p)
101    {
102        bind(p);
103    }
104
105    virtual void
106    bind(sc_port<sc_signal_inout_if<T>, 1> &p)
107    {
108        sc_port_base::bind(p);
109    }
110    void
111    operator () (sc_port<sc_signal_inout_if<T>, 1> &p)
112    {
113        bind(p);
114    }
115
116    virtual void
117    end_of_elaboration()
118    {
119        for (auto params: traceParamsVec)
120            sc_trace(params->tf, (*this)->read(), params->name);
121
122        traceParamsVec.clear();
123    }
124
125    const T &read() const { return (*this)->read(); }
126    operator const T& () const { return (*this)->read(); }
127
128    const sc_event &default_event() const { return (*this)->default_event(); }
129    const sc_event &
130    value_changed_event() const
131    {
132        return (*this)->value_changed_event();
133    }
134    bool event() const { return (*this)->event(); }
135    sc_event_finder &value_changed() const { return _valueChangedFinder; }
136
137    virtual const char *kind() const { return "sc_in"; }
138
139    void
140    add_trace(sc_trace_file *tf, const std::string &name) const
141    {
142        traceParamsVec.push_back(new sc_trace_params(tf, name));
143    }
144
145  private:
146    mutable sc_event_finder_t<sc_signal_in_if<T> > _valueChangedFinder;
147
148    mutable sc_trace_params_vec traceParamsVec;
149
150    // Disabled
151    sc_in(const sc_in<T> &);
152    sc_in<T> &operator = (const sc_in<T> &);
153};
154
155template <class T>
156inline void
157sc_trace(sc_trace_file *tf, const sc_in<T> &i, const std::string &name)
158{
159    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
160        i.add_trace(tf, name);
161    else
162        sc_trace(tf, i->read(), name);
163}
164
165template <>
166class sc_in<bool> : public sc_port<sc_signal_in_if<bool>, 1>
167{
168  public:
169    sc_in() : sc_port<sc_signal_in_if<bool>, 1>(),
170        _valueChangedFinder(*this,
171                &sc_signal_in_if<bool>::value_changed_event),
172        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
173        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
174    {}
175    explicit sc_in(const char *name) :
176        sc_port<sc_signal_in_if<bool>, 1>(name),
177        _valueChangedFinder(*this,
178                &sc_signal_in_if<bool>::value_changed_event),
179        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
180        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
181    {}
182    virtual ~sc_in() {}
183
184    // Deprecated binding constructors.
185    explicit sc_in(const sc_signal_in_if<bool> &interface) :
186        sc_port<sc_signal_in_if<bool>, 1>(interface),
187        _valueChangedFinder(*this,
188                &sc_signal_in_if<bool>::value_changed_event),
189        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
190        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
191    {}
192    sc_in(const char *name, const sc_signal_in_if<bool> &interface) :
193        sc_port<sc_signal_in_if<bool>, 1>(name, interface),
194        _valueChangedFinder(*this,
195                &sc_signal_in_if<bool>::value_changed_event),
196        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
197        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
198    {}
199    explicit sc_in(sc_port_b<sc_signal_in_if<bool> > &parent) :
200        sc_port<sc_signal_in_if<bool>, 1>(parent),
201        _valueChangedFinder(*this,
202                &sc_signal_in_if<bool>::value_changed_event),
203        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
204        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
205    {}
206    sc_in(const char *name, sc_port_b<sc_signal_in_if<bool> > &parent) :
207        sc_port<sc_signal_in_if<bool>, 1>(name, parent),
208        _valueChangedFinder(*this,
209                &sc_signal_in_if<bool>::value_changed_event),
210        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
211        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
212    {}
213    explicit sc_in(sc_port<sc_signal_in_if<bool>, 1> &parent) :
214        sc_port<sc_signal_in_if<bool>, 1>(parent),
215        _valueChangedFinder(*this,
216                &sc_signal_in_if<bool>::value_changed_event),
217        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
218        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
219    {}
220    sc_in(const char *name, sc_port<sc_signal_in_if<bool>, 1> &parent) :
221        sc_port<sc_signal_in_if<bool>, 1>(name, parent),
222        _valueChangedFinder(*this,
223                &sc_signal_in_if<bool>::value_changed_event),
224        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
225        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
226    {}
227
228    using sc_port<sc_signal_in_if<bool>, 1>::bind;
229
230    virtual void
231    bind(const sc_signal_in_if<bool> &i)
232    {
233        sc_port<sc_signal_in_if<bool>, 1>::bind(
234                const_cast<sc_signal_in_if<bool> &>(i));
235    }
236    void operator () (const sc_signal_in_if<bool> &i) { bind(i); }
237
238    virtual void
239    bind(sc_port<sc_signal_in_if<bool>, 1> &p)
240    {
241        sc_port<sc_signal_in_if<bool>, 1>::bind(p);
242    }
243    void
244    operator () (sc_port<sc_signal_in_if<bool>, 1> &p)
245    {
246        bind(p);
247    }
248
249    virtual void
250    bind(sc_port<sc_signal_inout_if<bool>, 1> &p)
251    {
252        sc_port_base::bind(p);
253    }
254    void
255    operator () (sc_port<sc_signal_inout_if<bool>, 1> &p)
256    {
257        bind(p);
258    }
259
260    virtual void
261    end_of_elaboration()
262    {
263        for (auto params: traceParamsVec)
264            sc_trace(params->tf, (*this)->read(), params->name);
265
266        traceParamsVec.clear();
267    }
268
269    const bool &read() const { return (*this)->read(); }
270    operator const bool& () const { return (*this)->read(); }
271
272    const sc_event &default_event() const { return (*this)->default_event(); }
273    const sc_event &
274    value_changed_event() const
275    {
276        return (*this)->value_changed_event();
277    }
278    const sc_event &
279    posedge_event() const
280    {
281        return (*this)->posedge_event();
282    }
283    const sc_event &
284    negedge_event() const
285    {
286        return (*this)->negedge_event();
287    }
288
289    bool event() const { return (*this)->event(); }
290    bool posedge() const { return (*this)->posedge(); }
291    bool negedge() const { return (*this)->negedge(); }
292
293    sc_event_finder &value_changed() const { return _valueChangedFinder; }
294    sc_event_finder &pos() const { return _posFinder; }
295    sc_event_finder &neg() const { return _negFinder; }
296
297    virtual const char *kind() const { return "sc_in"; }
298
299    void
300    add_trace(sc_trace_file *tf, const std::string &name) const
301    {
302        traceParamsVec.push_back(new sc_trace_params(tf, name));
303    }
304
305  private:
306    mutable sc_event_finder_t<sc_signal_in_if<bool> > _valueChangedFinder;
307    mutable sc_event_finder_t<sc_signal_in_if<bool> > _posFinder;
308    mutable sc_event_finder_t<sc_signal_in_if<bool> > _negFinder;
309
310    mutable sc_trace_params_vec traceParamsVec;
311
312    // Disabled
313    sc_in(const sc_in<bool> &);
314    sc_in<bool> &operator = (const sc_in<bool> &);
315};
316
317template <>
318inline void
319sc_trace<bool>(sc_trace_file *tf, const sc_in<bool> &i,
320        const std::string &name)
321{
322    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
323        i.add_trace(tf, name);
324    else
325        sc_trace(tf, i->read(), name);
326}
327
328template <>
329class sc_in<sc_dt::sc_logic> :
330    public sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>
331{
332  public:
333    sc_in() : sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(),
334        _valueChangedFinder(*this,
335                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
336        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
337        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
338    {}
339    explicit sc_in(const char *name) :
340        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name),
341        _valueChangedFinder(*this,
342                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
343        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
344        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
345    {}
346    virtual ~sc_in() {}
347
348    // Deprecated binding constructors.
349    explicit sc_in(const sc_signal_in_if<sc_dt::sc_logic> &interface) :
350        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(interface),
351        _valueChangedFinder(*this,
352                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
353        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
354        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
355    {}
356    sc_in(const char *name,
357            const sc_signal_in_if<sc_dt::sc_logic> &interface) :
358        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, interface),
359        _valueChangedFinder(*this,
360                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
361        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
362        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
363    {}
364    explicit sc_in(sc_port_b<sc_signal_in_if<sc_dt::sc_logic> > &parent) :
365        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(parent),
366        _valueChangedFinder(*this,
367                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
368        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
369        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
370    {}
371    sc_in(const char *name,
372            sc_port_b<sc_signal_in_if<sc_dt::sc_logic> > &parent) :
373        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, parent),
374        _valueChangedFinder(*this,
375                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
376        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
377        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
378    {}
379    explicit sc_in(sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &parent) :
380        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(parent),
381        _valueChangedFinder(*this,
382                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
383        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
384        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
385    {}
386    sc_in(const char *name,
387            sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &parent) :
388        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, parent),
389        _valueChangedFinder(*this,
390                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
391        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
392        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
393    {}
394
395    using sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind;
396
397    virtual void
398    bind(const sc_signal_in_if<sc_dt::sc_logic> &i)
399    {
400        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind(
401                const_cast<sc_signal_in_if<sc_dt::sc_logic> &>(i));
402    }
403    void
404    operator () (const sc_signal_in_if<sc_dt::sc_logic> &i) { bind(i); }
405
406    virtual void
407    bind(sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &i)
408    {
409        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind(i);
410    }
411    void
412    operator () (sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &p)
413    {
414        bind(p);
415    }
416
417    virtual void
418    bind(sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
419    {
420        sc_port_base::bind(p);
421    }
422    void
423    operator () (sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
424    {
425        bind(p);
426    }
427
428    virtual void
429    end_of_elaboration()
430    {
431        for (auto params: traceParamsVec)
432            sc_trace(params->tf, (*this)->read(), params->name);
433
434        traceParamsVec.clear();
435    }
436
437    const sc_dt::sc_logic &read() const { return (*this)->read(); }
438    operator const sc_dt::sc_logic& () const { return (*this)->read(); }
439
440    const sc_event &default_event() const { return (*this)->default_event(); }
441    const sc_event &
442    value_changed_event() const
443    {
444        return (*this)->value_changed_event();
445    }
446    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
447    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
448
449    bool event() const { return (*this)->event(); }
450    bool posedge() const { return (*this)->posedge(); }
451    bool negedge() const { return (*this)->negedge(); }
452
453    sc_event_finder &value_changed() const { return _valueChangedFinder; }
454    sc_event_finder &pos() const { return _posFinder; }
455    sc_event_finder &neg() const { return _negFinder; }
456
457    virtual const char *kind() const { return "sc_in"; }
458
459    void
460    add_trace(sc_trace_file *tf, const std::string &name) const
461    {
462        traceParamsVec.push_back(new sc_trace_params(tf, name));
463    }
464
465  private:
466    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> >
467        _valueChangedFinder;
468    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _posFinder;
469    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _negFinder;
470
471    mutable sc_trace_params_vec traceParamsVec;
472
473    // Disabled
474    sc_in(const sc_in<sc_dt::sc_logic> &);
475    sc_in<sc_dt::sc_logic> &operator = (const sc_in<sc_dt::sc_logic> &);
476};
477
478template <>
479inline void
480sc_trace<sc_dt::sc_logic>(sc_trace_file *tf, const sc_in<sc_dt::sc_logic> &i,
481        const std::string &name)
482{
483    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
484        i.add_trace(tf, name);
485    else
486        sc_trace(tf, i->read(), name);
487}
488
489} // namespace sc_core
490
491#endif  //__SYSTEMC_EXT_CHANNEL_SC_IN_HH__
492