34d33
< #include <sstream>
49,51c48,50
< template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER>
< class sc_signal : public sc_signal_inout_if<T>,
< public sc_prim_channel
---
> } // namespace sc_core
>
> namespace sc_gem5
52a52,56
>
> class Process;
>
> class ScSignalBase : public sc_core::sc_prim_channel
> {
54,57c58,160
< sc_signal() : sc_signal_inout_if<T>(),
< sc_prim_channel(sc_gen_unique_name("signal")),
< m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL),
< _gem5Writer(NULL)
---
> 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;
>
> sc_core::sc_event _valueChangedEvent;
> uint64_t _changeStamp;
> sc_core::sc_port_base *_gem5WriterPort;
> };
>
> class ScSignalBaseBinary : public ScSignalBase
> {
> protected:
> ScSignalBaseBinary(const char *_name);
>
> const sc_core::sc_event &posedgeEvent() const;
> const sc_core::sc_event &negedgeEvent() const;
>
> bool posedge() const;
> bool negedge() const;
>
> sc_core::sc_event _posedgeEvent;
> sc_core::sc_event _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)
59,62c162,164
< explicit sc_signal(const char *name) :
< sc_signal_inout_if<T>(), sc_prim_channel(name),
< m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL),
< _gem5Writer(NULL)
---
> ScSignalBaseT(const char *_name, const T &initial_value) :
> ScSignalBasePicker<T>(_name), m_cur_val(initial_value),
> m_new_val(initial_value), _checker(this)
64,69c166
< explicit sc_signal(const char *name, const T &initial_value) :
< sc_signal_inout_if<T>(), sc_prim_channel(name),
< m_cur_val(initial_value), m_new_val(initial_value),
< _changeStamp(~0ULL), _gem5Writer(NULL)
< {}
< virtual ~sc_signal() {}
---
> virtual ~ScSignalBaseT() {}
72c169
< register_port(sc_port_base &port, const char *iface_type_name)
---
> register_port(sc_core::sc_port_base &port, const char *iface_type_name)
74,89c171,174
< if (WRITER_POLICY == SC_ONE_WRITER &&
< std::string(iface_type_name) ==
< typeid(sc_signal_inout_if<T>).name()) {
< if (_gem5Writer) {
< std::ostringstream ss;
< ss << "\n signal " << "`" << name() << "' (" <<
< kind() << ")";
< ss << "\n first driver `" << _gem5Writer->name() << "' (" <<
< _gem5Writer->kind() << ")";
< ss << "\n second driver `" << port.name() << "' (" <<
< port.kind() << ")";
< SC_REPORT_ERROR(
< "(E115) sc_signal<T> cannot have more than one driver",
< ss.str().c_str());
< }
< _gem5Writer = &port;
---
> # if !defined(SC_NO_WRITE_CHECK)
> {
> _checker.checkPort(port, iface_type_name,
> typeid(sc_core::sc_signal_inout_if<T>).name());
90a176
> # endif
96,100d181
< virtual sc_writer_policy
< get_writer_policy() const
< {
< return WRITER_POLICY;
< }
103a185,189
> # if !defined(SC_NO_WRITE_CHECK)
> {
> _checker.checkWriter();
> }
> # endif
106d191
< //TODO check whether this write follows the write policy.
108c193
< request_update();
---
> this->request_update();
110,121d194
< sc_signal<T, WRITER_POLICY> &
< operator = (const T &t)
< {
< write(t);
< return *this;
< }
< sc_signal<T, WRITER_POLICY> &
< operator = (const sc_signal<T, WRITER_POLICY> &s)
< {
< write(s.read());
< return *this;
< }
123c196
< virtual const sc_event &
---
> virtual const sc_core::sc_event &
126c199
< return value_changed_event();
---
> return ScSignalBase::defaultEvent();
128c201,202
< virtual const sc_event &
---
>
> virtual const sc_core::sc_event &
131c205
< return _valueChangedEvent;
---
> return ScSignalBase::valueChangedEvent();
133,137d206
< virtual bool
< event() const
< {
< return _changeStamp == ::sc_gem5::getChangeStamp();
< }
143c212
< os << " name = " << name() << ::std::endl;
---
> os << " name = " << this->name() << ::std::endl;
147d215
< virtual const char *kind() const { return "sc_signal"; }
149,154c217
< protected:
< virtual void
< update()
< {
< if (m_new_val == m_cur_val)
< return;
---
> virtual bool event() const { return ScSignalBase::event(); }
156,163c219,220
< m_cur_val = m_new_val;
< _signalChange();
< _changeStamp = ::sc_gem5::getChangeStamp();
< _valueChangedEvent.notify(SC_ZERO_TIME);
< }
<
< void
< _signalChange()
---
> virtual sc_core::sc_writer_policy
> get_writer_policy() const
165,166c222
< _changeStamp = ::sc_gem5::getChangeStamp();
< _valueChangedEvent.notify(SC_ZERO_TIME);
---
> return WRITER_POLICY;
168a225
> protected:
175,178c232,233
< private:
< sc_event _valueChangedEvent;
< uint64_t _changeStamp;
< sc_port_base *_gem5Writer;
---
> WriteChecker<WRITER_POLICY> _checker;
> };
180,182c235,239
< // Disabled
< sc_signal(const sc_signal<T, WRITER_POLICY> &) :
< sc_signal_inout_if<T>(), sc_prim_channel("")
---
> 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)
183a241,257
> 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(); }
185a260,308
> } // 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> &);
> };
>
196c319
< public sc_signal_inout_if<bool>, public sc_prim_channel
---
> public sc_gem5::ScSignalBinary<bool, WRITER_POLICY>
199,203c322,324
< sc_signal() : sc_signal_inout_if<bool>(),
< sc_prim_channel(sc_gen_unique_name("signal")),
< m_cur_val(bool()), m_new_val(bool()),
< _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL),
< _gem5Writer(NULL)
---
> sc_signal() :
> sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(
> sc_gen_unique_name("signal"))
206,209c327
< sc_signal_inout_if<bool>(), sc_prim_channel(name),
< m_cur_val(bool()), m_new_val(bool()),
< _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL),
< _gem5Writer(NULL)
---
> sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name)
212,215c330
< sc_signal_inout_if<bool>(), sc_prim_channel(name),
< m_cur_val(initial_value), m_new_val(initial_value),
< _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL),
< _gem5Writer(NULL)
---
> sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name, initial_value)
219,257d333
< virtual void
< register_port(sc_port_base &port, const char *iface_type_name)
< {
< if (WRITER_POLICY == SC_ONE_WRITER &&
< std::string(iface_type_name) ==
< typeid(sc_signal_inout_if<bool>).name()) {
< if (_gem5Writer) {
< std::ostringstream ss;
< ss << "\n signal " << "`" << name() << "' (" <<
< kind() << ")";
< ss << "\n first driver `" << _gem5Writer->name() << "' (" <<
< _gem5Writer->kind() << ")";
< ss << "\n second driver `" << port.name() << "' (" <<
< port.kind() << ")";
< SC_REPORT_ERROR(
< "(E115) sc_signal<T> cannot have more than one driver",
< ss.str().c_str());
< }
< _gem5Writer = &port;
< }
< }
<
< virtual const bool &read() const { return m_cur_val; }
< operator const bool &() const { return read(); }
<
< virtual sc_writer_policy
< get_writer_policy() const
< {
< return WRITER_POLICY;
< }
< virtual void
< write(const bool &b)
< {
< m_new_val = b;
< bool changed = !(m_cur_val == m_new_val);
< //TODO check whether this write follows the write policy.
< if (changed)
< request_update();
< }
261c337
< write(b);
---
> this->write(b);
267c343
< write(s.read());
---
> this->write(s.read());
271,318d346
< virtual const sc_event &
< default_event() const
< {
< return value_changed_event();
< }
<
< virtual const sc_event &
< value_changed_event() const
< {
< return _valueChangedEvent;
< }
< virtual const sc_event &
< posedge_event() const
< {
< return _posedgeEvent;
< }
< virtual const sc_event &
< negedge_event() const
< {
< return _negedgeEvent;
< }
<
< virtual bool
< event() const
< {
< return _changeStamp == ::sc_gem5::getChangeStamp();
< }
< virtual bool
< posedge() const
< {
< return _posStamp == ::sc_gem5::getChangeStamp();
< }
< virtual bool
< negedge() const
< {
< return _negStamp == ::sc_gem5::getChangeStamp();
< }
<
< virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; }
< virtual void
< dump(std::ostream &os=std::cout) const
< {
< os << " name = " << name() << ::std::endl;
< os << " value = " << m_cur_val << ::std::endl;
< os << "new value = " << m_new_val << ::std::endl;
< }
< virtual const char *kind() const { return "sc_signal"; }
<
323c351
< if (m_new_val == m_cur_val)
---
> if (this->m_new_val == this->m_cur_val)
326,330c354,358
< m_cur_val = m_new_val;
< _signalChange();
< if (m_cur_val) {
< _posStamp = ::sc_gem5::getChangeStamp();
< _posedgeEvent.notify(SC_ZERO_TIME);
---
> this->m_cur_val = this->m_new_val;
> this->_signalChange();
> if (this->m_cur_val) {
> this->_posStamp = ::sc_gem5::getChangeStamp();
> this->_posedgeEvent.notify(SC_ZERO_TIME);
332,333c360,361
< _negStamp = ::sc_gem5::getChangeStamp();
< _negedgeEvent.notify(SC_ZERO_TIME);
---
> this->_negStamp = ::sc_gem5::getChangeStamp();
> this->_negedgeEvent.notify(SC_ZERO_TIME);
337,346d364
< void
< _signalChange()
< {
< _changeStamp = ::sc_gem5::getChangeStamp();
< _valueChangedEvent.notify(SC_ZERO_TIME);
< }
<
< bool m_cur_val;
< bool m_new_val;
<
348,357d365
< sc_event _valueChangedEvent;
< sc_event _posedgeEvent;
< sc_event _negedgeEvent;
<
< uint64_t _changeStamp;
< uint64_t _posStamp;
< uint64_t _negStamp;
<
< sc_port_base *_gem5Writer;
<
359,361c367
< sc_signal(const sc_signal<bool, WRITER_POLICY> &) :
< sc_signal_inout_if<bool>(), sc_prim_channel("")
< {}
---
> sc_signal(const sc_signal<bool, WRITER_POLICY> &);
366c372
< public sc_signal_inout_if<sc_dt::sc_logic>, public sc_prim_channel
---
> public sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>
369,373c375,377
< sc_signal() : sc_signal_inout_if<sc_dt::sc_logic>(),
< sc_prim_channel(sc_gen_unique_name("signal")),
< m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()),
< _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL),
< _gem5Writer(NULL)
---
> sc_signal() :
> sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(
> sc_gen_unique_name("signal"))
376,379c380
< sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name),
< m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()),
< _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL),
< _gem5Writer(NULL)
---
> sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(name)
383,386c384,385
< sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name),
< m_cur_val(initial_value), m_new_val(initial_value),
< _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL),
< _gem5Writer(NULL)
---
> sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(
> name, initial_value)
390,428d388
< virtual void
< register_port(sc_port_base &port, const char *iface_type_name)
< {
< if (WRITER_POLICY == SC_ONE_WRITER &&
< std::string(iface_type_name) ==
< typeid(sc_signal_inout_if<sc_dt::sc_logic>).name()) {
< if (_gem5Writer) {
< std::ostringstream ss;
< ss << "\n signal " << "`" << name() << "' (" <<
< kind() << ")";
< ss << "\n first driver `" << _gem5Writer->name() << "' (" <<
< _gem5Writer->kind() << ")";
< ss << "\n second driver `" << port.name() << "' (" <<
< port.kind() << ")";
< SC_REPORT_ERROR(
< "(E115) sc_signal<T> cannot have more than one driver",
< ss.str().c_str());
< }
< _gem5Writer = &port;
< }
< }
<
< virtual const sc_dt::sc_logic &read() const { return m_cur_val; }
< operator const sc_dt::sc_logic &() const { return read(); }
<
< virtual sc_writer_policy
< get_writer_policy() const
< {
< return WRITER_POLICY;
< }
< virtual void
< write(const sc_dt::sc_logic &l)
< {
< m_new_val = l;
< bool changed = !(m_cur_val == m_new_val);
< //TODO check whether this write follows the write policy.
< if (changed)
< request_update();
< }
432c392
< write(l);
---
> this->write(l);
438c398
< write(s.read());
---
> this->write(s.read());
442,489d401
< virtual const sc_event &
< default_event() const
< {
< return value_changed_event();
< }
<
< virtual const sc_event &
< value_changed_event() const
< {
< return _valueChangedEvent;
< }
< virtual const sc_event &
< posedge_event() const
< {
< return _posedgeEvent;
< }
< virtual const sc_event &
< negedge_event() const
< {
< return _negedgeEvent;
< }
<
< virtual bool
< event() const
< {
< return _changeStamp == ::sc_gem5::getChangeStamp();
< }
< virtual bool
< posedge() const
< {
< return _posStamp == ::sc_gem5::getChangeStamp();
< }
< virtual bool
< negedge() const
< {
< return _negStamp == ::sc_gem5::getChangeStamp();
< }
<
< virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; }
< virtual void
< dump(std::ostream &os=std::cout) const
< {
< os << " name = " << name() << ::std::endl;
< os << " value = " << m_cur_val << ::std::endl;
< os << "new value = " << m_new_val << ::std::endl;
< }
< virtual const char *kind() const { return "sc_signal"; }
<
494c406
< if (m_new_val == m_cur_val)
---
> if (this->m_new_val == this->m_cur_val)
497,504c409,416
< m_cur_val = m_new_val;
< _signalChange();
< if (m_cur_val == sc_dt::SC_LOGIC_1) {
< _posStamp = ::sc_gem5::getChangeStamp();
< _posedgeEvent.notify(SC_ZERO_TIME);
< } else if (m_cur_val == sc_dt::SC_LOGIC_0) {
< _negStamp = ::sc_gem5::getChangeStamp();
< _negedgeEvent.notify(SC_ZERO_TIME);
---
> 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);
508,517d419
< void
< _signalChange()
< {
< _changeStamp = ::sc_gem5::getChangeStamp();
< _valueChangedEvent.notify(SC_ZERO_TIME);
< }
<
< sc_dt::sc_logic m_cur_val;
< sc_dt::sc_logic m_new_val;
<
519,528d420
< sc_event _valueChangedEvent;
< sc_event _posedgeEvent;
< sc_event _negedgeEvent;
<
< uint64_t _changeStamp;
< uint64_t _posStamp;
< uint64_t _negStamp;
<
< sc_port_base *_gem5Writer;
<
530,532c422
< sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &) :
< sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel("")
< {}
---
> sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &);