sc_signal.hh (13274:79ce1482d383) | sc_signal.hh (13277:b479038de4d9) |
---|---|
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 --- 17 unchanged lines hidden (view full) --- 26 * 27 * Authors: Gabe Black 28 */ 29 30#ifndef __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ 31#define __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ 32 33#include <iostream> | 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 --- 17 unchanged lines hidden (view full) --- 26 * 27 * Authors: Gabe Black 28 */ 29 30#ifndef __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ 31#define __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ 32 33#include <iostream> |
34#include <sstream> | |
35#include <string> 36#include <vector> 37 38#include "../core/sc_event.hh" 39#include "../core/sc_module.hh" // for sc_gen_unique_name 40#include "../core/sc_prim.hh" 41#include "../dt/bit/sc_logic.hh" 42#include "sc_signal_inout_if.hh" 43 44namespace sc_core 45{ 46 47class sc_port_base; 48 | 34#include <string> 35#include <vector> 36 37#include "../core/sc_event.hh" 38#include "../core/sc_module.hh" // for sc_gen_unique_name 39#include "../core/sc_prim.hh" 40#include "../dt/bit/sc_logic.hh" 41#include "sc_signal_inout_if.hh" 42 43namespace sc_core 44{ 45 46class sc_port_base; 47 |
49template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER> 50class sc_signal : public sc_signal_inout_if<T>, 51 public sc_prim_channel | 48} // namespace sc_core 49 50namespace sc_gem5 |
52{ | 51{ |
52 53class Process; 54 55class ScSignalBase : public sc_core::sc_prim_channel 56{ |
|
53 public: | 57 public: |
54 sc_signal() : sc_signal_inout_if<T>(), 55 sc_prim_channel(sc_gen_unique_name("signal")), 56 m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL), 57 _gem5Writer(NULL) | 58 virtual const char *kind() const { return "sc_signal"; } 59 60 protected: 61 ScSignalBase(const char *_name); 62 virtual ~ScSignalBase(); 63 64 const sc_core::sc_event &defaultEvent() const; 65 const sc_core::sc_event &valueChangedEvent() const; 66 67 bool event() const; 68 69 void _signalChange(); 70 71 virtual sc_core::sc_writer_policy get_writer_policy() const = 0; 72 73 sc_core::sc_event _valueChangedEvent; 74 uint64_t _changeStamp; 75 sc_core::sc_port_base *_gem5WriterPort; 76}; 77 78class ScSignalBaseBinary : public ScSignalBase 79{ 80 protected: 81 ScSignalBaseBinary(const char *_name); 82 83 const sc_core::sc_event &posedgeEvent() const; 84 const sc_core::sc_event &negedgeEvent() const; 85 86 bool posedge() const; 87 bool negedge() const; 88 89 sc_core::sc_event _posedgeEvent; 90 sc_core::sc_event _negedgeEvent; 91 92 uint64_t _posStamp; 93 uint64_t _negStamp; 94}; 95 96template <class T> 97class ScSignalBasePicker : public ScSignalBase 98{ 99 protected: 100 ScSignalBasePicker(const char *_name) : ScSignalBase(_name) {} 101}; 102 103template <> 104class ScSignalBasePicker<bool> : public ScSignalBaseBinary 105{ 106 protected: 107 ScSignalBasePicker(const char *_name) : ScSignalBaseBinary(_name) {} 108}; 109 110template <> 111class ScSignalBasePicker<sc_dt::sc_logic> : public ScSignalBaseBinary 112{ 113 protected: 114 ScSignalBasePicker(const char *_name) : ScSignalBaseBinary(_name) {} 115}; 116 117template <sc_core::sc_writer_policy WRITER_POLICY> 118class WriteChecker; 119 120template <> 121class WriteChecker<sc_core::SC_ONE_WRITER> 122{ 123 public: 124 WriteChecker(ScSignalBase *_sig); 125 126 void checkPort(sc_core::sc_port_base &port, 127 std::string iface_type_name, std::string out_name); 128 void checkWriter(); 129 130 private: 131 ScSignalBase *sig; 132 sc_core::sc_port_base *firstPort; 133 Process *proc; 134 uint64_t writeStamp; 135}; 136 137template <> 138class WriteChecker<sc_core::SC_MANY_WRITERS> 139{ 140 public: 141 WriteChecker(ScSignalBase *_sig); 142 143 void checkPort(sc_core::sc_port_base &port, 144 std::string iface_type_name, std::string out_name); 145 void checkWriter(); 146 147 private: 148 ScSignalBase *sig; 149 Process *proc; 150 uint64_t writeStamp; 151}; 152 153template <class T, sc_core::sc_writer_policy WRITER_POLICY> 154class ScSignalBaseT : 155 public ScSignalBasePicker<T>, public sc_core::sc_signal_inout_if<T> 156{ 157 public: 158 ScSignalBaseT(const char *_name) : 159 ScSignalBasePicker<T>(_name), m_cur_val(T()), m_new_val(T()), 160 _checker(this) |
58 {} | 161 {} |
59 explicit sc_signal(const char *name) : 60 sc_signal_inout_if<T>(), sc_prim_channel(name), 61 m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL), 62 _gem5Writer(NULL) | 162 ScSignalBaseT(const char *_name, const T &initial_value) : 163 ScSignalBasePicker<T>(_name), m_cur_val(initial_value), 164 m_new_val(initial_value), _checker(this) |
63 {} | 165 {} |
64 explicit sc_signal(const char *name, const T &initial_value) : 65 sc_signal_inout_if<T>(), sc_prim_channel(name), 66 m_cur_val(initial_value), m_new_val(initial_value), 67 _changeStamp(~0ULL), _gem5Writer(NULL) 68 {} 69 virtual ~sc_signal() {} | 166 virtual ~ScSignalBaseT() {} |
70 71 virtual void | 167 168 virtual void |
72 register_port(sc_port_base &port, const char *iface_type_name) | 169 register_port(sc_core::sc_port_base &port, const char *iface_type_name) |
73 { | 170 { |
74 if (WRITER_POLICY == SC_ONE_WRITER && 75 std::string(iface_type_name) == 76 typeid(sc_signal_inout_if<T>).name()) { 77 if (_gem5Writer) { 78 std::ostringstream ss; 79 ss << "\n signal " << "`" << name() << "' (" << 80 kind() << ")"; 81 ss << "\n first driver `" << _gem5Writer->name() << "' (" << 82 _gem5Writer->kind() << ")"; 83 ss << "\n second driver `" << port.name() << "' (" << 84 port.kind() << ")"; 85 SC_REPORT_ERROR( 86 "(E115) sc_signal<T> cannot have more than one driver", 87 ss.str().c_str()); 88 } 89 _gem5Writer = &port; | 171# if !defined(SC_NO_WRITE_CHECK) 172 { 173 _checker.checkPort(port, iface_type_name, 174 typeid(sc_core::sc_signal_inout_if<T>).name()); |
90 } | 175 } |
176# endif |
|
91 } 92 93 virtual const T &read() const { return m_cur_val; } 94 operator const T&() const { return read(); } 95 | 177 } 178 179 virtual const T &read() const { return m_cur_val; } 180 operator const T&() const { return read(); } 181 |
96 virtual sc_writer_policy 97 get_writer_policy() const 98 { 99 return WRITER_POLICY; 100 } | |
101 virtual void 102 write(const T &t) 103 { | 182 virtual void 183 write(const T &t) 184 { |
185# if !defined(SC_NO_WRITE_CHECK) 186 { 187 _checker.checkWriter(); 188 } 189# endif |
|
104 m_new_val = t; 105 bool changed = !(m_cur_val == m_new_val); | 190 m_new_val = t; 191 bool changed = !(m_cur_val == m_new_val); |
106 //TODO check whether this write follows the write policy. | |
107 if (changed) | 192 if (changed) |
108 request_update(); | 193 this->request_update(); |
109 } | 194 } |
110 sc_signal<T, WRITER_POLICY> & 111 operator = (const T &t) 112 { 113 write(t); 114 return *this; 115 } 116 sc_signal<T, WRITER_POLICY> & 117 operator = (const sc_signal<T, WRITER_POLICY> &s) 118 { 119 write(s.read()); 120 return *this; 121 } | |
122 | 195 |
123 virtual const sc_event & | 196 virtual const sc_core::sc_event & |
124 default_event() const 125 { | 197 default_event() const 198 { |
126 return value_changed_event(); | 199 return ScSignalBase::defaultEvent(); |
127 } | 200 } |
128 virtual const sc_event & | 201 202 virtual const sc_core::sc_event & |
129 value_changed_event() const 130 { | 203 value_changed_event() const 204 { |
131 return _valueChangedEvent; | 205 return ScSignalBase::valueChangedEvent(); |
132 } | 206 } |
133 virtual bool 134 event() const 135 { 136 return _changeStamp == ::sc_gem5::getChangeStamp(); 137 } | |
138 139 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } 140 virtual void 141 dump(std::ostream &os=std::cout) const 142 { | 207 208 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } 209 virtual void 210 dump(std::ostream &os=std::cout) const 211 { |
143 os << " name = " << name() << ::std::endl; | 212 os << " name = " << this->name() << ::std::endl; |
144 os << " value = " << m_cur_val << ::std::endl; 145 os << "new value = " << m_new_val << ::std::endl; 146 } | 213 os << " value = " << m_cur_val << ::std::endl; 214 os << "new value = " << m_new_val << ::std::endl; 215 } |
147 virtual const char *kind() const { return "sc_signal"; } | |
148 | 216 |
149 protected: 150 virtual void 151 update() 152 { 153 if (m_new_val == m_cur_val) 154 return; | 217 virtual bool event() const { return ScSignalBase::event(); } |
155 | 218 |
156 m_cur_val = m_new_val; 157 _signalChange(); 158 _changeStamp = ::sc_gem5::getChangeStamp(); 159 _valueChangedEvent.notify(SC_ZERO_TIME); 160 } 161 162 void 163 _signalChange() | 219 virtual sc_core::sc_writer_policy 220 get_writer_policy() const |
164 { | 221 { |
165 _changeStamp = ::sc_gem5::getChangeStamp(); 166 _valueChangedEvent.notify(SC_ZERO_TIME); | 222 return WRITER_POLICY; |
167 } 168 | 223 } 224 |
225 protected: |
|
169 // These members which store the current and future value of the signal 170 // are not specified in the standard but are referred to directly by one 171 // of the tests. 172 T m_cur_val; 173 T m_new_val; 174 | 226 // These members which store the current and future value of the signal 227 // are not specified in the standard but are referred to directly by one 228 // of the tests. 229 T m_cur_val; 230 T m_new_val; 231 |
175 private: 176 sc_event _valueChangedEvent; 177 uint64_t _changeStamp; 178 sc_port_base *_gem5Writer; | 232 WriteChecker<WRITER_POLICY> _checker; 233}; |
179 | 234 |
180 // Disabled 181 sc_signal(const sc_signal<T, WRITER_POLICY> &) : 182 sc_signal_inout_if<T>(), sc_prim_channel("") | 235template <typename T, sc_core::sc_writer_policy WRITER_POLICY> 236class ScSignalBinary : public ScSignalBaseT<T, WRITER_POLICY> 237{ 238 public: 239 ScSignalBinary(const char *_name) : ScSignalBaseT<T, WRITER_POLICY>(_name) |
183 {} | 240 {} |
241 ScSignalBinary(const char *_name, const T& initial_value) : 242 ScSignalBaseT<T, WRITER_POLICY>(_name, initial_value) 243 {} 244 245 const sc_core::sc_event & 246 posedge_event() const 247 { 248 return ScSignalBaseBinary::posedgeEvent(); 249 } 250 const sc_core::sc_event & 251 negedge_event() const 252 { 253 return ScSignalBaseBinary::negedgeEvent(); 254 } 255 256 bool posedge() const { return ScSignalBaseBinary::posedge(); } 257 bool negedge() const { return ScSignalBaseBinary::negedge(); } |
|
184}; 185 | 258}; 259 |
260} // namespace sc_gem5 261 262namespace sc_core 263{ 264 265template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER> 266class sc_signal : public sc_gem5::ScSignalBaseT<T, WRITER_POLICY> 267{ 268 public: 269 sc_signal() : sc_gem5::ScSignalBaseT<T, WRITER_POLICY>( 270 sc_gen_unique_name("signal")) 271 {} 272 explicit sc_signal(const char *name) : 273 sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(name) 274 {} 275 explicit sc_signal(const char *name, const T &initial_value) : 276 sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(name, initial_value) 277 {} 278 virtual ~sc_signal() {} 279 280 sc_signal<T, WRITER_POLICY> & 281 operator = (const T &t) 282 { 283 this->write(t); 284 return *this; 285 } 286 sc_signal<T, WRITER_POLICY> & 287 operator = (const sc_signal<T, WRITER_POLICY> &s) 288 { 289 this->write(s.read()); 290 return *this; 291 } 292 293 protected: 294 virtual void 295 update() 296 { 297 if (this->m_new_val == this->m_cur_val) 298 return; 299 300 this->m_cur_val = this->m_new_val; 301 this->_signalChange(); 302 } 303 304 private: 305 // Disabled 306 sc_signal(const sc_signal<T, WRITER_POLICY> &); 307}; 308 |
|
186template <class T, sc_writer_policy WRITER_POLICY> 187inline std::ostream & 188operator << (std::ostream &os, const sc_signal<T, WRITER_POLICY> &s) 189{ 190 os << s.read(); 191 return os; 192} 193 194template <sc_writer_policy WRITER_POLICY> 195class sc_signal<bool, WRITER_POLICY> : | 309template <class T, sc_writer_policy WRITER_POLICY> 310inline std::ostream & 311operator << (std::ostream &os, const sc_signal<T, WRITER_POLICY> &s) 312{ 313 os << s.read(); 314 return os; 315} 316 317template <sc_writer_policy WRITER_POLICY> 318class sc_signal<bool, WRITER_POLICY> : |
196 public sc_signal_inout_if<bool>, public sc_prim_channel | 319 public sc_gem5::ScSignalBinary<bool, WRITER_POLICY> |
197{ 198 public: | 320{ 321 public: |
199 sc_signal() : sc_signal_inout_if<bool>(), 200 sc_prim_channel(sc_gen_unique_name("signal")), 201 m_cur_val(bool()), m_new_val(bool()), 202 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), 203 _gem5Writer(NULL) | 322 sc_signal() : 323 sc_gem5::ScSignalBinary<bool, WRITER_POLICY>( 324 sc_gen_unique_name("signal")) |
204 {} 205 explicit sc_signal(const char *name) : | 325 {} 326 explicit sc_signal(const char *name) : |
206 sc_signal_inout_if<bool>(), sc_prim_channel(name), 207 m_cur_val(bool()), m_new_val(bool()), 208 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), 209 _gem5Writer(NULL) | 327 sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name) |
210 {} 211 explicit sc_signal(const char *name, const bool &initial_value) : | 328 {} 329 explicit sc_signal(const char *name, const bool &initial_value) : |
212 sc_signal_inout_if<bool>(), sc_prim_channel(name), 213 m_cur_val(initial_value), m_new_val(initial_value), 214 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), 215 _gem5Writer(NULL) | 330 sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name, initial_value) |
216 {} 217 virtual ~sc_signal() {} 218 | 331 {} 332 virtual ~sc_signal() {} 333 |
219 virtual void 220 register_port(sc_port_base &port, const char *iface_type_name) 221 { 222 if (WRITER_POLICY == SC_ONE_WRITER && 223 std::string(iface_type_name) == 224 typeid(sc_signal_inout_if<bool>).name()) { 225 if (_gem5Writer) { 226 std::ostringstream ss; 227 ss << "\n signal " << "`" << name() << "' (" << 228 kind() << ")"; 229 ss << "\n first driver `" << _gem5Writer->name() << "' (" << 230 _gem5Writer->kind() << ")"; 231 ss << "\n second driver `" << port.name() << "' (" << 232 port.kind() << ")"; 233 SC_REPORT_ERROR( 234 "(E115) sc_signal<T> cannot have more than one driver", 235 ss.str().c_str()); 236 } 237 _gem5Writer = &port; 238 } 239 } 240 241 virtual const bool &read() const { return m_cur_val; } 242 operator const bool &() const { return read(); } 243 244 virtual sc_writer_policy 245 get_writer_policy() const 246 { 247 return WRITER_POLICY; 248 } 249 virtual void 250 write(const bool &b) 251 { 252 m_new_val = b; 253 bool changed = !(m_cur_val == m_new_val); 254 //TODO check whether this write follows the write policy. 255 if (changed) 256 request_update(); 257 } | |
258 sc_signal<bool, WRITER_POLICY> & 259 operator = (const bool &b) 260 { | 334 sc_signal<bool, WRITER_POLICY> & 335 operator = (const bool &b) 336 { |
261 write(b); | 337 this->write(b); |
262 return *this; 263 } 264 sc_signal<bool, WRITER_POLICY> & 265 operator = (const sc_signal<bool, WRITER_POLICY> &s) 266 { | 338 return *this; 339 } 340 sc_signal<bool, WRITER_POLICY> & 341 operator = (const sc_signal<bool, WRITER_POLICY> &s) 342 { |
267 write(s.read()); | 343 this->write(s.read()); |
268 return *this; 269 } 270 | 344 return *this; 345 } 346 |
271 virtual const sc_event & 272 default_event() const 273 { 274 return value_changed_event(); 275 } 276 277 virtual const sc_event & 278 value_changed_event() const 279 { 280 return _valueChangedEvent; 281 } 282 virtual const sc_event & 283 posedge_event() const 284 { 285 return _posedgeEvent; 286 } 287 virtual const sc_event & 288 negedge_event() const 289 { 290 return _negedgeEvent; 291 } 292 293 virtual bool 294 event() const 295 { 296 return _changeStamp == ::sc_gem5::getChangeStamp(); 297 } 298 virtual bool 299 posedge() const 300 { 301 return _posStamp == ::sc_gem5::getChangeStamp(); 302 } 303 virtual bool 304 negedge() const 305 { 306 return _negStamp == ::sc_gem5::getChangeStamp(); 307 } 308 309 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } 310 virtual void 311 dump(std::ostream &os=std::cout) const 312 { 313 os << " name = " << name() << ::std::endl; 314 os << " value = " << m_cur_val << ::std::endl; 315 os << "new value = " << m_new_val << ::std::endl; 316 } 317 virtual const char *kind() const { return "sc_signal"; } 318 | |
319 protected: 320 virtual void 321 update() 322 { | 347 protected: 348 virtual void 349 update() 350 { |
323 if (m_new_val == m_cur_val) | 351 if (this->m_new_val == this->m_cur_val) |
324 return; 325 | 352 return; 353 |
326 m_cur_val = m_new_val; 327 _signalChange(); 328 if (m_cur_val) { 329 _posStamp = ::sc_gem5::getChangeStamp(); 330 _posedgeEvent.notify(SC_ZERO_TIME); | 354 this->m_cur_val = this->m_new_val; 355 this->_signalChange(); 356 if (this->m_cur_val) { 357 this->_posStamp = ::sc_gem5::getChangeStamp(); 358 this->_posedgeEvent.notify(SC_ZERO_TIME); |
331 } else { | 359 } else { |
332 _negStamp = ::sc_gem5::getChangeStamp(); 333 _negedgeEvent.notify(SC_ZERO_TIME); | 360 this->_negStamp = ::sc_gem5::getChangeStamp(); 361 this->_negedgeEvent.notify(SC_ZERO_TIME); |
334 } 335 } 336 | 362 } 363 } 364 |
337 void 338 _signalChange() 339 { 340 _changeStamp = ::sc_gem5::getChangeStamp(); 341 _valueChangedEvent.notify(SC_ZERO_TIME); 342 } 343 344 bool m_cur_val; 345 bool m_new_val; 346 | |
347 private: | 365 private: |
348 sc_event _valueChangedEvent; 349 sc_event _posedgeEvent; 350 sc_event _negedgeEvent; 351 352 uint64_t _changeStamp; 353 uint64_t _posStamp; 354 uint64_t _negStamp; 355 356 sc_port_base *_gem5Writer; 357 | |
358 // Disabled | 366 // Disabled |
359 sc_signal(const sc_signal<bool, WRITER_POLICY> &) : 360 sc_signal_inout_if<bool>(), sc_prim_channel("") 361 {} | 367 sc_signal(const sc_signal<bool, WRITER_POLICY> &); |
362}; 363 364template <sc_writer_policy WRITER_POLICY> 365class sc_signal<sc_dt::sc_logic, WRITER_POLICY> : | 368}; 369 370template <sc_writer_policy WRITER_POLICY> 371class sc_signal<sc_dt::sc_logic, WRITER_POLICY> : |
366 public sc_signal_inout_if<sc_dt::sc_logic>, public sc_prim_channel | 372 public sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY> |
367{ 368 public: | 373{ 374 public: |
369 sc_signal() : sc_signal_inout_if<sc_dt::sc_logic>(), 370 sc_prim_channel(sc_gen_unique_name("signal")), 371 m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()), 372 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), 373 _gem5Writer(NULL) | 375 sc_signal() : 376 sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>( 377 sc_gen_unique_name("signal")) |
374 {} 375 explicit sc_signal(const char *name) : | 378 {} 379 explicit sc_signal(const char *name) : |
376 sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name), 377 m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()), 378 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), 379 _gem5Writer(NULL) | 380 sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(name) |
380 {} 381 explicit sc_signal(const char *name, 382 const sc_dt::sc_logic &initial_value) : | 381 {} 382 explicit sc_signal(const char *name, 383 const sc_dt::sc_logic &initial_value) : |
383 sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name), 384 m_cur_val(initial_value), m_new_val(initial_value), 385 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), 386 _gem5Writer(NULL) | 384 sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>( 385 name, initial_value) |
387 {} 388 virtual ~sc_signal() {} 389 | 386 {} 387 virtual ~sc_signal() {} 388 |
390 virtual void 391 register_port(sc_port_base &port, const char *iface_type_name) 392 { 393 if (WRITER_POLICY == SC_ONE_WRITER && 394 std::string(iface_type_name) == 395 typeid(sc_signal_inout_if<sc_dt::sc_logic>).name()) { 396 if (_gem5Writer) { 397 std::ostringstream ss; 398 ss << "\n signal " << "`" << name() << "' (" << 399 kind() << ")"; 400 ss << "\n first driver `" << _gem5Writer->name() << "' (" << 401 _gem5Writer->kind() << ")"; 402 ss << "\n second driver `" << port.name() << "' (" << 403 port.kind() << ")"; 404 SC_REPORT_ERROR( 405 "(E115) sc_signal<T> cannot have more than one driver", 406 ss.str().c_str()); 407 } 408 _gem5Writer = &port; 409 } 410 } 411 412 virtual const sc_dt::sc_logic &read() const { return m_cur_val; } 413 operator const sc_dt::sc_logic &() const { return read(); } 414 415 virtual sc_writer_policy 416 get_writer_policy() const 417 { 418 return WRITER_POLICY; 419 } 420 virtual void 421 write(const sc_dt::sc_logic &l) 422 { 423 m_new_val = l; 424 bool changed = !(m_cur_val == m_new_val); 425 //TODO check whether this write follows the write policy. 426 if (changed) 427 request_update(); 428 } | |
429 sc_signal<sc_dt::sc_logic, WRITER_POLICY> & 430 operator = (const sc_dt::sc_logic &l) 431 { | 389 sc_signal<sc_dt::sc_logic, WRITER_POLICY> & 390 operator = (const sc_dt::sc_logic &l) 391 { |
432 write(l); | 392 this->write(l); |
433 return *this; 434 } 435 sc_signal<sc_dt::sc_logic, WRITER_POLICY> & 436 operator = (const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &s) 437 { | 393 return *this; 394 } 395 sc_signal<sc_dt::sc_logic, WRITER_POLICY> & 396 operator = (const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &s) 397 { |
438 write(s.read()); | 398 this->write(s.read()); |
439 return *this; 440 } 441 | 399 return *this; 400 } 401 |
442 virtual const sc_event & 443 default_event() const 444 { 445 return value_changed_event(); 446 } 447 448 virtual const sc_event & 449 value_changed_event() const 450 { 451 return _valueChangedEvent; 452 } 453 virtual const sc_event & 454 posedge_event() const 455 { 456 return _posedgeEvent; 457 } 458 virtual const sc_event & 459 negedge_event() const 460 { 461 return _negedgeEvent; 462 } 463 464 virtual bool 465 event() const 466 { 467 return _changeStamp == ::sc_gem5::getChangeStamp(); 468 } 469 virtual bool 470 posedge() const 471 { 472 return _posStamp == ::sc_gem5::getChangeStamp(); 473 } 474 virtual bool 475 negedge() const 476 { 477 return _negStamp == ::sc_gem5::getChangeStamp(); 478 } 479 480 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } 481 virtual void 482 dump(std::ostream &os=std::cout) const 483 { 484 os << " name = " << name() << ::std::endl; 485 os << " value = " << m_cur_val << ::std::endl; 486 os << "new value = " << m_new_val << ::std::endl; 487 } 488 virtual const char *kind() const { return "sc_signal"; } 489 | |
490 protected: 491 virtual void 492 update() 493 { | 402 protected: 403 virtual void 404 update() 405 { |
494 if (m_new_val == m_cur_val) | 406 if (this->m_new_val == this->m_cur_val) |
495 return; 496 | 407 return; 408 |
497 m_cur_val = m_new_val; 498 _signalChange(); 499 if (m_cur_val == sc_dt::SC_LOGIC_1) { 500 _posStamp = ::sc_gem5::getChangeStamp(); 501 _posedgeEvent.notify(SC_ZERO_TIME); 502 } else if (m_cur_val == sc_dt::SC_LOGIC_0) { 503 _negStamp = ::sc_gem5::getChangeStamp(); 504 _negedgeEvent.notify(SC_ZERO_TIME); | 409 this->m_cur_val = this->m_new_val; 410 this->_signalChange(); 411 if (this->m_cur_val == sc_dt::SC_LOGIC_1) { 412 this->_posStamp = ::sc_gem5::getChangeStamp(); 413 this->_posedgeEvent.notify(SC_ZERO_TIME); 414 } else if (this->m_cur_val == sc_dt::SC_LOGIC_0) { 415 this->_negStamp = ::sc_gem5::getChangeStamp(); 416 this->_negedgeEvent.notify(SC_ZERO_TIME); |
505 } 506 } 507 | 417 } 418 } 419 |
508 void 509 _signalChange() 510 { 511 _changeStamp = ::sc_gem5::getChangeStamp(); 512 _valueChangedEvent.notify(SC_ZERO_TIME); 513 } 514 515 sc_dt::sc_logic m_cur_val; 516 sc_dt::sc_logic m_new_val; 517 | |
518 private: | 420 private: |
519 sc_event _valueChangedEvent; 520 sc_event _posedgeEvent; 521 sc_event _negedgeEvent; 522 523 uint64_t _changeStamp; 524 uint64_t _posStamp; 525 uint64_t _negStamp; 526 527 sc_port_base *_gem5Writer; 528 | |
529 // Disabled | 421 // Disabled |
530 sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &) : 531 sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel("") 532 {} | 422 sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &); |
533}; 534 535} // namespace sc_core 536 537#endif //__SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ | 423}; 424 425} // namespace sc_core 426 427#endif //__SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ |