sc_in.hh revision 13269:8807a4b970d4
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    virtual void
229    bind(const sc_signal_in_if<bool> &i)
230    {
231        sc_port<sc_signal_in_if<bool>, 1>::bind(
232                const_cast<sc_signal_in_if<bool> &>(i));
233    }
234    void operator () (const sc_signal_in_if<bool> &i) { bind(i); }
235
236    virtual void
237    bind(sc_port<sc_signal_in_if<bool>, 1> &p)
238    {
239        sc_port<sc_signal_in_if<bool>, 1>::bind(p);
240    }
241    void
242    operator () (sc_port<sc_signal_in_if<bool>, 1> &p)
243    {
244        bind(p);
245    }
246
247    virtual void
248    bind(sc_port<sc_signal_inout_if<bool>, 1> &p)
249    {
250        sc_port_base::bind(p);
251    }
252    void
253    operator () (sc_port<sc_signal_inout_if<bool>, 1> &p)
254    {
255        bind(p);
256    }
257
258    virtual void
259    end_of_elaboration()
260    {
261        for (auto params: traceParamsVec)
262            sc_trace(params->tf, (*this)->read(), params->name);
263
264        traceParamsVec.clear();
265    }
266
267    const bool &read() const { return (*this)->read(); }
268    operator const bool& () const { return (*this)->read(); }
269
270    const sc_event &default_event() const { return (*this)->default_event(); }
271    const sc_event &
272    value_changed_event() const
273    {
274        return (*this)->value_changed_event();
275    }
276    const sc_event &
277    posedge_event() const
278    {
279        return (*this)->posedge_event();
280    }
281    const sc_event &
282    negedge_event() const
283    {
284        return (*this)->negedge_event();
285    }
286
287    bool event() const { return (*this)->event(); }
288    bool posedge() const { return (*this)->posedge(); }
289    bool negedge() const { return (*this)->negedge(); }
290
291    sc_event_finder &value_changed() const { return _valueChangedFinder; }
292    sc_event_finder &pos() const { return _posFinder; }
293    sc_event_finder &neg() const { return _negFinder; }
294
295    virtual const char *kind() const { return "sc_in"; }
296
297    void
298    add_trace(sc_trace_file *tf, const std::string &name) const
299    {
300        traceParamsVec.push_back(new sc_trace_params(tf, name));
301    }
302
303  private:
304    mutable sc_event_finder_t<sc_signal_in_if<bool> > _valueChangedFinder;
305    mutable sc_event_finder_t<sc_signal_in_if<bool> > _posFinder;
306    mutable sc_event_finder_t<sc_signal_in_if<bool> > _negFinder;
307
308    mutable sc_trace_params_vec traceParamsVec;
309
310    // Disabled
311    sc_in(const sc_in<bool> &);
312    sc_in<bool> &operator = (const sc_in<bool> &);
313};
314
315template <>
316inline void
317sc_trace<bool>(sc_trace_file *tf, const sc_in<bool> &i,
318        const std::string &name)
319{
320    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
321        i.add_trace(tf, name);
322    else
323        sc_trace(tf, i->read(), name);
324}
325
326template <>
327class sc_in<sc_dt::sc_logic> :
328    public sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>
329{
330  public:
331    sc_in() : sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(),
332        _valueChangedFinder(*this,
333                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
334        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
335        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
336    {}
337    explicit sc_in(const char *name) :
338        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name),
339        _valueChangedFinder(*this,
340                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
341        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
342        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
343    {}
344    virtual ~sc_in() {}
345
346    // Deprecated binding constructors.
347    explicit sc_in(const sc_signal_in_if<sc_dt::sc_logic> &interface) :
348        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(interface),
349        _valueChangedFinder(*this,
350                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
351        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
352        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
353    {}
354    sc_in(const char *name,
355            const sc_signal_in_if<sc_dt::sc_logic> &interface) :
356        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, interface),
357        _valueChangedFinder(*this,
358                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
359        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
360        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
361    {}
362    explicit sc_in(sc_port_b<sc_signal_in_if<sc_dt::sc_logic> > &parent) :
363        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(parent),
364        _valueChangedFinder(*this,
365                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
366        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
367        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
368    {}
369    sc_in(const char *name,
370            sc_port_b<sc_signal_in_if<sc_dt::sc_logic> > &parent) :
371        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, parent),
372        _valueChangedFinder(*this,
373                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
374        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
375        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
376    {}
377    explicit sc_in(sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &parent) :
378        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(parent),
379        _valueChangedFinder(*this,
380                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
381        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
382        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
383    {}
384    sc_in(const char *name,
385            sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &parent) :
386        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, parent),
387        _valueChangedFinder(*this,
388                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
389        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
390        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
391    {}
392
393    virtual void
394    bind(const sc_signal_in_if<sc_dt::sc_logic> &i)
395    {
396        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind(
397                const_cast<sc_signal_in_if<sc_dt::sc_logic> &>(i));
398    }
399    void
400    operator () (const sc_signal_in_if<sc_dt::sc_logic> &i) { bind(i); }
401
402    virtual void
403    bind(sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &i)
404    {
405        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind(i);
406    }
407    void
408    operator () (sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &p)
409    {
410        bind(p);
411    }
412
413    virtual void
414    bind(sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
415    {
416        sc_port_base::bind(p);
417    }
418    void
419    operator () (sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
420    {
421        bind(p);
422    }
423
424    virtual void
425    end_of_elaboration()
426    {
427        for (auto params: traceParamsVec)
428            sc_trace(params->tf, (*this)->read(), params->name);
429
430        traceParamsVec.clear();
431    }
432
433    const sc_dt::sc_logic &read() const { return (*this)->read(); }
434    operator const sc_dt::sc_logic& () const { return (*this)->read(); }
435
436    const sc_event &default_event() const { return (*this)->default_event(); }
437    const sc_event &
438    value_changed_event() const
439    {
440        return (*this)->value_changed_event();
441    }
442    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
443    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
444
445    bool event() const { return (*this)->event(); }
446    bool posedge() const { return (*this)->posedge(); }
447    bool negedge() const { return (*this)->negedge(); }
448
449    sc_event_finder &value_changed() const { return _valueChangedFinder; }
450    sc_event_finder &pos() const { return _posFinder; }
451    sc_event_finder &neg() const { return _negFinder; }
452
453    virtual const char *kind() const { return "sc_in"; }
454
455    void
456    add_trace(sc_trace_file *tf, const std::string &name) const
457    {
458        traceParamsVec.push_back(new sc_trace_params(tf, name));
459    }
460
461  private:
462    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> >
463        _valueChangedFinder;
464    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _posFinder;
465    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _negFinder;
466
467    mutable sc_trace_params_vec traceParamsVec;
468
469    // Disabled
470    sc_in(const sc_in<sc_dt::sc_logic> &);
471    sc_in<sc_dt::sc_logic> &operator = (const sc_in<sc_dt::sc_logic> &);
472};
473
474template <>
475inline void
476sc_trace<sc_dt::sc_logic>(sc_trace_file *tf, const sc_in<sc_dt::sc_logic> &i,
477        const std::string &name)
478{
479    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
480        i.add_trace(tf, name);
481    else
482        sc_trace(tf, i->read(), name);
483}
484
485} // namespace sc_core
486
487#endif  //__SYSTEMC_EXT_CHANNEL_SC_IN_HH__
488