sc_inout.hh revision 13071
111661Stushar@ece.gatech.edu/*
211661Stushar@ece.gatech.edu * Copyright 2018 Google, Inc.
311661Stushar@ece.gatech.edu *
411661Stushar@ece.gatech.edu * Redistribution and use in source and binary forms, with or without
511661Stushar@ece.gatech.edu * modification, are permitted provided that the following conditions are
611661Stushar@ece.gatech.edu * met: redistributions of source code must retain the above copyright
711661Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer;
811661Stushar@ece.gatech.edu * redistributions in binary form must reproduce the above copyright
911661Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer in the
1011661Stushar@ece.gatech.edu * documentation and/or other materials provided with the distribution;
1111661Stushar@ece.gatech.edu * neither the name of the copyright holders nor the names of its
1211661Stushar@ece.gatech.edu * contributors may be used to endorse or promote products derived from
1311661Stushar@ece.gatech.edu * this software without specific prior written permission.
1411661Stushar@ece.gatech.edu *
1511661Stushar@ece.gatech.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1611661Stushar@ece.gatech.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1711661Stushar@ece.gatech.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1811661Stushar@ece.gatech.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1911661Stushar@ece.gatech.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2011661Stushar@ece.gatech.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2111661Stushar@ece.gatech.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2211661Stushar@ece.gatech.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2311661Stushar@ece.gatech.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2411661Stushar@ece.gatech.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2511661Stushar@ece.gatech.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2611661Stushar@ece.gatech.edu *
2711661Stushar@ece.gatech.edu * Authors: Gabe Black
2811661Stushar@ece.gatech.edu */
2912564Sgabeblack@google.com
3012564Sgabeblack@google.com#ifndef __SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
3111661Stushar@ece.gatech.edu#define __SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
3211661Stushar@ece.gatech.edu
3311661Stushar@ece.gatech.edu#include <string>
3411661Stushar@ece.gatech.edu
3511661Stushar@ece.gatech.edu#include "../core/sc_event.hh"
3611682Sandreas.hansson@arm.com#include "../core/sc_port.hh"
3711670Sandreas.hansson@arm.com#include "../dt/bit/sc_logic.hh"
3811661Stushar@ece.gatech.edu#include "sc_signal_inout_if.hh"
3911682Sandreas.hansson@arm.com#include "warn_unimpl.hh"
4011670Sandreas.hansson@arm.com
4111661Stushar@ece.gatech.edunamespace sc_dt
4211661Stushar@ece.gatech.edu{
4311661Stushar@ece.gatech.edu
4411661Stushar@ece.gatech.educlass sc_logic;
4511661Stushar@ece.gatech.edu
4611661Stushar@ece.gatech.edu} // namespace sc_dt
4711661Stushar@ece.gatech.edu
4811688Sandreas.hansson@arm.comnamespace sc_core
4911661Stushar@ece.gatech.edu{
5011661Stushar@ece.gatech.edu
5111661Stushar@ece.gatech.educlass sc_event;
5211661Stushar@ece.gatech.educlass sc_trace_file;
5311661Stushar@ece.gatech.edu
5411661Stushar@ece.gatech.edutemplate <class T>
5511661Stushar@ece.gatech.educlass sc_inout : public sc_port<sc_signal_inout_if<T>, 1>
5611661Stushar@ece.gatech.edu{
5711661Stushar@ece.gatech.edu  public:
5811661Stushar@ece.gatech.edu    sc_inout() : sc_port<sc_signal_inout_if<T>, 1>(), initValue(nullptr),
5911661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
6011661Stushar@ece.gatech.edu    {}
6111661Stushar@ece.gatech.edu    explicit sc_inout(const char *name) :
6211661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(name), initValue(nullptr),
6311661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
6411661Stushar@ece.gatech.edu    {}
6511661Stushar@ece.gatech.edu    virtual ~sc_inout() { delete initValue; }
6611661Stushar@ece.gatech.edu
6711661Stushar@ece.gatech.edu    // Deprecated binding constructors.
6811661Stushar@ece.gatech.edu    explicit sc_inout(const sc_signal_inout_if<T> &interface) :
6911661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(interface), initValue(nullptr),
7011661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
7111661Stushar@ece.gatech.edu    {}
7211661Stushar@ece.gatech.edu    sc_inout(const char *name, const sc_signal_inout_if<T> &interface) :
7311661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(name, interface), initValue(nullptr),
7411661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
7511661Stushar@ece.gatech.edu    {}
7611661Stushar@ece.gatech.edu    explicit sc_inout(sc_port_b<sc_signal_inout_if<T> > &parent) :
7711661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(parent), initValue(nullptr),
7811661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
7911661Stushar@ece.gatech.edu    {}
8011661Stushar@ece.gatech.edu    sc_inout(const char *name, sc_port_b<sc_signal_inout_if<T> > &parent) :
8111661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(name, parent), initValue(nullptr),
8211661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
8311661Stushar@ece.gatech.edu    {}
8411661Stushar@ece.gatech.edu    explicit sc_inout(sc_port<sc_signal_inout_if<T>, 1> &parent) :
8511661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(parent), initValue(nullptr),
8611661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
8711661Stushar@ece.gatech.edu    {}
8811661Stushar@ece.gatech.edu    sc_inout(const char *name, sc_port<sc_signal_inout_if<T>, 1> &parent) :
8911661Stushar@ece.gatech.edu        sc_port<sc_signal_inout_if<T>, 1>(name, parent), initValue(nullptr),
9011661Stushar@ece.gatech.edu        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
9111661Stushar@ece.gatech.edu    {}
9211661Stushar@ece.gatech.edu
9311661Stushar@ece.gatech.edu    void
9411661Stushar@ece.gatech.edu    initialize(const T &t)
9512564Sgabeblack@google.com    {
9611661Stushar@ece.gatech.edu        if (this->size()) {
9711661Stushar@ece.gatech.edu            (*this)->write(t);
9811661Stushar@ece.gatech.edu        } else {
9911661Stushar@ece.gatech.edu            if (!initValue)
10012564Sgabeblack@google.com                initValue = new T;
10112564Sgabeblack@google.com            *initValue = t;
10211661Stushar@ece.gatech.edu        }
10311661Stushar@ece.gatech.edu    }
10411661Stushar@ece.gatech.edu    void initialize(const sc_signal_in_if<T> &i) { initialize(i.read()); }
10511661Stushar@ece.gatech.edu
10611661Stushar@ece.gatech.edu    virtual void
10711661Stushar@ece.gatech.edu    end_of_elaboration()
10811661Stushar@ece.gatech.edu    {
10911661Stushar@ece.gatech.edu        if (initValue) {
11011661Stushar@ece.gatech.edu            write(*initValue);
11111661Stushar@ece.gatech.edu            delete initValue;
11211661Stushar@ece.gatech.edu            initValue = nullptr;
11311661Stushar@ece.gatech.edu        }
11411661Stushar@ece.gatech.edu    }
11511661Stushar@ece.gatech.edu
11611661Stushar@ece.gatech.edu    const T &read() const { return (*this)->read(); }
11711661Stushar@ece.gatech.edu    operator const T& () const { return (*this)->read(); }
11811661Stushar@ece.gatech.edu
11911661Stushar@ece.gatech.edu    void write(const T &t) { (*this)->write(t); }
12011661Stushar@ece.gatech.edu    sc_inout<T> &
12111661Stushar@ece.gatech.edu    operator = (const T &t)
12211661Stushar@ece.gatech.edu    {
12311661Stushar@ece.gatech.edu        (*this)->write(t);
12411661Stushar@ece.gatech.edu        return *this;
12511661Stushar@ece.gatech.edu    }
12611661Stushar@ece.gatech.edu    sc_inout<T> &
12711661Stushar@ece.gatech.edu    operator = (const sc_signal_in_if<T> &i)
12811661Stushar@ece.gatech.edu    {
12911661Stushar@ece.gatech.edu        (*this)->write(i.read());
13011661Stushar@ece.gatech.edu        return *this;
13111661Stushar@ece.gatech.edu    }
13211661Stushar@ece.gatech.edu    sc_inout<T> &
13311661Stushar@ece.gatech.edu    operator = (const sc_port<sc_signal_in_if<T>, 1> &p)
13411661Stushar@ece.gatech.edu    {
13511661Stushar@ece.gatech.edu        (*this)->write(p->read());
13611661Stushar@ece.gatech.edu        return *this;
13711661Stushar@ece.gatech.edu    }
13811661Stushar@ece.gatech.edu    sc_inout<T> &
13911661Stushar@ece.gatech.edu    operator = (const sc_port<sc_signal_inout_if<T>, 1> &p)
14011661Stushar@ece.gatech.edu    {
14111661Stushar@ece.gatech.edu        (*this)->write(p->read());
14211661Stushar@ece.gatech.edu        return *this;
14311661Stushar@ece.gatech.edu    }
14411661Stushar@ece.gatech.edu    sc_inout<T> &
14511661Stushar@ece.gatech.edu    operator = (const sc_inout<T> &p)
14611661Stushar@ece.gatech.edu    {
14711661Stushar@ece.gatech.edu        (*this)->write(p->read());
14811661Stushar@ece.gatech.edu        return *this;
14911661Stushar@ece.gatech.edu    }
15011661Stushar@ece.gatech.edu
15111661Stushar@ece.gatech.edu    const sc_event &default_event() const { return (*this)->default_event(); }
15211661Stushar@ece.gatech.edu    const sc_event &
15311661Stushar@ece.gatech.edu    value_changed_event() const
15411661Stushar@ece.gatech.edu    {
15511661Stushar@ece.gatech.edu        return (*this)->value_changed_event();
15611661Stushar@ece.gatech.edu    }
15712564Sgabeblack@google.com    bool event() const { return (*this)->event(); }
158    sc_event_finder &value_changed() const { return _valueChangedFinder; }
159
160    virtual const char *kind() const { return "sc_inout"; }
161
162  private:
163    T *initValue;
164    mutable sc_event_finder_t<sc_signal_inout_if<T> > _valueChangedFinder;
165
166    // Disabled
167    sc_inout(const sc_inout<T> &);
168};
169
170template <class T>
171inline void
172sc_trace(sc_trace_file *, const sc_inout<T> &, const std::string &)
173{
174    sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
175}
176
177template <>
178class sc_inout<bool> : public sc_port<sc_signal_inout_if<bool>, 1>
179{
180  public:
181    sc_inout() : sc_port<sc_signal_inout_if<bool>, 1>(), initValue(nullptr),
182        _valueChangedFinder(*this,
183                &sc_signal_inout_if<bool>::value_changed_event),
184        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
185        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
186    {}
187    explicit sc_inout(const char *name) :
188            sc_port<sc_signal_inout_if<bool>, 1>(name), initValue(nullptr),
189        _valueChangedFinder(*this,
190                &sc_signal_inout_if<bool>::value_changed_event),
191        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
192        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
193    {}
194    virtual ~sc_inout() { delete initValue; }
195
196    // Deprecated binding constructors.
197    explicit sc_inout(const sc_signal_inout_if<bool> &interface) :
198        sc_port<sc_signal_inout_if<bool>, 1>(interface), initValue(nullptr),
199        _valueChangedFinder(*this,
200                &sc_signal_inout_if<bool>::value_changed_event),
201        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
202        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
203    {}
204    sc_inout(const char *name, const sc_signal_inout_if<bool> &interface) :
205        sc_port<sc_signal_inout_if<bool>, 1>(name, interface),
206        initValue(nullptr),
207        _valueChangedFinder(*this,
208                &sc_signal_inout_if<bool>::value_changed_event),
209        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
210        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
211    {}
212    explicit sc_inout(sc_port_b<sc_signal_inout_if<bool> > &parent) :
213        sc_port<sc_signal_inout_if<bool>, 1>(parent), initValue(nullptr),
214        _valueChangedFinder(*this,
215                &sc_signal_inout_if<bool>::value_changed_event),
216        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
217        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
218    {}
219    sc_inout(const char *name, sc_port_b<sc_signal_inout_if<bool> > &parent) :
220        sc_port<sc_signal_inout_if<bool>, 1>(name, parent), initValue(nullptr),
221        _valueChangedFinder(*this,
222                &sc_signal_inout_if<bool>::value_changed_event),
223        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
224        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
225    {}
226    explicit sc_inout(sc_port<sc_signal_inout_if<bool>, 1> &parent) :
227        sc_port<sc_signal_inout_if<bool>, 1>(parent), initValue(nullptr),
228        _valueChangedFinder(*this,
229                &sc_signal_inout_if<bool>::value_changed_event),
230        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
231        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
232    {}
233    sc_inout(const char *name, sc_port<sc_signal_inout_if<bool>, 1> &parent) :
234        sc_port<sc_signal_inout_if<bool>, 1>(name, parent), initValue(nullptr),
235        _valueChangedFinder(*this,
236                &sc_signal_inout_if<bool>::value_changed_event),
237        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
238        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
239    {}
240
241    void
242    initialize(const bool &b)
243    {
244        if (this->size()) {
245            (*this)->write(b);
246        } else {
247            if (!initValue)
248                initValue = new bool;
249            *initValue = b;
250        }
251    }
252    void initialize(const sc_signal_in_if<bool> &i) { initialize(i.read()); }
253
254    virtual void
255    end_of_elaboration()
256    {
257        if (initValue) {
258            write(*initValue);
259            delete initValue;
260            initValue = nullptr;
261        }
262    }
263
264    const bool &read() const { return (*this)->read(); }
265    operator const bool& () const { return (*this)->read(); }
266
267    void write(const bool &b) { (*this)->write(b); }
268    sc_inout<bool> &
269    operator = (const bool &b)
270    {
271        (*this)->write(b);
272        return *this;
273    }
274    sc_inout<bool> &
275    operator = (const sc_signal_in_if<bool> &i)
276    {
277        (*this)->write(i.read());
278        return *this;
279    }
280    sc_inout<bool> &
281    operator = (const sc_port<sc_signal_in_if<bool>, 1> &p)
282    {
283        (*this)->write(p->read());
284        return *this;
285    }
286    sc_inout<bool> &
287    operator = (const sc_port<sc_signal_inout_if<bool>, 1> &p)
288    {
289        (*this)->write(p->read());
290        return *this;
291    }
292    sc_inout<bool> &
293    operator = (const sc_inout<bool> &p)
294    {
295        (*this)->write(p->read());
296        return *this;
297    }
298
299    const sc_event &default_event() const { return (*this)->default_event(); }
300    const sc_event &
301    value_changed_event() const
302    {
303        return (*this)->value_changed_event();
304    }
305    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
306    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
307    bool event() const { return (*this)->event(); }
308    bool posedge() const { return (*this)->posedge(); }
309    bool negedge() const { return (*this)->negedge(); }
310
311    sc_event_finder &value_changed() const { return _valueChangedFinder; }
312    sc_event_finder &pos() const { return _posFinder; }
313    sc_event_finder &neg() const { return _negFinder; }
314
315    virtual const char *kind() const { return "sc_inout"; }
316
317  private:
318    bool *initValue;
319    mutable sc_event_finder_t<sc_signal_inout_if<bool> > _valueChangedFinder;
320    mutable sc_event_finder_t<sc_signal_inout_if<bool> > _posFinder;
321    mutable sc_event_finder_t<sc_signal_inout_if<bool> > _negFinder;
322
323    // Disabled
324    sc_inout(const sc_inout<bool> &);
325};
326
327template <>
328inline void sc_trace<bool>(
329        sc_trace_file *, const sc_inout<bool> &, const std::string &)
330{
331    sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
332}
333
334template <>
335class sc_inout<sc_dt::sc_logic> :
336        public sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>
337{
338  public:
339    sc_inout() : sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(),
340        initValue(nullptr),
341        _valueChangedFinder(*this,
342                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
343        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
344        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
345    {}
346    explicit sc_inout(const char *name) :
347            sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name),
348        initValue(nullptr),
349        _valueChangedFinder(*this,
350                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
351        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
352        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
353    {}
354    virtual ~sc_inout() { delete initValue; }
355
356    // Deprecated binding constructors.
357    explicit sc_inout(const sc_signal_inout_if<sc_dt::sc_logic> &interface) :
358        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(interface),
359        initValue(nullptr),
360        _valueChangedFinder(*this,
361                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
362        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
363        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
364    {}
365    sc_inout(const char *name,
366            const sc_signal_inout_if<sc_dt::sc_logic> &interface) :
367        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, interface),
368        initValue(nullptr),
369        _valueChangedFinder(*this,
370                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
371        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
372        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
373    {}
374    explicit sc_inout(
375            sc_port_b<sc_signal_inout_if<sc_dt::sc_logic> > &parent) :
376        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(parent),
377        initValue(nullptr),
378        _valueChangedFinder(*this,
379                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
380        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
381        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
382    {}
383    sc_inout(const char *name,
384            sc_port_b<sc_signal_inout_if<sc_dt::sc_logic> > &parent) :
385        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, parent),
386        initValue(nullptr),
387        _valueChangedFinder(*this,
388                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
389        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
390        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
391    {}
392    explicit sc_inout(
393            sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &parent) :
394        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(parent),
395        initValue(nullptr),
396        _valueChangedFinder(*this,
397                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
398        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
399        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
400    {}
401    sc_inout(const char *name,
402            sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &parent) :
403        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, parent),
404        initValue(nullptr),
405        _valueChangedFinder(*this,
406                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
407        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
408        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
409    {}
410
411    void
412    initialize(const sc_dt::sc_logic &l)
413    {
414        if (this->size()) {
415            (*this)->write(l);
416        } else {
417            if (!initValue)
418                initValue = new sc_dt::sc_logic;
419            *initValue = l;
420        }
421    }
422    void
423    initialize(const sc_signal_in_if<sc_dt::sc_logic> &i)
424    {
425        initialize(i.read());
426    }
427
428    virtual void
429    end_of_elaboration()
430    {
431        if (initValue) {
432            write(*initValue);
433            delete initValue;
434            initValue = nullptr;
435        }
436    }
437
438    const sc_dt::sc_logic &read() const { return (*this)->read(); }
439    operator const sc_dt::sc_logic& () const { return (*this)->read(); }
440
441    void write(const sc_dt::sc_logic &l) { (*this)->write(l); }
442    sc_inout<sc_dt::sc_logic> &
443    operator = (const sc_dt::sc_logic &l)
444    {
445        (*this)->write(l);
446        return *this;
447    }
448    sc_inout<sc_dt::sc_logic> &
449    operator = (const sc_signal_in_if<sc_dt::sc_logic> &i)
450    {
451        (*this)->write(i.read());
452        return *this;
453    }
454    sc_inout<sc_dt::sc_logic> &
455    operator = (const sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &p)
456    {
457        (*this)->write(p->read());
458        return *this;
459    }
460    sc_inout<sc_dt::sc_logic> &
461    operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
462    {
463        (*this)->write(p->read());
464        return *this;
465    }
466    sc_inout<sc_dt::sc_logic> &
467    operator = (const sc_inout<sc_dt::sc_logic> &p)
468    {
469        (*this)->write(p->read());
470        return *this;
471    }
472
473    const sc_event &default_event() const { return (*this)->default_event(); }
474    const sc_event &
475    value_changed_event() const
476    {
477        return (*this)->value_changed_event();
478    }
479    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
480    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
481    bool event() const { return (*this)->event(); }
482    bool posedge() const { return (*this)->posedge(); }
483    bool negedge() const { return (*this)->negedge(); }
484
485    sc_event_finder &value_changed() const { return _valueChangedFinder; }
486    sc_event_finder &pos() const { return _posFinder; }
487    sc_event_finder &neg() const { return _negFinder; }
488
489    virtual const char *kind() const { return "sc_inout"; }
490
491  private:
492    sc_dt::sc_logic *initValue;
493    mutable sc_event_finder_t<
494        sc_signal_inout_if<sc_dt::sc_logic> > _valueChangedFinder;
495    mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _posFinder;
496    mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _negFinder;
497
498    // Disabled
499    sc_inout(const sc_inout<sc_dt::sc_logic> &);
500};
501
502template <>
503inline void
504sc_trace<sc_dt::sc_logic>(sc_trace_file *, const sc_inout<sc_dt::sc_logic> &,
505                          const std::string &)
506{
507    sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
508}
509
510} // namespace sc_core
511
512#endif  //__SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
513