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__