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 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution; 11 * neither the name of the copyright holders nor the names of its 12 * contributors may be used to endorse or promote products derived from 13 * this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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>
|
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 |
51{
|
52 53class Process; 54 55class ScSignalBase : public sc_core::sc_prim_channel 56{ |
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) |
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) |
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() {} |
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) |
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()); |
175 }
|
176# endif |
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 }
|
182 virtual void 183 write(const T &t) 184 {
|
185# if !defined(SC_NO_WRITE_CHECK) 186 { 187 _checker.checkWriter(); 188 } 189# endif |
190 m_new_val = t; 191 bool changed = !(m_cur_val == m_new_val);
|
106 //TODO check whether this write follows the write policy.
|
192 if (changed)
|
108 request_update();
|
193 this->request_update(); |
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 }
|
195
|
123 virtual const sc_event &
|
196 virtual const sc_core::sc_event & |
197 default_event() const 198 {
|
126 return value_changed_event();
|
199 return ScSignalBase::defaultEvent(); |
200 }
|
128 virtual const sc_event &
|
201 202 virtual const sc_core::sc_event & |
203 value_changed_event() const 204 {
|
131 return _valueChangedEvent;
|
205 return ScSignalBase::valueChangedEvent(); |
206 }
|
133 virtual bool
134 event() const
135 {
136 return _changeStamp == ::sc_gem5::getChangeStamp();
137 }
|
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; |
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"; }
|
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(); } |
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 |
221 {
|
165 _changeStamp = ::sc_gem5::getChangeStamp();
166 _valueChangedEvent.notify(SC_ZERO_TIME);
|
222 return WRITER_POLICY; |
223 } 224
|
225 protected: |
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}; |
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) |
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(); } |
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 |
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> |
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")) |
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) |
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) |
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 }
|
334 sc_signal<bool, WRITER_POLICY> & 335 operator = (const bool &b) 336 {
|
261 write(b);
|
337 this->write(b); |
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()); |
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
|
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) |
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); |
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); |
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
|
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
|
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> &); |
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> |
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")) |
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) |
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) |
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 }
|
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); |
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()); |
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
|
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) |
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); |
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
|
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
|
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> &); |
423}; 424 425} // namespace sc_core 426 427#endif //__SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__
|