sc_in.hh revision 13245:c666c5d4996b
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_port.hh"
37#include "../utils/sc_trace_file.hh"
38#include "sc_signal_in_if.hh"
39#include "sc_signal_inout_if.hh"
40
41namespace sc_core
42{
43
44class sc_event;
45class sc_trace_file;
46
47template <class T>
48class sc_in : public sc_port<sc_signal_in_if<T>, 1>
49{
50  public:
51    sc_in() : sc_port<sc_signal_in_if<T>, 1>(),
52        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
53    {}
54    explicit sc_in(const char *name) : sc_port<sc_signal_in_if<T>, 1>(name),
55        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
56    {}
57    virtual ~sc_in() {}
58
59    // Deprecated binding constructors.
60    explicit sc_in(const sc_signal_in_if<T> &interface) :
61        sc_port<sc_signal_in_if<T>, 1>(interface),
62        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
63    {}
64    sc_in(const char *name, const sc_signal_in_if<T> &interface) :
65        sc_port<sc_signal_in_if<T>, 1>(name, interface),
66        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
67    {}
68    explicit sc_in(sc_port_b<sc_signal_in_if<T> > &parent) :
69        sc_port<sc_signal_in_if<T>, 1>(parent),
70        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
71    {}
72    sc_in(const char *name, sc_port_b<sc_signal_in_if<T> > &parent) :
73        sc_port<sc_signal_in_if<T>, 1>(name, parent),
74        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
75    {}
76    explicit sc_in(sc_port<sc_signal_in_if<T>, 1> &parent) :
77        sc_port<sc_signal_in_if<T>, 1>(parent),
78        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
79    {}
80    sc_in(const char *name, sc_port<sc_signal_in_if<T>, 1> &parent) :
81        sc_port<sc_signal_in_if<T>, 1>(name, parent),
82        _valueChangedFinder(*this, &sc_signal_in_if<T>::value_changed_event)
83    {}
84
85    virtual void
86    bind(const sc_signal_in_if<T> &i)
87    {
88        sc_port<sc_signal_in_if<T>, 1>::bind(
89                const_cast<sc_signal_in_if<T> &>(i));
90    }
91    void operator () (const sc_signal_in_if<T> &i) { bind(i); }
92
93    virtual void
94    bind(sc_port<sc_signal_in_if<T>, 1> &i)
95    {
96        sc_port<sc_signal_in_if<T>, 1>::bind(i);
97    }
98    void
99    operator () (sc_port<sc_signal_in_if<T>, 1> &p)
100    {
101        bind(p);
102    }
103
104    virtual void
105    bind(sc_port<sc_signal_inout_if<T>, 1> &p)
106    {
107        sc_port_base::bind(p);
108    }
109    void
110    operator () (sc_port<sc_signal_inout_if<T>, 1> &p)
111    {
112        bind(p);
113    }
114
115    virtual void
116    end_of_elaboration()
117    {
118        for (auto params: traceParamsVec)
119            sc_trace(params->tf, (*this)->read(), params->name);
120
121        traceParamsVec.clear();
122    }
123
124    const T &read() const { return (*this)->read(); }
125    operator const T& () const { return (*this)->read(); }
126
127    const sc_event &default_event() const { return (*this)->default_event(); }
128    const sc_event &
129    value_changed_event() const
130    {
131        return (*this)->value_changed_event();
132    }
133    bool event() const { return (*this)->event(); }
134    sc_event_finder &value_changed() const { return _valueChangedFinder; }
135
136    virtual const char *kind() const { return "sc_in"; }
137
138    void
139    add_trace(sc_trace_file *tf, const std::string &name) const
140    {
141        traceParamsVec.push_back(new sc_trace_params(tf, name));
142    }
143
144  private:
145    mutable sc_event_finder_t<sc_signal_in_if<T> > _valueChangedFinder;
146
147    mutable sc_trace_params_vec traceParamsVec;
148
149    // Disabled
150    sc_in(const sc_in<T> &);
151    sc_in<T> &operator = (const sc_in<T> &);
152};
153
154template <class T>
155inline void
156sc_trace(sc_trace_file *tf, const sc_in<T> &i, const std::string &name)
157{
158    if (i.size())
159        sc_trace(tf, i->read(), name);
160    else
161        i.add_trace(tf, name);
162}
163
164template <>
165class sc_in<bool> : public sc_port<sc_signal_in_if<bool>, 1>
166{
167  public:
168    sc_in() : sc_port<sc_signal_in_if<bool>, 1>(),
169        _valueChangedFinder(*this,
170                &sc_signal_in_if<bool>::value_changed_event),
171        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
172        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
173    {}
174    explicit sc_in(const char *name) :
175        sc_port<sc_signal_in_if<bool>, 1>(name),
176        _valueChangedFinder(*this,
177                &sc_signal_in_if<bool>::value_changed_event),
178        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
179        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
180    {}
181    virtual ~sc_in() {}
182
183    // Deprecated binding constructors.
184    explicit sc_in(const sc_signal_in_if<bool> &interface) :
185        sc_port<sc_signal_in_if<bool>, 1>(interface),
186        _valueChangedFinder(*this,
187                &sc_signal_in_if<bool>::value_changed_event),
188        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
189        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
190    {}
191    sc_in(const char *name, const sc_signal_in_if<bool> &interface) :
192        sc_port<sc_signal_in_if<bool>, 1>(name, interface),
193        _valueChangedFinder(*this,
194                &sc_signal_in_if<bool>::value_changed_event),
195        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
196        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
197    {}
198    explicit sc_in(sc_port_b<sc_signal_in_if<bool> > &parent) :
199        sc_port<sc_signal_in_if<bool>, 1>(parent),
200        _valueChangedFinder(*this,
201                &sc_signal_in_if<bool>::value_changed_event),
202        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
203        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
204    {}
205    sc_in(const char *name, sc_port_b<sc_signal_in_if<bool> > &parent) :
206        sc_port<sc_signal_in_if<bool>, 1>(name, parent),
207        _valueChangedFinder(*this,
208                &sc_signal_in_if<bool>::value_changed_event),
209        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
210        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
211    {}
212    explicit sc_in(sc_port<sc_signal_in_if<bool>, 1> &parent) :
213        sc_port<sc_signal_in_if<bool>, 1>(parent),
214        _valueChangedFinder(*this,
215                &sc_signal_in_if<bool>::value_changed_event),
216        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
217        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
218    {}
219    sc_in(const char *name, sc_port<sc_signal_in_if<bool>, 1> &parent) :
220        sc_port<sc_signal_in_if<bool>, 1>(name, parent),
221        _valueChangedFinder(*this,
222                &sc_signal_in_if<bool>::value_changed_event),
223        _posFinder(*this, &sc_signal_in_if<bool>::posedge_event),
224        _negFinder(*this, &sc_signal_in_if<bool>::negedge_event)
225    {}
226
227    virtual void
228    bind(const sc_signal_in_if<bool> &i)
229    {
230        sc_port<sc_signal_in_if<bool>, 1>::bind(
231                const_cast<sc_signal_in_if<bool> &>(i));
232    }
233    void operator () (const sc_signal_in_if<bool> &i) { bind(i); }
234
235    virtual void
236    bind(sc_port<sc_signal_in_if<bool>, 1> &p)
237    {
238        sc_port<sc_signal_in_if<bool>, 1>::bind(p);
239    }
240    void
241    operator () (sc_port<sc_signal_in_if<bool>, 1> &p)
242    {
243        bind(p);
244    }
245
246    virtual void
247    bind(sc_port<sc_signal_inout_if<bool>, 1> &p)
248    {
249        sc_port_base::bind(p);
250    }
251    void
252    operator () (sc_port<sc_signal_inout_if<bool>, 1> &p)
253    {
254        bind(p);
255    }
256
257    virtual void
258    end_of_elaboration()
259    {
260        for (auto params: traceParamsVec)
261            sc_trace(params->tf, (*this)->read(), params->name);
262
263        traceParamsVec.clear();
264    }
265
266    const bool &read() const { return (*this)->read(); }
267    operator const bool& () const { return (*this)->read(); }
268
269    const sc_event &default_event() const { return (*this)->default_event(); }
270    const sc_event &
271    value_changed_event() const
272    {
273        return (*this)->value_changed_event();
274    }
275    const sc_event &
276    posedge_event() const
277    {
278        return (*this)->posedge_event();
279    }
280    const sc_event &
281    negedge_event() const
282    {
283        return (*this)->negedge_event();
284    }
285
286    bool event() const { return (*this)->event(); }
287    bool posedge() const { return (*this)->posedge(); }
288    bool negedge() const { return (*this)->negedge(); }
289
290    sc_event_finder &value_changed() const { return _valueChangedFinder; }
291    sc_event_finder &pos() const { return _posFinder; }
292    sc_event_finder &neg() const { return _negFinder; }
293
294    virtual const char *kind() const { return "sc_in"; }
295
296    void
297    add_trace(sc_trace_file *tf, const std::string &name) const
298    {
299        traceParamsVec.push_back(new sc_trace_params(tf, name));
300    }
301
302  private:
303    mutable sc_event_finder_t<sc_signal_in_if<bool> > _valueChangedFinder;
304    mutable sc_event_finder_t<sc_signal_in_if<bool> > _posFinder;
305    mutable sc_event_finder_t<sc_signal_in_if<bool> > _negFinder;
306
307    mutable sc_trace_params_vec traceParamsVec;
308
309    // Disabled
310    sc_in(const sc_in<bool> &);
311    sc_in<bool> &operator = (const sc_in<bool> &);
312};
313
314template <>
315inline void
316sc_trace<bool>(sc_trace_file *tf, const sc_in<bool> &i,
317        const std::string &name)
318{
319    if (i.size())
320        sc_trace(tf, i->read(), name);
321    else
322        i.add_trace(tf, name);
323}
324
325template <>
326class sc_in<sc_dt::sc_logic> :
327    public sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>
328{
329  public:
330    sc_in() : sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(),
331        _valueChangedFinder(*this,
332                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
333        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
334        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
335    {}
336    explicit sc_in(const char *name) :
337        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name),
338        _valueChangedFinder(*this,
339                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
340        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
341        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
342    {}
343    virtual ~sc_in() {}
344
345    // Deprecated binding constructors.
346    explicit sc_in(const sc_signal_in_if<sc_dt::sc_logic> &interface) :
347        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(interface),
348        _valueChangedFinder(*this,
349                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
350        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
351        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
352    {}
353    sc_in(const char *name,
354            const sc_signal_in_if<sc_dt::sc_logic> &interface) :
355        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, interface),
356        _valueChangedFinder(*this,
357                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
358        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
359        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
360    {}
361    explicit sc_in(sc_port_b<sc_signal_in_if<sc_dt::sc_logic> > &parent) :
362        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(parent),
363        _valueChangedFinder(*this,
364                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
365        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
366        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
367    {}
368    sc_in(const char *name,
369            sc_port_b<sc_signal_in_if<sc_dt::sc_logic> > &parent) :
370        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, parent),
371        _valueChangedFinder(*this,
372                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
373        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
374        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
375    {}
376    explicit sc_in(sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &parent) :
377        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(parent),
378        _valueChangedFinder(*this,
379                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
380        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
381        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
382    {}
383    sc_in(const char *name,
384            sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &parent) :
385        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>(name, parent),
386        _valueChangedFinder(*this,
387                &sc_signal_in_if<sc_dt::sc_logic>::value_changed_event),
388        _posFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::posedge_event),
389        _negFinder(*this, &sc_signal_in_if<sc_dt::sc_logic>::negedge_event)
390    {}
391
392    virtual void
393    bind(const sc_signal_in_if<sc_dt::sc_logic> &i)
394    {
395        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind(
396                const_cast<sc_signal_in_if<sc_dt::sc_logic> &>(i));
397    }
398    void
399    operator () (const sc_signal_in_if<sc_dt::sc_logic> &i) { bind(i); }
400
401    virtual void
402    bind(sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &i)
403    {
404        sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1>::bind(i);
405    }
406    void
407    operator () (sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &p)
408    {
409        bind(p);
410    }
411
412    virtual void
413    bind(sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
414    {
415        sc_port_base::bind(p);
416    }
417    void
418    operator () (sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
419    {
420        bind(p);
421    }
422
423    virtual void
424    end_of_elaboration()
425    {
426        for (auto params: traceParamsVec)
427            sc_trace(params->tf, (*this)->read(), params->name);
428
429        traceParamsVec.clear();
430    }
431
432    const sc_dt::sc_logic &read() const { return (*this)->read(); }
433    operator const sc_dt::sc_logic& () const { return (*this)->read(); }
434
435    const sc_event &default_event() const { return (*this)->default_event(); }
436    const sc_event &
437    value_changed_event() const
438    {
439        return (*this)->value_changed_event();
440    }
441    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
442    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
443
444    bool event() const { return (*this)->event(); }
445    bool posedge() const { return (*this)->posedge(); }
446    bool negedge() const { return (*this)->negedge(); }
447
448    sc_event_finder &value_changed() const { return _valueChangedFinder; }
449    sc_event_finder &pos() const { return _posFinder; }
450    sc_event_finder &neg() const { return _negFinder; }
451
452    virtual const char *kind() const { return "sc_in"; }
453
454    void
455    add_trace(sc_trace_file *tf, const std::string &name) const
456    {
457        traceParamsVec.push_back(new sc_trace_params(tf, name));
458    }
459
460  private:
461    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> >
462        _valueChangedFinder;
463    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _posFinder;
464    mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _negFinder;
465
466    mutable sc_trace_params_vec traceParamsVec;
467
468    // Disabled
469    sc_in(const sc_in<sc_dt::sc_logic> &);
470    sc_in<sc_dt::sc_logic> &operator = (const sc_in<sc_dt::sc_logic> &);
471};
472
473template <>
474inline void
475sc_trace<sc_dt::sc_logic>(sc_trace_file *tf, const sc_in<sc_dt::sc_logic> &i,
476        const std::string &name)
477{
478    if (i.size())
479        sc_trace(tf, i->read(), name);
480    else
481        i.add_trace(tf, name);
482}
483
484} // namespace sc_core
485
486#endif  //__SYSTEMC_EXT_CHANNEL_SC_IN_HH__
487