Deleted Added
sdiff udiff text old ( 13205:e965ce37608e ) new ( 13245:c666c5d4996b )
full compact
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 <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#include "warn_unimpl.hh" // for warn_unimpl
43
44namespace sc_core
45{
46
47class sc_port_base;
48
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
52{
53 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 {}
58 explicit sc_signal(const char *name) :
59 sc_signal_inout_if<T>(), sc_prim_channel(name),
60 m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL)
61 {}
62 explicit sc_signal(const char *name, const T &initial_value) :
63 sc_signal_inout_if<T>(), sc_prim_channel(name),
64 m_cur_val(initial_value), m_new_val(initial_value), _changeStamp(~0ULL)
65 {}
66 virtual ~sc_signal() {}
67
68 virtual void
69 register_port(sc_port_base &, const char *)
70 {
71 sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
72 }
73
74 virtual const T &read() const { return m_cur_val; }
75 operator const T&() const { return read(); }
76
77 virtual sc_writer_policy
78 get_writer_policy() const
79 {
80 return WRITER_POLICY;
81 }
82 virtual void
83 write(const T &t)
84 {
85 m_new_val = t;
86 bool changed = !(m_cur_val == m_new_val);
87 //TODO check whether this write follows the write policy.
88 if (changed)
89 request_update();
90 }
91 sc_signal<T, WRITER_POLICY> &
92 operator = (const T &t)
93 {
94 write(t);
95 return *this;
96 }
97 sc_signal<T, WRITER_POLICY> &
98 operator = (const sc_signal<T, WRITER_POLICY> &s)
99 {
100 write(s.read());
101 return *this;
102 }
103
104 virtual const sc_event &
105 default_event() const
106 {
107 return value_changed_event();
108 }
109 virtual const sc_event &
110 value_changed_event() const
111 {
112 return _valueChangedEvent;
113 }
114 virtual bool
115 event() const
116 {
117 return _changeStamp == ::sc_gem5::getChangeStamp();
118 }
119
120 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; }
121 virtual void
122 dump(std::ostream &os=std::cout) const
123 {
124 os << " name = " << name() << ::std::endl;
125 os << " value = " << m_cur_val << ::std::endl;
126 os << "new value = " << m_new_val << ::std::endl;
127 }
128 virtual const char *kind() const { return "sc_signal"; }
129
130 protected:
131 virtual void
132 update()
133 {
134 if (m_new_val == m_cur_val)
135 return;
136
137 m_cur_val = m_new_val;
138 _signalChange();
139 _changeStamp = ::sc_gem5::getChangeStamp();
140 _valueChangedEvent.notify(SC_ZERO_TIME);
141 }
142
143 void
144 _signalChange()
145 {
146 _changeStamp = ::sc_gem5::getChangeStamp();
147 _valueChangedEvent.notify(SC_ZERO_TIME);
148 }
149
150 // These members which store the current and future value of the signal
151 // are not specified in the standard but are referred to directly by one
152 // of the tests.
153 T m_cur_val;
154 T m_new_val;
155
156 private:
157 sc_event _valueChangedEvent;
158 uint64_t _changeStamp;
159
160 // Disabled
161 sc_signal(const sc_signal<T, WRITER_POLICY> &) :
162 sc_signal_inout_if<T>(), sc_prim_channel("")
163 {}
164};
165
166template <class T, sc_writer_policy WRITER_POLICY>
167inline std::ostream &
168operator << (std::ostream &os, const sc_signal<T, WRITER_POLICY> &s)
169{
170 os << s.read();
171 return os;
172}
173
174template <sc_writer_policy WRITER_POLICY>
175class sc_signal<bool, WRITER_POLICY> :
176 public sc_signal_inout_if<bool>, public sc_prim_channel
177{
178 public:
179 sc_signal() : sc_signal_inout_if<bool>(),
180 sc_prim_channel(sc_gen_unique_name("signal")),
181 m_cur_val(bool()), m_new_val(bool()),
182 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL)
183 {}
184 explicit sc_signal(const char *name) :
185 sc_signal_inout_if<bool>(), sc_prim_channel(name),
186 m_cur_val(bool()), m_new_val(bool()),
187 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL)
188 {}
189 explicit sc_signal(const char *name, const bool &initial_value) :
190 sc_signal_inout_if<bool>(), sc_prim_channel(name),
191 m_cur_val(initial_value), m_new_val(initial_value),
192 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL)
193 {}
194 virtual ~sc_signal() {}
195
196 virtual void
197 register_port(sc_port_base &, const char *)
198 {
199 sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
200 }
201
202 virtual const bool &read() const { return m_cur_val; }
203 operator const bool &() const { return read(); }
204
205 virtual sc_writer_policy
206 get_writer_policy() const
207 {
208 return WRITER_POLICY;
209 }
210 virtual void
211 write(const bool &b)
212 {
213 m_new_val = b;
214 bool changed = !(m_cur_val == m_new_val);
215 //TODO check whether this write follows the write policy.
216 if (changed)
217 request_update();
218 }
219 sc_signal<bool, WRITER_POLICY> &
220 operator = (const bool &b)
221 {
222 write(b);
223 return *this;
224 }
225 sc_signal<bool, WRITER_POLICY> &
226 operator = (const sc_signal<bool, WRITER_POLICY> &s)
227 {
228 write(s.read());
229 return *this;
230 }
231
232 virtual const sc_event &
233 default_event() const
234 {
235 return value_changed_event();
236 }
237
238 virtual const sc_event &
239 value_changed_event() const
240 {
241 return _valueChangedEvent;
242 }
243 virtual const sc_event &
244 posedge_event() const
245 {
246 return _posedgeEvent;
247 }
248 virtual const sc_event &
249 negedge_event() const
250 {
251 return _negedgeEvent;
252 }
253
254 virtual bool
255 event() const
256 {
257 return _changeStamp == ::sc_gem5::getChangeStamp();
258 }
259 virtual bool
260 posedge() const
261 {
262 return _posStamp == ::sc_gem5::getChangeStamp();
263 }
264 virtual bool
265 negedge() const
266 {
267 return _negStamp == ::sc_gem5::getChangeStamp();
268 }
269
270 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; }
271 virtual void
272 dump(std::ostream &os=std::cout) const
273 {
274 os << " name = " << name() << ::std::endl;
275 os << " value = " << m_cur_val << ::std::endl;
276 os << "new value = " << m_new_val << ::std::endl;
277 }
278 virtual const char *kind() const { return "sc_signal"; }
279
280 protected:
281 virtual void
282 update()
283 {
284 if (m_new_val == m_cur_val)
285 return;
286
287 m_cur_val = m_new_val;
288 _signalChange();
289 if (m_cur_val) {
290 _posStamp = ::sc_gem5::getChangeStamp();
291 _posedgeEvent.notify(SC_ZERO_TIME);
292 } else {
293 _negStamp = ::sc_gem5::getChangeStamp();
294 _negedgeEvent.notify(SC_ZERO_TIME);
295 }
296 }
297
298 void
299 _signalChange()
300 {
301 _changeStamp = ::sc_gem5::getChangeStamp();
302 _valueChangedEvent.notify(SC_ZERO_TIME);
303 }
304
305 bool m_cur_val;
306 bool m_new_val;
307
308 private:
309 sc_event _valueChangedEvent;
310 sc_event _posedgeEvent;
311 sc_event _negedgeEvent;
312
313 uint64_t _changeStamp;
314 uint64_t _posStamp;
315 uint64_t _negStamp;
316
317 // Disabled
318 sc_signal(const sc_signal<bool, WRITER_POLICY> &) :
319 sc_signal_inout_if<bool>(), sc_prim_channel("")
320 {}
321};
322
323template <sc_writer_policy WRITER_POLICY>
324class sc_signal<sc_dt::sc_logic, WRITER_POLICY> :
325 public sc_signal_inout_if<sc_dt::sc_logic>, public sc_prim_channel
326{
327 public:
328 sc_signal() : sc_signal_inout_if<sc_dt::sc_logic>(),
329 sc_prim_channel(sc_gen_unique_name("signal")),
330 m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()),
331 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL)
332 {}
333 explicit sc_signal(const char *name) :
334 sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name),
335 m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()),
336 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL)
337 {}
338 explicit sc_signal(const char *name,
339 const sc_dt::sc_logic &initial_value) :
340 sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name),
341 m_cur_val(initial_value), m_new_val(initial_value),
342 _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL)
343 {}
344 virtual ~sc_signal() {}
345
346 virtual void
347 register_port(sc_port_base &, const char *)
348 {
349 sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
350 }
351
352 virtual const sc_dt::sc_logic &read() const { return m_cur_val; }
353 operator const sc_dt::sc_logic &() const { return read(); }
354
355 virtual sc_writer_policy
356 get_writer_policy() const
357 {
358 return WRITER_POLICY;
359 }
360 virtual void
361 write(const sc_dt::sc_logic &l)
362 {
363 m_new_val = l;
364 bool changed = !(m_cur_val == m_new_val);
365 //TODO check whether this write follows the write policy.
366 if (changed)
367 request_update();
368 }
369 sc_signal<sc_dt::sc_logic, WRITER_POLICY> &
370 operator = (const sc_dt::sc_logic &l)
371 {
372 write(l);
373 return *this;
374 }
375 sc_signal<sc_dt::sc_logic, WRITER_POLICY> &
376 operator = (const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &s)
377 {
378 write(s.read());
379 return *this;
380 }
381
382 virtual const sc_event &
383 default_event() const
384 {
385 return value_changed_event();
386 }
387
388 virtual const sc_event &
389 value_changed_event() const
390 {
391 return _valueChangedEvent;
392 }
393 virtual const sc_event &
394 posedge_event() const
395 {
396 return _posedgeEvent;
397 }
398 virtual const sc_event &
399 negedge_event() const
400 {
401 return _negedgeEvent;
402 }
403
404 virtual bool
405 event() const
406 {
407 return _changeStamp == ::sc_gem5::getChangeStamp();
408 }
409 virtual bool
410 posedge() const
411 {
412 return _posStamp == ::sc_gem5::getChangeStamp();
413 }
414 virtual bool
415 negedge() const
416 {
417 return _negStamp == ::sc_gem5::getChangeStamp();
418 }
419
420 virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; }
421 virtual void
422 dump(std::ostream &os=std::cout) const
423 {
424 os << " name = " << name() << ::std::endl;
425 os << " value = " << m_cur_val << ::std::endl;
426 os << "new value = " << m_new_val << ::std::endl;
427 }
428 virtual const char *kind() const { return "sc_signal"; }
429
430 protected:
431 virtual void
432 update()
433 {
434 if (m_new_val == m_cur_val)
435 return;
436
437 m_cur_val = m_new_val;
438 _signalChange();
439 if (m_cur_val == sc_dt::SC_LOGIC_1) {
440 _posStamp = ::sc_gem5::getChangeStamp();
441 _posedgeEvent.notify(SC_ZERO_TIME);
442 } else if (m_cur_val == sc_dt::SC_LOGIC_0) {
443 _negStamp = ::sc_gem5::getChangeStamp();
444 _negedgeEvent.notify(SC_ZERO_TIME);
445 }
446 }
447
448 void
449 _signalChange()
450 {
451 _changeStamp = ::sc_gem5::getChangeStamp();
452 _valueChangedEvent.notify(SC_ZERO_TIME);
453 }
454
455 sc_dt::sc_logic m_cur_val;
456 sc_dt::sc_logic m_new_val;
457
458 private:
459 sc_event _valueChangedEvent;
460 sc_event _posedgeEvent;
461 sc_event _negedgeEvent;
462
463 uint64_t _changeStamp;
464 uint64_t _posStamp;
465 uint64_t _negStamp;
466
467 // Disabled
468 sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &) :
469 sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel("")
470 {}
471};
472
473} // namespace sc_core
474
475#endif //__SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__