112841Sgabeblack@google.com/*
212841Sgabeblack@google.com * Copyright 2018 Google, Inc.
312841Sgabeblack@google.com *
412841Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
512841Sgabeblack@google.com * modification, are permitted provided that the following conditions are
612841Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
712841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
812841Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
912841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1012841Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1112841Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1212841Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1312841Sgabeblack@google.com * this software without specific prior written permission.
1412841Sgabeblack@google.com *
1512841Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612841Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712841Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812841Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912841Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012841Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112841Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212841Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312841Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412841Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512841Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612841Sgabeblack@google.com *
2712841Sgabeblack@google.com * Authors: Gabe Black
2812841Sgabeblack@google.com */
2912841Sgabeblack@google.com
3012841Sgabeblack@google.com#ifndef __SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
3112841Sgabeblack@google.com#define __SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
3212841Sgabeblack@google.com
3312841Sgabeblack@google.com#include <string>
3412841Sgabeblack@google.com
3513071Sgabeblack@google.com#include "../core/sc_event.hh"
3613269Sgabeblack@google.com#include "../core/sc_main.hh"
3712841Sgabeblack@google.com#include "../core/sc_port.hh"
3813071Sgabeblack@google.com#include "../dt/bit/sc_logic.hh"
3913245Sgabeblack@google.com#include "../utils/sc_trace_file.hh"
4012841Sgabeblack@google.com#include "sc_signal_inout_if.hh"
4112841Sgabeblack@google.com
4212841Sgabeblack@google.comnamespace sc_dt
4312841Sgabeblack@google.com{
4412841Sgabeblack@google.com
4512841Sgabeblack@google.comclass sc_logic;
4612841Sgabeblack@google.com
4712841Sgabeblack@google.com} // namespace sc_dt
4812841Sgabeblack@google.com
4912841Sgabeblack@google.comnamespace sc_core
5012841Sgabeblack@google.com{
5112841Sgabeblack@google.com
5212841Sgabeblack@google.comclass sc_event;
5312841Sgabeblack@google.comclass sc_trace_file;
5412841Sgabeblack@google.com
5512841Sgabeblack@google.comtemplate <class T>
5612841Sgabeblack@google.comclass sc_inout : public sc_port<sc_signal_inout_if<T>, 1>
5712841Sgabeblack@google.com{
5812841Sgabeblack@google.com  public:
5913071Sgabeblack@google.com    sc_inout() : sc_port<sc_signal_inout_if<T>, 1>(), initValue(nullptr),
6013071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
6113071Sgabeblack@google.com    {}
6212841Sgabeblack@google.com    explicit sc_inout(const char *name) :
6313071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(name), initValue(nullptr),
6413071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
6512841Sgabeblack@google.com    {}
6613071Sgabeblack@google.com    virtual ~sc_inout() { delete initValue; }
6712841Sgabeblack@google.com
6812868Sgabeblack@google.com    // Deprecated binding constructors.
6912868Sgabeblack@google.com    explicit sc_inout(const sc_signal_inout_if<T> &interface) :
7013071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(interface), initValue(nullptr),
7113071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
7212868Sgabeblack@google.com    {}
7312868Sgabeblack@google.com    sc_inout(const char *name, const sc_signal_inout_if<T> &interface) :
7413071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(name, interface), initValue(nullptr),
7513071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
7612868Sgabeblack@google.com    {}
7712868Sgabeblack@google.com    explicit sc_inout(sc_port_b<sc_signal_inout_if<T> > &parent) :
7813071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(parent), initValue(nullptr),
7913071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
8012868Sgabeblack@google.com    {}
8112868Sgabeblack@google.com    sc_inout(const char *name, sc_port_b<sc_signal_inout_if<T> > &parent) :
8213071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(name, parent), initValue(nullptr),
8313071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
8412868Sgabeblack@google.com    {}
8512868Sgabeblack@google.com    explicit sc_inout(sc_port<sc_signal_inout_if<T>, 1> &parent) :
8613071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(parent), initValue(nullptr),
8713071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
8812868Sgabeblack@google.com    {}
8912868Sgabeblack@google.com    sc_inout(const char *name, sc_port<sc_signal_inout_if<T>, 1> &parent) :
9013071Sgabeblack@google.com        sc_port<sc_signal_inout_if<T>, 1>(name, parent), initValue(nullptr),
9113071Sgabeblack@google.com        _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
9212868Sgabeblack@google.com    {}
9312868Sgabeblack@google.com
9412841Sgabeblack@google.com    void
9513071Sgabeblack@google.com    initialize(const T &t)
9612841Sgabeblack@google.com    {
9713071Sgabeblack@google.com        if (this->size()) {
9813071Sgabeblack@google.com            (*this)->write(t);
9913071Sgabeblack@google.com        } else {
10013071Sgabeblack@google.com            if (!initValue)
10113071Sgabeblack@google.com                initValue = new T;
10213071Sgabeblack@google.com            *initValue = t;
10313071Sgabeblack@google.com        }
10412841Sgabeblack@google.com    }
10513071Sgabeblack@google.com    void initialize(const sc_signal_in_if<T> &i) { initialize(i.read()); }
10613071Sgabeblack@google.com
10713071Sgabeblack@google.com    virtual void
10813071Sgabeblack@google.com    end_of_elaboration()
10912841Sgabeblack@google.com    {
11013071Sgabeblack@google.com        if (initValue) {
11113071Sgabeblack@google.com            write(*initValue);
11213071Sgabeblack@google.com            delete initValue;
11313071Sgabeblack@google.com            initValue = nullptr;
11413071Sgabeblack@google.com        }
11513245Sgabeblack@google.com
11613245Sgabeblack@google.com        for (auto params: traceParamsVec)
11713245Sgabeblack@google.com            sc_trace(params->tf, (*this)->read(), params->name);
11813245Sgabeblack@google.com
11913245Sgabeblack@google.com        traceParamsVec.clear();
12012841Sgabeblack@google.com    }
12112841Sgabeblack@google.com
12213071Sgabeblack@google.com    const T &read() const { return (*this)->read(); }
12313071Sgabeblack@google.com    operator const T& () const { return (*this)->read(); }
12412841Sgabeblack@google.com
12513071Sgabeblack@google.com    void write(const T &t) { (*this)->write(t); }
12613071Sgabeblack@google.com    sc_inout<T> &
12713071Sgabeblack@google.com    operator = (const T &t)
12812841Sgabeblack@google.com    {
12913071Sgabeblack@google.com        (*this)->write(t);
13013071Sgabeblack@google.com        return *this;
13112841Sgabeblack@google.com    }
13213071Sgabeblack@google.com    sc_inout<T> &
13313071Sgabeblack@google.com    operator = (const sc_signal_in_if<T> &i)
13412841Sgabeblack@google.com    {
13513071Sgabeblack@google.com        (*this)->write(i.read());
13613071Sgabeblack@google.com        return *this;
13713071Sgabeblack@google.com    }
13813071Sgabeblack@google.com    sc_inout<T> &
13913071Sgabeblack@google.com    operator = (const sc_port<sc_signal_in_if<T>, 1> &p)
14013071Sgabeblack@google.com    {
14113071Sgabeblack@google.com        (*this)->write(p->read());
14213071Sgabeblack@google.com        return *this;
14313071Sgabeblack@google.com    }
14413071Sgabeblack@google.com    sc_inout<T> &
14513071Sgabeblack@google.com    operator = (const sc_port<sc_signal_inout_if<T>, 1> &p)
14613071Sgabeblack@google.com    {
14713071Sgabeblack@google.com        (*this)->write(p->read());
14813071Sgabeblack@google.com        return *this;
14913071Sgabeblack@google.com    }
15013071Sgabeblack@google.com    sc_inout<T> &
15113071Sgabeblack@google.com    operator = (const sc_inout<T> &p)
15213071Sgabeblack@google.com    {
15313071Sgabeblack@google.com        (*this)->write(p->read());
15413071Sgabeblack@google.com        return *this;
15512841Sgabeblack@google.com    }
15612841Sgabeblack@google.com
15713071Sgabeblack@google.com    const sc_event &default_event() const { return (*this)->default_event(); }
15812841Sgabeblack@google.com    const sc_event &
15912841Sgabeblack@google.com    value_changed_event() const
16012841Sgabeblack@google.com    {
16113071Sgabeblack@google.com        return (*this)->value_changed_event();
16212841Sgabeblack@google.com    }
16313071Sgabeblack@google.com    bool event() const { return (*this)->event(); }
16413071Sgabeblack@google.com    sc_event_finder &value_changed() const { return _valueChangedFinder; }
16512841Sgabeblack@google.com
16612841Sgabeblack@google.com    virtual const char *kind() const { return "sc_inout"; }
16712841Sgabeblack@google.com
16813245Sgabeblack@google.com    void
16913245Sgabeblack@google.com    add_trace(sc_trace_file *tf, const std::string &name) const
17013245Sgabeblack@google.com    {
17113245Sgabeblack@google.com        traceParamsVec.push_back(new sc_trace_params(tf, name));
17213245Sgabeblack@google.com    }
17313245Sgabeblack@google.com
17412841Sgabeblack@google.com  private:
17513071Sgabeblack@google.com    T *initValue;
17613071Sgabeblack@google.com    mutable sc_event_finder_t<sc_signal_inout_if<T> > _valueChangedFinder;
17713071Sgabeblack@google.com
17813245Sgabeblack@google.com    mutable sc_trace_params_vec traceParamsVec;
17913245Sgabeblack@google.com
18012841Sgabeblack@google.com    // Disabled
18113071Sgabeblack@google.com    sc_inout(const sc_inout<T> &);
18212841Sgabeblack@google.com};
18312841Sgabeblack@google.com
18412841Sgabeblack@google.comtemplate <class T>
18512841Sgabeblack@google.cominline void
18613245Sgabeblack@google.comsc_trace(sc_trace_file *tf, const sc_inout<T> &i, const std::string &name)
18712841Sgabeblack@google.com{
18813269Sgabeblack@google.com    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
18913269Sgabeblack@google.com        i.add_trace(tf, name);
19013269Sgabeblack@google.com    else
19113245Sgabeblack@google.com        sc_trace(tf, i->read(), name);
19212841Sgabeblack@google.com}
19312841Sgabeblack@google.com
19412841Sgabeblack@google.comtemplate <>
19512841Sgabeblack@google.comclass sc_inout<bool> : public sc_port<sc_signal_inout_if<bool>, 1>
19612841Sgabeblack@google.com{
19712841Sgabeblack@google.com  public:
19813071Sgabeblack@google.com    sc_inout() : sc_port<sc_signal_inout_if<bool>, 1>(), initValue(nullptr),
19913071Sgabeblack@google.com        _valueChangedFinder(*this,
20013071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
20113071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
20213071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
20313071Sgabeblack@google.com    {}
20412841Sgabeblack@google.com    explicit sc_inout(const char *name) :
20513071Sgabeblack@google.com            sc_port<sc_signal_inout_if<bool>, 1>(name), initValue(nullptr),
20613071Sgabeblack@google.com        _valueChangedFinder(*this,
20713071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
20813071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
20913071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
21012841Sgabeblack@google.com    {}
21113071Sgabeblack@google.com    virtual ~sc_inout() { delete initValue; }
21212841Sgabeblack@google.com
21312868Sgabeblack@google.com    // Deprecated binding constructors.
21412868Sgabeblack@google.com    explicit sc_inout(const sc_signal_inout_if<bool> &interface) :
21513071Sgabeblack@google.com        sc_port<sc_signal_inout_if<bool>, 1>(interface), initValue(nullptr),
21613071Sgabeblack@google.com        _valueChangedFinder(*this,
21713071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
21813071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
21913071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
22012868Sgabeblack@google.com    {}
22112868Sgabeblack@google.com    sc_inout(const char *name, const sc_signal_inout_if<bool> &interface) :
22213071Sgabeblack@google.com        sc_port<sc_signal_inout_if<bool>, 1>(name, interface),
22313071Sgabeblack@google.com        initValue(nullptr),
22413071Sgabeblack@google.com        _valueChangedFinder(*this,
22513071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
22613071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
22713071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
22812868Sgabeblack@google.com    {}
22912868Sgabeblack@google.com    explicit sc_inout(sc_port_b<sc_signal_inout_if<bool> > &parent) :
23013071Sgabeblack@google.com        sc_port<sc_signal_inout_if<bool>, 1>(parent), initValue(nullptr),
23113071Sgabeblack@google.com        _valueChangedFinder(*this,
23213071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
23313071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
23413071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
23512868Sgabeblack@google.com    {}
23612868Sgabeblack@google.com    sc_inout(const char *name, sc_port_b<sc_signal_inout_if<bool> > &parent) :
23713071Sgabeblack@google.com        sc_port<sc_signal_inout_if<bool>, 1>(name, parent), initValue(nullptr),
23813071Sgabeblack@google.com        _valueChangedFinder(*this,
23913071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
24013071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
24113071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
24212868Sgabeblack@google.com    {}
24312868Sgabeblack@google.com    explicit sc_inout(sc_port<sc_signal_inout_if<bool>, 1> &parent) :
24413071Sgabeblack@google.com        sc_port<sc_signal_inout_if<bool>, 1>(parent), initValue(nullptr),
24513071Sgabeblack@google.com        _valueChangedFinder(*this,
24613071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
24713071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
24813071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
24912868Sgabeblack@google.com    {}
25012868Sgabeblack@google.com    sc_inout(const char *name, sc_port<sc_signal_inout_if<bool>, 1> &parent) :
25113071Sgabeblack@google.com        sc_port<sc_signal_inout_if<bool>, 1>(name, parent), initValue(nullptr),
25213071Sgabeblack@google.com        _valueChangedFinder(*this,
25313071Sgabeblack@google.com                &sc_signal_inout_if<bool>::value_changed_event),
25413071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
25513071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
25612868Sgabeblack@google.com    {}
25712868Sgabeblack@google.com
25812841Sgabeblack@google.com    void
25913071Sgabeblack@google.com    initialize(const bool &b)
26012841Sgabeblack@google.com    {
26113071Sgabeblack@google.com        if (this->size()) {
26213071Sgabeblack@google.com            (*this)->write(b);
26313071Sgabeblack@google.com        } else {
26413071Sgabeblack@google.com            if (!initValue)
26513071Sgabeblack@google.com                initValue = new bool;
26613071Sgabeblack@google.com            *initValue = b;
26713071Sgabeblack@google.com        }
26812841Sgabeblack@google.com    }
26913071Sgabeblack@google.com    void initialize(const sc_signal_in_if<bool> &i) { initialize(i.read()); }
27013071Sgabeblack@google.com
27113071Sgabeblack@google.com    virtual void
27213071Sgabeblack@google.com    end_of_elaboration()
27312841Sgabeblack@google.com    {
27413071Sgabeblack@google.com        if (initValue) {
27513071Sgabeblack@google.com            write(*initValue);
27613071Sgabeblack@google.com            delete initValue;
27713071Sgabeblack@google.com            initValue = nullptr;
27813071Sgabeblack@google.com        }
27913245Sgabeblack@google.com
28013245Sgabeblack@google.com        for (auto params: traceParamsVec)
28113245Sgabeblack@google.com            sc_trace(params->tf, (*this)->read(), params->name);
28213245Sgabeblack@google.com
28313245Sgabeblack@google.com        traceParamsVec.clear();
28412841Sgabeblack@google.com    }
28512841Sgabeblack@google.com
28613071Sgabeblack@google.com    const bool &read() const { return (*this)->read(); }
28713071Sgabeblack@google.com    operator const bool& () const { return (*this)->read(); }
28812841Sgabeblack@google.com
28913071Sgabeblack@google.com    void write(const bool &b) { (*this)->write(b); }
29013071Sgabeblack@google.com    sc_inout<bool> &
29113071Sgabeblack@google.com    operator = (const bool &b)
29212841Sgabeblack@google.com    {
29313071Sgabeblack@google.com        (*this)->write(b);
29413071Sgabeblack@google.com        return *this;
29512841Sgabeblack@google.com    }
29613071Sgabeblack@google.com    sc_inout<bool> &
29713071Sgabeblack@google.com    operator = (const sc_signal_in_if<bool> &i)
29812841Sgabeblack@google.com    {
29913071Sgabeblack@google.com        (*this)->write(i.read());
30013071Sgabeblack@google.com        return *this;
30113071Sgabeblack@google.com    }
30213071Sgabeblack@google.com    sc_inout<bool> &
30313071Sgabeblack@google.com    operator = (const sc_port<sc_signal_in_if<bool>, 1> &p)
30413071Sgabeblack@google.com    {
30513071Sgabeblack@google.com        (*this)->write(p->read());
30613071Sgabeblack@google.com        return *this;
30713071Sgabeblack@google.com    }
30813071Sgabeblack@google.com    sc_inout<bool> &
30913071Sgabeblack@google.com    operator = (const sc_port<sc_signal_inout_if<bool>, 1> &p)
31013071Sgabeblack@google.com    {
31113071Sgabeblack@google.com        (*this)->write(p->read());
31213071Sgabeblack@google.com        return *this;
31313071Sgabeblack@google.com    }
31413071Sgabeblack@google.com    sc_inout<bool> &
31513071Sgabeblack@google.com    operator = (const sc_inout<bool> &p)
31613071Sgabeblack@google.com    {
31713071Sgabeblack@google.com        (*this)->write(p->read());
31813071Sgabeblack@google.com        return *this;
31912841Sgabeblack@google.com    }
32012841Sgabeblack@google.com
32113071Sgabeblack@google.com    const sc_event &default_event() const { return (*this)->default_event(); }
32212841Sgabeblack@google.com    const sc_event &
32312841Sgabeblack@google.com    value_changed_event() const
32412841Sgabeblack@google.com    {
32513071Sgabeblack@google.com        return (*this)->value_changed_event();
32612841Sgabeblack@google.com    }
32713071Sgabeblack@google.com    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
32813071Sgabeblack@google.com    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
32913071Sgabeblack@google.com    bool event() const { return (*this)->event(); }
33013071Sgabeblack@google.com    bool posedge() const { return (*this)->posedge(); }
33113071Sgabeblack@google.com    bool negedge() const { return (*this)->negedge(); }
33212841Sgabeblack@google.com
33313071Sgabeblack@google.com    sc_event_finder &value_changed() const { return _valueChangedFinder; }
33413071Sgabeblack@google.com    sc_event_finder &pos() const { return _posFinder; }
33513071Sgabeblack@google.com    sc_event_finder &neg() const { return _negFinder; }
33612841Sgabeblack@google.com
33712841Sgabeblack@google.com    virtual const char *kind() const { return "sc_inout"; }
33812841Sgabeblack@google.com
33913245Sgabeblack@google.com    void
34013245Sgabeblack@google.com    add_trace(sc_trace_file *tf, const std::string &name) const
34113245Sgabeblack@google.com    {
34213245Sgabeblack@google.com        traceParamsVec.push_back(new sc_trace_params(tf, name));
34313245Sgabeblack@google.com    }
34413245Sgabeblack@google.com
34512841Sgabeblack@google.com  private:
34613071Sgabeblack@google.com    bool *initValue;
34713071Sgabeblack@google.com    mutable sc_event_finder_t<sc_signal_inout_if<bool> > _valueChangedFinder;
34813071Sgabeblack@google.com    mutable sc_event_finder_t<sc_signal_inout_if<bool> > _posFinder;
34913071Sgabeblack@google.com    mutable sc_event_finder_t<sc_signal_inout_if<bool> > _negFinder;
35013071Sgabeblack@google.com
35113245Sgabeblack@google.com    mutable sc_trace_params_vec traceParamsVec;
35213245Sgabeblack@google.com
35312841Sgabeblack@google.com    // Disabled
35413071Sgabeblack@google.com    sc_inout(const sc_inout<bool> &);
35512841Sgabeblack@google.com};
35612841Sgabeblack@google.com
35712841Sgabeblack@google.comtemplate <>
35812841Sgabeblack@google.cominline void sc_trace<bool>(
35913245Sgabeblack@google.com        sc_trace_file *tf, const sc_inout<bool> &i, const std::string &name)
36012841Sgabeblack@google.com{
36113269Sgabeblack@google.com    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
36213269Sgabeblack@google.com        i.add_trace(tf, name);
36313269Sgabeblack@google.com    else
36413245Sgabeblack@google.com        sc_trace(tf, i->read(), name);
36512841Sgabeblack@google.com}
36612841Sgabeblack@google.com
36712841Sgabeblack@google.comtemplate <>
36812841Sgabeblack@google.comclass sc_inout<sc_dt::sc_logic> :
36912841Sgabeblack@google.com        public sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>
37012841Sgabeblack@google.com{
37112841Sgabeblack@google.com  public:
37213071Sgabeblack@google.com    sc_inout() : sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(),
37313071Sgabeblack@google.com        initValue(nullptr),
37413071Sgabeblack@google.com        _valueChangedFinder(*this,
37513071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
37613071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
37713071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
37813071Sgabeblack@google.com    {}
37912841Sgabeblack@google.com    explicit sc_inout(const char *name) :
38013071Sgabeblack@google.com            sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name),
38113071Sgabeblack@google.com        initValue(nullptr),
38213071Sgabeblack@google.com        _valueChangedFinder(*this,
38313071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
38413071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
38513071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
38612841Sgabeblack@google.com    {}
38713071Sgabeblack@google.com    virtual ~sc_inout() { delete initValue; }
38812841Sgabeblack@google.com
38912868Sgabeblack@google.com    // Deprecated binding constructors.
39012868Sgabeblack@google.com    explicit sc_inout(const sc_signal_inout_if<sc_dt::sc_logic> &interface) :
39113071Sgabeblack@google.com        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(interface),
39213071Sgabeblack@google.com        initValue(nullptr),
39313071Sgabeblack@google.com        _valueChangedFinder(*this,
39413071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
39513071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
39613071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
39712868Sgabeblack@google.com    {}
39812868Sgabeblack@google.com    sc_inout(const char *name,
39912868Sgabeblack@google.com            const sc_signal_inout_if<sc_dt::sc_logic> &interface) :
40013071Sgabeblack@google.com        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, interface),
40113071Sgabeblack@google.com        initValue(nullptr),
40213071Sgabeblack@google.com        _valueChangedFinder(*this,
40313071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
40413071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
40513071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
40612868Sgabeblack@google.com    {}
40712868Sgabeblack@google.com    explicit sc_inout(
40812868Sgabeblack@google.com            sc_port_b<sc_signal_inout_if<sc_dt::sc_logic> > &parent) :
40913071Sgabeblack@google.com        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(parent),
41013071Sgabeblack@google.com        initValue(nullptr),
41113071Sgabeblack@google.com        _valueChangedFinder(*this,
41213071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
41313071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
41413071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
41512868Sgabeblack@google.com    {}
41612868Sgabeblack@google.com    sc_inout(const char *name,
41712868Sgabeblack@google.com            sc_port_b<sc_signal_inout_if<sc_dt::sc_logic> > &parent) :
41813071Sgabeblack@google.com        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, parent),
41913071Sgabeblack@google.com        initValue(nullptr),
42013071Sgabeblack@google.com        _valueChangedFinder(*this,
42113071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
42213071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
42313071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
42412868Sgabeblack@google.com    {}
42512868Sgabeblack@google.com    explicit sc_inout(
42612868Sgabeblack@google.com            sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &parent) :
42713071Sgabeblack@google.com        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(parent),
42813071Sgabeblack@google.com        initValue(nullptr),
42913071Sgabeblack@google.com        _valueChangedFinder(*this,
43013071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
43113071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
43213071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
43312868Sgabeblack@google.com    {}
43412868Sgabeblack@google.com    sc_inout(const char *name,
43512868Sgabeblack@google.com            sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &parent) :
43613071Sgabeblack@google.com        sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, parent),
43713071Sgabeblack@google.com        initValue(nullptr),
43813071Sgabeblack@google.com        _valueChangedFinder(*this,
43913071Sgabeblack@google.com                &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
44013071Sgabeblack@google.com        _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
44113071Sgabeblack@google.com        _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
44212868Sgabeblack@google.com    {}
44312868Sgabeblack@google.com
44412841Sgabeblack@google.com    void
44513071Sgabeblack@google.com    initialize(const sc_dt::sc_logic &l)
44612841Sgabeblack@google.com    {
44713071Sgabeblack@google.com        if (this->size()) {
44813071Sgabeblack@google.com            (*this)->write(l);
44913071Sgabeblack@google.com        } else {
45013071Sgabeblack@google.com            if (!initValue)
45113071Sgabeblack@google.com                initValue = new sc_dt::sc_logic;
45213071Sgabeblack@google.com            *initValue = l;
45313071Sgabeblack@google.com        }
45412841Sgabeblack@google.com    }
45512841Sgabeblack@google.com    void
45613071Sgabeblack@google.com    initialize(const sc_signal_in_if<sc_dt::sc_logic> &i)
45712841Sgabeblack@google.com    {
45813071Sgabeblack@google.com        initialize(i.read());
45912841Sgabeblack@google.com    }
46012841Sgabeblack@google.com
46113071Sgabeblack@google.com    virtual void
46213071Sgabeblack@google.com    end_of_elaboration()
46312841Sgabeblack@google.com    {
46413071Sgabeblack@google.com        if (initValue) {
46513071Sgabeblack@google.com            write(*initValue);
46613071Sgabeblack@google.com            delete initValue;
46713071Sgabeblack@google.com            initValue = nullptr;
46813071Sgabeblack@google.com        }
46913245Sgabeblack@google.com
47013245Sgabeblack@google.com        for (auto params: traceParamsVec)
47113245Sgabeblack@google.com            sc_trace(params->tf, (*this)->read(), params->name);
47213245Sgabeblack@google.com
47313245Sgabeblack@google.com        traceParamsVec.clear();
47412841Sgabeblack@google.com    }
47512841Sgabeblack@google.com
47613071Sgabeblack@google.com    const sc_dt::sc_logic &read() const { return (*this)->read(); }
47713071Sgabeblack@google.com    operator const sc_dt::sc_logic& () const { return (*this)->read(); }
47813071Sgabeblack@google.com
47913071Sgabeblack@google.com    void write(const sc_dt::sc_logic &l) { (*this)->write(l); }
48013071Sgabeblack@google.com    sc_inout<sc_dt::sc_logic> &
48113071Sgabeblack@google.com    operator = (const sc_dt::sc_logic &l)
48212841Sgabeblack@google.com    {
48313071Sgabeblack@google.com        (*this)->write(l);
48413071Sgabeblack@google.com        return *this;
48512841Sgabeblack@google.com    }
48612841Sgabeblack@google.com    sc_inout<sc_dt::sc_logic> &
48713071Sgabeblack@google.com    operator = (const sc_signal_in_if<sc_dt::sc_logic> &i)
48812841Sgabeblack@google.com    {
48913071Sgabeblack@google.com        (*this)->write(i.read());
49013071Sgabeblack@google.com        return *this;
49112841Sgabeblack@google.com    }
49212841Sgabeblack@google.com    sc_inout<sc_dt::sc_logic> &
49313071Sgabeblack@google.com    operator = (const sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &p)
49412841Sgabeblack@google.com    {
49513071Sgabeblack@google.com        (*this)->write(p->read());
49613071Sgabeblack@google.com        return *this;
49712841Sgabeblack@google.com    }
49812841Sgabeblack@google.com    sc_inout<sc_dt::sc_logic> &
49913071Sgabeblack@google.com    operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
50012841Sgabeblack@google.com    {
50113071Sgabeblack@google.com        (*this)->write(p->read());
50213071Sgabeblack@google.com        return *this;
50312841Sgabeblack@google.com    }
50412841Sgabeblack@google.com    sc_inout<sc_dt::sc_logic> &
50513071Sgabeblack@google.com    operator = (const sc_inout<sc_dt::sc_logic> &p)
50612841Sgabeblack@google.com    {
50713071Sgabeblack@google.com        (*this)->write(p->read());
50813071Sgabeblack@google.com        return *this;
50912841Sgabeblack@google.com    }
51012841Sgabeblack@google.com
51113071Sgabeblack@google.com    const sc_event &default_event() const { return (*this)->default_event(); }
51212841Sgabeblack@google.com    const sc_event &
51312841Sgabeblack@google.com    value_changed_event() const
51412841Sgabeblack@google.com    {
51513071Sgabeblack@google.com        return (*this)->value_changed_event();
51612841Sgabeblack@google.com    }
51713071Sgabeblack@google.com    const sc_event &posedge_event() const { return (*this)->posedge_event(); }
51813071Sgabeblack@google.com    const sc_event &negedge_event() const { return (*this)->negedge_event(); }
51913071Sgabeblack@google.com    bool event() const { return (*this)->event(); }
52013071Sgabeblack@google.com    bool posedge() const { return (*this)->posedge(); }
52113071Sgabeblack@google.com    bool negedge() const { return (*this)->negedge(); }
52212841Sgabeblack@google.com
52313071Sgabeblack@google.com    sc_event_finder &value_changed() const { return _valueChangedFinder; }
52413071Sgabeblack@google.com    sc_event_finder &pos() const { return _posFinder; }
52513071Sgabeblack@google.com    sc_event_finder &neg() const { return _negFinder; }
52612841Sgabeblack@google.com
52712841Sgabeblack@google.com    virtual const char *kind() const { return "sc_inout"; }
52812841Sgabeblack@google.com
52913245Sgabeblack@google.com    void
53013245Sgabeblack@google.com    add_trace(sc_trace_file *tf, const std::string &name) const
53113245Sgabeblack@google.com    {
53213245Sgabeblack@google.com        traceParamsVec.push_back(new sc_trace_params(tf, name));
53313245Sgabeblack@google.com    }
53413245Sgabeblack@google.com
53512841Sgabeblack@google.com  private:
53613071Sgabeblack@google.com    sc_dt::sc_logic *initValue;
53713071Sgabeblack@google.com    mutable sc_event_finder_t<
53813071Sgabeblack@google.com        sc_signal_inout_if<sc_dt::sc_logic> > _valueChangedFinder;
53913071Sgabeblack@google.com    mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _posFinder;
54013071Sgabeblack@google.com    mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _negFinder;
54113071Sgabeblack@google.com
54213245Sgabeblack@google.com    mutable sc_trace_params_vec traceParamsVec;
54313245Sgabeblack@google.com
54412841Sgabeblack@google.com    // Disabled
54513071Sgabeblack@google.com    sc_inout(const sc_inout<sc_dt::sc_logic> &);
54612841Sgabeblack@google.com};
54712841Sgabeblack@google.com
54812841Sgabeblack@google.comtemplate <>
54912841Sgabeblack@google.cominline void
55013245Sgabeblack@google.comsc_trace<sc_dt::sc_logic>(sc_trace_file *tf,
55113245Sgabeblack@google.com        const sc_inout<sc_dt::sc_logic> &i, const std::string &name)
55212841Sgabeblack@google.com{
55313269Sgabeblack@google.com    if (::sc_core::sc_get_status() < ::sc_core::SC_START_OF_SIMULATION)
55413269Sgabeblack@google.com        i.add_trace(tf, name);
55513269Sgabeblack@google.com    else
55613245Sgabeblack@google.com        sc_trace(tf, i->read(), name);
55712841Sgabeblack@google.com}
55812841Sgabeblack@google.com
55912841Sgabeblack@google.com} // namespace sc_core
56012841Sgabeblack@google.com
56112841Sgabeblack@google.com#endif  //__SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
562