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