1 /*
2 * Copyright (c) 2004-2020 Stephen Williams (steve@icarus.com)
3 *
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 # include "config.h"
21 # include "vvp_net.h"
22 # include "vvp_net_sig.h"
23 # include "statistics.h"
24 # include "vpi_priv.h"
25 # include <vector>
26 # include <cassert>
27 #ifdef CHECK_WITH_VALGRIND
28 # include <valgrind/memcheck.h>
29 # include <map>
30 #endif
31
32 # include <iostream>
33
34 using namespace std;
35
36 /*
37 * The filter_mask_ method takes as an input the value to propagate,
38 * the mask of what is being forced, and returns a propagation
39 * mode. In the process, it may update the filtered output value.
40 *
41 * The input value is the subvector "val" that is placed as "base" in
42 * the output. The val may be shorter then the target vector.
43 *
44 * The "force" vector in the value being force, with the force_mask_
45 * member a bit mask of which parts of the force vector really apply.
46 */
filter_mask_(const T & val,const T & force,T & filter,unsigned base)47 template <class T> vvp_net_fil_t::prop_t vvp_net_fil_t::filter_mask_(const T&val, const T&force, T&filter, unsigned base)
48 {
49 if (!test_force_mask_is_zero()) {
50 // Some bits are being forced. Go through the
51 // force_mask_ and force value to see which bits are
52 // propagated and which are kept from the forced
53 // value. Update the filter with the filtered result and
54 // return REPL to indicate that some bits have changed,
55 // or STOP if no bits change.
56 bool propagate_flag = force_propagate_;
57 force_propagate_ = false;
58 assert(force_mask_.size() == force.size());
59 assert((base+val.size()) <= force_mask_.size());
60
61 filter = val;
62 for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
63 if (force_mask_.value(base+idx))
64 filter.set_bit(idx, force.value(base+idx));
65 else
66 propagate_flag = true;
67 }
68
69 if (propagate_flag) {
70 run_vpi_callbacks();
71 return REPL;
72 } else {
73 return STOP;
74 }
75
76 } else {
77 run_vpi_callbacks();
78 return PROP;
79 }
80 }
81
filter_mask_(T & val,T force)82 template <class T> vvp_net_fil_t::prop_t vvp_net_fil_t::filter_mask_(T&val, T force)
83 {
84
85 if (test_force_mask(0)) {
86 val = force;
87 run_vpi_callbacks();
88 return REPL;
89 }
90 run_vpi_callbacks();
91 return PROP;
92 }
93
filter_input_mask_(const T & val,const T & force,T & rep) const94 template <class T> vvp_net_fil_t::prop_t vvp_net_fil_t::filter_input_mask_(const T&val, const T&force, T&rep) const
95 {
96 if (test_force_mask_is_zero())
97 return PROP;
98
99 assert(force_mask_.size() == force.size());
100
101 rep = val;
102 for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
103 if (force_mask_.value(idx))
104 rep.set_bit(idx, force.value(idx));
105 }
106
107 return REPL;
108 }
109
~vvp_signal_value()110 vvp_signal_value::~vvp_signal_value()
111 {
112 }
113
real_value() const114 double vvp_signal_value::real_value() const
115 {
116 assert(0);
117 return 0;
118 }
119
force_vec4(const vvp_vector4_t & val,const vvp_vector2_t & mask)120 void vvp_net_t::force_vec4(const vvp_vector4_t&val, const vvp_vector2_t&mask)
121 {
122 assert(fil);
123 fil->force_fil_vec4(val, mask);
124 fun->force_flag(false);
125 vvp_send_vec4(out_, val, 0);
126 }
127
force_vec8(const vvp_vector8_t & val,const vvp_vector2_t & mask)128 void vvp_net_t::force_vec8(const vvp_vector8_t&val, const vvp_vector2_t&mask)
129 {
130 assert(fil);
131 fil->force_fil_vec8(val, mask);
132 fun->force_flag(false);
133 vvp_send_vec8(out_, val);
134 }
135
force_real(double val,const vvp_vector2_t & mask)136 void vvp_net_t::force_real(double val, const vvp_vector2_t&mask)
137 {
138 assert(fil);
139 fil->force_fil_real(val, mask);
140 fun->force_flag(false);
141 vvp_send_real(out_, val, 0);
142 }
143
144 /* **** vvp_fun_signal methods **** */
145
vvp_fun_signal_base()146 vvp_fun_signal_base::vvp_fun_signal_base()
147 {
148 continuous_assign_active_ = false;
149 needs_init_ = true;
150 cassign_link = 0;
151 count_functors_sig += 1;
152 }
153
vvp_fun_signal4_sa(unsigned wid,vvp_bit4_t init)154 vvp_fun_signal4_sa::vvp_fun_signal4_sa(unsigned wid, vvp_bit4_t init)
155 : bits4_(wid, init)
156 {
157 }
158
159 /*
160 * Nets simply reflect their input to their output.
161 *
162 * NOTE: It is a quirk of vvp_fun_signal that it has an initial value
163 * that needs to be propagated, but after that it only needs to
164 * propagate if the value changes. Eliminating duplicate propagations
165 * should improve performance, but has the quirk that an input that
166 * matches the initial value might not be propagated. The hack used
167 * herein is to keep a "needs_init_" flag that is turned false after
168 * the first propagation, and forces the first propagation to happen
169 * even if it matches the initial value.
170 */
recv_vec4(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,vvp_context_t)171 void vvp_fun_signal4_sa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
172 vvp_context_t)
173 {
174 switch (ptr.port()) {
175 case 0: // Normal input (feed from net, or set from process)
176 /* If we don't have a continuous assign mask then just
177 copy the bits, otherwise we need to see if there are
178 any holes in the mask so we can set those bits. */
179 if (assign_mask_.size() == 0) {
180 if (needs_init_ || !bits4_.eeq(bit)) {
181 assert(bit.size() == bits4_.size());
182 bits4_ = bit;
183 needs_init_ = false;
184 ptr.ptr()->send_vec4(bits4_, 0);
185 }
186 } else {
187 bool changed = false;
188 assert(bits4_.size() == assign_mask_.size());
189 for (unsigned idx = 0 ; idx < bit.size() ; idx += 1) {
190 if (idx >= bits4_.size()) break;
191 if (assign_mask_.value(idx)) continue;
192 bits4_.set_bit(idx, bit.value(idx));
193 changed = true;
194 }
195 if (changed) {
196 needs_init_ = false;
197 ptr.ptr()->send_vec4(bits4_, 0);
198 }
199 }
200 break;
201
202 case 1: // Continuous assign value
203 // Handle the simple case of the linked source being wider
204 // than this signal. Note we don't yet support the case of
205 // the linked source being narrower than this signal, or
206 // the case of an expression being assigned.
207 bits4_ = coerce_to_width(bit, bits4_.size());
208 assign_mask_ = vvp_vector2_t(vvp_vector2_t::FILL1, bits4_.size());
209 ptr.ptr()->send_vec4(bits4_, 0);
210 break;
211
212 default:
213 fprintf(stderr, "Unsupported port type %u.\n", ptr.port());
214 assert(0);
215 break;
216 }
217 }
218
recv_vec8(vvp_net_ptr_t ptr,const vvp_vector8_t & bit)219 void vvp_fun_signal4_sa::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
220 {
221 recv_vec4(ptr, reduce4(bit), 0);
222 }
223
recv_vec4_pv(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,unsigned base,unsigned wid,unsigned vwid,vvp_context_t)224 void vvp_fun_signal4_sa::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
225 unsigned base, unsigned wid, unsigned vwid,
226 vvp_context_t)
227 {
228 assert(bit.size() == wid);
229 assert(bits4_.size() == vwid);
230
231 switch (ptr.port()) {
232 case 0: // Normal input
233 if (assign_mask_.size() == 0) {
234 for (unsigned idx = 0 ; idx < wid ; idx += 1) {
235 if (base+idx >= bits4_.size()) break;
236 bits4_.set_bit(base+idx, bit.value(idx));
237 }
238 needs_init_ = false;
239 ptr.ptr()->send_vec4(bits4_,0);
240 } else {
241 bool changed = false;
242 assert(bits4_.size() == assign_mask_.size());
243 for (unsigned idx = 0 ; idx < wid ; idx += 1) {
244 if (base+idx >= bits4_.size()) break;
245 if (assign_mask_.value(base+idx)) continue;
246 bits4_.set_bit(base+idx, bit.value(idx));
247 changed = true;
248 }
249 if (changed) {
250 needs_init_ = false;
251 ptr.ptr()->send_vec4(bits4_,0);
252 }
253 }
254 break;
255
256 case 1: // Continuous assign value
257 if (assign_mask_.size() == 0)
258 assign_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, bits4_.size());
259 for (unsigned idx = 0 ; idx < wid ; idx += 1) {
260 if (base+idx >= bits4_.size())
261 break;
262 bits4_.set_bit(base+idx, bit.value(idx));
263 assign_mask_.set_bit(base+idx, 1);
264 }
265 ptr.ptr()->send_vec4(bits4_,0);
266 break;
267
268 default:
269 fprintf(stderr, "Unsupported port type %u.\n", ptr.port());
270 assert(0);
271 break;
272 }
273 }
274
recv_vec8_pv(vvp_net_ptr_t ptr,const vvp_vector8_t & bit,unsigned base,unsigned wid,unsigned vwid)275 void vvp_fun_signal4_sa::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
276 unsigned base, unsigned wid, unsigned vwid)
277 {
278 recv_vec4_pv(ptr, reduce4(bit), base, wid, vwid, 0);
279 }
280
deassign()281 void vvp_fun_signal_base::deassign()
282 {
283 continuous_assign_active_ = false;
284 assign_mask_ = vvp_vector2_t();
285 }
286
deassign_pv(unsigned base,unsigned wid)287 void vvp_fun_signal_base::deassign_pv(unsigned base, unsigned wid)
288 {
289 for (unsigned idx = 0 ; idx < wid ; idx += 1) {
290 assign_mask_.set_bit(base+idx, 0);
291 }
292
293 if (assign_mask_.is_zero()) {
294 assign_mask_ = vvp_vector2_t();
295 }
296 }
297
release(vvp_net_ptr_t,bool)298 void automatic_signal_base::release(vvp_net_ptr_t,bool)
299 {
300 assert(0);
301 }
302
release_pv(vvp_net_ptr_t,unsigned,unsigned,bool)303 void automatic_signal_base::release_pv(vvp_net_ptr_t,unsigned,unsigned,bool)
304 {
305 assert(0);
306 }
307
filter_size() const308 unsigned automatic_signal_base::filter_size() const
309 {
310 assert(0);
311 return(0);
312 }
force_fil_vec4(const vvp_vector4_t &,const vvp_vector2_t &)313 void automatic_signal_base::force_fil_vec4(const vvp_vector4_t&, const vvp_vector2_t&)
314 {
315 assert(0);
316 }
force_fil_vec8(const vvp_vector8_t &,const vvp_vector2_t &)317 void automatic_signal_base::force_fil_vec8(const vvp_vector8_t&, const vvp_vector2_t&)
318 {
319 assert(0);
320 }
force_fil_real(double,const vvp_vector2_t &)321 void automatic_signal_base::force_fil_real(double, const vvp_vector2_t&)
322 {
323 assert(0);
324 }
get_value(struct t_vpi_value *)325 void automatic_signal_base::get_value(struct t_vpi_value*)
326 {
327 assert(0);
328 }
329
vec4_unfiltered_value() const330 const vvp_vector4_t& vvp_fun_signal4_sa::vec4_unfiltered_value() const
331 {
332 return bits4_;
333 }
334
vvp_fun_signal4_aa(unsigned wid,vvp_bit4_t init)335 vvp_fun_signal4_aa::vvp_fun_signal4_aa(unsigned wid, vvp_bit4_t init)
336 {
337 /* To make init work we would need to save it and then use the
338 * saved value when we ran reset_instance(). For now just make
339 * sure it matches the value we use in reset_instance(). */
340 assert(init == BIT4_X);
341 context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
342 size_ = wid;
343 }
344
~vvp_fun_signal4_aa()345 vvp_fun_signal4_aa::~vvp_fun_signal4_aa()
346 {
347 assert(0);
348 }
349
alloc_instance(vvp_context_t context)350 void vvp_fun_signal4_aa::alloc_instance(vvp_context_t context)
351 {
352 vvp_set_context_item(context, context_idx_, new vvp_vector4_t(size_));
353 }
354
reset_instance(vvp_context_t context)355 void vvp_fun_signal4_aa::reset_instance(vvp_context_t context)
356 {
357 vvp_vector4_t*bits = static_cast<vvp_vector4_t*>
358 (vvp_get_context_item(context, context_idx_));
359
360 bits->set_to_x();
361 }
362
363 #ifdef CHECK_WITH_VALGRIND
free_instance(vvp_context_t context)364 void vvp_fun_signal4_aa::free_instance(vvp_context_t context)
365 {
366 vvp_vector4_t*bits = static_cast<vvp_vector4_t*>
367 (vvp_get_context_item(context, context_idx_));
368 delete bits;
369 }
370 #endif
371
372 /*
373 * Continuous and forced assignments are not permitted on automatic
374 * variables. So we only expect to receive on port 0.
375 */
recv_vec4(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,vvp_context_t context)376 void vvp_fun_signal4_aa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
377 vvp_context_t context)
378 {
379 assert(ptr.port() == 0);
380 assert(context);
381
382 vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
383 (vvp_get_context_item(context, context_idx_));
384
385 if (!bits4->eeq(bit)) {
386 *bits4 = bit;
387 ptr.ptr()->send_vec4(*bits4, context);
388 }
389 }
390
recv_vec4_pv(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,unsigned base,unsigned wid,unsigned vwid,vvp_context_t context)391 void vvp_fun_signal4_aa::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
392 unsigned base, unsigned wid, unsigned vwid,
393 vvp_context_t context)
394 {
395 assert(ptr.port() == 0);
396 assert(bit.size() == wid);
397 assert(size_ == vwid);
398 assert(context);
399
400 vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
401 (vvp_get_context_item(context, context_idx_));
402
403 for (unsigned idx = 0 ; idx < wid ; idx += 1) {
404 if (base+idx >= bits4->size()) break;
405 bits4->set_bit(base+idx, bit.value(idx));
406 }
407 ptr.ptr()->send_vec4(*bits4, context);
408 }
409
value_size() const410 unsigned vvp_fun_signal4_aa::value_size() const
411 {
412 return size_;
413 }
414
value(unsigned idx) const415 vvp_bit4_t vvp_fun_signal4_aa::value(unsigned idx) const
416 {
417 vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
418 (vthread_get_rd_context_item(context_idx_));
419
420 return bits4->value(idx);
421 }
422
scalar_value(unsigned idx) const423 vvp_scalar_t vvp_fun_signal4_aa::scalar_value(unsigned idx) const
424 {
425 vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
426 (vthread_get_rd_context_item(context_idx_));
427
428 return vvp_scalar_t(bits4->value(idx), 6, 6);
429 }
430
vec4_value(vvp_vector4_t & val) const431 void vvp_fun_signal4_aa::vec4_value(vvp_vector4_t&val) const
432 {
433 vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
434 (vthread_get_rd_context_item(context_idx_));
435
436 val = *bits4;
437 }
438
vec4_unfiltered_value() const439 const vvp_vector4_t&vvp_fun_signal4_aa::vec4_unfiltered_value() const
440 {
441 vvp_vector4_t*bits4 = static_cast<vvp_vector4_t*>
442 (vthread_get_rd_context_item(context_idx_));
443
444 return *bits4;
445 }
446
operator delete(void *)447 void vvp_fun_signal4_aa::operator delete(void*)
448 {
449 assert(0);
450 }
451
452 /*
453 * Testing for equality, we want a bitwise test instead of an
454 * arithmetic test because we want to treat for example -0 different
455 * from +0.
456 */
bits_equal(double a,double b)457 bool bits_equal(double a, double b)
458 {
459 return memcmp(&a, &b, sizeof a) == 0;
460 }
461
vvp_fun_signal_real_sa()462 vvp_fun_signal_real_sa::vvp_fun_signal_real_sa()
463 {
464 bits_ = 0.0;
465 }
466
real_unfiltered_value() const467 double vvp_fun_signal_real_sa::real_unfiltered_value() const
468 {
469 return bits_;
470 }
471
recv_real(vvp_net_ptr_t ptr,double bit,vvp_context_t)472 void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit,
473 vvp_context_t)
474 {
475 switch (ptr.port()) {
476 case 0:
477 if (!continuous_assign_active_) {
478 if (needs_init_ || !bits_equal(bits_, bit)) {
479 bits_ = bit;
480 needs_init_ = false;
481 ptr.ptr()->send_real(bit, 0);
482 }
483 }
484 break;
485
486 case 1: // Continuous assign value
487 continuous_assign_active_ = true;
488 bits_ = bit;
489 ptr.ptr()->send_real(bit, 0);
490 break;
491
492 default:
493 fprintf(stderr, "Unsupported port type %u.\n", ptr.port());
494 assert(0);
495 break;
496 }
497 }
498
vvp_fun_signal_real_aa()499 vvp_fun_signal_real_aa::vvp_fun_signal_real_aa()
500 {
501 context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
502 }
503
~vvp_fun_signal_real_aa()504 vvp_fun_signal_real_aa::~vvp_fun_signal_real_aa()
505 {
506 assert(0);
507 }
508
alloc_instance(vvp_context_t context)509 void vvp_fun_signal_real_aa::alloc_instance(vvp_context_t context)
510 {
511 double*bits = new double;
512 vvp_set_context_item(context, context_idx_, bits);
513
514 *bits = 0.0;
515 }
516
reset_instance(vvp_context_t context)517 void vvp_fun_signal_real_aa::reset_instance(vvp_context_t context)
518 {
519 double*bits = static_cast<double*>
520 (vvp_get_context_item(context, context_idx_));
521
522 *bits = 0.0;
523 }
524
525 #ifdef CHECK_WITH_VALGRIND
free_instance(vvp_context_t context)526 void vvp_fun_signal_real_aa::free_instance(vvp_context_t context)
527 {
528 double*bits = static_cast<double*>
529 (vvp_get_context_item(context, context_idx_));
530 delete bits;
531 }
532 #endif
533
real_unfiltered_value() const534 double vvp_fun_signal_real_aa::real_unfiltered_value() const
535 {
536 double*bits = static_cast<double*>
537 (vthread_get_rd_context_item(context_idx_));
538
539 return *bits;
540 }
541
real_value() const542 double vvp_fun_signal_real_aa::real_value() const
543 {
544 return real_unfiltered_value();
545 }
546
recv_real(vvp_net_ptr_t ptr,double bit,vvp_context_t context)547 void vvp_fun_signal_real_aa::recv_real(vvp_net_ptr_t ptr, double bit,
548 vvp_context_t context)
549 {
550 assert(ptr.port() == 0);
551 assert(context);
552
553 double*bits = static_cast<double*>
554 (vvp_get_context_item(context, context_idx_));
555
556 if (!bits_equal(*bits,bit)) {
557 *bits = bit;
558 ptr.ptr()->send_real(bit, context);
559 }
560 }
561
value_size() const562 unsigned vvp_fun_signal_real_aa::value_size() const
563 {
564 assert(0);
565 return 1;
566 }
567
value(unsigned) const568 vvp_bit4_t vvp_fun_signal_real_aa::value(unsigned) const
569 {
570 assert(0);
571 return BIT4_X;
572 }
573
scalar_value(unsigned) const574 vvp_scalar_t vvp_fun_signal_real_aa::scalar_value(unsigned) const
575 {
576 assert(0);
577 return vvp_scalar_t();
578 }
579
vec4_value(vvp_vector4_t &) const580 void vvp_fun_signal_real_aa::vec4_value(vvp_vector4_t&) const
581 {
582 assert(0);
583 }
584
operator new(std::size_t size)585 void* vvp_fun_signal_real_aa::operator new(std::size_t size)
586 {
587 return vvp_net_fun_t::heap_.alloc(size);
588 }
589
operator delete(void *)590 void vvp_fun_signal_real_aa::operator delete(void*)
591 {
592 assert(0);
593 }
594
595
vvp_fun_signal_string_sa()596 vvp_fun_signal_string_sa::vvp_fun_signal_string_sa()
597 {
598 }
599
recv_string(vvp_net_ptr_t ptr,const std::string & bit,vvp_context_t)600 void vvp_fun_signal_string_sa::recv_string(vvp_net_ptr_t ptr, const std::string&bit,
601 vvp_context_t)
602 {
603 assert(ptr.port() == 0);
604
605 if (needs_init_ || value_ != bit) {
606 value_ = bit;
607 needs_init_ = false;
608
609 ptr.ptr()->send_string(bit, 0);
610 }
611 }
612
get_string() const613 const string& vvp_fun_signal_string_sa::get_string() const
614 {
615 return value_;
616 }
617
vvp_fun_signal_string_aa()618 vvp_fun_signal_string_aa::vvp_fun_signal_string_aa()
619 {
620 context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
621 }
622
~vvp_fun_signal_string_aa()623 vvp_fun_signal_string_aa::~vvp_fun_signal_string_aa()
624 {
625 assert(0);
626 }
627
alloc_instance(vvp_context_t context)628 void vvp_fun_signal_string_aa::alloc_instance(vvp_context_t context)
629 {
630 string*bits = new std::string;
631 vvp_set_context_item(context, context_idx_, bits);
632 *bits = "";
633 }
634
reset_instance(vvp_context_t context)635 void vvp_fun_signal_string_aa::reset_instance(vvp_context_t context)
636 {
637 string*bits = static_cast<std::string*>
638 (vvp_get_context_item(context, context_idx_));
639 *bits = "";
640 }
641
642 #ifdef CHECK_WITH_VALGRIND
free_instance(vvp_context_t context)643 void vvp_fun_signal_string_aa::free_instance(vvp_context_t context)
644 {
645 string*bits = static_cast<std::string*>
646 (vvp_get_context_item(context, context_idx_));
647 delete bits;
648 }
649 #endif
650
recv_string(vvp_net_ptr_t ptr,const std::string & bit,vvp_context_t context)651 void vvp_fun_signal_string_aa::recv_string(vvp_net_ptr_t ptr, const std::string&bit, vvp_context_t context)
652 {
653 assert(ptr.port() == 0);
654 assert(context);
655
656 string*bits = static_cast<std::string*>
657 (vvp_get_context_item(context, context_idx_));
658
659 if (*bits != bit) {
660 *bits = bit;
661 ptr.ptr()->send_string(bit, context);
662 }
663 }
664
value_size() const665 unsigned vvp_fun_signal_string_aa::value_size() const
666 {
667 assert(0);
668 return 1;
669 }
670
value(unsigned) const671 vvp_bit4_t vvp_fun_signal_string_aa::value(unsigned) const
672 {
673 assert(0);
674 return BIT4_X;
675 }
676
scalar_value(unsigned) const677 vvp_scalar_t vvp_fun_signal_string_aa::scalar_value(unsigned) const
678 {
679 assert(0);
680 return vvp_scalar_t();
681 }
682
vec4_value(vvp_vector4_t &) const683 void vvp_fun_signal_string_aa::vec4_value(vvp_vector4_t&) const
684 {
685 assert(0);
686 }
687
real_value() const688 double vvp_fun_signal_string_aa::real_value() const
689 {
690 assert(0);
691 return 0.0;
692 }
693
get_string() const694 const std::string& vvp_fun_signal_string_aa::get_string() const
695 {
696 string*bits = static_cast<std::string*>
697 (vthread_get_rd_context_item(context_idx_));
698
699 return *bits;
700 }
701
operator new(std::size_t size)702 void* vvp_fun_signal_string_aa::operator new(std::size_t size)
703 {
704 return vvp_net_fun_t::heap_.alloc(size);
705 }
706
operator delete(void *)707 void vvp_fun_signal_string_aa::operator delete(void*)
708 {
709 assert(0);
710 }
711
712 /* OBJECT signals */
713
vvp_fun_signal_object_sa(unsigned size)714 vvp_fun_signal_object_sa::vvp_fun_signal_object_sa(unsigned size)
715 : vvp_fun_signal_object(size)
716 {
717 }
718
719 #ifdef CHECK_WITH_VALGRIND
free_instance(vvp_context_t context)720 void vvp_fun_signal_object_aa::free_instance(vvp_context_t context)
721 {
722 vvp_object_t*bits = static_cast<vvp_object_t*>
723 (vvp_get_context_item(context, context_idx_));
724 delete bits;
725 }
726 #endif
727
recv_object(vvp_net_ptr_t ptr,vvp_object_t bit,vvp_context_t)728 void vvp_fun_signal_object_sa::recv_object(vvp_net_ptr_t ptr, vvp_object_t bit,
729 vvp_context_t)
730 {
731 assert(ptr.port() == 0);
732
733 if (needs_init_ || value_ != bit) {
734 value_ = bit;
735 needs_init_ = false;
736
737 ptr.ptr()->send_object(bit, 0);
738 }
739 }
740
get_object() const741 vvp_object_t vvp_fun_signal_object_sa::get_object() const
742 {
743 return value_;
744 }
745
vvp_fun_signal_object_aa(unsigned size)746 vvp_fun_signal_object_aa::vvp_fun_signal_object_aa(unsigned size)
747 : vvp_fun_signal_object(size)
748 {
749 context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
750 }
751
~vvp_fun_signal_object_aa()752 vvp_fun_signal_object_aa::~vvp_fun_signal_object_aa()
753 {
754 assert(0);
755 }
756
alloc_instance(vvp_context_t context)757 void vvp_fun_signal_object_aa::alloc_instance(vvp_context_t context)
758 {
759 vvp_object_t*bits = new vvp_object_t;
760 vvp_set_context_item(context, context_idx_, bits);
761 bits->reset();
762 }
763
reset_instance(vvp_context_t context)764 void vvp_fun_signal_object_aa::reset_instance(vvp_context_t context)
765 {
766 vvp_object_t*bits = static_cast<vvp_object_t*>
767 (vvp_get_context_item(context, context_idx_));
768 bits->reset();
769 }
770
get_object() const771 vvp_object_t vvp_fun_signal_object_aa::get_object() const
772 {
773 vvp_object_t*bits = static_cast<vvp_object_t*>
774 (vthread_get_rd_context_item(context_idx_));
775 return *bits;
776 }
777
recv_object(vvp_net_ptr_t ptr,vvp_object_t bit,vvp_context_t context)778 void vvp_fun_signal_object_aa::recv_object(vvp_net_ptr_t ptr, vvp_object_t bit,
779 vvp_context_t context)
780 {
781 assert(ptr.port() == 0);
782 assert(context);
783
784 vvp_object_t*bits = static_cast<vvp_object_t*>
785 (vvp_get_context_item(context, context_idx_));
786
787 if (*bits != bit) {
788 *bits = bit;
789 ptr.ptr()->send_object(bit, context);
790 }
791 }
792
value_size() const793 unsigned vvp_fun_signal_object_aa::value_size() const
794 {
795 return 1;
796 }
797
value(unsigned) const798 vvp_bit4_t vvp_fun_signal_object_aa::value(unsigned) const
799 {
800 assert(0);
801 return BIT4_X;
802 }
803
scalar_value(unsigned) const804 vvp_scalar_t vvp_fun_signal_object_aa::scalar_value(unsigned) const
805 {
806 assert(0);
807 return vvp_scalar_t();
808 }
809
vec4_value(vvp_vector4_t &) const810 void vvp_fun_signal_object_aa::vec4_value(vvp_vector4_t&) const
811 {
812 assert(0);
813 }
814
operator new(std::size_t size)815 void* vvp_fun_signal_object_aa::operator new(std::size_t size)
816 {
817 return vvp_net_fun_t::heap_.alloc(size);
818 }
819
operator delete(void *)820 void vvp_fun_signal_object_aa::operator delete(void*)
821 {
822 assert(0);
823 }
824
825 /* **** */
826
vvp_fun_force()827 vvp_fun_force::vvp_fun_force()
828 {
829 }
830
~vvp_fun_force()831 vvp_fun_force::~vvp_fun_force()
832 {
833 }
834
recv_vec4(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,vvp_context_t)835 void vvp_fun_force::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
836 vvp_context_t)
837 {
838 assert(ptr.port() == 0);
839 vvp_net_t*net = ptr.ptr();
840
841 vvp_net_t*dst = net->port[3].ptr();
842 assert(dst->fil);
843
844 dst->force_vec4(coerce_to_width(bit, dst->fil->filter_size()), vvp_vector2_t(vvp_vector2_t::FILL1, dst->fil->filter_size()));
845 }
846
recv_real(vvp_net_ptr_t ptr,double bit,vvp_context_t)847 void vvp_fun_force::recv_real(vvp_net_ptr_t ptr, double bit, vvp_context_t)
848 {
849 assert(ptr.port() == 0);
850 vvp_net_t*net = ptr.ptr();
851 vvp_net_t*dst = net->port[3].ptr();
852 dst->force_real(bit, vvp_vector2_t(vvp_vector2_t::FILL1, 1));
853 }
854
vvp_wire_base()855 vvp_wire_base::vvp_wire_base()
856 {
857 }
858
~vvp_wire_base()859 vvp_wire_base::~vvp_wire_base()
860 {
861 }
862
driven_value(unsigned) const863 vvp_bit4_t vvp_wire_base::driven_value(unsigned) const
864 {
865 assert(0);
866 return BIT4_X;
867 }
868
is_forced(unsigned) const869 bool vvp_wire_base::is_forced(unsigned) const
870 {
871 assert(0);
872 return false;
873 }
874
vvp_wire_vec4(unsigned wid,vvp_bit4_t init)875 vvp_wire_vec4::vvp_wire_vec4(unsigned wid, vvp_bit4_t init)
876 : bits4_(wid, init)
877 {
878 needs_init_ = true;
879 }
880
filter_vec4(const vvp_vector4_t & bit,vvp_vector4_t & rep,unsigned base,unsigned vwid)881 vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep,
882 unsigned base, unsigned vwid)
883 {
884 // Special case! the input bit is 0 wid. Interpret this as a
885 // vector of BIT4_X to match the width of the bits4_ vector.
886 // FIXME! This is a hack to work around some buggy gate
887 // implementations! This should be removed!
888 if (base==0 && vwid==0) {
889 vvp_vector4_t tmp (bits4_.size(), BIT4_X);
890 if (bits4_ .eeq(tmp) && !needs_init_) return STOP;
891 bits4_ = tmp;
892 needs_init_ = false;
893 return filter_mask_(tmp, force4_, rep, 0);
894 }
895
896 if (vwid != bits4_.size()) {
897 cerr << "Internal error: Input vector expected width="
898 << bits4_.size() << ", got "
899 << "bit=" << bit << ", base=" << base << ", vwid=" << vwid
900 << endl;
901 }
902 assert(bits4_.size() == vwid);
903
904 // Keep track of the value being driven from this net, even if
905 // it is not ultimately what survives the force filter.
906 if (base==0 && bit.size()==vwid) {
907 if (bits4_ .eeq( bit ) && !needs_init_) return STOP;
908 bits4_ = bit;
909 } else {
910 bool rc = bits4_.set_vec(base, bit);
911 if (rc == false && !needs_init_) return STOP;
912 }
913
914 needs_init_ = false;
915 return filter_mask_(bit, force4_, rep, base);
916 }
917
filter_vec8(const vvp_vector8_t & bit,vvp_vector8_t & rep,unsigned base,unsigned vwid)918 vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec8(const vvp_vector8_t&bit,
919 vvp_vector8_t&rep,
920 unsigned base,
921 unsigned vwid)
922 {
923 assert(bits4_.size() == vwid);
924
925 // Keep track of the value being driven from this net, even if
926 // it is not ultimately what survives the force filter.
927 vvp_vector4_t bit4 (reduce4(bit));
928 if (base==0 && bit4.size()==vwid) {
929 if (bits4_ .eeq( bit4 ) && !needs_init_) return STOP;
930 bits4_ = bit4;
931 } else {
932 bool rc = bits4_.set_vec(base, bit4);
933 if (rc == false && !needs_init_) return STOP;
934 }
935
936 needs_init_ = false;
937 return filter_mask_(bit, vvp_vector8_t(force4_,6,6), rep, base);
938 }
939
filter_size() const940 unsigned vvp_wire_vec4::filter_size() const
941 {
942 return bits4_.size();
943 }
944
force_fil_vec4(const vvp_vector4_t & val,const vvp_vector2_t & mask)945 void vvp_wire_vec4::force_fil_vec4(const vvp_vector4_t&val, const vvp_vector2_t&mask)
946 {
947 force_mask(mask);
948
949 if (force4_.size() == 0) {
950 force4_ = val;
951 } else {
952 for (unsigned idx = 0; idx < mask.size() ; idx += 1) {
953 if (mask.value(idx) == 0)
954 continue;
955
956 force4_.set_bit(idx, val.value(idx));
957 }
958 }
959 run_vpi_callbacks();
960 }
961
force_fil_vec8(const vvp_vector8_t &,const vvp_vector2_t &)962 void vvp_wire_vec4::force_fil_vec8(const vvp_vector8_t&, const vvp_vector2_t&)
963 {
964 assert(0);
965 }
966
force_fil_real(double,const vvp_vector2_t &)967 void vvp_wire_vec4::force_fil_real(double, const vvp_vector2_t&)
968 {
969 assert(0);
970 }
971
release(vvp_net_ptr_t ptr,bool net_flag)972 void vvp_wire_vec4::release(vvp_net_ptr_t ptr, bool net_flag)
973 {
974 vvp_vector2_t mask (vvp_vector2_t::FILL1, bits4_.size());
975 if (net_flag) {
976 // Wires revert to their unforced value after release.
977 release_mask(mask);
978 needs_init_ = ! force4_ .eeq(bits4_);
979 ptr.ptr()->send_vec4(bits4_, 0);
980 run_vpi_callbacks();
981 } else {
982 // Variables keep the current value.
983 vvp_vector4_t res (bits4_.size());
984 for (unsigned idx=0; idx<bits4_.size(); idx += 1)
985 res.set_bit(idx,value(idx));
986 release_mask(mask);
987 ptr.ptr()->fun->recv_vec4(ptr, res, 0);
988 }
989 }
990
release_pv(vvp_net_ptr_t ptr,unsigned base,unsigned wid,bool net_flag)991 void vvp_wire_vec4::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag)
992 {
993 assert(bits4_.size() >= base + wid);
994
995 vvp_vector2_t mask (vvp_vector2_t::FILL0, bits4_.size());
996 for (unsigned idx = 0 ; idx < wid ; idx += 1)
997 mask.set_bit(base+idx, 1);
998
999 if (net_flag) {
1000 // Wires revert to their unforced value after release.
1001 release_mask(mask);
1002 needs_init_ = ! force4_.subvalue(base,wid) .eeq(bits4_.subvalue(base,wid));
1003 ptr.ptr()->send_vec4_pv(bits4_.subvalue(base,wid),
1004 base, wid, bits4_.size(), 0);
1005 run_vpi_callbacks();
1006 } else {
1007 // Variables keep the current value.
1008 vvp_vector4_t res (wid);
1009 for (unsigned idx=0; idx<wid; idx += 1)
1010 res.set_bit(idx,value(base+idx));
1011 release_mask(mask);
1012 ptr.ptr()->fun->recv_vec4_pv(ptr, res, base, wid, bits4_.size(), 0);
1013 }
1014 }
1015
value_size() const1016 unsigned vvp_wire_vec4::value_size() const
1017 {
1018 return bits4_.size();
1019 }
1020
filtered_value_(unsigned idx) const1021 vvp_bit4_t vvp_wire_vec4::filtered_value_(unsigned idx) const
1022 {
1023 if (test_force_mask(idx))
1024 return force4_.value(idx);
1025 else
1026 return bits4_.value(idx);
1027 }
1028
value(unsigned idx) const1029 vvp_bit4_t vvp_wire_vec4::value(unsigned idx) const
1030 {
1031 return filtered_value_(idx);
1032 }
1033
scalar_value(unsigned idx) const1034 vvp_scalar_t vvp_wire_vec4::scalar_value(unsigned idx) const
1035 {
1036 return vvp_scalar_t(value(idx),6,6);
1037 }
1038
vec4_value(vvp_vector4_t & val) const1039 void vvp_wire_vec4::vec4_value(vvp_vector4_t&val) const
1040 {
1041 val = bits4_;
1042 if (test_force_mask_is_zero())
1043 return;
1044
1045 for (unsigned idx = 0 ; idx < bits4_.size() ; idx += 1)
1046 val.set_bit(idx, filtered_value_(idx));
1047 }
1048
driven_value(unsigned idx) const1049 vvp_bit4_t vvp_wire_vec4::driven_value(unsigned idx) const
1050 {
1051 return bits4_.value(idx);
1052 }
1053
is_forced(unsigned idx) const1054 bool vvp_wire_vec4::is_forced(unsigned idx) const
1055 {
1056 return test_force_mask(idx);
1057 }
1058
vvp_wire_vec8(unsigned wid)1059 vvp_wire_vec8::vvp_wire_vec8(unsigned wid)
1060 : bits8_(wid)
1061 {
1062 needs_init_ = true;
1063 }
1064
filter_vec4(const vvp_vector4_t & bit,vvp_vector4_t & rep,unsigned base,unsigned vwid)1065 vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec4(const vvp_vector4_t&bit,
1066 vvp_vector4_t&rep,
1067 unsigned base,
1068 unsigned vwid)
1069 {
1070 // For now there is no support for a non-zero base.
1071 assert(0 == base);
1072 assert(bits8_.size() == vwid);
1073 assert(bits8_.size() == bit.size());
1074 // QUESTION: Is it really correct to propagate a vec4 if this
1075 // is a vec8 node? In fact, it is really possible for a vec4
1076 // value to get through to a vec8 filter?
1077 vvp_vector8_t rep8;
1078 prop_t rc = filter_vec8(vvp_vector8_t(bit,6,6), rep8, 0, vwid);
1079 if (rc == REPL)
1080 rep = reduce4(rep8);
1081
1082 needs_init_ = false;
1083 return rc;
1084 }
1085
filter_vec8(const vvp_vector8_t & bit,vvp_vector8_t & rep,unsigned base,unsigned vwid)1086 vvp_net_fil_t::prop_t vvp_wire_vec8::filter_vec8(const vvp_vector8_t&bit, vvp_vector8_t&rep, unsigned base, unsigned vwid)
1087 {
1088 assert(vwid == bits8_.size());
1089 // Keep track of the value being driven from this net, even if
1090 // it is not ultimately what survives the force filter.
1091 if (base==0 && bit.size()==vwid) {
1092 bits8_ = bit;
1093 } else {
1094 if (bits8_.size() == 0)
1095 bits8_ = vvp_vector8_t(vwid);
1096 assert(bits8_.size() == vwid);
1097 bits8_.set_vec(base, bit);
1098 }
1099 needs_init_ = false;
1100 return filter_mask_(bit, force8_, rep, base);
1101 }
1102
filter_input_vec8(const vvp_vector8_t & bit,vvp_vector8_t & rep) const1103 vvp_net_fil_t::prop_t vvp_wire_vec8::filter_input_vec8(const vvp_vector8_t&bit, vvp_vector8_t&rep) const
1104 {
1105 return filter_input_mask_(bit, force8_, rep);
1106 }
1107
filter_size() const1108 unsigned vvp_wire_vec8::filter_size() const
1109 {
1110 return bits8_.size();
1111 }
1112
force_fil_vec4(const vvp_vector4_t & val,const vvp_vector2_t & mask)1113 void vvp_wire_vec8::force_fil_vec4(const vvp_vector4_t&val, const vvp_vector2_t&mask)
1114 {
1115 force_fil_vec8(vvp_vector8_t(val,6,6), mask);
1116 }
1117
force_fil_vec8(const vvp_vector8_t & val,const vvp_vector2_t & mask)1118 void vvp_wire_vec8::force_fil_vec8(const vvp_vector8_t&val, const vvp_vector2_t&mask)
1119 {
1120 force_mask(mask);
1121
1122 if (force8_.size() == 0) {
1123 force8_ = val;
1124 } else {
1125 for (unsigned idx = 0; idx < mask.size() ; idx += 1) {
1126 if (mask.value(idx) == 0)
1127 continue;
1128
1129 force8_.set_bit(idx, val.value(idx));
1130 }
1131 }
1132 run_vpi_callbacks();
1133 }
1134
force_fil_real(double,const vvp_vector2_t &)1135 void vvp_wire_vec8::force_fil_real(double, const vvp_vector2_t&)
1136 {
1137 assert(0);
1138 }
1139
release(vvp_net_ptr_t ptr,bool net_flag)1140 void vvp_wire_vec8::release(vvp_net_ptr_t ptr, bool net_flag)
1141 {
1142 // Wires revert to their unforced value after release.
1143 vvp_vector2_t mask (vvp_vector2_t::FILL1, bits8_.size());
1144 release_mask(mask);
1145 if (net_flag) {
1146 needs_init_ = !force8_ .eeq(bits8_);
1147 ptr.ptr()->send_vec8(bits8_);
1148 } else {
1149 // Variable do not know about strength so this should not be able
1150 // to happen. If for some reason it can then it should not be too
1151 // hard to fix this code like was done for vvp_wire_vec4 above.
1152 assert(0);
1153 // ptr.ptr()->fun->recv_vec8(ptr, force8_);
1154 }
1155 }
1156
release_pv(vvp_net_ptr_t ptr,unsigned base,unsigned wid,bool net_flag)1157 void vvp_wire_vec8::release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag)
1158 {
1159 assert(bits8_.size() >= base + wid);
1160
1161 vvp_vector2_t mask (vvp_vector2_t::FILL0, bits8_.size());
1162 for (unsigned idx = 0 ; idx < wid ; idx += 1)
1163 mask.set_bit(base+idx, 1);
1164
1165 release_mask(mask);
1166
1167 if (net_flag) {
1168 needs_init_ = !force8_.subvalue(base,wid) .eeq((bits8_.subvalue(base,wid)));
1169 ptr.ptr()->send_vec8_pv(bits8_.subvalue(base,wid),
1170 base, wid, bits8_.size());
1171 run_vpi_callbacks();
1172 } else {
1173 // Variable do not know about strength so this should not be able
1174 // to happen. If for some reason it can then it should not be too
1175 // hard to fix this code like was done for vvp_wire_vec4 above.
1176 assert(0);
1177 // ptr.ptr()->fun->recv_vec8_pv(ptr, force8_.subvalue(base,wid),
1178 // base, wid, force8_.size());
1179 }
1180 }
1181
value_size() const1182 unsigned vvp_wire_vec8::value_size() const
1183 {
1184 return bits8_.size();
1185 }
1186
filtered_value_(unsigned idx) const1187 vvp_scalar_t vvp_wire_vec8::filtered_value_(unsigned idx) const
1188 {
1189 if (test_force_mask(idx))
1190 return force8_.value(idx);
1191 else
1192 return bits8_.value(idx);
1193 }
1194
value(unsigned idx) const1195 vvp_bit4_t vvp_wire_vec8::value(unsigned idx) const
1196 {
1197 return filtered_value_(idx).value();
1198 }
1199
scalar_value(unsigned idx) const1200 vvp_scalar_t vvp_wire_vec8::scalar_value(unsigned idx) const
1201 {
1202 return filtered_value_(idx);
1203 }
1204
vec8_value() const1205 vvp_vector8_t vvp_wire_vec8::vec8_value() const
1206 {
1207 vvp_vector8_t tmp = bits8_;
1208 for (unsigned idx = 0 ; idx < bits8_.size() ; idx += 1)
1209 tmp.set_bit(idx, filtered_value_(idx));
1210 return tmp;
1211 }
1212
vec4_value(vvp_vector4_t & val) const1213 void vvp_wire_vec8::vec4_value(vvp_vector4_t&val) const
1214 {
1215 val = reduce4(vec8_value());
1216 }
1217
driven_value(unsigned idx) const1218 vvp_bit4_t vvp_wire_vec8::driven_value(unsigned idx) const
1219 {
1220 return bits8_.value(idx).value();
1221 }
1222
is_forced(unsigned idx) const1223 bool vvp_wire_vec8::is_forced(unsigned idx) const
1224 {
1225 return test_force_mask(idx);
1226 }
1227
vvp_wire_real()1228 vvp_wire_real::vvp_wire_real()
1229 : bit_(0.0), force_(0.0)
1230 {
1231 }
1232
filter_real(double & bit)1233 vvp_net_fil_t::prop_t vvp_wire_real::filter_real(double&bit)
1234 {
1235 bit_ = bit;
1236 return filter_mask_(bit, force_);
1237 }
1238
filter_size() const1239 unsigned vvp_wire_real::filter_size() const
1240 {
1241 assert(0);
1242 return 0;
1243 }
1244
force_fil_vec4(const vvp_vector4_t &,const vvp_vector2_t &)1245 void vvp_wire_real::force_fil_vec4(const vvp_vector4_t&, const vvp_vector2_t&)
1246 {
1247 assert(0);
1248 }
1249
force_fil_vec8(const vvp_vector8_t &,const vvp_vector2_t &)1250 void vvp_wire_real::force_fil_vec8(const vvp_vector8_t&, const vvp_vector2_t&)
1251 {
1252 assert(0);
1253 }
1254
force_fil_real(double val,const vvp_vector2_t & mask)1255 void vvp_wire_real::force_fil_real(double val, const vvp_vector2_t&mask)
1256 {
1257 force_mask(mask);
1258 if (mask.value(0))
1259 force_ = val;
1260
1261 run_vpi_callbacks();
1262 }
1263
release(vvp_net_ptr_t ptr,bool net_flag)1264 void vvp_wire_real::release(vvp_net_ptr_t ptr, bool net_flag)
1265 {
1266 vvp_vector2_t mask (vvp_vector2_t::FILL1, 1);
1267 if (net_flag) {
1268 // Wires revert to their unforced value after release.
1269 release_mask(mask);
1270 ptr.ptr()->send_real(bit_, 0);
1271 } else {
1272 // Variables keep the current value.
1273 double res = real_value();
1274 release_mask(mask);
1275 ptr.ptr()->fun->recv_real(ptr, res, 0);
1276 }
1277 }
1278
release_pv(vvp_net_ptr_t,unsigned,unsigned,bool)1279 void vvp_wire_real::release_pv(vvp_net_ptr_t, unsigned, unsigned, bool)
1280 {
1281 assert(0);
1282 #if 0
1283 // A real is a single value. If for some reason this part release
1284 // can happen the following code should work correctly (requires
1285 // a base of 0 and a width of 1).
1286 vvp_vector2_t mask (vvp_vector2_t::FILL1, 1);
1287 assert(base == 0 && wid == 1);
1288
1289 if (net_flag) {
1290 // Wires revert to their unforced value after release.
1291 release_mask(mask);
1292 ptr.ptr()->send_real(bit_, 0);
1293 } else {
1294 // Variables keep the current value.
1295 double res = real_value();
1296 release_mask(mask);
1297 ptr.ptr()->fun->recv_real(ptr, res, 0);
1298 }
1299 #endif
1300 }
1301
value_size() const1302 unsigned vvp_wire_real::value_size() const
1303 {
1304 assert(0);
1305 return 1;
1306 }
1307
value(unsigned) const1308 vvp_bit4_t vvp_wire_real::value(unsigned) const
1309 {
1310 assert(0);
1311 return BIT4_X;
1312 }
1313
scalar_value(unsigned) const1314 vvp_scalar_t vvp_wire_real::scalar_value(unsigned) const
1315 {
1316 assert(0);
1317 return vvp_scalar_t();
1318 }
1319
vec4_value(vvp_vector4_t &) const1320 void vvp_wire_real::vec4_value(vvp_vector4_t&) const
1321 {
1322 assert(0);
1323 }
1324
real_value() const1325 double vvp_wire_real::real_value() const
1326 {
1327 if (test_force_mask(0))
1328 return force_;
1329 else
1330 return bit_;
1331 }
1332
1333 #if 0
1334 vvp_wire_string::vvp_wire_string()
1335 {
1336 }
1337
1338 unsigned vvp_wire_string::filter_size() const
1339 {
1340 assert(0);
1341 return 0;
1342 }
1343
1344 void vvp_wire_string::force_fil_vec4(const vvp_vector4_t&, const vvp_vector2_t&)
1345 {
1346 assert(0);
1347 }
1348 void vvp_wire_string::force_fil_vec8(const vvp_vector8_t&, const vvp_vector2_t&)
1349 {
1350 assert(0);
1351 }
1352 void vvp_wire_string::force_fil_real(double, const vvp_vector2_t&)
1353 {
1354 assert(0);
1355 }
1356
1357 void vvp_wire_string::release(vvp_net_ptr_t ptr, bool net_flag)
1358 {
1359 assert(0);
1360 }
1361
1362 void vvp_wire_string::release_pv(vvp_net_ptr_t, unsigned, unsigned, bool)
1363 {
1364 assert(0);
1365 }
1366
1367 unsigned vvp_wire_string::value_size() const
1368 {
1369 assert(0);
1370 return 1;
1371 }
1372
1373 vvp_bit4_t vvp_wire_string::value(unsigned) const
1374 {
1375 assert(0);
1376 return BIT4_X;
1377 }
1378
1379 vvp_scalar_t vvp_wire_string::scalar_value(unsigned) const
1380 {
1381 assert(0);
1382 return vvp_scalar_t();
1383 }
1384
1385 void vvp_wire_string::vec4_value(vvp_vector4_t&) const
1386 {
1387 assert(0);
1388 }
1389
1390 double vvp_wire_string::real_value() const
1391 {
1392 assert(0);
1393 return 0.0;
1394 }
1395 #endif
1396