Deleted Added
sdiff udiff text old ( 13274:79ce1482d383 ) new ( 13277:b479038de4d9 )
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

--- 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 <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
48} // namespace sc_core
49
50namespace sc_gem5
51{
52
53class Process;
54
55class ScSignalBase : public sc_core::sc_prim_channel
56{
57 public:
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 {}
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 {}
166 virtual ~ScSignalBaseT() {}
167
168 virtual void
169 register_port(sc_core::sc_port_base &port, const char *iface_type_name)
170 {
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
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);
192 if (changed)
193 this->request_update();
194 }
195
196 virtual const sc_core::sc_event &
197 default_event() const
198 {
199 return ScSignalBase::defaultEvent();
200 }
201
202 virtual const sc_core::sc_event &
203 value_changed_event() const
204 {
205 return ScSignalBase::valueChangedEvent();
206 }
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 {
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 }
216
217 virtual bool event() const { return ScSignalBase::event(); }
218
219 virtual sc_core::sc_writer_policy
220 get_writer_policy() const
221 {
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
232 WriteChecker<WRITER_POLICY> _checker;
233};
234
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> :
319 public sc_gem5::ScSignalBinary<bool, WRITER_POLICY>
320{
321 public:
322 sc_signal() :
323 sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(
324 sc_gen_unique_name("signal"))
325 {}
326 explicit sc_signal(const char *name) :
327 sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name)
328 {}
329 explicit sc_signal(const char *name, const bool &initial_value) :
330 sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name, initial_value)
331 {}
332 virtual ~sc_signal() {}
333
334 sc_signal<bool, WRITER_POLICY> &
335 operator = (const bool &b)
336 {
337 this->write(b);
338 return *this;
339 }
340 sc_signal<bool, WRITER_POLICY> &
341 operator = (const sc_signal<bool, WRITER_POLICY> &s)
342 {
343 this->write(s.read());
344 return *this;
345 }
346
347 protected:
348 virtual void
349 update()
350 {
351 if (this->m_new_val == this->m_cur_val)
352 return;
353
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 {
360 this->_negStamp = ::sc_gem5::getChangeStamp();
361 this->_negedgeEvent.notify(SC_ZERO_TIME);
362 }
363 }
364
365 private:
366 // Disabled
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> :
372 public sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>
373{
374 public:
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) :
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) :
384 sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(
385 name, initial_value)
386 {}
387 virtual ~sc_signal() {}
388
389 sc_signal<sc_dt::sc_logic, WRITER_POLICY> &
390 operator = (const sc_dt::sc_logic &l)
391 {
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 {
398 this->write(s.read());
399 return *this;
400 }
401
402 protected:
403 virtual void
404 update()
405 {
406 if (this->m_new_val == this->m_cur_val)
407 return;
408
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
420 private:
421 // Disabled
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__