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