Deleted Added
sdiff udiff text old ( 13071:91e07c3feb64 ) 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_INOUT_HH__
31#define __SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__
32
33#include <string>
34
35#include "../core/sc_event.hh"
36#include "../core/sc_port.hh"
37#include "../dt/bit/sc_logic.hh"
38#include "sc_signal_inout_if.hh"
39#include "warn_unimpl.hh"
40
41namespace sc_dt
42{
43
44class sc_logic;
45
46} // namespace sc_dt
47
48namespace sc_core
49{
50
51class sc_event;
52class sc_trace_file;
53
54template <class T>
55class sc_inout : public sc_port<sc_signal_inout_if<T>, 1>
56{
57 public:
58 sc_inout() : sc_port<sc_signal_inout_if<T>, 1>(), initValue(nullptr),
59 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
60 {}
61 explicit sc_inout(const char *name) :
62 sc_port<sc_signal_inout_if<T>, 1>(name), initValue(nullptr),
63 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
64 {}
65 virtual ~sc_inout() { delete initValue; }
66
67 // Deprecated binding constructors.
68 explicit sc_inout(const sc_signal_inout_if<T> &interface) :
69 sc_port<sc_signal_inout_if<T>, 1>(interface), initValue(nullptr),
70 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
71 {}
72 sc_inout(const char *name, const sc_signal_inout_if<T> &interface) :
73 sc_port<sc_signal_inout_if<T>, 1>(name, interface), initValue(nullptr),
74 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
75 {}
76 explicit sc_inout(sc_port_b<sc_signal_inout_if<T> > &parent) :
77 sc_port<sc_signal_inout_if<T>, 1>(parent), initValue(nullptr),
78 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
79 {}
80 sc_inout(const char *name, sc_port_b<sc_signal_inout_if<T> > &parent) :
81 sc_port<sc_signal_inout_if<T>, 1>(name, parent), initValue(nullptr),
82 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
83 {}
84 explicit sc_inout(sc_port<sc_signal_inout_if<T>, 1> &parent) :
85 sc_port<sc_signal_inout_if<T>, 1>(parent), initValue(nullptr),
86 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
87 {}
88 sc_inout(const char *name, sc_port<sc_signal_inout_if<T>, 1> &parent) :
89 sc_port<sc_signal_inout_if<T>, 1>(name, parent), initValue(nullptr),
90 _valueChangedFinder(*this, &sc_signal_inout_if<T>::value_changed_event)
91 {}
92
93 void
94 initialize(const T &t)
95 {
96 if (this->size()) {
97 (*this)->write(t);
98 } else {
99 if (!initValue)
100 initValue = new T;
101 *initValue = t;
102 }
103 }
104 void initialize(const sc_signal_in_if<T> &i) { initialize(i.read()); }
105
106 virtual void
107 end_of_elaboration()
108 {
109 if (initValue) {
110 write(*initValue);
111 delete initValue;
112 initValue = nullptr;
113 }
114 }
115
116 const T &read() const { return (*this)->read(); }
117 operator const T& () const { return (*this)->read(); }
118
119 void write(const T &t) { (*this)->write(t); }
120 sc_inout<T> &
121 operator = (const T &t)
122 {
123 (*this)->write(t);
124 return *this;
125 }
126 sc_inout<T> &
127 operator = (const sc_signal_in_if<T> &i)
128 {
129 (*this)->write(i.read());
130 return *this;
131 }
132 sc_inout<T> &
133 operator = (const sc_port<sc_signal_in_if<T>, 1> &p)
134 {
135 (*this)->write(p->read());
136 return *this;
137 }
138 sc_inout<T> &
139 operator = (const sc_port<sc_signal_inout_if<T>, 1> &p)
140 {
141 (*this)->write(p->read());
142 return *this;
143 }
144 sc_inout<T> &
145 operator = (const sc_inout<T> &p)
146 {
147 (*this)->write(p->read());
148 return *this;
149 }
150
151 const sc_event &default_event() const { return (*this)->default_event(); }
152 const sc_event &
153 value_changed_event() const
154 {
155 return (*this)->value_changed_event();
156 }
157 bool event() const { return (*this)->event(); }
158 sc_event_finder &value_changed() const { return _valueChangedFinder; }
159
160 virtual const char *kind() const { return "sc_inout"; }
161
162 private:
163 T *initValue;
164 mutable sc_event_finder_t<sc_signal_inout_if<T> > _valueChangedFinder;
165
166 // Disabled
167 sc_inout(const sc_inout<T> &);
168};
169
170template <class T>
171inline void
172sc_trace(sc_trace_file *, const sc_inout<T> &, const std::string &)
173{
174 sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
175}
176
177template <>
178class sc_inout<bool> : public sc_port<sc_signal_inout_if<bool>, 1>
179{
180 public:
181 sc_inout() : sc_port<sc_signal_inout_if<bool>, 1>(), initValue(nullptr),
182 _valueChangedFinder(*this,
183 &sc_signal_inout_if<bool>::value_changed_event),
184 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
185 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
186 {}
187 explicit sc_inout(const char *name) :
188 sc_port<sc_signal_inout_if<bool>, 1>(name), initValue(nullptr),
189 _valueChangedFinder(*this,
190 &sc_signal_inout_if<bool>::value_changed_event),
191 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
192 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
193 {}
194 virtual ~sc_inout() { delete initValue; }
195
196 // Deprecated binding constructors.
197 explicit sc_inout(const sc_signal_inout_if<bool> &interface) :
198 sc_port<sc_signal_inout_if<bool>, 1>(interface), initValue(nullptr),
199 _valueChangedFinder(*this,
200 &sc_signal_inout_if<bool>::value_changed_event),
201 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
202 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
203 {}
204 sc_inout(const char *name, const sc_signal_inout_if<bool> &interface) :
205 sc_port<sc_signal_inout_if<bool>, 1>(name, interface),
206 initValue(nullptr),
207 _valueChangedFinder(*this,
208 &sc_signal_inout_if<bool>::value_changed_event),
209 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
210 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
211 {}
212 explicit sc_inout(sc_port_b<sc_signal_inout_if<bool> > &parent) :
213 sc_port<sc_signal_inout_if<bool>, 1>(parent), initValue(nullptr),
214 _valueChangedFinder(*this,
215 &sc_signal_inout_if<bool>::value_changed_event),
216 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
217 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
218 {}
219 sc_inout(const char *name, sc_port_b<sc_signal_inout_if<bool> > &parent) :
220 sc_port<sc_signal_inout_if<bool>, 1>(name, parent), initValue(nullptr),
221 _valueChangedFinder(*this,
222 &sc_signal_inout_if<bool>::value_changed_event),
223 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
224 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
225 {}
226 explicit sc_inout(sc_port<sc_signal_inout_if<bool>, 1> &parent) :
227 sc_port<sc_signal_inout_if<bool>, 1>(parent), initValue(nullptr),
228 _valueChangedFinder(*this,
229 &sc_signal_inout_if<bool>::value_changed_event),
230 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
231 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
232 {}
233 sc_inout(const char *name, sc_port<sc_signal_inout_if<bool>, 1> &parent) :
234 sc_port<sc_signal_inout_if<bool>, 1>(name, parent), initValue(nullptr),
235 _valueChangedFinder(*this,
236 &sc_signal_inout_if<bool>::value_changed_event),
237 _posFinder(*this, &sc_signal_inout_if<bool>::posedge_event),
238 _negFinder(*this, &sc_signal_inout_if<bool>::negedge_event)
239 {}
240
241 void
242 initialize(const bool &b)
243 {
244 if (this->size()) {
245 (*this)->write(b);
246 } else {
247 if (!initValue)
248 initValue = new bool;
249 *initValue = b;
250 }
251 }
252 void initialize(const sc_signal_in_if<bool> &i) { initialize(i.read()); }
253
254 virtual void
255 end_of_elaboration()
256 {
257 if (initValue) {
258 write(*initValue);
259 delete initValue;
260 initValue = nullptr;
261 }
262 }
263
264 const bool &read() const { return (*this)->read(); }
265 operator const bool& () const { return (*this)->read(); }
266
267 void write(const bool &b) { (*this)->write(b); }
268 sc_inout<bool> &
269 operator = (const bool &b)
270 {
271 (*this)->write(b);
272 return *this;
273 }
274 sc_inout<bool> &
275 operator = (const sc_signal_in_if<bool> &i)
276 {
277 (*this)->write(i.read());
278 return *this;
279 }
280 sc_inout<bool> &
281 operator = (const sc_port<sc_signal_in_if<bool>, 1> &p)
282 {
283 (*this)->write(p->read());
284 return *this;
285 }
286 sc_inout<bool> &
287 operator = (const sc_port<sc_signal_inout_if<bool>, 1> &p)
288 {
289 (*this)->write(p->read());
290 return *this;
291 }
292 sc_inout<bool> &
293 operator = (const sc_inout<bool> &p)
294 {
295 (*this)->write(p->read());
296 return *this;
297 }
298
299 const sc_event &default_event() const { return (*this)->default_event(); }
300 const sc_event &
301 value_changed_event() const
302 {
303 return (*this)->value_changed_event();
304 }
305 const sc_event &posedge_event() const { return (*this)->posedge_event(); }
306 const sc_event &negedge_event() const { return (*this)->negedge_event(); }
307 bool event() const { return (*this)->event(); }
308 bool posedge() const { return (*this)->posedge(); }
309 bool negedge() const { return (*this)->negedge(); }
310
311 sc_event_finder &value_changed() const { return _valueChangedFinder; }
312 sc_event_finder &pos() const { return _posFinder; }
313 sc_event_finder &neg() const { return _negFinder; }
314
315 virtual const char *kind() const { return "sc_inout"; }
316
317 private:
318 bool *initValue;
319 mutable sc_event_finder_t<sc_signal_inout_if<bool> > _valueChangedFinder;
320 mutable sc_event_finder_t<sc_signal_inout_if<bool> > _posFinder;
321 mutable sc_event_finder_t<sc_signal_inout_if<bool> > _negFinder;
322
323 // Disabled
324 sc_inout(const sc_inout<bool> &);
325};
326
327template <>
328inline void sc_trace<bool>(
329 sc_trace_file *, const sc_inout<bool> &, const std::string &)
330{
331 sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
332}
333
334template <>
335class sc_inout<sc_dt::sc_logic> :
336 public sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>
337{
338 public:
339 sc_inout() : sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(),
340 initValue(nullptr),
341 _valueChangedFinder(*this,
342 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
343 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
344 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
345 {}
346 explicit sc_inout(const char *name) :
347 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name),
348 initValue(nullptr),
349 _valueChangedFinder(*this,
350 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
351 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
352 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
353 {}
354 virtual ~sc_inout() { delete initValue; }
355
356 // Deprecated binding constructors.
357 explicit sc_inout(const sc_signal_inout_if<sc_dt::sc_logic> &interface) :
358 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(interface),
359 initValue(nullptr),
360 _valueChangedFinder(*this,
361 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
362 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
363 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
364 {}
365 sc_inout(const char *name,
366 const sc_signal_inout_if<sc_dt::sc_logic> &interface) :
367 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, interface),
368 initValue(nullptr),
369 _valueChangedFinder(*this,
370 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
371 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
372 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
373 {}
374 explicit sc_inout(
375 sc_port_b<sc_signal_inout_if<sc_dt::sc_logic> > &parent) :
376 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(parent),
377 initValue(nullptr),
378 _valueChangedFinder(*this,
379 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
380 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
381 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
382 {}
383 sc_inout(const char *name,
384 sc_port_b<sc_signal_inout_if<sc_dt::sc_logic> > &parent) :
385 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, parent),
386 initValue(nullptr),
387 _valueChangedFinder(*this,
388 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
389 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
390 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
391 {}
392 explicit sc_inout(
393 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &parent) :
394 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(parent),
395 initValue(nullptr),
396 _valueChangedFinder(*this,
397 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
398 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
399 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
400 {}
401 sc_inout(const char *name,
402 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &parent) :
403 sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1>(name, parent),
404 initValue(nullptr),
405 _valueChangedFinder(*this,
406 &sc_signal_inout_if<sc_dt::sc_logic>::value_changed_event),
407 _posFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::posedge_event),
408 _negFinder(*this, &sc_signal_inout_if<sc_dt::sc_logic>::negedge_event)
409 {}
410
411 void
412 initialize(const sc_dt::sc_logic &l)
413 {
414 if (this->size()) {
415 (*this)->write(l);
416 } else {
417 if (!initValue)
418 initValue = new sc_dt::sc_logic;
419 *initValue = l;
420 }
421 }
422 void
423 initialize(const sc_signal_in_if<sc_dt::sc_logic> &i)
424 {
425 initialize(i.read());
426 }
427
428 virtual void
429 end_of_elaboration()
430 {
431 if (initValue) {
432 write(*initValue);
433 delete initValue;
434 initValue = nullptr;
435 }
436 }
437
438 const sc_dt::sc_logic &read() const { return (*this)->read(); }
439 operator const sc_dt::sc_logic& () const { return (*this)->read(); }
440
441 void write(const sc_dt::sc_logic &l) { (*this)->write(l); }
442 sc_inout<sc_dt::sc_logic> &
443 operator = (const sc_dt::sc_logic &l)
444 {
445 (*this)->write(l);
446 return *this;
447 }
448 sc_inout<sc_dt::sc_logic> &
449 operator = (const sc_signal_in_if<sc_dt::sc_logic> &i)
450 {
451 (*this)->write(i.read());
452 return *this;
453 }
454 sc_inout<sc_dt::sc_logic> &
455 operator = (const sc_port<sc_signal_in_if<sc_dt::sc_logic>, 1> &p)
456 {
457 (*this)->write(p->read());
458 return *this;
459 }
460 sc_inout<sc_dt::sc_logic> &
461 operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_logic>, 1> &p)
462 {
463 (*this)->write(p->read());
464 return *this;
465 }
466 sc_inout<sc_dt::sc_logic> &
467 operator = (const sc_inout<sc_dt::sc_logic> &p)
468 {
469 (*this)->write(p->read());
470 return *this;
471 }
472
473 const sc_event &default_event() const { return (*this)->default_event(); }
474 const sc_event &
475 value_changed_event() const
476 {
477 return (*this)->value_changed_event();
478 }
479 const sc_event &posedge_event() const { return (*this)->posedge_event(); }
480 const sc_event &negedge_event() const { return (*this)->negedge_event(); }
481 bool event() const { return (*this)->event(); }
482 bool posedge() const { return (*this)->posedge(); }
483 bool negedge() const { return (*this)->negedge(); }
484
485 sc_event_finder &value_changed() const { return _valueChangedFinder; }
486 sc_event_finder &pos() const { return _posFinder; }
487 sc_event_finder &neg() const { return _negFinder; }
488
489 virtual const char *kind() const { return "sc_inout"; }
490
491 private:
492 sc_dt::sc_logic *initValue;
493 mutable sc_event_finder_t<
494 sc_signal_inout_if<sc_dt::sc_logic> > _valueChangedFinder;
495 mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _posFinder;
496 mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _negFinder;
497
498 // Disabled
499 sc_inout(const sc_inout<sc_dt::sc_logic> &);
500};
501
502template <>
503inline void
504sc_trace<sc_dt::sc_logic>(sc_trace_file *, const sc_inout<sc_dt::sc_logic> &,
505 const std::string &)
506{
507 sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
508}
509
510} // namespace sc_core
511
512#endif //__SYSTEMC_EXT_CHANNEL_SC_INOUT_HH__