/*
 * Copyright 2018 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__
#define __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__

#include <iostream>
#include <string>
#include <vector>

#include "../core/sc_event.hh"
#include "../core/sc_module.hh" // for sc_gen_unique_name
#include "../core/sc_prim.hh"
#include "../dt/bit/sc_logic.hh"
#include "sc_signal_inout_if.hh"

namespace sc_core
{

class sc_port_base;

} // namespace sc_core

namespace sc_gem5
{

class Process;
class Reset;

class ScSignalBase : public sc_core::sc_prim_channel
{
  public:
    virtual const char *kind() const { return "sc_signal"; }

  protected:
    ScSignalBase(const char *_name);
    virtual ~ScSignalBase();

    const sc_core::sc_event &defaultEvent() const;
    const sc_core::sc_event &valueChangedEvent() const;

    bool event() const;

    void _signalChange();

    virtual sc_core::sc_writer_policy get_writer_policy() const = 0;

    InternalScEvent _valueChangedEvent;
    uint64_t _changeStamp;
    sc_core::sc_port_base *_gem5WriterPort;
};

class ScSignalBaseBinary : public ScSignalBase
{
  protected:
    ScSignalBaseBinary(const char *_name);

    mutable std::vector<sc_gem5::Reset *> _resets;
    void _signalReset(sc_gem5::Reset *reset);
    void _signalReset();

    const sc_core::sc_event &posedgeEvent() const;
    const sc_core::sc_event &negedgeEvent() const;

    bool posedge() const;
    bool negedge() const;

    InternalScEvent _posedgeEvent;
    InternalScEvent _negedgeEvent;

    uint64_t _posStamp;
    uint64_t _negStamp;
};

template <class T>
class ScSignalBasePicker : public ScSignalBase
{
  protected:
    ScSignalBasePicker(const char *_name) : ScSignalBase(_name) {}
};

template <>
class ScSignalBasePicker<bool> : public ScSignalBaseBinary
{
  protected:
    ScSignalBasePicker(const char *_name) : ScSignalBaseBinary(_name) {}
};

template <>
class ScSignalBasePicker<sc_dt::sc_logic> : public ScSignalBaseBinary
{
  protected:
    ScSignalBasePicker(const char *_name) : ScSignalBaseBinary(_name) {}
};

template <sc_core::sc_writer_policy WRITER_POLICY>
class WriteChecker;

template <>
class WriteChecker<sc_core::SC_ONE_WRITER>
{
  public:
    WriteChecker(ScSignalBase *_sig);

    void checkPort(sc_core::sc_port_base &port,
            std::string iface_type_name, std::string out_name);
    void checkWriter();

  private:
    ScSignalBase *sig;
    sc_core::sc_port_base *firstPort;
    Process *proc;
    uint64_t writeStamp;
};

template <>
class WriteChecker<sc_core::SC_MANY_WRITERS>
{
  public:
    WriteChecker(ScSignalBase *_sig);

    void checkPort(sc_core::sc_port_base &port,
            std::string iface_type_name, std::string out_name);
    void checkWriter();

  private:
    ScSignalBase *sig;
    Process *proc;
    uint64_t writeStamp;
};

template <class T, sc_core::sc_writer_policy WRITER_POLICY>
class ScSignalBaseT :
    public ScSignalBasePicker<T>, public sc_core::sc_signal_inout_if<T>
{
  public:
    ScSignalBaseT(const char *_name) :
        ScSignalBasePicker<T>(_name), m_cur_val(T()), m_new_val(T()),
        _checker(this)
    {}
    ScSignalBaseT(const char *_name, const T &initial_value) :
        ScSignalBasePicker<T>(_name), m_cur_val(initial_value),
        m_new_val(initial_value), _checker(this)
    {}
    virtual ~ScSignalBaseT() {}

    virtual void
    register_port(sc_core::sc_port_base &port, const char *iface_type_name)
    {
#       if !defined(SC_NO_WRITE_CHECK)
        {
            _checker.checkPort(port, iface_type_name,
                typeid(sc_core::sc_signal_inout_if<T>).name());
        }
#       endif
    }

    virtual const T &read() const { return m_cur_val; }
    operator const T&() const { return read(); }

    virtual void
    write(const T &t)
    {
#       if !defined(SC_NO_WRITE_CHECK)
        {
            _checker.checkWriter();
        }
#       endif
        m_new_val = t;
        bool changed = !(m_cur_val == m_new_val);
        if (changed)
            this->request_update();
    }

    virtual const sc_core::sc_event &
    default_event() const
    {
        return ScSignalBase::defaultEvent();
    }

    virtual const sc_core::sc_event &
    value_changed_event() const
    {
        return ScSignalBase::valueChangedEvent();
    }

    virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; }
    virtual void
    dump(std::ostream &os=std::cout) const
    {
        os << "     name = " << this->name() << ::std::endl;
        os << "    value = " << m_cur_val << ::std::endl;
        os << "new value = " << m_new_val << ::std::endl;
    }

    virtual bool event() const { return ScSignalBase::event(); }

    virtual sc_core::sc_writer_policy
    get_writer_policy() const
    {
        return WRITER_POLICY;
    }

  protected:
    // These members which store the current and future value of the signal
    // are not specified in the standard but are referred to directly by one
    // of the tests.
    T m_cur_val;
    T m_new_val;

    WriteChecker<WRITER_POLICY> _checker;
};

template <typename T, sc_core::sc_writer_policy WRITER_POLICY>
class ScSignalBinary : public ScSignalBaseT<T, WRITER_POLICY>
{
  public:
    ScSignalBinary(const char *_name) : ScSignalBaseT<T, WRITER_POLICY>(_name)
    {}
    ScSignalBinary(const char *_name, const T& initial_value) :
        ScSignalBaseT<T, WRITER_POLICY>(_name, initial_value)
    {}

    const sc_core::sc_event &
    posedge_event() const
    {
        return ScSignalBaseBinary::posedgeEvent();
    }
    const sc_core::sc_event &
    negedge_event() const
    {
        return ScSignalBaseBinary::negedgeEvent();
    }

    bool posedge() const { return ScSignalBaseBinary::posedge(); }
    bool negedge() const { return ScSignalBaseBinary::negedge(); }
};

} // namespace sc_gem5

namespace sc_core
{

template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER>
class sc_signal : public sc_gem5::ScSignalBaseT<T, WRITER_POLICY>
{
  public:
    sc_signal() : sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(
            sc_gen_unique_name("signal"))
    {}
    explicit sc_signal(const char *name) :
        sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(name)
    {}
    explicit sc_signal(const char *name, const T &initial_value) :
        sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(name, initial_value)
    {}
    virtual ~sc_signal() {}

    sc_signal<T, WRITER_POLICY> &
    operator = (const T &t)
    {
        this->write(t);
        return *this;
    }
    sc_signal<T, WRITER_POLICY> &
    operator = (const sc_signal<T, WRITER_POLICY> &s)
    {
        this->write(s.read());
        return *this;
    }

  protected:
    virtual void
    update()
    {
        if (this->m_new_val == this->m_cur_val)
            return;

        this->m_cur_val = this->m_new_val;
        this->_signalChange();
    }

  private:
    // Disabled
    sc_signal(const sc_signal<T, WRITER_POLICY> &);
};

template <class T, sc_writer_policy WRITER_POLICY>
inline std::ostream &
operator << (std::ostream &os, const sc_signal<T, WRITER_POLICY> &s)
{
    os << s.read();
    return os;
}

template <sc_writer_policy WRITER_POLICY>
class sc_signal<bool, WRITER_POLICY> :
    public sc_gem5::ScSignalBinary<bool, WRITER_POLICY>
{
  public:
    sc_signal() :
        sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(
                sc_gen_unique_name("signal"))
    {}
    explicit sc_signal(const char *name) :
        sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name)
    {}
    explicit sc_signal(const char *name, const bool &initial_value) :
        sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name, initial_value)
    {}
    virtual ~sc_signal() {}

    sc_signal<bool, WRITER_POLICY> &
    operator = (const bool &b)
    {
        this->write(b);
        return *this;
    }
    sc_signal<bool, WRITER_POLICY> &
    operator = (const sc_signal<bool, WRITER_POLICY> &s)
    {
        this->write(s.read());
        return *this;
    }

  protected:
    virtual void
    update()
    {
        if (this->m_new_val == this->m_cur_val)
            return;

        this->m_cur_val = this->m_new_val;
        this->_signalReset();
        this->_signalChange();
        if (this->m_cur_val) {
            this->_posStamp = ::sc_gem5::getChangeStamp();
            this->_posedgeEvent.notify(SC_ZERO_TIME);
        } else {
            this->_negStamp = ::sc_gem5::getChangeStamp();
            this->_negedgeEvent.notify(SC_ZERO_TIME);
        }
    }

  private:
    bool
    _addReset(sc_gem5::Reset *reset) const
    {
        this->_resets.push_back(reset);
        return true;
    }

    // Disabled
    sc_signal(const sc_signal<bool, WRITER_POLICY> &);
};

template <sc_writer_policy WRITER_POLICY>
class sc_signal<sc_dt::sc_logic, WRITER_POLICY> :
    public sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>
{
  public:
    sc_signal() :
        sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(
                sc_gen_unique_name("signal"))
    {}
    explicit sc_signal(const char *name) :
        sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(name)
    {}
    explicit sc_signal(const char *name,
            const sc_dt::sc_logic &initial_value) :
        sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(
                name, initial_value)
    {}
    virtual ~sc_signal() {}

    sc_signal<sc_dt::sc_logic, WRITER_POLICY> &
    operator = (const sc_dt::sc_logic &l)
    {
        this->write(l);
        return *this;
    }
    sc_signal<sc_dt::sc_logic, WRITER_POLICY> &
    operator = (const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &s)
    {
        this->write(s.read());
        return *this;
    }

  protected:
    virtual void
    update()
    {
        if (this->m_new_val == this->m_cur_val)
            return;

        this->m_cur_val = this->m_new_val;
        this->_signalChange();
        if (this->m_cur_val == sc_dt::SC_LOGIC_1) {
            this->_posStamp = ::sc_gem5::getChangeStamp();
            this->_posedgeEvent.notify(SC_ZERO_TIME);
        } else if (this->m_cur_val == sc_dt::SC_LOGIC_0) {
            this->_negStamp = ::sc_gem5::getChangeStamp();
            this->_negedgeEvent.notify(SC_ZERO_TIME);
        }
    }

  private:
    // Disabled
    sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &);
};

} // namespace sc_core

#endif  //__SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__
