1 /*
2  * Copyright (c) 2004-2018 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  "vvp_island.h"
24 # include  "vpi_priv.h"
25 # include  "resolv.h"
26 # include  "schedule.h"
27 # include  "statistics.h"
28 # include  <cstdio>
29 # include  <cstring>
30 # include  <cstdlib>
31 # include  <iostream>
32 # include  <typeinfo>
33 # include  <climits>
34 # include  <cmath>
35 # include  <cassert>
36 #ifdef CHECK_WITH_VALGRIND
37 # include  <valgrind/memcheck.h>
38 # include  <map>
39 # include  "sfunc.h"
40 # include  "udp.h"
41 # include  "ivl_alloc.h"
42 #endif
43 
44 /* This is the size of an unsigned long in bits. This is just a
45    convenience macro. */
46 # define CPU_WORD_BITS (8*sizeof(unsigned long))
47 # define TOP_BIT (1UL << (CPU_WORD_BITS-1))
48 
49 permaheap vvp_net_fun_t::heap_;
50 permaheap vvp_net_fil_t::heap_;
51 
52 // Allocate around 1Megabyte/chunk.
53 static const size_t VVP_NET_CHUNK = 1024*1024/sizeof(vvp_net_t);
54 static vvp_net_t*vvp_net_alloc_table = NULL;
55 #ifdef CHECK_WITH_VALGRIND
56 static vvp_net_t **vvp_net_pool = NULL;
57 static unsigned vvp_net_pool_count = 0;
58 #endif
59 static size_t vvp_net_alloc_remaining = 0;
60 // For statistics, count the vvp_nets allocated and the bytes of alloc
61 // chunks allocated.
62 unsigned long count_vvp_nets = 0;
63 size_t size_vvp_nets = 0;
64 
operator new(size_t size)65 void* vvp_net_t::operator new (size_t size)
66 {
67       assert(size == sizeof(vvp_net_t));
68       if (vvp_net_alloc_remaining == 0) {
69 	    vvp_net_alloc_table = ::new vvp_net_t[VVP_NET_CHUNK];
70 	    vvp_net_alloc_remaining = VVP_NET_CHUNK;
71 	    size_vvp_nets += size*VVP_NET_CHUNK;
72 #ifdef CHECK_WITH_VALGRIND
73 	    VALGRIND_MAKE_MEM_NOACCESS(vvp_net_alloc_table, size*VVP_NET_CHUNK);
74 	    VALGRIND_CREATE_MEMPOOL(vvp_net_alloc_table, 0, 0);
75 	    vvp_net_pool_count += 1;
76 	    vvp_net_pool = (vvp_net_t **) realloc(vvp_net_pool,
77 	                   vvp_net_pool_count*sizeof(vvp_net_t **));
78 	    vvp_net_pool[vvp_net_pool_count-1] = vvp_net_alloc_table;
79 #endif
80       }
81 
82       vvp_net_t*return_this = vvp_net_alloc_table;
83 #ifdef CHECK_WITH_VALGRIND
84       VALGRIND_MEMPOOL_ALLOC(vvp_net_pool[vvp_net_pool_count-1],
85                              return_this, size);
86       return_this->pool = vvp_net_pool[vvp_net_pool_count-1];
87 #endif
88       vvp_net_alloc_table += 1;
89       vvp_net_alloc_remaining -= 1;
90       count_vvp_nets += 1;
91       return return_this;
92 }
93 
94 #ifdef CHECK_WITH_VALGRIND
95 static map<vvp_net_t*, bool> vvp_net_map;
96 static map<sfunc_core*, bool> sfunc_map;
97 static map<vvp_udp_fun_core*, bool> udp_map;
98 static map<resolv_core*, bool> resolv_map;
99 static vvp_net_t **local_net_pool = 0;
100 static unsigned local_net_pool_count = 0;
101 
pool_local_net(vvp_net_t * net)102 void pool_local_net(vvp_net_t*net)
103 {
104       local_net_pool_count += 1;
105       local_net_pool = (vvp_net_t **) realloc(local_net_pool,
106                        local_net_pool_count*sizeof(vvp_net_t **));
107       local_net_pool[local_net_pool_count-1] = net;
108 }
109 
vvp_net_delete(vvp_net_t * item)110 void vvp_net_delete(vvp_net_t *item)
111 {
112       vvp_net_map[item] = true;
113       if (sfunc_core*tmp = dynamic_cast<sfunc_core*> (item->fun)) {
114 	    sfunc_map[tmp] = true;
115       }
116       if (vvp_udp_fun_core*tmp = dynamic_cast<vvp_udp_fun_core*> (item->fun)) {
117 	    udp_map[tmp] = true;
118       }
119       if (resolv_core*tmp = dynamic_cast<resolv_core*> (item->fun)) {
120 	    resolv_map[tmp] = true;
121       }
122 	/* Only delete static object variables. */
123       if (vvp_fun_signal_object_sa*tmp = dynamic_cast<vvp_fun_signal_object_sa*> (item->fun)) {
124 	    delete tmp;
125       }
126 	/* Only delete static string variables. */
127       if (vvp_fun_signal_string_sa*tmp = dynamic_cast<vvp_fun_signal_string_sa*> (item->fun)) {
128 	    delete tmp;
129       }
130 }
131 
vvp_net_pool_delete()132 void vvp_net_pool_delete()
133 {
134       unsigned long vvp_nets_del = 0;
135 
136       for (unsigned idx = 0; idx < local_net_pool_count; idx += 1) {
137 	    vvp_net_delete(local_net_pool[idx]);
138       }
139       free(local_net_pool);
140       local_net_pool = 0;
141       local_net_pool_count = 0;
142 
143       map<vvp_net_t*, bool>::iterator iter;
144       for (iter = vvp_net_map.begin(); iter != vvp_net_map.end(); ++ iter ) {
145 	    vvp_nets_del += 1;
146 	    VALGRIND_MEMPOOL_FREE(iter->first->pool, iter->first);
147       }
148       vvp_net_map.clear();
149 
150       map<sfunc_core*, bool>::iterator siter;
151       for (siter = sfunc_map.begin(); siter != sfunc_map.end(); ++ siter ) {
152 	    delete siter->first;
153       }
154       sfunc_map.clear();
155 
156       map<vvp_udp_fun_core*, bool>::iterator uiter;
157       for (uiter = udp_map.begin(); uiter != udp_map.end(); ++ uiter ) {
158 	    delete uiter->first;
159       }
160       udp_map.clear();
161 
162       map<resolv_core*, bool>::iterator riter;
163       for (riter = resolv_map.begin(); riter != resolv_map.end(); ++ riter ) {
164 	    delete riter->first;
165       }
166       resolv_map.clear();
167 
168       if (RUNNING_ON_VALGRIND && (vvp_nets_del != count_vvp_nets)) {
169 	    fflush(NULL);
170 	    VALGRIND_PRINTF("Error: vvp missed deleting %ld of %lu net(s).",
171 	                    (long) count_vvp_nets - vvp_nets_del,
172 	                    count_vvp_nets);
173       }
174 
175       for (unsigned idx = 0; idx < vvp_net_pool_count; idx += 1) {
176 	    VALGRIND_DESTROY_MEMPOOL(vvp_net_pool[idx]);
177 	    ::delete [] vvp_net_pool[idx];
178       }
179       free(vvp_net_pool);
180       vvp_net_pool = NULL;
181       vvp_net_pool_count = 0;
182 }
183 #endif
184 
operator delete(void *)185 void vvp_net_t::operator delete(void*)
186 {
187       assert(0);
188 }
189 
vvp_net_t()190 vvp_net_t::vvp_net_t()
191 : out_(vvp_net_ptr_t(0,0))
192 {
193       fun = 0;
194       fil = 0;
195 }
196 
link(vvp_net_ptr_t port_to_link)197 void vvp_net_t::link(vvp_net_ptr_t port_to_link)
198 {
199       vvp_net_t*net = port_to_link.ptr();
200       net->port[port_to_link.port()] = out_;
201       out_ = port_to_link;
202 }
203 
204 /*
205  * Unlink a ptr object from the driver. The input is the driver in the
206  * form of a vvp_net_t pointer. The .out member of that object is the
207  * driver. The dst_ptr argument is the receiver pin to be located and
208  * removed from the fan-out list.
209  */
unlink(vvp_net_ptr_t dst_ptr)210 void vvp_net_t::unlink(vvp_net_ptr_t dst_ptr)
211 {
212       vvp_net_t*net = dst_ptr.ptr();
213       unsigned net_port = dst_ptr.port();
214 
215       if (out_ == dst_ptr) {
216 	      /* If the drive fan-out list starts with this pointer,
217 		 then the unlink is easy. Pull the list forward. */
218 	    out_ = net->port[net_port];
219       } else if (! out_.nil()) {
220 	      /* Scan the linked list, looking for the net_ptr_t
221 		 pointer *before* the one we wish to remove. */
222 	    vvp_net_ptr_t cur = out_;
223 	    assert(!cur.nil());
224 	    vvp_net_t*cur_net = cur.ptr();
225 	    unsigned cur_port = cur.port();
226 	    while (cur_net && cur_net->port[cur_port] != dst_ptr) {
227 		  cur = cur_net->port[cur_port];
228 		  cur_net = cur.ptr();
229 		  cur_port = cur.port();
230 	    }
231 	      /* Unlink. */
232 	    if (cur_net) cur_net->port[cur_port] = net->port[net_port];
233       }
234 
235       net->port[net_port] = vvp_net_ptr_t(0,0);
236 }
237 
count_drivers(unsigned idx,unsigned counts[4])238 void vvp_net_t::count_drivers(unsigned idx, unsigned counts[4])
239 {
240       counts[0] = 0;
241       counts[1] = 0;
242       counts[2] = 0;
243       counts[3] = 0;
244 
245         /* $countdrivers can only be used on wires. */
246       vvp_wire_base*wire=dynamic_cast<vvp_wire_base*>(fil);
247       assert(wire);
248 
249       if (wire->is_forced(idx))
250             counts[3] = 1;
251 
252         /* If the net has multiple drivers, we need to interrogate the
253            resolver network to get the driven values. */
254       if (resolv_core*resolver = dynamic_cast<resolv_core*>(fun)) {
255             resolver->count_drivers(idx, counts);
256             return;
257       }
258       if (vvp_island_port*resolver = dynamic_cast<vvp_island_port*>(fun)) {
259             resolver->count_drivers(idx, counts);
260             return;
261       }
262 
263         /* If the functor is not a resolver, there is only one driver, so
264            we can just interrogate the filter to get the driven value. */
265       update_driver_counts(wire->driven_value(idx), counts);
266 }
267 
operator delete(void *)268 void vvp_net_fun_t::operator delete(void*)
269 {
270 #ifndef CHECK_WITH_VALGRIND
271       assert(0);
272 #endif
273 }
274 
275 
vvp_net_fil_t()276 vvp_net_fil_t::vvp_net_fil_t()
277 {
278       force_link_ = 0;
279       force_propagate_ = false;
280       count_filters += 1;
281 }
282 
~vvp_net_fil_t()283 vvp_net_fil_t::~vvp_net_fil_t()
284 {
285       assert(force_link_ == 0);
286 }
287 
filter_vec4(const vvp_vector4_t &,vvp_vector4_t &,unsigned,unsigned)288 vvp_net_fil_t::prop_t vvp_net_fil_t::filter_vec4(const vvp_vector4_t&,
289                                                  vvp_vector4_t&,
290                                                  unsigned, unsigned)
291 {
292       return PROP;
293 }
294 
filter_vec8(const vvp_vector8_t &,vvp_vector8_t &,unsigned,unsigned)295 vvp_net_fil_t::prop_t vvp_net_fil_t::filter_vec8(const vvp_vector8_t&,
296                                                  vvp_vector8_t&,
297                                                  unsigned, unsigned)
298 {
299       return PROP;
300 }
301 
filter_real(double &)302 vvp_net_fil_t::prop_t vvp_net_fil_t::filter_real(double&)
303 {
304       return PROP;
305 }
306 
filter_long(long &)307 vvp_net_fil_t::prop_t vvp_net_fil_t::filter_long(long&)
308 {
309       return PROP;
310 }
311 
filter_string(const string &)312 vvp_net_fil_t::prop_t vvp_net_fil_t::filter_string(const string&)
313 {
314       return PROP;
315 }
316 
filter_object(vvp_object_t &)317 vvp_net_fil_t::prop_t vvp_net_fil_t::filter_object(vvp_object_t&)
318 {
319       return PROP;
320 }
321 
force_mask(const vvp_vector2_t & mask)322 void vvp_net_fil_t::force_mask(const vvp_vector2_t&mask)
323 {
324       if (force_mask_.size() == 0)
325 	    force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, mask.size());
326 
327       assert(force_mask_.size() == mask.size());
328       for (unsigned idx = 0 ; idx < mask.size() ; idx += 1) {
329 	    if (mask.value(idx) == 0)
330 		  continue;
331 
332 	    force_mask_.set_bit(idx, 1);
333 	    force_propagate_ = true;
334       }
335 }
336 
release_mask(const vvp_vector2_t & mask)337 void vvp_net_fil_t::release_mask(const vvp_vector2_t&mask)
338 {
339       if (force_mask_.size() == 0)
340 	    return;
341 
342       assert(force_mask_.size() == mask.size());
343       for (unsigned idx = 0 ; idx < mask.size() ; idx += 1) {
344 	    if (mask.value(idx))
345 		  force_mask_.set_bit(idx, 0);
346       }
347 
348       if (force_mask_.is_zero())
349 	    force_mask_ = vvp_vector2_t();
350 }
351 
352 /*
353  * Force link/unlink uses a thunk vvp_net_t node with a vvp_fun_force
354  * functor to translate the net values to filter commands. The ports
355  * of this vvp_net_t object are use a little differently:
356  *
357  *     port[3]  - Point to the destination node where the forced
358  *                filter resides.
359  *
360  *     port[2]  - Point to the input node that drives port[0] for use
361  *                by the unlink method.
362  *
363  *     port[0]  - This is the normal input.
364  */
force_link(vvp_net_t * dst,vvp_net_t * src)365 void vvp_net_fil_t::force_link(vvp_net_t*dst, vvp_net_t*src)
366 {
367       assert(dst->fil == this);
368 
369       if (force_link_ == 0) {
370 	    force_link_ = new vvp_net_t;
371 	      // Use port[3] to hold the force destination.
372 	    force_link_->port[3] = vvp_net_ptr_t(dst, 0);
373 	    force_link_->port[2] = vvp_net_ptr_t(0,0);
374 	    force_link_->fun = new vvp_fun_force;
375       }
376 
377       force_unlink();
378       assert(force_link_->port[2] == vvp_net_ptr_t(0,0));
379 
380 	// Use port[2] to hold the force source.
381       force_link_->port[2] = vvp_net_ptr_t(src,0);
382 
383       vvp_net_ptr_t dst_ptr(force_link_, 0);
384       src->link(dst_ptr);
385 }
386 
operator delete(void *)387 void vvp_net_fil_t::operator delete(void*)
388 {
389       assert(0);
390 }
391 
force_unlink(void)392 void vvp_net_fil_t::force_unlink(void)
393 {
394       if (force_link_ == 0) return;
395       vvp_net_t*src = force_link_->port[2].ptr();
396       if (src == 0) return;
397 
398       src->unlink(vvp_net_ptr_t(force_link_,0));
399       force_link_->port[2] = vvp_net_ptr_t(0,0);
400 }
401 
402 /* *** BIT operations *** */
add_with_carry(vvp_bit4_t a,vvp_bit4_t b,vvp_bit4_t & c)403 vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c)
404 {
405       if (bit4_is_xz(a) || bit4_is_xz(b) || bit4_is_xz(c)) {
406 	    c = BIT4_X;
407 	    return BIT4_X;
408       }
409 
410 	// NOTE: This relies on the facts that XZ values have been
411 	// weeded out, and that BIT4_1 is 1 and BIT4_0 is 0.
412       int sum = (int)a + (int)b + (int)c;
413 
414       switch (sum) {
415 	  case 0:
416 	      // c must already be 0.
417 	    return BIT4_0;
418 	  case 1:
419 	    c = BIT4_0;
420 	    return BIT4_1;
421 	  case 2:
422 	    c = BIT4_1;
423 	    return BIT4_0;
424 	  case 3:
425 	    c = BIT4_1;
426 	    return BIT4_1;
427       }
428       fprintf(stderr, "Incorrect result %d.\n", sum);
429       assert(0);
430       return BIT4_X;
431 }
432 
scalar_to_bit4(PLI_INT32 scalar)433 vvp_bit4_t scalar_to_bit4(PLI_INT32 scalar)
434 {
435       switch(scalar) {
436 	  case vpi0:
437 	    return BIT4_0;
438 	  case vpi1:
439 	    return BIT4_1;
440 	  case vpiX:
441 	    return BIT4_X;
442 	  case vpiZ:
443 	    return BIT4_Z;
444       }
445       fprintf(stderr, "Unsupported scalar value %d.\n", (int)scalar);
446       assert(0);
447       return BIT4_X;
448 }
449 
operator ^(vvp_bit4_t a,vvp_bit4_t b)450 vvp_bit4_t operator ^ (vvp_bit4_t a, vvp_bit4_t b)
451 {
452       if (bit4_is_xz(a))
453 	    return BIT4_X;
454       if (bit4_is_xz(b))
455 	    return BIT4_X;
456       if (a == BIT4_0)
457 	    return b;
458       if (b == BIT4_0)
459 	    return a;
460       return BIT4_0;
461 }
462 
operator <<(ostream & out,vvp_bit4_t bit)463 ostream& operator<<(ostream&out, vvp_bit4_t bit)
464 {
465       switch (bit) {
466 	  case BIT4_0:
467 	    out << "0";
468 	    break;
469 	  case BIT4_1:
470 	    out << "1";
471 	    break;
472 	  case BIT4_X:
473 	    out << "X";
474 	    break;
475 	  case BIT4_Z:
476 	    out << "Z";
477 	    break;
478 	  default:
479 	    out << "?";
480 	    break;
481       }
482       return out;
483 }
484 
485 typedef unsigned short edge_t;
486 
VVP_EDGE(vvp_bit4_t from,vvp_bit4_t to)487 inline edge_t VVP_EDGE(vvp_bit4_t from, vvp_bit4_t to)
488 {
489       return 1 << ((from << 2) | to);
490 }
491 
492 const edge_t vvp_edge_posedge
493       = VVP_EDGE(BIT4_0,BIT4_1)
494       | VVP_EDGE(BIT4_0,BIT4_X)
495       | VVP_EDGE(BIT4_0,BIT4_Z)
496       | VVP_EDGE(BIT4_X,BIT4_1)
497       | VVP_EDGE(BIT4_Z,BIT4_1)
498       ;
499 
500 const edge_t vvp_edge_negedge
501       = VVP_EDGE(BIT4_1,BIT4_0)
502       | VVP_EDGE(BIT4_1,BIT4_X)
503       | VVP_EDGE(BIT4_1,BIT4_Z)
504       | VVP_EDGE(BIT4_X,BIT4_0)
505       | VVP_EDGE(BIT4_Z,BIT4_0)
506       ;
507 
edge(vvp_bit4_t from,vvp_bit4_t to)508 int edge(vvp_bit4_t from, vvp_bit4_t to)
509 {
510       edge_t mask = VVP_EDGE(from, to);
511       if (mask & vvp_edge_posedge)
512 	    return 1;
513       if (mask & vvp_edge_negedge)
514 	    return -1;
515       return 0;
516 }
517 
multiply_with_carry(unsigned long a,unsigned long b,unsigned long & carry)518 unsigned long multiply_with_carry(unsigned long a, unsigned long b,
519 				  unsigned long&carry)
520 {
521       const unsigned long mask = (1UL << (CPU_WORD_BITS/2)) - 1;
522       unsigned long a0 = a & mask;
523       unsigned long a1 = (a >> (CPU_WORD_BITS/2)) & mask;
524       unsigned long b0 = b & mask;
525       unsigned long b1 = (b >> (CPU_WORD_BITS/2)) & mask;
526 
527       unsigned long tmp = a0 * b0;
528 
529       unsigned long r00 = tmp & mask;
530       unsigned long c00 = (tmp >> (CPU_WORD_BITS/2)) & mask;
531 
532       tmp = a0 * b1;
533 
534       unsigned long r01 = tmp & mask;
535       unsigned long c01 = (tmp >> (CPU_WORD_BITS/2)) & mask;
536 
537       tmp = a1 * b0;
538 
539       unsigned long r10 = tmp & mask;
540       unsigned long c10 = (tmp >> (CPU_WORD_BITS/2)) & mask;
541 
542       tmp = a1 * b1;
543 
544       unsigned long r11 = tmp & mask;
545       unsigned long c11 = (tmp >> (CPU_WORD_BITS/2)) & mask;
546 
547       unsigned long r1 = c00 + r01 + r10;
548       unsigned long r2 = (r1 >> (CPU_WORD_BITS/2)) & mask;
549       r1 &= mask;
550       r2 += c01 + c10 + r11;
551       unsigned long r3 = (r2 >> (CPU_WORD_BITS/2)) & mask;
552       r2 &= mask;
553       r3 += c11;
554       r3 &= mask;
555 
556       carry = (r3 << (CPU_WORD_BITS/2)) + r2;
557       return (r1 << (CPU_WORD_BITS/2)) + r00;
558 }
559 
560 
vvp_send_vec8(vvp_net_ptr_t ptr,const vvp_vector8_t & val)561 void vvp_send_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&val)
562 {
563       while (vvp_net_t*cur = ptr.ptr()) {
564 	    vvp_net_ptr_t next = cur->port[ptr.port()];
565 
566 	    if (cur->fun)
567 		  cur->fun->recv_vec8(ptr, val);
568 
569 	    ptr = next;
570       }
571 }
572 
vvp_send_real(vvp_net_ptr_t ptr,double val,vvp_context_t context)573 void vvp_send_real(vvp_net_ptr_t ptr, double val, vvp_context_t context)
574 {
575       while (vvp_net_t*cur = ptr.ptr()) {
576 	    vvp_net_ptr_t next = cur->port[ptr.port()];
577 
578 	    if (cur->fun)
579 		  cur->fun->recv_real(ptr, val, context);
580 
581 	    ptr = next;
582       }
583 }
584 
vvp_send_long(vvp_net_ptr_t ptr,long val)585 void vvp_send_long(vvp_net_ptr_t ptr, long val)
586 {
587       while (vvp_net_t*cur = ptr.ptr()) {
588 	    vvp_net_ptr_t next = cur->port[ptr.port()];
589 
590 	    if (cur->fun)
591 		  cur->fun->recv_long(ptr, val);
592 
593 	    ptr = next;
594       }
595 }
596 
vvp_send_long_pv(vvp_net_ptr_t ptr,long val,unsigned base,unsigned wid)597 void vvp_send_long_pv(vvp_net_ptr_t ptr, long val,
598                       unsigned base, unsigned wid)
599 {
600       while (vvp_net_t*cur = ptr.ptr()) {
601 	    vvp_net_ptr_t next = cur->port[ptr.port()];
602 
603 	    if (cur->fun)
604 		  cur->fun->recv_long_pv(ptr, val, base, wid);
605 
606 	    ptr = next;
607       }
608 }
609 
610 const vvp_vector4_t vvp_vector4_t::nil;
611 
copy_bits(const vvp_vector4_t & that)612 void vvp_vector4_t::copy_bits(const vvp_vector4_t&that)
613 {
614 
615       if (size_ == that.size_) {
616 	    if (size_ > BITS_PER_WORD) {
617 		  unsigned words = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
618 		  for (unsigned idx = 0 ;  idx < words ;  idx += 1)
619 			abits_ptr_[idx] = that.abits_ptr_[idx];
620 		  for (unsigned idx = 0 ;  idx < words ;  idx += 1)
621 			bbits_ptr_[idx] = that.bbits_ptr_[idx];
622 	    } else {
623 		  abits_val_ = that.abits_val_;
624 		  bbits_val_ = that.bbits_val_;
625 	    }
626 	    return;
627       }
628 
629 	/* Now we know that the sizes of this and that are definitely
630 	   different. We can use that in code below. In any case, we
631 	   need to copy only the smaller of the sizes. */
632 
633 	/* If source and destination are both short, then mask/copy
634 	   the bit values. */
635       if (size_ <= BITS_PER_WORD && that.size_ <= BITS_PER_WORD) {
636 	    unsigned bits_to_copy = (that.size_ < size_) ? that.size_ : size_;
637 	    unsigned long mask = (1UL << bits_to_copy) - 1UL;
638 	    abits_val_ &= ~mask;
639 	    bbits_val_ &= ~mask;
640 	    abits_val_ |= that.abits_val_&mask;
641 	    bbits_val_ |= that.bbits_val_&mask;
642 	    return;
643       }
644 
645 	/* Now we know that either source or destination are long. If
646 	   the destination is short, then mask/copy from the low word
647 	   of the long source. */
648       if (size_ <= BITS_PER_WORD) {
649 	    abits_val_ = that.abits_ptr_[0];
650 	    bbits_val_ = that.bbits_ptr_[0];
651 	    if (size_ < BITS_PER_WORD) {
652 		  unsigned long mask = (1UL << size_) - 1UL;
653 		  abits_val_ &= mask;
654 		  bbits_val_ &= mask;
655 	    }
656 	    return;
657       }
658 
659 	/* Now we know that the destination must be long. If the
660 	   source is short, then mask/copy from its value. */
661       if (that.size_ <= BITS_PER_WORD) {
662 	    unsigned long mask;
663 	    if (that.size_ < BITS_PER_WORD) {
664 		  mask = (1UL << that.size_) - 1UL;
665 		  abits_ptr_[0] &= ~mask;
666 		  bbits_ptr_[0] &= ~mask;
667 	    } else {
668 		  mask = -1UL;
669 	    }
670 	    abits_ptr_[0] |= that.abits_val_&mask;
671 	    bbits_ptr_[0] |= that.bbits_val_&mask;
672 	    return;
673       }
674 
675 	/* Finally, we know that source and destination are long. copy
676 	   words until we get to the last. */
677       unsigned bits_to_copy = (that.size_ < size_) ? that.size_ : size_;
678       unsigned word = 0;
679       while (bits_to_copy >= BITS_PER_WORD) {
680 	    abits_ptr_[word] = that.abits_ptr_[word];
681 	    bbits_ptr_[word] = that.bbits_ptr_[word];
682 	    bits_to_copy -= BITS_PER_WORD;
683 	    word += 1;
684       }
685       if (bits_to_copy > 0) {
686 	    unsigned long mask = (1UL << bits_to_copy) - 1UL;
687 	    abits_ptr_[word] &= ~mask;
688 	    bbits_ptr_[word] &= ~mask;
689 	    abits_ptr_[word] |= that.abits_ptr_[word] & mask;
690 	    bbits_ptr_[word] |= that.bbits_ptr_[word] & mask;
691       }
692 }
693 
694 /*
695  * This function should ONLY BE CALLED FROM vvp_vector4_t::copy_from_,
696  * as it performs part of that functions tasks.
697  */
copy_from_big_(const vvp_vector4_t & that)698 void vvp_vector4_t::copy_from_big_(const vvp_vector4_t&that)
699 {
700       unsigned words = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
701       abits_ptr_ = new unsigned long[2*words];
702       bbits_ptr_ = abits_ptr_ + words;
703 
704       for (unsigned idx = 0 ;  idx < words ;  idx += 1)
705 	    abits_ptr_[idx] = that.abits_ptr_[idx];
706       for (unsigned idx = 0 ;  idx < words ;  idx += 1)
707 	    bbits_ptr_[idx] = that.bbits_ptr_[idx];
708 }
709 
710 /*
711  * The copy_inverted_from_ method is just like the copy_from_ method,
712  * except that we combine that with an invert. This allows the ~ and
713  * the assignment to be blended in many common cases.
714  */
copy_inverted_from_(const vvp_vector4_t & that)715 void vvp_vector4_t::copy_inverted_from_(const vvp_vector4_t&that)
716 {
717       size_ = that.size_;
718       if (size_ > BITS_PER_WORD) {
719 	    unsigned words = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
720 	    abits_ptr_ = new unsigned long[2*words];
721 	    bbits_ptr_ = abits_ptr_ + words;
722 
723 	    unsigned remaining = size_;
724 	    unsigned idx = 0;
725 	    while (remaining >= BITS_PER_WORD) {
726 		  abits_ptr_[idx] = that.bbits_ptr_[idx] | ~that.abits_ptr_[idx];
727 		  idx += 1;
728 		  remaining -= BITS_PER_WORD;
729 	    }
730 	    if (remaining > 0) {
731 		  unsigned long mask = (1UL<<remaining) - 1UL;
732 		  abits_ptr_[idx] = mask & (that.bbits_ptr_[idx] | ~that.abits_ptr_[idx]);
733 	    }
734 
735 	    for (idx = 0 ;  idx < words ;  idx += 1)
736 		  bbits_ptr_[idx] = that.bbits_ptr_[idx];
737 
738       } else {
739 	    unsigned long mask = (size_<BITS_PER_WORD)? (1UL<<size_)-1UL : -1UL;
740 	    abits_val_ = mask & (that.bbits_val_ | ~that.abits_val_);
741 	    bbits_val_ = that.bbits_val_;
742       }
743 }
744 
745 /* Make sure to set size_ before calling this routine. */
allocate_words_(unsigned long inita,unsigned long initb)746 void vvp_vector4_t::allocate_words_(unsigned long inita, unsigned long initb)
747 {
748       if (size_ > BITS_PER_WORD) {
749 	    unsigned cnt = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD;
750 	    abits_ptr_ = new unsigned long[2*cnt];
751 	    bbits_ptr_ = abits_ptr_ + cnt;
752 	    for (unsigned idx = 0 ;  idx < cnt ;  idx += 1)
753 		  abits_ptr_[idx] = inita;
754 	    for (unsigned idx = 0 ;  idx < cnt ;  idx += 1)
755 		  bbits_ptr_[idx] = initb;
756 
757       } else {
758 	    abits_val_ = inita;
759 	    bbits_val_ = initb;
760       }
761 }
762 
vvp_vector4_t(unsigned size__,double val)763 vvp_vector4_t::vvp_vector4_t(unsigned size__, double val)
764 : size_(size__)
765 {
766       bool is_neg = false;
767       double fraction;
768       int exponent;
769 
770 	/* We return 'bx for a NaN or +/- infinity. */
771       if (val != val || (val && (val == 0.5*val)))  {
772 	    allocate_words_(WORD_X_ABITS, WORD_X_BBITS);
773 	    return;
774       }
775 
776 	/* Convert to a positive result. */
777       if (val < 0.0) {
778 	    is_neg = true;
779 	    val = -val;
780       }
781       allocate_words_(WORD_0_ABITS, WORD_0_BBITS);
782 
783 	/* Get the exponent and fractional part of the number. */
784       fraction = frexp(val, &exponent);
785 
786 	/* If the value is small enough just use lround(). */
787       if (exponent < BITS_PER_WORD-2) {
788 	    if (is_neg) this->invert();  // Invert the bits if negative.
789 	    long sval = lround(val);
790 	    if (is_neg) sval = -sval;
791 	      /* This requires that 0 and 1 have the same bbit value. */
792 	    if (size_ > BITS_PER_WORD) {
793 		  abits_ptr_[0] = sval;
794 	    } else {
795 		  abits_val_ = sval;
796 	    }
797 	    return;
798       }
799 
800       unsigned nwords = (exponent-1) / BITS_PER_WORD;
801       unsigned my_words = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD - 1;
802 
803       fraction = ldexp(fraction, (exponent-1) % BITS_PER_WORD + 1);
804 
805 	/* Skip any leading bits. */
806       for (int idx = (signed) nwords; idx > (signed) my_words; idx -=1) {
807 	    unsigned long bits = (unsigned long) fraction;
808 	    fraction = fraction - (double) bits;
809 	    fraction = ldexp(fraction, BITS_PER_WORD);
810       }
811 
812 	/* Convert the remaining bits as appropriate. */
813       if (my_words == 0) {
814 		  unsigned long bits = (unsigned long) fraction;
815 		  abits_val_ = bits;
816 		  fraction = fraction - (double) bits;
817 		    /* Round any fractional part up. */
818 		  if (fraction >= 0.5) *this += (int64_t) 1;
819       } else {
820 	    if (nwords < my_words) my_words = nwords;
821 	    for (int idx = (signed)my_words; idx >= 0; idx -= 1) {
822 		  unsigned long bits = (unsigned long) fraction;
823 		  abits_ptr_[idx] = bits;
824 		  fraction = fraction - (double) bits;
825 		  fraction = ldexp(fraction, BITS_PER_WORD);
826 	    }
827 	      /* Round any fractional part up. */
828 	    if (fraction >= ldexp(0.5, BITS_PER_WORD)) *this += (int64_t) 1;
829        }
830 
831 	/* Convert to a negative number if needed. */
832       if (is_neg) {
833 	    this->invert();
834 	    *this += (int64_t) 1;
835       }
836 }
837 
vvp_vector4_t(const vvp_vector4_t & that,unsigned adr,unsigned wid)838 vvp_vector4_t::vvp_vector4_t(const vvp_vector4_t&that,
839 			    unsigned adr, unsigned wid)
840 {
841 	// Set up and initialize the destination.
842       size_ = wid;
843       allocate_words_(WORD_X_ABITS, WORD_X_BBITS);
844 
845 	// Special case: selecting from far beyond the source vector,
846 	// to the result is all X bits. We're done.
847       if (adr >= that.size_)
848 	    return;
849 
850 	// Special case: The source is not quite big enough to supply
851 	// all bits, so get the bits that we can. The remainder will
852 	// be left at BIT4_X.
853       if ((adr + wid) > that.size_) {
854 	    unsigned use_wid = that.size_ - adr;
855 	    for (unsigned idx = 0 ; idx < use_wid ; idx += 1)
856 		  set_bit(idx, that.value(adr+idx));
857 
858 	    return;
859       }
860 
861 	// At the point, we know that the source part is entirely
862 	// contained in the source vector.
863 	// assert((adr + wid) <= that.size_);
864 
865       if (wid > BITS_PER_WORD) {
866 	      /* In this case, the subvector and the source vector are
867 		 long. Do the transfer reasonably efficiently. */
868 	    unsigned ptr = adr / BITS_PER_WORD;
869 	    unsigned long off = adr % BITS_PER_WORD;
870 	    unsigned long noff = BITS_PER_WORD - off;
871 	    unsigned long lmask = (1UL << off) - 1UL;
872 	    unsigned trans = 0;
873 	    unsigned dst = 0;
874 	    while (trans < wid) {
875 		    // The low bits of the result.
876 		  abits_ptr_[dst] = (that.abits_ptr_[ptr] & ~lmask) >> off;
877 		  bbits_ptr_[dst] = (that.bbits_ptr_[ptr] & ~lmask) >> off;
878 		  trans += noff;
879 
880 		  if (trans >= wid)
881 			break;
882 
883 		  ptr += 1;
884 
885 		    // The high bits of the result. Skip this if the
886 		    // source and destination are perfectly aligned.
887 		  if (noff != BITS_PER_WORD) {
888 			abits_ptr_[dst] |= (that.abits_ptr_[ptr]&lmask) << noff;
889 			bbits_ptr_[dst] |= (that.bbits_ptr_[ptr]&lmask) << noff;
890 			trans += off;
891 		  }
892 
893 		  dst += 1;
894 	    }
895 
896       } else if (that.size_ > BITS_PER_WORD) {
897 	      /* In this case, the subvector fits in a single word,
898 		 but the source is large. */
899 	    unsigned ptr = adr / BITS_PER_WORD;
900 	    unsigned long off = adr % BITS_PER_WORD;
901 	    unsigned trans = BITS_PER_WORD - off;
902 	    if (trans > wid)
903 		  trans = wid;
904 
905 	    if (trans == BITS_PER_WORD) {
906 		    // Very special case: Copy exactly 1 perfectly
907 		    // aligned word.
908 		  abits_val_ = that.abits_ptr_[ptr];
909 		  bbits_val_ = that.bbits_ptr_[ptr];
910 
911 	    } else {
912 		    // lmask is the low bits of the destination,
913 		    // masked into the source.
914 		  unsigned long lmask = (1UL<<trans) - 1UL;
915 		  lmask <<= off;
916 
917 		    // The low bits of the result.
918 		  abits_val_ = (that.abits_ptr_[ptr] & lmask) >> off;
919 		  bbits_val_ = (that.bbits_ptr_[ptr] & lmask) >> off;
920 
921 		  if (trans < wid) {
922 			  // If there are more bits, then get them
923 			  // from the bottom of the next word of the
924 			  // source.
925 			unsigned long hmask = (1UL << (wid-trans)) - 1UL;
926 
927 			  // The high bits of the result.
928 			abits_val_ |= (that.abits_ptr_[ptr+1]&hmask) << trans;
929 			bbits_val_ |= (that.bbits_ptr_[ptr+1]&hmask) << trans;
930 		  }
931 	    }
932 
933       } else if (size_ == BITS_PER_WORD) {
934 	      /* We know that source and destination are short. If the
935 		 destination is a full word, then we know the copy is
936 		 aligned and complete. */
937 	    abits_val_ = that.abits_val_;
938 	    bbits_val_ = that.bbits_val_;
939 
940       } else {
941 	      /* Finally, the source and destination vectors are both
942 		 short, so there is a single mask/shift/copy. */
943 	    unsigned long mask = (1UL << size_) - 1UL;
944 	    mask <<= adr;
945 
946 	    abits_val_ = (that.abits_val_ & mask) >> adr;
947 	    bbits_val_ = (that.bbits_val_ & mask) >> adr;
948       }
949 
950 }
951 
952 /*
953  * Change the size of the vvp_vector4_t vector to the new size. Copy
954  * the old values, as many as well fit, into the new vector.
955  */
resize(unsigned newsize,vvp_bit4_t pad_bit)956 void vvp_vector4_t::resize(unsigned newsize, vvp_bit4_t pad_bit)
957 {
958       if (size_ == newsize)
959 	    return;
960 
961       unsigned cnt = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD;
962       unsigned long word_pad_abits = 0;
963       unsigned long word_pad_bbits = 0;
964       switch (pad_bit) {
965 	  case BIT4_0:
966 	    word_pad_abits = WORD_0_ABITS;
967 	    word_pad_bbits = WORD_0_BBITS;
968 	    break;
969 	  case BIT4_1:
970 	    word_pad_abits = WORD_1_ABITS;
971 	    word_pad_bbits = WORD_1_BBITS;
972 	    break;
973 	  case BIT4_X:
974 	    word_pad_abits = WORD_X_ABITS;
975 	    word_pad_bbits = WORD_X_BBITS;
976 	    break;
977 	  case BIT4_Z:
978 	    word_pad_abits = WORD_Z_ABITS;
979 	    word_pad_bbits = WORD_Z_BBITS;
980 	    break;
981       }
982 
983       if (newsize > BITS_PER_WORD) {
984 	    unsigned newcnt = (newsize + BITS_PER_WORD - 1) / BITS_PER_WORD;
985 	    if (newcnt == cnt) {
986 		    // If the word count doesn't change, then there is
987 		    // no need for re-allocation so we are done now.
988 		  if (newsize > size_) {
989 			if (unsigned fill = size_ % BITS_PER_WORD) {
990 			      abits_ptr_[cnt-1] &= ~((-1UL) << fill);
991 			      bbits_ptr_[cnt-1] &= ~((-1UL) << fill);
992 			      abits_ptr_[cnt-1] |= word_pad_abits << fill;
993 			      bbits_ptr_[cnt-1] |= word_pad_bbits << fill;
994 			}
995 		  }
996 		  size_ = newsize;
997 		  return;
998 	    }
999 
1000 	    unsigned long*newbits = new unsigned long[2*newcnt];
1001 
1002 	    if (cnt > 1) {
1003 		  unsigned trans = cnt;
1004 		  if (trans > newcnt)
1005 			trans = newcnt;
1006 
1007 		  for (unsigned idx = 0 ;  idx < trans ;  idx += 1)
1008 			newbits[idx] = abits_ptr_[idx];
1009 		  for (unsigned idx = 0 ;  idx < trans ;  idx += 1)
1010 			newbits[newcnt+idx] = bbits_ptr_[idx];
1011 
1012 		  delete[]abits_ptr_;
1013 
1014 	    } else {
1015 		  newbits[0] = abits_val_;
1016 		  newbits[newcnt] = bbits_val_;
1017 	    }
1018 
1019 	    if (newsize > size_) {
1020 		  if (unsigned fill = size_ % BITS_PER_WORD) {
1021 			newbits[cnt-1] &= ~((-1UL) << fill);
1022 			newbits[cnt-1] |= word_pad_abits << fill;
1023 			newbits[newcnt+cnt-1] &= ~((-1UL) << fill);
1024 			newbits[newcnt+cnt-1] |= word_pad_bbits << fill;
1025 		  }
1026 		  for (unsigned idx = cnt ;  idx < newcnt ;  idx += 1)
1027 			newbits[idx] = word_pad_abits;
1028 		  for (unsigned idx = cnt ;  idx < newcnt ;  idx += 1)
1029 			newbits[newcnt+idx] = word_pad_bbits;
1030 	    }
1031 
1032 	    size_ = newsize;
1033 	    abits_ptr_ = newbits;
1034 	    bbits_ptr_ = newbits + newcnt;
1035 
1036       } else {
1037 	    if (cnt > 1) {
1038 		  unsigned long newvala = abits_ptr_[0];
1039 		  unsigned long newvalb = bbits_ptr_[0];
1040 		  delete[]abits_ptr_;
1041 		  abits_val_ = newvala;
1042 		  bbits_val_ = newvalb;
1043 	    }
1044 
1045 	    if (newsize > size_) {
1046 		  abits_val_ &= ~((-1UL) << size_);
1047 		  bbits_val_ &= ~((-1UL) << size_);
1048 		  abits_val_ |= word_pad_abits << size_;
1049 		  bbits_val_ |= word_pad_bbits << size_;
1050 	    }
1051 
1052 	    size_ = newsize;
1053       }
1054 }
1055 
1056 
subarray(unsigned adr,unsigned wid,bool xz_to_0) const1057 unsigned long* vvp_vector4_t::subarray(unsigned adr, unsigned wid, bool xz_to_0) const
1058 {
1059       const unsigned BIT2_PER_WORD = 8*sizeof(unsigned long);
1060       unsigned awid = (wid + BIT2_PER_WORD - 1) / (BIT2_PER_WORD);
1061       unsigned long*val = new unsigned long[awid];
1062 
1063       for (unsigned idx = 0 ;  idx < awid ;  idx += 1)
1064 	    val[idx] = 0;
1065 
1066       if (size_ <= BITS_PER_WORD) {
1067 	      /* Handle the special case that the array is small. The
1068 		 entire value of the vector4 is within the xbits_val_
1069 		 so we know that the result is a single word, the
1070 		 source is a single word, and we just have to loop
1071 		 through that word. */
1072 	    unsigned long atmp = abits_val_ >> adr;
1073 	    unsigned long btmp = bbits_val_ >> adr;
1074 	    if (wid < BIT2_PER_WORD) {
1075 		  atmp &= (1UL << wid) - 1;
1076 		  btmp &= (1UL << wid) - 1;
1077 	    }
1078 	    if (btmp) {
1079 		  if (xz_to_0)
1080 			atmp &= ~btmp;
1081 		  else
1082 			goto x_out;
1083 	    }
1084 
1085 	    val[0] = atmp;
1086 
1087       } else {
1088 
1089 	    unsigned val_ptr = 0;
1090 	    unsigned val_off = 0;
1091 
1092 	      /* Get the first word we are scanning. We may in fact be
1093 		 somewhere in the middle of that word. */
1094 	    while (wid > 0) {
1095 		  unsigned long atmp = abits_ptr_[adr/BITS_PER_WORD];
1096 		  unsigned long btmp = bbits_ptr_[adr/BITS_PER_WORD];
1097 		  unsigned long off = adr%BITS_PER_WORD;
1098 		  atmp >>= off;
1099 		  btmp >>= off;
1100 
1101 		  unsigned long trans = BITS_PER_WORD - off;
1102 		  if (trans > (BIT2_PER_WORD - val_off))
1103 			trans = BIT2_PER_WORD - val_off;
1104 		  if (wid < trans)
1105 			trans = wid;
1106 		  if (trans < BIT2_PER_WORD) {
1107 			atmp &= (1UL << trans) - 1;
1108 			btmp &= (1UL << trans) - 1;
1109 		  }
1110 		  if (btmp) {
1111 			if (xz_to_0)
1112 			      atmp &= ~btmp;
1113 			else
1114 			      goto x_out;
1115 		  }
1116 
1117 		  val[val_ptr] |= atmp << val_off;
1118 		  adr += trans;
1119 		  wid -= trans;
1120 		  val_off += trans;
1121 		  if (val_off == BIT2_PER_WORD) {
1122 			val_ptr += 1;
1123 			val_off = 0;
1124 		  }
1125 	    }
1126       }
1127 
1128       return val;
1129 
1130  x_out:
1131       delete[]val;
1132       return 0;
1133 }
1134 
setarray(unsigned adr,unsigned wid,const unsigned long * val)1135 void vvp_vector4_t::setarray(unsigned adr, unsigned wid, const unsigned long*val)
1136 {
1137       assert(adr+wid <= size_);
1138 
1139       const unsigned BIT2_PER_WORD = 8*sizeof(unsigned long);
1140 
1141       if (size_ <= BITS_PER_WORD) {
1142 	      // We know here that both the source and the target are
1143 	      // within a single word. Write the bits into the
1144 	      // abits_val_ directly.
1145 
1146 	    assert(BIT2_PER_WORD <= BITS_PER_WORD);
1147 	    unsigned long lmask = (1UL << adr) - 1UL;
1148 	    unsigned long hmask = ((adr+wid) < BITS_PER_WORD)
1149 		  ? -1UL << (adr+wid)
1150 		  : 0;
1151 	    unsigned long mask = ~(hmask | lmask);
1152 
1153 	    abits_val_ &= ~mask;
1154 	    bbits_val_ &= ~mask;
1155 
1156 	    abits_val_ |= mask & (val[0] << adr);
1157 
1158       } else {
1159 	      // The general case, there are multiple words of
1160 	      // destination, and possibly multiple words of source
1161 	      // data. Shift and mask as we go.
1162 	    unsigned off = adr % BITS_PER_WORD;
1163 	    unsigned ptr = adr / BITS_PER_WORD;
1164 	    unsigned val_off = 0;
1165 	    unsigned val_ptr = 0;
1166 	    while (wid > 0) {
1167 		  unsigned trans = wid;
1168 		  if (trans > (BIT2_PER_WORD-val_off))
1169 			trans = BIT2_PER_WORD-val_off;
1170 		  if (trans > (BITS_PER_WORD-off))
1171 			trans = BITS_PER_WORD-off;
1172 
1173 		  unsigned long lmask = (1UL << off) - 1UL;
1174 		  unsigned long hmask = ((off+trans) < BITS_PER_WORD)
1175 			? -1UL << (off+trans)
1176 			: 0;
1177 		  unsigned long mask = ~(hmask | lmask);
1178 
1179 		  abits_ptr_[ptr] &= ~mask;
1180 		  bbits_ptr_[ptr] &= ~mask;
1181 		  if (val_off >= off)
1182 			abits_ptr_[ptr] |= mask & (val[val_ptr] >> (val_off-off));
1183 		  else
1184 			abits_ptr_[ptr] |= mask & (val[val_ptr] << (off-val_off));
1185 
1186 		  wid -= trans;
1187 		  val_off += trans;
1188 		  if (val_off == BIT2_PER_WORD) {
1189 			val_off = 0;
1190 			val_ptr += 1;
1191 		  }
1192 		  off += trans;
1193 		  if (off == BITS_PER_WORD) {
1194 			off = 0;
1195 			ptr += 1;
1196 		  }
1197 	    }
1198       }
1199 }
1200 
1201 /*
1202  * Set the bits of that vector, which must be a subset of this vector,
1203  * into the addressed part of this vector. Use bit masking and word
1204  * copies to go as fast as reasonably possible.
1205  */
set_vec(unsigned adr,const vvp_vector4_t & that)1206 bool vvp_vector4_t::set_vec(unsigned adr, const vvp_vector4_t&that)
1207 {
1208       assert(adr+that.size_  <= size_);
1209       bool diff_flag = false;
1210 
1211       if (size_ <= BITS_PER_WORD) {
1212 
1213 	      /* The destination vector (me!) is within a bits_val_
1214 		 word, so the subvector is certainly within a
1215 		 bits_val_ word. Therefore, the entire operation is a
1216 		 matter of writing the bits of that into the addressed
1217 		 bits of this. The mask below is calculated to be 1
1218 		 for all the bits that are to come from that. Do the
1219 		 job by some shifting, masking and OR. */
1220 
1221 	    unsigned long lmask = (1UL << adr) - 1;
1222 	    unsigned long hmask;
1223 	    unsigned long hshift = adr+that.size_;
1224 	    if (hshift >= BITS_PER_WORD)
1225 		  hmask = -1UL;
1226 	    else
1227 		  hmask = (1UL << (adr+that.size_)) - 1;
1228 	    unsigned long mask = hmask & ~lmask;
1229 
1230 	    unsigned long tmp = (that.abits_val_<<adr)&mask;
1231 	    if ((abits_val_&mask) != tmp) {
1232 		  diff_flag = true;
1233 		  abits_val_ = (abits_val_ & ~mask) | tmp;
1234 	    }
1235 	    tmp = (that.bbits_val_<<adr) & mask;
1236 	    if ((bbits_val_&mask) != tmp) {
1237 		  diff_flag = true;
1238 		  bbits_val_ = (bbits_val_ & ~mask) | tmp;
1239 	    }
1240 
1241       } else if (that.size_ <= BITS_PER_WORD) {
1242 
1243 	      /* This vector is more than a word, but that vector is
1244 		 still small. Write into the destination, possibly
1245 		 spanning two destination words, depending on whether
1246 		 the source vector spans a word transition. */
1247 	    unsigned long dptr = adr / BITS_PER_WORD;
1248 	    unsigned long doff = adr % BITS_PER_WORD;
1249 
1250 	    unsigned long lmask = (1UL << doff) - 1;
1251 	    unsigned long hshift = doff+that.size_;
1252 	    unsigned long hmask;
1253 	    if (hshift >= BITS_PER_WORD)
1254 		  hmask = -1UL;
1255 	    else
1256 		  hmask = (1UL << hshift) - 1UL;
1257 
1258 	    unsigned long mask = hmask & ~lmask;
1259 	    unsigned long tmp;
1260 
1261 	    tmp = (that.abits_val_ << doff) & mask;
1262 	    if ((abits_ptr_[dptr] & mask) != tmp) {
1263 		  diff_flag = true;
1264 		  abits_ptr_[dptr] = (abits_ptr_[dptr] & ~mask) | tmp;
1265 	    }
1266 	    tmp = (that.bbits_val_ << doff) & mask;
1267 	    if ((bbits_ptr_[dptr] & mask) != tmp) {
1268 		  diff_flag = true;
1269 		  bbits_ptr_[dptr] = (bbits_ptr_[dptr] & ~mask) | tmp;
1270 	    }
1271 
1272 	    if ((doff + that.size_) > BITS_PER_WORD) {
1273 		  unsigned tail = doff + that.size_ - BITS_PER_WORD;
1274 		  mask = (1UL << tail) - 1;
1275 
1276 		  dptr += 1;
1277 		  tmp = (that.abits_val_ >> (that.size_-tail)) & mask;
1278 		  if ((abits_ptr_[dptr] & mask) != tmp) {
1279 			diff_flag = true;
1280 			abits_ptr_[dptr] = (abits_ptr_[dptr] & ~mask) | tmp;
1281 		  }
1282 		  tmp = (that.bbits_val_ >> (that.size_-tail)) & mask;
1283 		  if ((bbits_ptr_[dptr] & mask) != tmp) {
1284 			diff_flag = true;
1285 			bbits_ptr_[dptr] = (bbits_ptr_[dptr] & ~mask) | tmp;
1286 		  }
1287 	    }
1288 
1289       } else if (adr%BITS_PER_WORD == 0) {
1290 
1291 	      /* In this case, both vectors are long, but the
1292 		 destination is neatly aligned. That means all but the
1293 		 last word can be simply copied with no masking. */
1294 
1295 	    unsigned remain = that.size_;
1296 	    unsigned sptr = 0;
1297 	    unsigned dptr = adr / BITS_PER_WORD;
1298 	    while (remain >= BITS_PER_WORD) {
1299 		  if (abits_ptr_[dptr] != that.abits_ptr_[sptr]) {
1300 			diff_flag = true;
1301 			abits_ptr_[dptr] = that.abits_ptr_[sptr];
1302 		  }
1303 		  if (bbits_ptr_[dptr] != that.bbits_ptr_[sptr]) {
1304 			diff_flag = true;
1305 			bbits_ptr_[dptr] = that.bbits_ptr_[sptr];
1306 		  }
1307 		  dptr += 1;
1308 		  sptr += 1;
1309 		  remain -= BITS_PER_WORD;
1310 	    }
1311 
1312 	    if (remain > 0) {
1313 		  unsigned long mask = (1UL << remain) - 1;
1314 		  unsigned long tmp;
1315 
1316 		  tmp = that.abits_ptr_[sptr] & mask;
1317 		  if ((abits_ptr_[dptr] & mask) != tmp) {
1318 			diff_flag = true;
1319 			abits_ptr_[dptr] = (abits_ptr_[dptr] & ~mask) | tmp;
1320 		  }
1321 		  tmp = that.bbits_ptr_[sptr] & mask;
1322 		  if ((bbits_ptr_[dptr] & mask) != tmp) {
1323 			diff_flag = true;
1324 			bbits_ptr_[dptr] = (bbits_ptr_[dptr] & ~mask) | tmp;
1325 		  }
1326 	    }
1327 
1328       } else {
1329 
1330 	      /* We know that there are two long vectors, and we know
1331 		 that the destination is definitely NOT aligned. */
1332 
1333 	    unsigned remain = that.size_;
1334 	    unsigned sptr = 0;
1335 	    unsigned dptr = adr / BITS_PER_WORD;
1336 	    unsigned doff = adr % BITS_PER_WORD;
1337 	    unsigned long lmask = (1UL << doff) - 1;
1338 	    unsigned ndoff = BITS_PER_WORD - doff;
1339 	    while (remain >= BITS_PER_WORD) {
1340 		  unsigned long tmp;
1341 
1342 		  tmp = (that.abits_ptr_[sptr] << doff) & ~lmask;
1343 		  if ((abits_ptr_[dptr] & ~lmask) != tmp) {
1344 			diff_flag = true;
1345 			abits_ptr_[dptr] = (abits_ptr_[dptr] & lmask) | tmp;
1346 		  }
1347 		  tmp = (that.bbits_ptr_[sptr] << doff) & ~lmask;
1348 		  if ((bbits_ptr_[dptr] & ~lmask) != tmp) {
1349 			diff_flag = true;
1350 			bbits_ptr_[dptr] = (bbits_ptr_[dptr] & lmask) | tmp;
1351 		  }
1352 		  dptr += 1;
1353 
1354 		  tmp = (that.abits_ptr_[sptr] >> ndoff) & lmask;
1355 		  if ((abits_ptr_[dptr] & lmask) != tmp) {
1356 			diff_flag = true;
1357 			abits_ptr_[dptr] = (abits_ptr_[dptr] & ~lmask) | tmp;
1358 		  }
1359 		  tmp = (that.bbits_ptr_[sptr] >> ndoff) & lmask;
1360 		  if ((bbits_ptr_[dptr] & lmask) != tmp) {
1361 			diff_flag = true;
1362 			bbits_ptr_[dptr] = (bbits_ptr_[dptr] & ~lmask) | tmp;
1363 		  }
1364 
1365 		  remain -= BITS_PER_WORD;
1366 		  sptr += 1;
1367 	    }
1368 
1369 	    if (remain > 0) {
1370 		  unsigned long hshift = doff+remain;
1371 		  unsigned long hmask;
1372 		  if (hshift >= BITS_PER_WORD)
1373 			hmask = -1UL;
1374 		  else
1375 			hmask = (1UL << (doff+remain)) - 1;
1376 
1377 		  unsigned long mask = hmask & ~lmask;
1378 		  unsigned long tmp;
1379 
1380 		  tmp = (that.abits_ptr_[sptr] << doff) & mask;
1381 		  if ((abits_ptr_[dptr] & mask) != tmp) {
1382 			diff_flag = true;
1383 			abits_ptr_[dptr] = (abits_ptr_[dptr] & ~mask) | tmp;
1384 		  }
1385 		  tmp = (that.bbits_ptr_[sptr] << doff) & mask;
1386 		  if ((bbits_ptr_[dptr] & mask) != tmp) {
1387 			diff_flag = true;
1388 			bbits_ptr_[dptr] = (bbits_ptr_[dptr] & ~mask) | tmp;
1389 		  }
1390 
1391 		  if ((doff + remain) > BITS_PER_WORD) {
1392 			unsigned tail = doff + remain - BITS_PER_WORD;
1393 			if (tail >= BITS_PER_WORD)
1394 			      mask = -1UL;
1395 			else
1396 			      mask = (1UL << tail) - 1;
1397 
1398 			dptr += 1;
1399 
1400 			tmp = (that.abits_ptr_[sptr] >> (remain-tail))&mask;
1401 			if ((abits_ptr_[dptr] & mask) != tmp) {
1402 			      diff_flag = true;
1403 			      abits_ptr_[dptr] = (abits_ptr_[dptr] & ~mask) | tmp;
1404 			}
1405 			tmp = (that.bbits_ptr_[sptr] >> (remain-tail))&mask;
1406 			if ((bbits_ptr_[dptr] & mask) != tmp) {
1407 			      diff_flag = true;
1408 			      bbits_ptr_[dptr] = (bbits_ptr_[dptr] & ~mask) | tmp;
1409 			}
1410 		  }
1411 	    }
1412       }
1413 
1414       return diff_flag;
1415 }
1416 
1417 /*
1418  * Add that vector to this vector. Do it in the Verilog way, which
1419  * means if we detect any X or Z bits, change the entire results to
1420  * all X.
1421  *
1422  * Assume both vectors are the same size.
1423  */
add(const vvp_vector4_t & that)1424 void vvp_vector4_t::add(const vvp_vector4_t&that)
1425 {
1426       assert(size_ == that.size_);
1427 
1428       if (size_ < BITS_PER_WORD) {
1429 	    unsigned long mask = ~(-1UL << size_);
1430 	    if ((bbits_val_|that.bbits_val_) & mask) {
1431 		  abits_val_ |= mask;
1432 		  bbits_val_ |= mask;
1433 		  return;
1434 	    }
1435 
1436 	    abits_val_ += that.abits_val_;
1437 	    abits_val_ &= mask;
1438 	    return;
1439       }
1440 
1441       if (size_ == BITS_PER_WORD) {
1442 	    if (bbits_val_ | that.bbits_val_) {
1443 		  abits_val_ = WORD_X_ABITS;
1444 		  bbits_val_ = WORD_X_BBITS;
1445 	    } else {
1446 		  abits_val_ += that.abits_val_;
1447 	    }
1448 	    return;
1449       }
1450 
1451       int cnt = size_ / BITS_PER_WORD;
1452       unsigned long carry = 0;
1453       for (int idx = 0 ; idx < cnt ; idx += 1) {
1454 	    if (bbits_ptr_[idx] | that.bbits_ptr_[idx])
1455 		  goto x_out;
1456 
1457 	    abits_ptr_[idx] = add_with_carry(abits_ptr_[idx], that.abits_ptr_[idx], carry);
1458       }
1459 
1460       if (unsigned tail = size_ % BITS_PER_WORD) {
1461 	    unsigned long mask = ~( -1UL << tail );
1462 	    if ((bbits_ptr_[cnt] | that.bbits_ptr_[cnt])&mask)
1463 		  goto x_out;
1464 
1465 	    abits_ptr_[cnt] = add_with_carry(abits_ptr_[cnt], that.abits_ptr_[cnt], carry);
1466 	    abits_ptr_[cnt] &= mask;
1467       }
1468 
1469       return;
1470 
1471  x_out:
1472       for (int idx = 0 ; idx < cnt ; idx += 1) {
1473 	    abits_ptr_[idx] = WORD_X_ABITS;
1474 	    bbits_ptr_[idx] = WORD_X_BBITS;
1475       }
1476       if (unsigned tail = size_%BITS_PER_WORD) {
1477 	    unsigned long mask = ~( -1UL << tail );
1478 	    abits_ptr_[cnt] = WORD_X_ABITS&mask;
1479 	    bbits_ptr_[cnt] = WORD_X_BBITS&mask;
1480       }
1481 }
1482 
sub(const vvp_vector4_t & that)1483 void vvp_vector4_t::sub(const vvp_vector4_t&that)
1484 {
1485       assert(size_ == that.size_);
1486 
1487       if (size_ < BITS_PER_WORD) {
1488 	    unsigned long mask = ~(-1UL << size_);
1489 	    if ((bbits_val_|that.bbits_val_) & mask) {
1490 		  abits_val_ |= mask;
1491 		  bbits_val_ |= mask;
1492 		  return;
1493 	    }
1494 
1495 	    abits_val_ -= that.abits_val_;
1496 	    abits_val_ &= mask;
1497 	    return;
1498       }
1499 
1500       if (size_ == BITS_PER_WORD) {
1501 	    if (bbits_val_ | that.bbits_val_) {
1502 		  abits_val_ = WORD_X_ABITS;
1503 		  bbits_val_ = WORD_X_BBITS;
1504 	    } else {
1505 		  abits_val_ -= that.abits_val_;
1506 	    }
1507 	    return;
1508       }
1509 
1510       int cnt = size_ / BITS_PER_WORD;
1511       unsigned long carry = 1;
1512       for (int idx = 0 ; idx < cnt ; idx += 1) {
1513 	    if (bbits_ptr_[idx] | that.bbits_ptr_[idx])
1514 		  goto x_out;
1515 
1516 	    abits_ptr_[idx] = add_with_carry(abits_ptr_[idx], ~that.abits_ptr_[idx], carry);
1517       }
1518 
1519       if (unsigned tail = size_ % BITS_PER_WORD) {
1520 	    unsigned long mask = ~( -1UL << tail );
1521 	    if ((bbits_ptr_[cnt] | that.bbits_ptr_[cnt])&mask)
1522 		  goto x_out;
1523 
1524 	    abits_ptr_[cnt] = add_with_carry(abits_ptr_[cnt], ~that.abits_ptr_[cnt], carry);
1525 	    abits_ptr_[cnt] &= mask;
1526       }
1527 
1528       return;
1529 
1530  x_out:
1531       for (int idx = 0 ; idx < cnt ; idx += 1) {
1532 	    abits_ptr_[idx] = WORD_X_ABITS;
1533 	    bbits_ptr_[idx] = WORD_X_BBITS;
1534       }
1535       if (unsigned tail = size_%BITS_PER_WORD) {
1536 	    unsigned long mask = ~( -1UL << tail );
1537 	    abits_ptr_[cnt] = WORD_X_ABITS&mask;
1538 	    bbits_ptr_[cnt] = WORD_X_BBITS&mask;
1539       }
1540 
1541 }
1542 
mov(unsigned dst,unsigned src,unsigned cnt)1543 void vvp_vector4_t::mov(unsigned dst, unsigned src, unsigned cnt)
1544 {
1545       assert(dst+cnt <= size_);
1546       assert(src+cnt <= size_);
1547 
1548       if (size_ <= BITS_PER_WORD) {
1549 	    unsigned long vmask = (1UL << cnt) - 1;
1550 	    unsigned long tmp;
1551 
1552 	    tmp = (abits_val_ >> src) & vmask;
1553 	    abits_val_ &= ~ (vmask << dst);
1554 	    abits_val_ |= tmp << dst;
1555 
1556 	    tmp = (bbits_val_ >> src) & vmask;
1557 	    bbits_val_ &= ~ (vmask << dst);
1558 	    bbits_val_ |= tmp << dst;
1559 
1560       } else {
1561 	    unsigned sptr = src / BITS_PER_WORD;
1562 	    unsigned dptr = dst / BITS_PER_WORD;
1563 	    unsigned soff = src % BITS_PER_WORD;
1564 	    unsigned doff = dst % BITS_PER_WORD;
1565 
1566 	    while (cnt > 0) {
1567 		  unsigned trans = cnt;
1568 		  if ((soff+trans) > BITS_PER_WORD)
1569 			trans = BITS_PER_WORD - soff;
1570 
1571 		  if ((doff+trans) > BITS_PER_WORD)
1572 			trans = BITS_PER_WORD - doff;
1573 
1574 		  if (trans == BITS_PER_WORD) {
1575 			  // Special case: the transfer count is
1576 			  // exactly an entire word. For this to be
1577 			  // true, it must also be true that the
1578 			  // pointers are aligned. The work is easy,
1579 			abits_ptr_[dptr] = abits_ptr_[sptr];
1580 			bbits_ptr_[dptr] = bbits_ptr_[sptr];
1581 			dptr += 1;
1582 			sptr += 1;
1583 			cnt -= BITS_PER_WORD;
1584 			continue;
1585 		  }
1586 
1587 		    // Here we know that either the source or
1588 		    // destination is unaligned, and also we know that
1589 		    // the count is less than a full word.
1590 		  unsigned long vmask = (1UL << trans) - 1;
1591 		  unsigned long tmp;
1592 
1593 		  tmp = (abits_ptr_[sptr] >> soff) & vmask;
1594 		  abits_ptr_[dptr] &= ~ (vmask << doff);
1595 		  abits_ptr_[dptr] |= tmp << doff;
1596 
1597 		  tmp = (bbits_ptr_[sptr] >> soff) & vmask;
1598 		  bbits_ptr_[dptr] &= ~ (vmask << doff);
1599 		  bbits_ptr_[dptr] |= tmp << doff;
1600 
1601 		  cnt -= trans;
1602 		  soff += trans;
1603 		  if (soff >= BITS_PER_WORD) {
1604 			soff = 0;
1605 			sptr += 1;
1606 		  }
1607 		  doff += trans;
1608 		  if (doff >= BITS_PER_WORD) {
1609 			doff = 0;
1610 			dptr += 1;
1611 		  }
1612 	    }
1613       }
1614 }
1615 
mul(const vvp_vector4_t & that)1616 void vvp_vector4_t::mul(const vvp_vector4_t&that)
1617 {
1618       assert(size_ == that.size_);
1619 
1620       if (size_ < BITS_PER_WORD) {
1621 	    unsigned long mask = ~(-1UL << size_);
1622 	    if ((bbits_val_|that.bbits_val_) & mask) {
1623 		  abits_val_ |= mask;
1624 		  bbits_val_ |= mask;
1625 		  return;
1626 	    }
1627 
1628 	    abits_val_ *= that.abits_val_;
1629 	    abits_val_ &= mask;
1630 	    return;
1631       }
1632 
1633       if (size_ == BITS_PER_WORD) {
1634 	    if (bbits_val_ || that.bbits_val_) {
1635 		  abits_val_ = WORD_X_ABITS;
1636 		  bbits_val_ = WORD_X_BBITS;
1637 	    } else {
1638 		  abits_val_ *= that.abits_val_;
1639 	    }
1640 	    return;
1641       }
1642 
1643       const int cnt = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
1644 
1645       unsigned long mask;
1646       if (unsigned tail = size_%BITS_PER_WORD) {
1647 	    mask = ~( -1UL << tail );
1648       } else {
1649 	    mask = ~0UL;
1650       }
1651 
1652 	// Check for any XZ values ahead of time in a first pass. If
1653 	// we find any, then force the entire result to be X and be
1654 	// done.
1655       for (int idx = 0 ; idx < cnt ; idx += 1) {
1656 	    unsigned long lval = bbits_ptr_[idx];
1657 	    unsigned long rval = that.bbits_ptr_[idx];
1658 	    if (idx == (cnt-1)) {
1659 		  lval &= mask;
1660 		  rval &= mask;
1661 	    }
1662 	    if (lval || rval) {
1663 		  for (int xdx = 0 ; xdx < cnt-1 ; xdx += 1) {
1664 			abits_ptr_[xdx] = WORD_X_ABITS;
1665 			bbits_ptr_[xdx] = WORD_X_BBITS;
1666 		  }
1667 		  abits_ptr_[cnt-1] = WORD_X_ABITS & mask;
1668 		  bbits_ptr_[cnt-1] = WORD_X_BBITS & mask;
1669 		  return;
1670 	    }
1671       }
1672 
1673 	// Calculate the result into a res array. We need to keep is
1674 	// separate from the "this" array because we are making
1675 	// multiple passes.
1676       unsigned long*res = new unsigned long[cnt];
1677       for (int idx = 0 ; idx < cnt ; idx += 1)
1678 	    res[idx] = 0;
1679 
1680       for (int mul_a = 0 ; mul_a < cnt ; mul_a += 1) {
1681 	    unsigned long lval = abits_ptr_[mul_a];
1682 	    if (mul_a == (cnt-1))
1683 		  lval &= mask;
1684 
1685 	    for (int mul_b = 0 ; mul_b < (cnt-mul_a) ; mul_b += 1) {
1686 		  unsigned long rval = that.abits_ptr_[mul_b];
1687 		  if (mul_b == (cnt-1))
1688 			rval &= mask;
1689 
1690 		  unsigned long sum;
1691 		  unsigned long tmp = multiply_with_carry(lval, rval, sum);
1692 		  int base = mul_a + mul_b;
1693 		  unsigned long carry = 0;
1694 		  res[base] = add_with_carry(res[base], tmp, carry);
1695 		  for (int add_idx = base+1 ; add_idx < cnt ; add_idx += 1) {
1696 			res[add_idx] = add_with_carry(res[add_idx], sum, carry);
1697 			sum = 0;
1698 		  }
1699 	    }
1700       }
1701 
1702 	// Replace the "this" value with the calculated result. We
1703 	// know a-priori that the bbits are zero and unchanged.
1704       res[cnt-1] &= mask;
1705       for (int idx = 0 ; idx < cnt ; idx += 1)
1706 	    abits_ptr_[idx] = res[idx];
1707 
1708       delete[]res;
1709       return;
1710 
1711 
1712 }
1713 
eeq(const vvp_vector4_t & that) const1714 bool vvp_vector4_t::eeq(const vvp_vector4_t&that) const
1715 {
1716       if (size_ != that.size_)
1717 	    return false;
1718 
1719       if (size_ < BITS_PER_WORD) {
1720 	    unsigned long mask = (1UL << size_) - 1;
1721 	    return (abits_val_&mask) == (that.abits_val_&mask)
1722 		  && (bbits_val_&mask) == (that.bbits_val_&mask);
1723       }
1724 
1725       if (size_ == BITS_PER_WORD) {
1726 	    return (abits_val_ == that.abits_val_)
1727 		  && (bbits_val_ == that.bbits_val_);
1728       }
1729 
1730       unsigned words = size_ / BITS_PER_WORD;
1731       for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
1732 	    if (abits_ptr_[idx] != that.abits_ptr_[idx])
1733 		  return false;
1734 	    if (bbits_ptr_[idx] != that.bbits_ptr_[idx])
1735 		  return false;
1736       }
1737 
1738       unsigned long mask = size_%BITS_PER_WORD;
1739       if (mask > 0) {
1740 	    mask = (1UL << mask) - 1;
1741 	    return (abits_ptr_[words]&mask) == (that.abits_ptr_[words]&mask)
1742 		  && (bbits_ptr_[words]&mask) == (that.bbits_ptr_[words]&mask);
1743       }
1744 
1745       return true;
1746 }
1747 
eq_xz(const vvp_vector4_t & that) const1748 bool vvp_vector4_t::eq_xz(const vvp_vector4_t&that) const
1749 {
1750       if (size_ != that.size_)
1751 	    return false;
1752 
1753       if (size_ < BITS_PER_WORD) {
1754 	    unsigned long mask = (1UL << size_) - 1;
1755 	    return ((abits_val_|bbits_val_)&mask) == ((that.abits_val_|that.bbits_val_)&mask)
1756 		  && (bbits_val_&mask) == (that.bbits_val_&mask);
1757       }
1758 
1759       if (size_ == BITS_PER_WORD) {
1760 	    return ((abits_val_|bbits_val_) == (that.abits_val_|that.bbits_val_))
1761 		  && (bbits_val_ == that.bbits_val_);
1762       }
1763 
1764       unsigned words = size_ / BITS_PER_WORD;
1765       for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
1766 	    if ((abits_ptr_[idx]|bbits_ptr_[idx]) != (that.abits_ptr_[idx]|that.bbits_ptr_[idx]))
1767 		  return false;
1768 	    if (bbits_ptr_[idx] != that.bbits_ptr_[idx])
1769 		  return false;
1770       }
1771 
1772       unsigned long mask = size_%BITS_PER_WORD;
1773       if (mask > 0) {
1774 	    mask = (1UL << mask) - 1;
1775 	    return ((abits_ptr_[words]|bbits_ptr_[words])&mask) == ((that.abits_ptr_[words]|that.bbits_ptr_[words])&mask)
1776 		  && (bbits_ptr_[words]&mask) == (that.bbits_ptr_[words]&mask);
1777       }
1778 
1779       return true;
1780 }
1781 
has_xz() const1782 bool vvp_vector4_t::has_xz() const
1783 {
1784       if (size_ < BITS_PER_WORD) {
1785 	    unsigned long mask = -1UL >> (BITS_PER_WORD - size_);
1786 	    return bbits_val_&mask;
1787       }
1788 
1789       if (size_ == BITS_PER_WORD) {
1790 	    return bbits_val_;
1791       }
1792 
1793       unsigned words = size_ / BITS_PER_WORD;
1794       for (unsigned idx = 0 ; idx < words ; idx += 1) {
1795 	    if (bbits_ptr_[idx])
1796 		  return true;
1797       }
1798 
1799       unsigned long mask = size_%BITS_PER_WORD;
1800       if (mask > 0) {
1801 	    mask = -1UL >> (BITS_PER_WORD - mask);
1802 	    return bbits_ptr_[words]&mask;
1803       }
1804 
1805       return false;
1806 }
1807 
change_z2x()1808 void vvp_vector4_t::change_z2x()
1809 {
1810 	// This method relies on the fact that both BIT4_X and BIT4_Z
1811 	// have the bbit set in the vector4 encoding, and also that
1812 	// the BIT4_X has abit set in the vector4 encoding. By simply
1813 	// or-ing the bbit into the abit, BIT4_X and BIT4_Z both
1814 	// become BIT4_X.
1815 
1816       if (size_ <= BITS_PER_WORD) {
1817 	    abits_val_ |= bbits_val_;
1818       } else {
1819 	    unsigned words = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
1820 	    for (unsigned idx = 0 ;  idx < words ;  idx += 1)
1821 		  abits_ptr_[idx] |= bbits_ptr_[idx];
1822       }
1823 }
1824 
set_to_x()1825 void vvp_vector4_t::set_to_x()
1826 {
1827       if (size_ <= BITS_PER_WORD) {
1828 	    abits_val_ = vvp_vector4_t::WORD_X_ABITS;
1829             bbits_val_ = vvp_vector4_t::WORD_X_BBITS;
1830       } else {
1831 	    unsigned words = (size_+BITS_PER_WORD-1) / BITS_PER_WORD;
1832 	    for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
1833 		  abits_ptr_[idx] = vvp_vector4_t::WORD_X_ABITS;
1834                   bbits_ptr_[idx] = vvp_vector4_t::WORD_X_BBITS;
1835             }
1836       }
1837 }
1838 
as_string(char * buf,size_t buf_len) const1839 char* vvp_vector4_t::as_string(char*buf, size_t buf_len) const
1840 {
1841       char*res = buf;
1842       *buf++ = 'C';
1843       *buf++ = '4';
1844       *buf++ = '<';
1845       buf_len -= 3;
1846 
1847       for (unsigned idx = 0 ;  idx < size() && buf_len >= 2 ;  idx += 1) {
1848 	    switch (value(size()-idx-1)) {
1849 		case BIT4_0:
1850 		  *buf++ = '0';
1851 		  break;
1852 		case BIT4_1:
1853 		  *buf++ = '1';
1854 		  break;
1855 		case BIT4_X:
1856 		  *buf++ = 'x';
1857 		  break;
1858 		case BIT4_Z:
1859 		  *buf++ = 'z';
1860 	    }
1861 	    buf_len -= 1;
1862       }
1863 
1864       *buf++ = '>';
1865       *buf++ = 0;
1866       return res;
1867 }
1868 
invert()1869 void vvp_vector4_t::invert()
1870 {
1871       if (size_ <= BITS_PER_WORD) {
1872 	    unsigned long mask = (size_<BITS_PER_WORD)? (1UL<<size_)-1UL : -1UL;
1873 	    abits_val_ = mask & ~abits_val_;
1874 	    abits_val_ |= bbits_val_;
1875       } else {
1876 	    unsigned remaining = size_;
1877 	    unsigned idx = 0;
1878 	    while (remaining >= BITS_PER_WORD) {
1879 		  abits_ptr_[idx] = ~abits_ptr_[idx];
1880 		  abits_ptr_[idx] |= bbits_ptr_[idx];
1881 		  idx += 1;
1882 		  remaining -= BITS_PER_WORD;
1883 	    }
1884 	    if (remaining > 0) {
1885 		  unsigned long mask = (1UL<<remaining) - 1UL;
1886 		  abits_ptr_[idx] = mask & ~abits_ptr_[idx];
1887 		  abits_ptr_[idx] |= bbits_ptr_[idx];
1888 	    }
1889       }
1890 }
1891 
operator &=(const vvp_vector4_t & that)1892 vvp_vector4_t& vvp_vector4_t::operator &= (const vvp_vector4_t&that)
1893 {
1894 	// The truth table is:
1895 	//     00 01 11 10
1896 	//  00 00 00 00 00
1897 	//  01 00 01 11 11
1898 	//  11 00 11 11 11
1899 	//  10 00 11 11 11
1900       if (size_ <= BITS_PER_WORD) {
1901 	    unsigned long tmp1 = abits_val_ | bbits_val_;
1902 	    unsigned long tmp2 = that.abits_val_ | that.bbits_val_;
1903 	    abits_val_ = tmp1 & tmp2;
1904 	    bbits_val_ = (tmp1 & that.bbits_val_) | (tmp2 & bbits_val_);
1905       } else {
1906 	    unsigned words = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD;
1907 	    for (unsigned idx = 0; idx < words ; idx += 1) {
1908 		  unsigned long tmp1 = abits_ptr_[idx] | bbits_ptr_[idx];
1909 		  unsigned long tmp2 = that.abits_ptr_[idx] |
1910 		                       that.bbits_ptr_[idx];
1911 		  abits_ptr_[idx] = tmp1 & tmp2;
1912 		  bbits_ptr_[idx] = (tmp1 & that.bbits_ptr_[idx]) |
1913 		                    (tmp2 & bbits_ptr_[idx]);
1914 	    }
1915       }
1916 
1917       return *this;
1918 }
1919 
operator |=(const vvp_vector4_t & that)1920 vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that)
1921 {
1922 	// The truth table is:
1923 	//     00 01 11 10
1924 	//  00 00 01 11 11
1925 	//  01 01 01 01 01
1926 	//  11 11 01 11 11
1927 	//  10 11 01 11 11
1928       if (size_ <= BITS_PER_WORD) {
1929 	    unsigned long tmp = abits_val_ | bbits_val_ |
1930 	                        that.abits_val_ | that.bbits_val_;
1931 	    bbits_val_ = ((~abits_val_ | bbits_val_) & that.bbits_val_) |
1932 	                 ((~that.abits_val_ | that.bbits_val_) & bbits_val_);
1933 	    abits_val_ = tmp;
1934 
1935       } else {
1936 	    unsigned words = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD;
1937 	    for (unsigned idx = 0; idx < words ; idx += 1) {
1938 		  unsigned long tmp = abits_ptr_[idx] | bbits_ptr_[idx] |
1939 	                        that.abits_ptr_[idx] | that.bbits_ptr_[idx];
1940 		  bbits_ptr_[idx] = ((~abits_ptr_[idx] | bbits_ptr_[idx]) &
1941 		                     that.bbits_ptr_[idx]) |
1942 		                    ((~that.abits_ptr_[idx] |
1943 		                      that.bbits_ptr_[idx]) & bbits_ptr_[idx]);
1944 		  abits_ptr_[idx] = tmp;
1945 	    }
1946       }
1947 
1948       return *this;
1949 }
1950 
1951 /*
1952 * Add an integer to the vvp_vector4_t in place, bit by bit so that
1953 * there is no size limitations.
1954 */
operator +=(int64_t that)1955 vvp_vector4_t& vvp_vector4_t::operator += (int64_t that)
1956 {
1957       vvp_bit4_t carry = BIT4_0;
1958       unsigned idx;
1959 
1960       if (has_xz()) {
1961 	    vvp_vector4_t xxx (size(), BIT4_X);
1962 	    *this = xxx;
1963 	    return *this;
1964       }
1965 
1966       for (idx = 0 ; idx < size() ; idx += 1) {
1967 	    if (that == 0 && carry==BIT4_0)
1968 		  break;
1969 
1970 	    vvp_bit4_t that_bit = (that&1)? BIT4_1 : BIT4_0;
1971 	    that >>= 1;
1972 
1973 	    if (that_bit==BIT4_0 && carry==BIT4_0)
1974 		  continue;
1975 
1976 	    vvp_bit4_t bit = value(idx);
1977 	    bit = add_with_carry(bit, that_bit, carry);
1978 
1979 	    set_bit(idx, bit);
1980       }
1981 
1982       return *this;
1983 }
1984 
operator <<(ostream & out,const vvp_vector4_t & that)1985 ostream& operator<< (ostream&out, const vvp_vector4_t&that)
1986 {
1987       out << that.size() << "'b";
1988       for (unsigned idx = 0 ;  idx < that.size() ;  idx += 1)
1989 	    out << that.value(that.size()-idx-1);
1990       return out;
1991 }
1992 
vector4_to_value(const vvp_vector4_t & vec,INT & val,bool is_signed,bool is_arithmetic)1993 template <class INT>bool vector4_to_value(const vvp_vector4_t&vec, INT&val,
1994 					  bool is_signed, bool is_arithmetic)
1995 {
1996       INT res = 0;
1997       INT msk = 1;
1998       bool rc_flag = true;
1999 
2000       unsigned size = vec.size();
2001       if (size > 8*sizeof(val)) size = 8*sizeof(val);
2002       for (unsigned idx = 0 ;  idx < size ;  idx += 1) {
2003 	    switch (vec.value(idx)) {
2004 		case BIT4_0:
2005 		  break;
2006 		case BIT4_1:
2007 		  res |= msk;
2008 		  break;
2009 		default:
2010 		  if (is_arithmetic)
2011 			return false;
2012 		  else
2013 			rc_flag = false;
2014 	    }
2015 
2016 	    msk <<= 1;
2017       }
2018 
2019       if (is_signed && vec.value(vec.size()-1) == BIT4_1) {
2020 	    if (vec.size() < 8*sizeof(val))
2021 		  res |= static_cast<INT>(-1ULL << vec.size());
2022       }
2023 
2024       val = res;
2025       return rc_flag;
2026 }
2027 
2028 template bool vector4_to_value(const vvp_vector4_t&vec, int8_t&val,
2029 			       bool is_signed, bool is_arithmetic);
2030 template bool vector4_to_value(const vvp_vector4_t&vec, int16_t&val,
2031 			       bool is_signed, bool is_arithmetic);
2032 template bool vector4_to_value(const vvp_vector4_t&vec, int32_t&val,
2033 			       bool is_signed, bool is_arithmetic);
2034 template bool vector4_to_value(const vvp_vector4_t&vec, int64_t&val,
2035 			       bool is_signed, bool is_arithmetic);
2036 template bool vector4_to_value(const vvp_vector4_t&vec, uint8_t&val,
2037 			       bool is_signed, bool is_arithmetic);
2038 template bool vector4_to_value(const vvp_vector4_t&vec, uint16_t&val,
2039 			       bool is_signed, bool is_arithmetic);
2040 template bool vector4_to_value(const vvp_vector4_t&vec, uint32_t&val,
2041 			       bool is_signed, bool is_arithmetic);
2042 template bool vector4_to_value(const vvp_vector4_t&vec, uint64_t&val,
2043 			       bool is_signed, bool is_arithmetic);
2044 
vector4_to_value(const vvp_vector4_t & vec,bool & overflow_flag,T & val)2045 template <class T> bool vector4_to_value(const vvp_vector4_t&vec,
2046                                          bool&overflow_flag, T&val)
2047 {
2048       T res = 0;
2049       T msk = 1;
2050 
2051       overflow_flag = false;
2052       unsigned size = vec.size();
2053       for (unsigned idx = 0 ;  idx < size ;  idx += 1) {
2054 	    switch (vec.value(idx)) {
2055 		case BIT4_0:
2056 		  break;
2057 		case BIT4_1:
2058 		  if (msk == 0)
2059 			overflow_flag = true;
2060 		  else
2061 			res |= msk;
2062 		  break;
2063 		default:
2064 		  return false;
2065 	    }
2066 
2067 	    msk <<= static_cast<T>(1);
2068       }
2069 
2070       val = res;
2071       return true;
2072 }
2073 
2074 template bool vector4_to_value(const vvp_vector4_t&vec, bool&overflow_flag,
2075                                unsigned long&val);
2076 #ifndef UL_AND_TIME64_SAME
2077 template bool vector4_to_value(const vvp_vector4_t&vec, bool&overflow_flag,
2078                                vvp_time64_t&val);
2079 #endif
2080 
vector4_to_value(const vvp_vector4_t & vec,double & val,bool signed_flag)2081 bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag)
2082 {
2083 
2084       if (vec.size() == 0) {
2085 	    val = 0.0;
2086 	    return true;
2087       }
2088 
2089       bool flag = true;
2090 
2091       if (vec.value(vec.size()-1) != BIT4_1) {
2092 	    signed_flag = false;
2093       }
2094 
2095       double res = 0.0;
2096       if (signed_flag) {
2097 	    vvp_bit4_t carry = BIT4_1;
2098 	    for (unsigned idx = 0 ;  idx < vec.size() ;  idx += 1) {
2099 		  vvp_bit4_t a = ~vec.value(idx);
2100 		  vvp_bit4_t x = add_with_carry(a, BIT4_0, carry);
2101 		  switch (x) {
2102 		      case BIT4_0:
2103 			break;
2104 		      case BIT4_1:
2105 			res += pow(2.0, (int)idx);
2106 			break;
2107 		      default:
2108 			flag = false;
2109 		  }
2110 	    }
2111 	    res *= -1.0;
2112       } else {
2113 	    for (unsigned idx = 0 ;  idx < vec.size() ;  idx += 1) {
2114 		  switch (vec.value(idx)) {
2115 		      case BIT4_0:
2116 			break;
2117 		      case BIT4_1:
2118 			res += pow(2.0, (int)idx);
2119 			break;
2120 		      default:
2121 			flag = false;
2122 		  }
2123 	    }
2124       }
2125       val = res;
2126       return flag;
2127 }
2128 
vector2_to_value(const vvp_vector2_t & a,int32_t & val,bool is_signed)2129 bool vector2_to_value(const vvp_vector2_t&a, int32_t&val, bool is_signed)
2130 {
2131       val = 0;
2132       unsigned idx;
2133       int32_t mask;
2134       for (idx = 0, mask = 1 ; idx < a.size() && idx < 32 ; idx += 1, mask <<= 1) {
2135 	    if (a.value(idx)) val |= mask;
2136       }
2137 
2138       if (is_signed && a.size() < 32 && a.value(a.size()-1)) {
2139 	    mask = -1;
2140 	    mask <<= a.size();
2141 	    val |= mask;
2142       }
2143 
2144       return a.size() <= 32;
2145 }
2146 
vvp_vector4array_t(unsigned width__,unsigned words__)2147 vvp_vector4array_t::vvp_vector4array_t(unsigned width__, unsigned words__)
2148 : width_(width__), words_(words__)
2149 {
2150 }
2151 
~vvp_vector4array_t()2152 vvp_vector4array_t::~vvp_vector4array_t()
2153 {
2154 }
2155 
set_word_(v4cell * cell,const vvp_vector4_t & that)2156 void vvp_vector4array_t::set_word_(v4cell*cell, const vvp_vector4_t&that)
2157 {
2158       assert(that.size_ == width_);
2159 
2160       if (width_ <= vvp_vector4_t::BITS_PER_WORD) {
2161 	    cell->abits_val_ = that.abits_val_;
2162 	    cell->bbits_val_ = that.bbits_val_;
2163 	    return;
2164       }
2165 
2166       unsigned cnt = (width_ + vvp_vector4_t::BITS_PER_WORD-1)/vvp_vector4_t::BITS_PER_WORD;
2167 
2168       if (cell->abits_ptr_ == 0) {
2169 	    cell->abits_ptr_ = new unsigned long[2*cnt];
2170 	    cell->bbits_ptr_ = cell->abits_ptr_ + cnt;
2171       }
2172 
2173       for (unsigned idx = 0 ; idx < cnt ; idx += 1)
2174 	    cell->abits_ptr_[idx] = that.abits_ptr_[idx];
2175       for (unsigned idx = 0 ; idx < cnt ; idx += 1)
2176 	    cell->bbits_ptr_[idx] = that.bbits_ptr_[idx];
2177 }
2178 
get_word_(v4cell * cell) const2179 vvp_vector4_t vvp_vector4array_t::get_word_(v4cell*cell) const
2180 {
2181       if (width_ <= vvp_vector4_t::BITS_PER_WORD) {
2182 	    vvp_vector4_t res;
2183 	    res.size_ = width_;
2184 	    res.abits_val_ = cell->abits_val_;
2185 	    res.bbits_val_ = cell->bbits_val_;
2186 	    return res;
2187       }
2188 
2189       vvp_vector4_t res (width_, BIT4_X);
2190       if (cell->abits_ptr_ == 0)
2191 	    return res;
2192 
2193       unsigned cnt = (width_ + vvp_vector4_t::BITS_PER_WORD-1)/vvp_vector4_t::BITS_PER_WORD;
2194 
2195       for (unsigned idx = 0 ; idx < cnt ; idx += 1)
2196 	    res.abits_ptr_[idx] = cell->abits_ptr_[idx];
2197       for (unsigned idx = 0 ; idx < cnt ; idx += 1)
2198 	    res.bbits_ptr_[idx] = cell->bbits_ptr_[idx];
2199 
2200       return res;
2201 }
2202 
vvp_vector4array_sa(unsigned width__,unsigned words__)2203 vvp_vector4array_sa::vvp_vector4array_sa(unsigned width__, unsigned words__)
2204 : vvp_vector4array_t(width__, words__)
2205 {
2206       array_ = new v4cell[words_];
2207 
2208       if (width_ <= vvp_vector4_t::BITS_PER_WORD) {
2209 	    for (unsigned idx = 0 ; idx < words_ ; idx += 1) {
2210 		  array_[idx].abits_val_ = vvp_vector4_t::WORD_X_ABITS;
2211 		  array_[idx].bbits_val_ = vvp_vector4_t::WORD_X_BBITS;
2212 	    }
2213       } else {
2214 	    for (unsigned idx = 0 ; idx < words_ ; idx += 1) {
2215 		  array_[idx].abits_ptr_ = 0;
2216 		  array_[idx].bbits_ptr_ = 0;
2217 	    }
2218       }
2219 }
2220 
~vvp_vector4array_sa()2221 vvp_vector4array_sa::~vvp_vector4array_sa()
2222 {
2223       if (array_) {
2224 	    if (width_ > vvp_vector4_t::BITS_PER_WORD) {
2225 		  for (unsigned idx = 0 ; idx < words_ ; idx += 1)
2226 			if (array_[idx].abits_ptr_)
2227 			      delete[]array_[idx].abits_ptr_;
2228 	    }
2229 	    delete[]array_;
2230       }
2231 }
2232 
set_word(unsigned index,const vvp_vector4_t & that)2233 void vvp_vector4array_sa::set_word(unsigned index, const vvp_vector4_t&that)
2234 {
2235       assert(index < words_);
2236 
2237       v4cell*cell = &array_[index];
2238 
2239       set_word_(cell, that);
2240 }
2241 
get_word(unsigned index) const2242 vvp_vector4_t vvp_vector4array_sa::get_word(unsigned index) const
2243 {
2244       if (index >= words_)
2245 	    return vvp_vector4_t(width_, BIT4_X);
2246 
2247       assert(index < words_);
2248 
2249       v4cell*cell = &array_[index];
2250 
2251       return get_word_(cell);
2252 }
2253 
vvp_vector4array_aa(unsigned width__,unsigned words__)2254 vvp_vector4array_aa::vvp_vector4array_aa(unsigned width__, unsigned words__)
2255 : vvp_vector4array_t(width__, words__)
2256 {
2257       context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
2258 }
2259 
~vvp_vector4array_aa()2260 vvp_vector4array_aa::~vvp_vector4array_aa()
2261 {
2262 }
2263 
alloc_instance(vvp_context_t context)2264 void vvp_vector4array_aa::alloc_instance(vvp_context_t context)
2265 {
2266       v4cell*array = new v4cell[words_];
2267 
2268       if (width_ <= vvp_vector4_t::BITS_PER_WORD) {
2269 	    for (unsigned idx = 0 ; idx < words_ ; idx += 1) {
2270 		  array[idx].abits_val_ = vvp_vector4_t::WORD_X_ABITS;
2271 		  array[idx].bbits_val_ = vvp_vector4_t::WORD_X_BBITS;
2272 	    }
2273       } else {
2274 	    for (unsigned idx = 0 ; idx < words_ ; idx += 1) {
2275 		  array[idx].abits_ptr_ = 0;
2276 		  array[idx].bbits_ptr_ = 0;
2277 	    }
2278       }
2279 
2280       vvp_set_context_item(context, context_idx_, array);
2281 }
2282 
reset_instance(vvp_context_t context)2283 void vvp_vector4array_aa::reset_instance(vvp_context_t context)
2284 {
2285       v4cell*cell = static_cast<v4cell*>
2286             (vvp_get_context_item(context, context_idx_));
2287 
2288       if (width_ <= vvp_vector4_t::BITS_PER_WORD) {
2289 	    for (unsigned idx = 0 ; idx < words_ ; idx += 1) {
2290 		  cell->abits_val_ = vvp_vector4_t::WORD_X_ABITS;
2291 		  cell->bbits_val_ = vvp_vector4_t::WORD_X_BBITS;
2292                   cell++;
2293 	    }
2294       } else {
2295             unsigned cnt = (width_ + vvp_vector4_t::BITS_PER_WORD-1)/vvp_vector4_t::BITS_PER_WORD;
2296 	    for (unsigned idx = 0 ; idx < words_ ; idx += 1) {
2297 		  if (cell->abits_ptr_) {
2298                         for (unsigned n = 0 ; n < cnt ; n += 1) {
2299 			      cell->abits_ptr_[n] = vvp_vector4_t::WORD_X_ABITS;
2300 			      cell->bbits_ptr_[n] = vvp_vector4_t::WORD_X_BBITS;
2301                         }
2302                   }
2303                   cell++;
2304 	    }
2305       }
2306 }
2307 
2308 #ifdef CHECK_WITH_VALGRIND
free_instance(vvp_context_t context)2309 void vvp_vector4array_aa::free_instance(vvp_context_t context)
2310 {
2311       v4cell*cell = static_cast<v4cell*>
2312             (vvp_get_context_item(context, context_idx_));
2313       delete [] cell;
2314 }
2315 #endif
2316 
set_word(unsigned index,const vvp_vector4_t & that)2317 void vvp_vector4array_aa::set_word(unsigned index, const vvp_vector4_t&that)
2318 {
2319       assert(index < words_);
2320 
2321       v4cell*cell = static_cast<v4cell*>
2322             (vthread_get_wt_context_item(context_idx_)) + index;
2323 
2324       set_word_(cell, that);
2325 }
2326 
get_word(unsigned index) const2327 vvp_vector4_t vvp_vector4array_aa::get_word(unsigned index) const
2328 {
2329       if (index >= words_)
2330 	    return vvp_vector4_t(width_, BIT4_X);
2331 
2332       assert(index < words_);
2333 
2334       v4cell*cell = static_cast<v4cell*>
2335             (vthread_get_rd_context_item(context_idx_)) + index;
2336 
2337       return get_word_(cell);
2338 }
2339 
vvp_vector2_t()2340 vvp_vector2_t::vvp_vector2_t()
2341 {
2342       vec_ = 0;
2343       wid_ = 0;
2344 }
2345 
vvp_vector2_t(unsigned long v,unsigned wid)2346 vvp_vector2_t::vvp_vector2_t(unsigned long v, unsigned wid)
2347 {
2348       wid_ = wid;
2349       const unsigned bits_per_word = 8 * sizeof(vec_[0]);
2350       const unsigned words = (wid_ + bits_per_word-1) / bits_per_word;
2351 
2352       vec_ = new unsigned long[words];
2353       vec_[0] = v;
2354       for (unsigned idx = 1 ;  idx < words ;  idx += 1)
2355 	    vec_[idx] = 0;
2356 }
2357 
vvp_vector2_t(vvp_vector2_t::fill_t fill,unsigned wid)2358 vvp_vector2_t::vvp_vector2_t(vvp_vector2_t::fill_t fill, unsigned wid)
2359 {
2360       wid_ = wid;
2361       const unsigned bits_per_word = 8 * sizeof(vec_[0]);
2362       const unsigned words = (wid_ + bits_per_word-1) / bits_per_word;
2363 
2364       vec_ = new unsigned long[words];
2365       for (unsigned idx = 0 ;  idx < words ;  idx += 1)
2366 	    vec_[idx] = fill? -1 : 0;
2367 }
2368 
vvp_vector2_t(const vvp_vector2_t & that,unsigned base,unsigned wid)2369 vvp_vector2_t::vvp_vector2_t(const vvp_vector2_t&that, unsigned base, unsigned wid)
2370 {
2371       wid_ = wid;
2372       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2373 
2374       vec_ = new unsigned long[words];
2375 
2376       for (unsigned idx = 0 ; idx < wid ; idx += 1) {
2377 	    int bit = that.value(base+idx);
2378 	    if (bit == 0)
2379 		  continue;
2380 	    unsigned word = idx / BITS_PER_WORD;
2381 	    unsigned long mask = 1UL << (idx % BITS_PER_WORD);
2382 	    vec_[word] |= mask;
2383       }
2384 }
2385 
copy_from_that_(const vvp_vector4_t & that)2386 void vvp_vector2_t::copy_from_that_(const vvp_vector4_t&that)
2387 {
2388       wid_ = that.size();
2389       const unsigned words = (that.size() + BITS_PER_WORD-1) / BITS_PER_WORD;
2390 
2391       if (words == 0) {
2392 	    vec_ = 0;
2393 	    wid_ = 0;
2394 	    return;
2395       }
2396 
2397 	// Use the subarray method with the xz_to_0 flag set so that
2398 	// we get values even when there are xz bits.
2399       vec_ = that.subarray(0, wid_, true);
2400 }
2401 
copy_from_that_(const vvp_vector2_t & that)2402 void vvp_vector2_t::copy_from_that_(const vvp_vector2_t&that)
2403 {
2404       wid_ = that.wid_;
2405       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2406 
2407       if (words == 0) {
2408 	    vec_ = 0;
2409 	    wid_ = 0;
2410 	    return;
2411       }
2412 
2413       vec_ = new unsigned long[words];
2414       for (unsigned idx = 0 ;  idx < words ;  idx += 1)
2415 	    vec_[idx] = that.vec_[idx];
2416 }
2417 
vvp_vector2_t(const vvp_vector2_t & that,unsigned newsize)2418 vvp_vector2_t::vvp_vector2_t(const vvp_vector2_t&that, unsigned newsize)
2419 {
2420       wid_ = newsize;
2421       if (newsize == 0) {
2422 	    vec_ = 0;
2423 	    return;
2424       }
2425 
2426       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2427       const unsigned twords = (that.wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2428 
2429       vec_ = new unsigned long[words];
2430       for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
2431 	    if (idx < twords)
2432 		  vec_[idx] = that.vec_[idx];
2433 	    else
2434 		  vec_[idx] = 0;
2435       }
2436 }
2437 
operator =(const vvp_vector2_t & that)2438 vvp_vector2_t& vvp_vector2_t::operator= (const vvp_vector2_t&that)
2439 {
2440       if (this == &that)
2441 	    return *this;
2442 
2443       delete[] vec_;
2444       vec_ = 0;
2445 
2446       copy_from_that_(that);
2447       return *this;
2448 }
2449 
operator =(const vvp_vector4_t & that)2450 vvp_vector2_t& vvp_vector2_t::operator= (const vvp_vector4_t&that)
2451 {
2452       delete[]vec_;
2453       vec_ = 0;
2454       copy_from_that_(that);
2455       return *this;
2456 }
2457 
operator <<=(unsigned int shift)2458 vvp_vector2_t& vvp_vector2_t::operator <<= (unsigned int shift)
2459 {
2460       if (wid_ == 0)
2461 	    return *this;
2462 
2463       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2464 
2465 	// Number of words to shift
2466       const unsigned wshift = shift / BITS_PER_WORD;
2467 	// bits to shift within each word.
2468       const unsigned long oshift = shift % BITS_PER_WORD;
2469 
2470 	// If shifting the entire value away, then return zeros.
2471       if (wshift >= words) {
2472 	    for (unsigned idx = 0 ;  idx < words ;  idx += 1)
2473 		  vec_[idx] = 0;
2474 
2475 	    return *this;
2476       }
2477 
2478 	// Do the word shift first.
2479       if (wshift > 0) {
2480 	    for (unsigned idx = 0 ;  idx < words-wshift ;  idx += 1) {
2481 		  unsigned sel = words - idx - 1;
2482 		  vec_[sel] = vec_[sel-wshift];
2483 	    }
2484 
2485 	    for (unsigned idx = 0 ;  idx < wshift ;  idx += 1)
2486 		  vec_[idx] = 0;
2487       }
2488 
2489 	// Do the fine shift.
2490       if (oshift != 0) {
2491 	    unsigned long pad = 0;
2492 	    for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
2493 		  unsigned long next_pad = vec_[idx] >> (BITS_PER_WORD-oshift);
2494 		  vec_[idx] = (vec_[idx] << oshift) | pad;
2495 		  pad = next_pad;
2496 	    }
2497 
2498 	      // Cleanup the tail bits.
2499 	    unsigned long mask = -1UL >> (BITS_PER_WORD - wid_%BITS_PER_WORD);
2500 	    vec_[words-1] &= mask;
2501       }
2502 
2503       return *this;
2504 }
2505 
operator >>=(unsigned shift)2506 vvp_vector2_t& vvp_vector2_t::operator >>= (unsigned shift)
2507 {
2508       if (wid_ == 0)
2509 	    return *this;
2510 
2511       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2512 
2513 	// Number of words to shift
2514       const unsigned wshift = shift / BITS_PER_WORD;
2515 	// bits to shift within each word.
2516       const unsigned long oshift = shift % BITS_PER_WORD;
2517 
2518 	// If shifting the entire value away, then return zeros.
2519       if (wshift >= words) {
2520 	    for (unsigned idx = 0 ;  idx < words ;  idx += 1)
2521 		  vec_[idx] = 0;
2522 
2523 	    return *this;
2524       }
2525 
2526       if (wshift > 0) {
2527 	    for (unsigned idx = 0 ;  idx < words-wshift ;  idx += 1)
2528 		  vec_[idx] = vec_[idx+wshift];
2529 
2530 	    for (unsigned idx = words-wshift ;  idx < words ;  idx += 1)
2531 		  vec_[idx] = 0;
2532       }
2533 
2534       if (oshift > 0) {
2535 	    unsigned long pad = 0;
2536 	    for (unsigned idx = words ;  idx > 0 ;  idx -= 1) {
2537 		  unsigned long new_pad = vec_[idx-1] <<(BITS_PER_WORD-oshift);
2538 		  vec_[idx-1] = pad | (vec_[idx-1] >> oshift);
2539 		  pad = new_pad;
2540 	    }
2541 
2542 	      // Cleanup the tail bits.
2543 
2544 	    unsigned use_words = words;
2545 	      // Mask_shift is the number of high bits of the top word
2546 	      // that are to be masked off. We start with the number
2547 	      // of bits that are not included even in the original,
2548 	      // then we include the bits of the shift, that are to be
2549 	      // masked to zero.
2550 	    unsigned long mask_shift = BITS_PER_WORD - wid_%BITS_PER_WORD;
2551 	    mask_shift %= BITS_PER_WORD;
2552 	    mask_shift += oshift;
2553 	    while (mask_shift >= BITS_PER_WORD) {
2554 		  vec_[use_words-1] = 0;
2555 		  use_words -= 1;
2556 		  mask_shift -= BITS_PER_WORD;
2557 	    }
2558 	    if (mask_shift > 0) {
2559 		  assert(use_words > 0);
2560 		  unsigned long mask = -1UL >> mask_shift;
2561 		  vec_[use_words-1] &= mask;
2562 	    }
2563       }
2564 
2565       return *this;
2566 }
2567 
add_carry(unsigned long a,unsigned long b,unsigned long & carry)2568 static unsigned long add_carry(unsigned long a, unsigned long b,
2569 			       unsigned long&carry)
2570 {
2571       unsigned long out = carry;
2572       carry = 0;
2573 
2574       if ((ULONG_MAX - out) < a)
2575 	    carry += 1;
2576       out += a;
2577 
2578       if ((ULONG_MAX - out) < b)
2579 	    carry += 1;
2580       out += b;
2581 
2582       return out;
2583 }
2584 
operator +=(const vvp_vector2_t & that)2585 vvp_vector2_t& vvp_vector2_t::operator += (const vvp_vector2_t&that)
2586 {
2587       assert(wid_ == that.wid_);
2588       if (wid_ == 0)
2589 	    return *this;
2590 
2591       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2592 
2593       unsigned long carry = 0;
2594       for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
2595 	    vec_[idx] = add_carry(vec_[idx], that.vec_[idx], carry);
2596       }
2597 
2598 
2599 	// Cleanup the tail bits.
2600       unsigned long mask = -1UL >> (BITS_PER_WORD - wid_%BITS_PER_WORD);
2601       vec_[words-1] &= mask;
2602 
2603       return *this;
2604 }
2605 
operator -=(const vvp_vector2_t & that)2606 vvp_vector2_t& vvp_vector2_t::operator -= (const vvp_vector2_t&that)
2607 {
2608       assert(wid_ == that.wid_);
2609       if (wid_ == 0)
2610 	    return *this;
2611 
2612       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2613 
2614       unsigned long carry = 1;
2615       for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
2616 	    vec_[idx] = add_carry(vec_[idx], ~that.vec_[idx], carry);
2617       }
2618 
2619       return *this;
2620 }
2621 
trim()2622 void vvp_vector2_t::trim()
2623 {
2624       while (value(wid_-1) == 0 && wid_ > 1) wid_ -= 1;
2625 }
2626 
2627 /* This is a special trim that is used on numbers we know represent a
2628  * negative signed value (they came from a negative real value). */
trim_neg()2629 void vvp_vector2_t::trim_neg()
2630 {
2631       if (value(wid_-1) == 1 && wid_ > 32) {
2632 	    while (value(wid_-2) == 1 && wid_ > 32) wid_ -= 1;
2633       }
2634 }
2635 
value(unsigned idx) const2636 int vvp_vector2_t::value(unsigned idx) const
2637 {
2638       if (idx >= wid_)
2639 	    return 0;
2640 
2641       const unsigned bits_per_word = 8 * sizeof(vec_[0]);
2642       unsigned addr = idx/bits_per_word;
2643       unsigned mask = idx%bits_per_word;
2644 
2645       if (vec_[addr] & (1UL<<mask))
2646 	    return 1;
2647       else
2648 	    return 0;
2649 }
2650 
set_bit(unsigned idx,int bit)2651 void vvp_vector2_t::set_bit(unsigned idx, int bit)
2652 {
2653       assert(idx < wid_);
2654 
2655       const unsigned bits_per_word = 8 * sizeof(vec_[0]);
2656       unsigned addr = idx/bits_per_word;
2657       unsigned long mask = idx%bits_per_word;
2658 
2659       if (bit)
2660 	    vec_[addr] |= 1UL << mask;
2661       else
2662 	    vec_[addr] &= ~(1UL << mask);
2663 }
2664 
set_vec(unsigned adr,const vvp_vector2_t & that)2665 void vvp_vector2_t::set_vec(unsigned adr, const vvp_vector2_t&that)
2666 {
2667       assert((adr + that.wid_) <= wid_);
2668 
2669       for (unsigned idx = 0 ; idx < that.wid_ ; idx += 1)
2670 	    set_bit(adr+idx, that.value(idx));
2671 }
2672 
is_NaN() const2673 bool vvp_vector2_t::is_NaN() const
2674 {
2675       return wid_ == 0;
2676 }
2677 
is_zero() const2678 bool vvp_vector2_t::is_zero() const
2679 {
2680       const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
2681 
2682       for (unsigned idx = 0; idx < words; idx += 1) {
2683 	    if (vec_[idx] == 0) continue;
2684 	    return false;
2685       }
2686 
2687       return true;
2688 }
2689 
2690 /*
2691  * Basic idea from "Introduction to Programming using SML" by
2692  * Michael R. Hansen and Hans Rischel page 261 and "Seminumerical
2693  * Algorithms, Third Edition" by Donald E. Knuth section 4.6.3.
2694  */
pow(const vvp_vector2_t & x,vvp_vector2_t & y)2695 vvp_vector2_t pow(const vvp_vector2_t&x, vvp_vector2_t&y)
2696 {
2697         /* If we have a zero exponent just return 1. */
2698       if (y == vvp_vector2_t(0L, 1)) {
2699 	    return vvp_vector2_t(1L, x.size());
2700       }
2701 
2702         /* Is the value odd? */
2703       if (y.value(0) == 1) {
2704 	    y.set_bit(0, 0);  // A quick subtract by 1.
2705 	    vvp_vector2_t res = x * pow(x, y);
2706 	    return res;
2707       }
2708 
2709       y >>= 1;  // A fast divide by two. We know the LSB is zero.
2710       vvp_vector2_t z = pow(x, y);
2711       vvp_vector2_t res = z * z;
2712       return res;
2713 }
2714 
multiply_long(unsigned long a,unsigned long b,unsigned long & low,unsigned long & high)2715 static void multiply_long(unsigned long a, unsigned long b,
2716 			  unsigned long&low, unsigned long&high)
2717 {
2718       assert(sizeof(unsigned long) %2 == 0);
2719 
2720       const unsigned long word_mask = (1UL << 4UL*sizeof(a)) - 1UL;
2721       unsigned long tmpa;
2722       unsigned long tmpb;
2723       unsigned long res[4];
2724 
2725       tmpa = a & word_mask;
2726       tmpb = b & word_mask;
2727       res[0] = tmpa * tmpb;
2728       res[1] = res[0] >> 4UL*sizeof(unsigned long);
2729       res[0] &= word_mask;
2730 
2731       tmpa = (a >> 4UL*sizeof(unsigned long)) & word_mask;
2732       tmpb = b & word_mask;
2733       res[1] += tmpa * tmpb;
2734       res[2] = res[1] >> 4UL*sizeof(unsigned long);
2735       res[1] &= word_mask;
2736 
2737       tmpa = a & word_mask;
2738       tmpb = (b >> 4UL*sizeof(unsigned long)) & word_mask;
2739       res[1] += tmpa * tmpb;
2740       res[2] += res[1] >> 4UL*sizeof(unsigned long);
2741       res[3]  = res[2] >> 4UL*sizeof(unsigned long);
2742       res[1] &= word_mask;
2743       res[2] &= word_mask;
2744 
2745       tmpa = (a >> 4UL*sizeof(unsigned long)) & word_mask;
2746       tmpb = (b >> 4UL*sizeof(unsigned long)) & word_mask;
2747       res[2] += tmpa * tmpb;
2748       res[3] += res[2] >> 4UL*sizeof(unsigned long);
2749       res[2] &= word_mask;
2750 
2751       high = (res[3] << 4UL*sizeof(unsigned long)) | res[2];
2752       low  = (res[1] << 4UL*sizeof(unsigned long)) | res[0];
2753 }
2754 
operator *(const vvp_vector2_t & a,const vvp_vector2_t & b)2755 vvp_vector2_t operator * (const vvp_vector2_t&a, const vvp_vector2_t&b)
2756 {
2757       const unsigned bits_per_word = 8 * sizeof(a.vec_[0]);
2758 
2759 	// The compiler ensures that the two operands are of equal size.
2760       assert(a.size() == b.size());
2761       vvp_vector2_t r (0, a.size());
2762 
2763       unsigned words = (r.wid_ + bits_per_word - 1) / bits_per_word;
2764 
2765       for (unsigned bdx = 0 ;  bdx < words ;  bdx += 1) {
2766 	    unsigned long tmpb = b.vec_[bdx];
2767 	    if (tmpb == 0)
2768 		  continue;
2769 
2770 	    for (unsigned adx = 0 ;  adx < words ;  adx += 1) {
2771 		  unsigned long tmpa = a.vec_[adx];
2772 		  if (tmpa == 0)
2773 			continue;
2774 
2775 		  unsigned long low, hig;
2776 		  multiply_long(tmpa, tmpb, low, hig);
2777 
2778 		  unsigned long carry = 0;
2779 		  for (unsigned sdx = 0
2780 			     ; (adx+bdx+sdx) < words
2781 			     ;  sdx += 1) {
2782 
2783 			r.vec_[adx+bdx+sdx] = add_carry(r.vec_[adx+bdx+sdx],
2784 							low, carry);
2785 			low = hig;
2786 			hig = 0;
2787 		  }
2788 	    }
2789       }
2790 
2791       return r;
2792 }
2793 
div_mod(vvp_vector2_t dividend,vvp_vector2_t divisor,vvp_vector2_t & quotient,vvp_vector2_t & remainder)2794 static void div_mod (vvp_vector2_t dividend, vvp_vector2_t divisor,
2795 		     vvp_vector2_t&quotient, vvp_vector2_t&remainder)
2796 {
2797 
2798       quotient = vvp_vector2_t(0, dividend.size());
2799 
2800       if (divisor == quotient) {
2801 	    cerr << "ERROR: division by zero, exiting." << endl;
2802 	    exit(255);
2803       }
2804 
2805       if (dividend < divisor) {
2806 	    remainder = dividend;
2807 	    return;
2808       }
2809 
2810       vvp_vector2_t mask (1, dividend.size());
2811 
2812 	// Make the dividend 1 bit larger to prevent overflow of
2813 	// divtmp in startup.
2814       dividend = vvp_vector2_t(dividend, dividend.size()+1);
2815       vvp_vector2_t divtmp (divisor, dividend.size());
2816 
2817       while (divtmp < dividend) {
2818 	    divtmp <<= 1;
2819 	    mask <<= 1;
2820       }
2821 
2822       while (dividend >= divisor) {
2823 	    if (divtmp <= dividend) {
2824 		  dividend -= divtmp;
2825 		  quotient += mask;
2826 	    }
2827 
2828 	    divtmp >>= 1;
2829 	    mask >>= 1;
2830       }
2831 
2832       remainder = vvp_vector2_t(dividend, mask.size());
2833 }
2834 
operator -(const vvp_vector2_t & that)2835 vvp_vector2_t operator - (const vvp_vector2_t&that)
2836 {
2837       vvp_vector2_t neg(that);
2838       if (neg.wid_ == 0) return neg;
2839 
2840       const unsigned words = (neg.wid_ + neg.BITS_PER_WORD-1) /
2841                                          neg.BITS_PER_WORD;
2842       for (unsigned idx = 0 ;  idx < words ;  idx += 1) {
2843 	    neg.vec_[idx] = ~neg.vec_[idx];
2844       }
2845       neg += vvp_vector2_t(1, neg.wid_);
2846 
2847       return neg;
2848 }
2849 
operator /(const vvp_vector2_t & dividend,const vvp_vector2_t & divisor)2850 vvp_vector2_t operator / (const vvp_vector2_t&dividend,
2851 			  const vvp_vector2_t&divisor)
2852 {
2853       vvp_vector2_t quot, rem;
2854       div_mod(dividend, divisor, quot, rem);
2855       return quot;
2856 }
2857 
operator %(const vvp_vector2_t & dividend,const vvp_vector2_t & divisor)2858 vvp_vector2_t operator % (const vvp_vector2_t&dividend,
2859 			  const vvp_vector2_t&divisor)
2860 {
2861       vvp_vector2_t quot, rem;
2862       div_mod(dividend, divisor, quot, rem);
2863       return rem;
2864 }
2865 
operator >(const vvp_vector2_t & a,const vvp_vector2_t & b)2866 bool operator > (const vvp_vector2_t&a, const vvp_vector2_t&b)
2867 {
2868       const unsigned awords = (a.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2869       const unsigned bwords = (b.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2870 
2871       const unsigned words = awords > bwords? awords : bwords;
2872 
2873       for (unsigned idx = words ;  idx > 0 ;  idx -= 1) {
2874 	    unsigned long aw = (idx <= awords)? a.vec_[idx-1] : 0;
2875 	    unsigned long bw = (idx <= bwords)? b.vec_[idx-1] : 0;
2876 
2877 	    if (aw > bw)
2878 		  return true;
2879 	    if (aw < bw)
2880 		  return false;
2881       }
2882 
2883 	// If the above loop finishes, then the vectors are equal.
2884       return false;
2885 }
2886 
operator >=(const vvp_vector2_t & a,const vvp_vector2_t & b)2887 bool operator >= (const vvp_vector2_t&a, const vvp_vector2_t&b)
2888 {
2889       const unsigned awords = (a.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2890       const unsigned bwords = (b.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2891 
2892       const unsigned words = awords > bwords? awords : bwords;
2893 
2894       for (unsigned idx = words ;  idx > 0 ;  idx -= 1) {
2895 	    unsigned long aw = (idx <= awords)? a.vec_[idx-1] : 0;
2896 	    unsigned long bw = (idx <= bwords)? b.vec_[idx-1] : 0;
2897 
2898 	    if (aw > bw)
2899 		  return true;
2900 	    if (aw < bw)
2901 		  return false;
2902       }
2903 
2904 	// If the above loop finishes, then the vectors are equal.
2905       return true;
2906 }
2907 
operator <(const vvp_vector2_t & a,const vvp_vector2_t & b)2908 bool operator < (const vvp_vector2_t&a, const vvp_vector2_t&b)
2909 {
2910       const unsigned awords = (a.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2911       const unsigned bwords = (b.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2912 
2913       unsigned words = awords;
2914       if (bwords > words)
2915 	    words = bwords;
2916 
2917       for (unsigned idx = words ;  idx > 0 ;  idx -= 1) {
2918 	    unsigned long aw = (idx <= awords)? a.vec_[idx-1] : 0;
2919 	    unsigned long bw = (idx <= bwords)? b.vec_[idx-1] : 0;
2920 
2921 	    if (aw < bw)
2922 		  return true;
2923 	    if (aw > bw)
2924 		  return false;
2925       }
2926 
2927 	// If the above loop finishes, then the vectors are equal.
2928       return false;
2929 }
2930 
operator <=(const vvp_vector2_t & a,const vvp_vector2_t & b)2931 bool operator <= (const vvp_vector2_t&a, const vvp_vector2_t&b)
2932 {
2933 	// XXXX For now, only support equal width vectors.
2934       assert(a.wid_ == b.wid_);
2935 
2936       const unsigned awords = (a.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2937 
2938       for (unsigned idx = awords ;  idx > 0 ;  idx -= 1) {
2939 	    if (a.vec_[idx-1] < b.vec_[idx-1])
2940 		  return true;
2941 	    if (a.vec_[idx-1] > b.vec_[idx-1])
2942 		  return false;
2943       }
2944 
2945 	// If the above loop finishes, then the vectors are equal.
2946       return true;
2947 }
2948 
operator ==(const vvp_vector2_t & a,const vvp_vector2_t & b)2949 bool operator == (const vvp_vector2_t&a, const vvp_vector2_t&b)
2950 {
2951       const unsigned awords = (a.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2952       const unsigned bwords = (b.wid_ + vvp_vector2_t::BITS_PER_WORD-1) / vvp_vector2_t::BITS_PER_WORD;
2953 
2954       const unsigned words = awords > bwords? awords : bwords;
2955 
2956       for (unsigned idx = words ;  idx > 0 ;  idx -= 1) {
2957 	    unsigned long aw = (idx <= awords)? a.vec_[idx-1] : 0;
2958 	    unsigned long bw = (idx <= bwords)? b.vec_[idx-1] : 0;
2959 
2960 	    if (aw > bw)
2961 		  return false;
2962 	    if (aw < bw)
2963 		  return false;
2964       }
2965 
2966 	// If the above loop finishes, then the vectors are equal.
2967       return true;
2968 }
2969 
2970 
vector2_to_vector4(const vvp_vector2_t & that,unsigned wid)2971 vvp_vector4_t vector2_to_vector4(const vvp_vector2_t&that, unsigned wid)
2972 {
2973       vvp_vector4_t res (wid);
2974 
2975       for (unsigned idx = 0 ;  idx < res.size() ;  idx += 1) {
2976 	    vvp_bit4_t bit = BIT4_0;
2977 
2978 	    if (that.value(idx))
2979 		  bit = BIT4_1;
2980 
2981 	    res.set_bit(idx, bit);
2982       }
2983 
2984       return res;
2985 }
2986 
c4string_test(const char * str)2987 bool c4string_test(const char*str)
2988 {
2989       if (strncmp(str, "C4<", 3) != 0)
2990 	    return false;
2991       size_t value_size = strspn(str+3, "01xz");
2992       if (str[3+value_size] != '>')
2993 	    return false;
2994       if (str[3+value_size+1] != 0)
2995 	    return false;
2996 
2997       return true;
2998 }
2999 
c4string_to_vector4(const char * str)3000 vvp_vector4_t c4string_to_vector4(const char*str)
3001 {
3002       assert((str[0]=='C') && (str[1]=='4') && (str[2]=='<'));
3003 
3004       str += 3;
3005       const char*tp = str + strspn(str,"01xz");
3006       assert(tp[0] == '>');
3007 
3008       vvp_vector4_t tmp (tp-str);
3009 
3010       for (unsigned idx = 0 ;  idx < tmp.size() ;  idx += 1) {
3011 	    vvp_bit4_t bit;
3012 	    switch (str[idx]) {
3013 		case '0':
3014 		  bit = BIT4_0;
3015 		  break;
3016 		case '1':
3017 		  bit = BIT4_1;
3018 		  break;
3019 		case 'x':
3020 		  bit = BIT4_X;
3021 		  break;
3022 		case 'z':
3023 		  bit = BIT4_Z;
3024 		  break;
3025 		default:
3026 		  fprintf(stderr, "Unsupported bit value %c(%d).\n", str[idx],
3027 		          str[idx]);
3028 		  assert(0);
3029 		  bit = BIT4_0;
3030 		  break;
3031 	    }
3032 	    tmp.set_bit(tmp.size()-idx-1, bit);
3033       }
3034 
3035       return tmp;
3036 }
3037 
operator <<(ostream & out,const vvp_vector2_t & that)3038 ostream& operator<< (ostream&out, const vvp_vector2_t&that)
3039 {
3040       if (that.is_NaN()) {
3041 	    out << "NaN";
3042 
3043       } else {
3044 	    out << vector2_to_vector4(that, that.size());
3045       }
3046       return out;
3047 }
3048 
vvp_vector8_t(const vvp_vector8_t & that)3049 vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
3050 {
3051       size_ = that.size_;
3052       if (size_ <= sizeof(val_)) {
3053 	    memcpy(val_, that.val_, sizeof val_);
3054       } else {
3055 	    ptr_ = new unsigned char[size_];
3056 	    memcpy(ptr_, that.ptr_, size_);
3057       }
3058 }
3059 
vvp_vector8_t(const vvp_vector4_t & that,unsigned str0,unsigned str1)3060 vvp_vector8_t::vvp_vector8_t(const vvp_vector4_t&that,
3061 			     unsigned str0, unsigned str1)
3062 : size_(that.size())
3063 {
3064       if (size_ == 0)
3065 	    return;
3066 
3067       if (size_ <= sizeof(val_)) {
3068 	    ptr_ = 0; // Prefill all val_ bytes
3069 	    for (unsigned idx = 0 ; idx < size_ ; idx += 1)
3070 		  val_[idx] = vvp_scalar_t(that.value(idx),str0, str1).raw();
3071       } else {
3072 	    ptr_ = new unsigned char[size_];
3073 	    for (unsigned idx = 0 ;  idx < size_ ;  idx += 1)
3074 		  ptr_[idx] = vvp_scalar_t(that.value(idx), str0, str1).raw();
3075       }
3076 }
3077 
vvp_vector8_t(const vvp_vector2_t & that,unsigned str0,unsigned str1)3078 vvp_vector8_t::vvp_vector8_t(const vvp_vector2_t&that,
3079 			     unsigned str0, unsigned str1)
3080 : size_(that.size())
3081 {
3082       if (size_ == 0)
3083 	    return;
3084 
3085       if (size_ <= sizeof(val_)) {
3086 	    ptr_ = 0;
3087 	    for (unsigned idx = 0 ; idx < size_ ; idx += 1)
3088 		  val_[idx] = vvp_scalar_t(that.value(idx)? BIT4_1:BIT4_0, str0, str1).raw();
3089       } else {
3090 	    ptr_ = new unsigned char[size_];
3091 	    for (unsigned idx = 0 ; idx < size_ ; idx += 1)
3092 		  ptr_[idx] = vvp_scalar_t(that.value(idx)? BIT4_1:BIT4_0, str0, str1).raw();
3093       }
3094 }
3095 
3096 const vvp_vector8_t vvp_vector8_t::nil;
3097 
operator =(const vvp_vector8_t & that)3098 vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
3099 {
3100 	// Assign to self.
3101       if (this == &that)
3102 	    return *this;
3103 
3104       if (size_ != that.size_) {
3105 	    if (size_ > sizeof(val_))
3106 		  delete[]ptr_;
3107 	    size_ = 0;
3108       }
3109 
3110       if (that.size_ == 0) {
3111 	    assert(size_ == 0);
3112 	    return *this;
3113       }
3114 
3115       if (that.size_ <= sizeof(val_)) {
3116 	    size_ = that.size_;
3117 	    memcpy(val_, that.val_, sizeof(val_));
3118 	    return *this;
3119       }
3120 
3121       if (size_ == 0) {
3122 	    size_ = that.size_;
3123 	    ptr_ = new unsigned char[size_];
3124       }
3125 
3126       memcpy(ptr_, that.ptr_, size_);
3127 
3128       return *this;
3129 }
3130 
subvalue(unsigned base,unsigned wid) const3131 vvp_vector8_t vvp_vector8_t::subvalue(unsigned base, unsigned wid) const
3132 {
3133       vvp_vector8_t tmp (wid);
3134 
3135       unsigned char*tmp_ptr = tmp.size_ <= sizeof(val_) ? tmp.val_ : tmp.ptr_;
3136       const unsigned char*use_ptr = size_ <= sizeof(val_) ? val_ : ptr_;
3137 
3138       unsigned idx = 0;
3139       while ((idx < wid) && (base+idx < size_)) {
3140 	    tmp_ptr[idx] = use_ptr[base+idx];
3141 	    idx += 1;
3142       }
3143 
3144       return tmp;
3145 }
3146 
set_vec(unsigned base,const vvp_vector8_t & that)3147 void vvp_vector8_t::set_vec(unsigned base, const vvp_vector8_t&that)
3148 {
3149       assert((base+that.size()) <= size());
3150       for (unsigned idx = 0 ; idx < that.size() ; idx += 1)
3151 	    set_bit(base+idx, that.value(idx));
3152 }
3153 
part_expand(const vvp_vector8_t & that,unsigned wid,unsigned off)3154 vvp_vector8_t part_expand(const vvp_vector8_t&that, unsigned wid, unsigned off)
3155 {
3156       assert(off < wid);
3157       vvp_vector8_t tmp (wid);
3158 
3159       unsigned char* tmp_ptr = tmp.size_<= sizeof(tmp.val_) ?
3160                                tmp.val_ : tmp.ptr_;
3161       const unsigned char* that_ptr = that.size_<= sizeof(that.val_) ?
3162                                       that.val_ : that.ptr_;
3163 
3164       unsigned idx = off;
3165 
3166       while (idx < wid && that.size_ > (idx-off)) {
3167 	    tmp_ptr[idx] = that_ptr[idx-off];
3168 	    idx += 1;
3169       }
3170 
3171       return tmp;
3172 }
3173 
c8string_test(const char * str)3174 bool c8string_test(const char*str)
3175 {
3176       const char*cp;
3177       if (str[0] != 'C') return false;
3178       if (str[1] != '8') return false;
3179       if (str[2] != '<') return false;
3180 
3181       cp = str+3;
3182       for (;; cp += 1) {
3183 	    if (cp[0] == '>' && cp[1] == 0) return true;
3184 	    if (cp[0] >= '0' && cp[0] <= '9') continue;
3185 	    if (cp[0] == 'x') continue;
3186 	    if (cp[0] == 'z') continue;
3187 	    return false;
3188       }
3189       return false;
3190 }
3191 /*
3192  * The format of a C8<> string is:
3193  *   C8<aaabbbccc...>
3194  * where aaa... is a 3 character bit descriptor.
3195  */
c8string_to_vector8(const char * str)3196 vvp_vector8_t c8string_to_vector8(const char*str)
3197 {
3198       size_t vsize = strlen(str)-4;
3199       assert(vsize%3 == 0);
3200       vsize /= 3;
3201       vvp_vector8_t tmp (vsize);
3202 
3203       for (size_t idx = 0 ; idx < vsize ; idx += 1) {
3204 	    const char*cp = str+3+3*idx;
3205 	    vvp_bit4_t bit = BIT4_X;
3206 	    unsigned dr0 = cp[0]-'0';
3207 	    unsigned dr1 = cp[1]-'0';
3208 	    switch (cp[2]) {
3209 		case '0':
3210 		  bit = BIT4_0;
3211 		  break;
3212 		case '1':
3213 		  bit = BIT4_1;
3214 		  break;
3215 		case 'x':
3216 		  bit = BIT4_X;
3217 		  break;
3218 		case 'z':
3219 		  bit = BIT4_Z;
3220 		  break;
3221 	    }
3222 	    tmp.set_bit(vsize-idx-1, vvp_scalar_t(bit, dr0, dr1));
3223       }
3224 
3225       return tmp;
3226 }
3227 
operator <<(ostream & out,const vvp_vector8_t & that)3228 ostream& operator<<(ostream&out, const vvp_vector8_t&that)
3229 {
3230       out << "C8<";
3231       for (unsigned idx = 0 ;  idx < that.size() ; idx += 1)
3232 	    out << that.value(that.size()-idx-1);
3233 
3234       out << ">";
3235       return out;
3236 }
3237 
vvp_net_fun_t()3238 vvp_net_fun_t::vvp_net_fun_t()
3239 {
3240       count_functors += 1;
3241 }
3242 
~vvp_net_fun_t()3243 vvp_net_fun_t::~vvp_net_fun_t()
3244 {
3245 }
3246 
recv_vec4(vvp_net_ptr_t,const vvp_vector4_t &,vvp_context_t)3247 void vvp_net_fun_t::recv_vec4(vvp_net_ptr_t, const vvp_vector4_t&,
3248                               vvp_context_t)
3249 {
3250       fprintf(stderr, "internal error: %s: recv_vec4 not implemented\n",
3251 	      typeid(*this).name());
3252       assert(0);
3253 }
3254 
recv_vec4_pv_(vvp_net_ptr_t p,const vvp_vector4_t & bit,unsigned base,unsigned wid,unsigned vwid,vvp_context_t)3255 void vvp_net_fun_t::recv_vec4_pv_(vvp_net_ptr_t p, const vvp_vector4_t&bit,
3256                                   unsigned base, unsigned wid, unsigned vwid,
3257                                   vvp_context_t)
3258 {
3259 	// The majority of functors don't normally expect to receive part
3260 	// values, because the primary operands of an expression will be
3261 	// extended to the expression width. But in the case that a primary
3262 	// operand is a wire that is only partly driven by a single driver,
3263 	// the part value driven onto the wire propagates directly to the
3264 	// inputs of any functors connected to that wire. In this case we
3265 	// know that the remaining bits are undriven, so can simply build
3266 	// the full width value from the part we have received.
3267 	//
3268 	// Note that this case is almost certainly a bug in the user's
3269 	// code, but we still need to handle it correctly. See GitHub
3270 	// issue #99 and br_gh99*.v in the test suite for examples.
3271 
3272       assert(bit.size() == wid);
3273       assert(base + wid <= vwid);
3274 
3275       vvp_vector4_t tmp(vwid, BIT4_Z);
3276       tmp.set_vec(base, bit);
3277       recv_vec4(p, tmp, 0);
3278 }
3279 
recv_vec4_pv(vvp_net_ptr_t,const vvp_vector4_t & bit,unsigned base,unsigned wid,unsigned vwid,vvp_context_t)3280 void vvp_net_fun_t::recv_vec4_pv(vvp_net_ptr_t, const vvp_vector4_t&bit,
3281                                  unsigned base, unsigned wid, unsigned vwid,
3282                                  vvp_context_t)
3283 {
3284       cerr << "internal error: " << typeid(*this).name() << ": "
3285 	   << "recv_vec4_pv(" << bit << ", " << base
3286 	   << ", " << wid << ", " << vwid << ") not implemented" << endl;
3287       assert(0);
3288 }
3289 
recv_vec8(vvp_net_ptr_t port,const vvp_vector8_t & bit)3290 void vvp_net_fun_t::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
3291 {
3292       recv_vec4(port, reduce4(bit), 0);
3293 }
3294 
recv_vec8_pv_(vvp_net_ptr_t p,const vvp_vector8_t & bit,unsigned base,unsigned wid,unsigned vwid)3295 void vvp_net_fun_t::recv_vec8_pv_(vvp_net_ptr_t p, const vvp_vector8_t&bit,
3296 				  unsigned base, unsigned wid, unsigned vwid)
3297 {
3298 	// This is the strength-aware version of recv_vec4_pv_.
3299 
3300       assert(bit.size() == wid);
3301       assert(base + wid <= vwid);
3302 
3303       vvp_vector8_t tmp(vwid);
3304       tmp.set_vec(base, bit);
3305       recv_vec8(p, tmp);
3306 }
3307 
recv_vec8_pv(vvp_net_ptr_t port,const vvp_vector8_t & bit,unsigned base,unsigned wid,unsigned vwid)3308 void vvp_net_fun_t::recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit,
3309 				 unsigned base, unsigned wid, unsigned vwid)
3310 {
3311       recv_vec4_pv(port, reduce4(bit), base, wid, vwid, 0);
3312 }
3313 
recv_real(vvp_net_ptr_t,double bit,vvp_context_t)3314 void vvp_net_fun_t::recv_real(vvp_net_ptr_t, double bit, vvp_context_t)
3315 {
3316       fprintf(stderr, "internal error: %s: recv_real(%f) not implemented\n",
3317 	      typeid(*this).name(), bit);
3318       assert(0);
3319 }
3320 
recv_long(vvp_net_ptr_t,long)3321 void vvp_net_fun_t::recv_long(vvp_net_ptr_t, long)
3322 {
3323       fprintf(stderr, "internal error: %s: recv_long not implemented\n",
3324 	      typeid(*this).name());
3325       assert(0);
3326 }
3327 
recv_long_pv(vvp_net_ptr_t,long,unsigned,unsigned)3328 void vvp_net_fun_t::recv_long_pv(vvp_net_ptr_t, long, unsigned, unsigned)
3329 {
3330       fprintf(stderr, "internal error: %s: recv_long_pv not implemented\n",
3331 	      typeid(*this).name());
3332       assert(0);
3333 }
3334 
recv_string(vvp_net_ptr_t,const std::string & bit,vvp_context_t)3335 void vvp_net_fun_t::recv_string(vvp_net_ptr_t, const std::string&bit, vvp_context_t)
3336 {
3337       fprintf(stderr, "internal error: %s: recv_string(%s) not implemented\n",
3338 	      typeid(*this).name(), bit.c_str());
3339       assert(0);
3340 }
3341 
recv_object(vvp_net_ptr_t,vvp_object_t,vvp_context_t)3342 void vvp_net_fun_t::recv_object(vvp_net_ptr_t, vvp_object_t, vvp_context_t)
3343 {
3344       fprintf(stderr, "internal error: %s: recv_object(...) not implemented\n",
3345 	      typeid(*this).name());
3346       assert(0);
3347 }
3348 
force_flag(bool)3349 void vvp_net_fun_t::force_flag(bool)
3350 {
3351 }
3352 
3353 /* **** vvp_fun_drive methods **** */
3354 
vvp_fun_drive(unsigned str0,unsigned str1)3355 vvp_fun_drive::vvp_fun_drive(unsigned str0, unsigned str1)
3356 {
3357       assert(str0 < 8);
3358       assert(str1 < 8);
3359 
3360       drive0_ = str0;
3361       drive1_ = str1;
3362 }
3363 
~vvp_fun_drive()3364 vvp_fun_drive::~vvp_fun_drive()
3365 {
3366 }
3367 
recv_vec4(vvp_net_ptr_t port,const vvp_vector4_t & bit,vvp_context_t)3368 void vvp_fun_drive::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
3369                               vvp_context_t)
3370 {
3371       assert(port.port() == 0);
3372       port.ptr()->send_vec8(vvp_vector8_t(bit, drive0_, drive1_));
3373 }
3374 
recv_vec4_pv(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,unsigned base,unsigned wid,unsigned vwid,vvp_context_t ctx)3375 void vvp_fun_drive::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
3376 				 unsigned base, unsigned wid, unsigned vwid,
3377 				 vvp_context_t ctx)
3378 {
3379       recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
3380 }
3381 
3382 /* **** vvp_wide_fun_* methods **** */
3383 
vvp_wide_fun_core(vvp_net_t * net,unsigned nports)3384 vvp_wide_fun_core::vvp_wide_fun_core(vvp_net_t*net, unsigned nports)
3385 {
3386       ptr_ = net;
3387       nports_ = nports;
3388       port_values_ = 0;
3389       port_rvalues_ = 0;
3390 }
3391 
~vvp_wide_fun_core()3392 vvp_wide_fun_core::~vvp_wide_fun_core()
3393 {
3394       delete[] port_values_;
3395       delete[] port_rvalues_;
3396 }
3397 
propagate_vec4(const vvp_vector4_t & bit,vvp_time64_t delay)3398 void vvp_wide_fun_core::propagate_vec4(const vvp_vector4_t&bit,
3399 				       vvp_time64_t delay)
3400 {
3401       if (delay)
3402 	    schedule_propagate_vector(ptr_, delay, bit);
3403       else
3404 	    ptr_->send_vec4(bit, 0);
3405 }
3406 
propagate_real(double bit,vvp_time64_t delay)3407 void vvp_wide_fun_core::propagate_real(double bit,
3408 				       vvp_time64_t delay)
3409 {
3410       if (delay) {
3411 	      // schedule_assign_vector(ptr_->out, bit, delay);
3412 	    assert(0); // Need a real-value version of assign_vector.
3413       } else {
3414 	    ptr_->send_real(bit, 0);
3415       }
3416 }
3417 
3418 
port_count() const3419 unsigned vvp_wide_fun_core::port_count() const
3420 {
3421       return nports_;
3422 }
3423 
value(unsigned idx)3424 vvp_vector4_t& vvp_wide_fun_core::value(unsigned idx)
3425 {
3426       assert(idx < nports_);
3427       if (port_values_ == 0)
3428 	    port_values_ = new vvp_vector4_t [nports_];
3429       return port_values_[idx];
3430 }
3431 
value_r(unsigned idx)3432 double vvp_wide_fun_core::value_r(unsigned idx)
3433 {
3434       assert(idx < nports_);
3435       return port_rvalues_? port_rvalues_[idx] : 0.0;
3436 }
3437 
recv_real_from_inputs(unsigned)3438 void vvp_wide_fun_core::recv_real_from_inputs(unsigned)
3439 {
3440       assert(0);
3441 }
3442 
dispatch_vec4_from_input_(unsigned port,vvp_vector4_t bit)3443 void vvp_wide_fun_core::dispatch_vec4_from_input_(unsigned port,
3444 						   vvp_vector4_t bit)
3445 {
3446       assert(port < nports_);
3447       if (port_values_ == 0) port_values_ = new vvp_vector4_t [nports_];
3448       port_values_[port] = bit;
3449       recv_vec4_from_inputs(port);
3450 }
3451 
dispatch_real_from_input_(unsigned port,double bit)3452 void vvp_wide_fun_core::dispatch_real_from_input_(unsigned port,
3453 						  double bit)
3454 {
3455       assert(port < nports_);
3456       if (port_rvalues_ == 0) port_rvalues_ = new double[nports_];
3457       port_rvalues_[port] = bit;
3458       recv_real_from_inputs(port);
3459 }
3460 
vvp_wide_fun_t(vvp_wide_fun_core * c,unsigned base)3461 vvp_wide_fun_t::vvp_wide_fun_t(vvp_wide_fun_core*c, unsigned base)
3462 : core_(c), port_base_(base)
3463 {
3464 }
3465 
~vvp_wide_fun_t()3466 vvp_wide_fun_t::~vvp_wide_fun_t()
3467 {
3468 }
3469 
recv_vec4(vvp_net_ptr_t port,const vvp_vector4_t & bit,vvp_context_t)3470 void vvp_wide_fun_t::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
3471                                vvp_context_t)
3472 {
3473       unsigned pidx = port_base_ + port.port();
3474       core_->dispatch_vec4_from_input_(pidx, bit);
3475 }
3476 
recv_vec4_pv(vvp_net_ptr_t ptr,const vvp_vector4_t & bit,unsigned base,unsigned wid,unsigned vwid,vvp_context_t ctx)3477 void vvp_wide_fun_t::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
3478 				  unsigned base, unsigned wid, unsigned vwid,
3479 				  vvp_context_t ctx)
3480 {
3481       recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
3482 }
3483 
recv_real(vvp_net_ptr_t port,double bit,vvp_context_t)3484 void vvp_wide_fun_t::recv_real(vvp_net_ptr_t port, double bit,
3485                                vvp_context_t)
3486 {
3487       unsigned pidx = port_base_ + port.port();
3488       core_->dispatch_real_from_input_(pidx, bit);
3489 }
3490 
3491 /* **** vvp_scalar_t methods **** */
3492 
3493 /*
3494  * DRIVE STRENGTHS:
3495  *
3496  * The normal functor is not aware of strengths. It generates strength
3497  * simply by virtue of having strength specifications. The drive
3498  * strength specification includes a drive0 and drive1 strength, each
3499  * with 8 possible values (that can be represented in 3 bits) as given
3500  * in this table:
3501  *
3502  *    HiZ    = 0,
3503  *    SMALL  = 1,
3504  *    MEDIUM = 2,
3505  *    WEAK   = 3,
3506  *    LARGE  = 4,
3507  *    PULL   = 5,
3508  *    STRONG = 6,
3509  *    SUPPLY = 7
3510  *
3511  * The vvp_scalar_t value, however, is a combination of value and
3512  * strength, used in strength-aware contexts.
3513  *
3514  * OUTPUT STRENGTHS:
3515  *
3516  * The strength-aware values are specified as an 8 bit value, that is
3517  * two 4 bit numbers. The value is encoded with two drive strengths (0-7)
3518  * and two drive values (0 or 1). Each nibble contains three bits of
3519  * strength and one bit of value, like so: VSSS. The high nibble has
3520  * the strength-value closest to supply1, and the low nibble has the
3521  * strength-value closest to supply0.
3522  */
3523 
3524 /*
3525  * A signal value is unambiguous if the top 4 bits and the bottom 4
3526  * bits are identical. This means that the VSSSvsss bits of the 8bit
3527  * value have V==v and SSS==sss.
3528  */
3529 # define UNAMBIG(v)  (((v) & 0x0f) == (((v) >> 4) & 0x0f))
3530 
3531 # define STREN1(v) (((v)&0x70) >> 4)
3532 # define STREN0(v) ((v)&0x07)
3533 
strength0() const3534 unsigned vvp_scalar_t::strength0() const
3535 {
3536       return STREN0(value_);
3537 }
3538 
strength1() const3539 unsigned vvp_scalar_t::strength1() const
3540 {
3541       return STREN1(value_);
3542 }
3543 
operator <<(ostream & out,vvp_scalar_t a)3544 ostream& operator <<(ostream&out, vvp_scalar_t a)
3545 {
3546       out << a.strength0() << a.strength1();
3547       switch (a.value()) {
3548 	  case BIT4_0:
3549 	    out << "0";
3550 	    break;
3551 	  case BIT4_1:
3552 	    out << "1";
3553 	    break;
3554 	  case BIT4_X:
3555 	    out << "X";
3556 	    break;
3557 	  case BIT4_Z:
3558 	    out << "Z";
3559 	    break;
3560       }
3561       return out;
3562 }
3563 
3564 /*
3565  * This function is only called if the actual interface function rules
3566  * out some of the easy cases. If we get here, we can assume that
3567  * neither of the values is HiZ, and the values are not exactly equal.
3568  */
fully_featured_resolv_(vvp_scalar_t a,vvp_scalar_t b)3569 vvp_scalar_t fully_featured_resolv_(vvp_scalar_t a, vvp_scalar_t b)
3570 {
3571 
3572       if (UNAMBIG(a.value_) && UNAMBIG(b.value_)) {
3573 
3574 	      /* If both signals are unambiguous, simply choose
3575 		 the stronger. If they have the same strength
3576 		 but different values, then this becomes
3577 		 ambiguous. */
3578 
3579 	    if ((b.value_&0x07) > (a.value_&0x07)) {
3580 
3581 		    /* b value is stronger. Take it. */
3582 		  return b;
3583 
3584 	    } else if ((b.value_&0x77) == (a.value_&0x77)) {
3585 
3586 		    // Strengths are the same. Since we know already
3587 		    // that the values are not the same, Make value
3588 		    // into "x".
3589 		  vvp_scalar_t tmp (a);
3590 		  tmp.value_ = (tmp.value_&0x77) | 0x80;
3591 		  return tmp;
3592 
3593 	    } else {
3594 
3595 		    /* Must be "a" is the stronger one. */
3596 		  return a;
3597 	    }
3598 
3599       }
3600 
3601 	/* If one of the signals is unambiguous, then it
3602 	   will sweep up the weaker parts of the ambiguous
3603 	   signal. The result may be ambiguous, or maybe not. */
3604 
3605       if (UNAMBIG(a.value_)) {
3606 	    vvp_scalar_t res;
3607 
3608 	    if ((a.value_&0x70) > (b.value_&0x70))
3609 		  res.value_ |= a.value_&0xf0;
3610 	    else
3611 		  res.value_ |= b.value_&0xf0;
3612 
3613 	    if ((a.value_&0x07) > (b.value_&0x07))
3614 		  res.value_ |= a.value_&0x0f;
3615 	    else
3616 		  res.value_ |= b.value_&0x0f;
3617 
3618 	    return res;
3619 
3620       } else if (UNAMBIG(b.value_)) {
3621 
3622 	    vvp_scalar_t res;
3623 
3624 	    if ((b.value_&0x70) > (a.value_&0x70))
3625 		  res.value_ |= b.value_&0xf0;
3626 	    else
3627 		  res.value_ |= a.value_&0xf0;
3628 
3629 	    if ((b.value_&0x07) > (a.value_&0x07))
3630 		  res.value_ |= b.value_&0x0f;
3631 	    else
3632 		  res.value_ |= a.value_&0x0f;
3633 
3634 	    return res;
3635 
3636       }
3637 
3638 
3639 	/* If both signals are ambiguous, then the result
3640 	   has an even wider ambiguity. */
3641 
3642       unsigned tmp = 0;
3643       int sv1a = (a.value_ & 0x80) ? STREN1(a.value_) : - STREN1(a.value_);
3644       int sv0a = (a.value_ & 0x08) ? STREN0(a.value_) : - STREN0(a.value_);
3645       int sv1b = (b.value_ & 0x80) ? STREN1(b.value_) : - STREN1(b.value_);
3646       int sv0b = (b.value_ & 0x08) ? STREN0(b.value_) : - STREN0(b.value_);
3647 
3648       int sv1 = sv1a;
3649       int sv0 = sv0a;
3650 
3651       if (sv0a > sv1)
3652 	    sv1 = sv0a;
3653       if (sv1b > sv1)
3654 	    sv1 = sv1b;
3655       if (sv0b > sv1)
3656 	    sv1 = sv0b;
3657 
3658       if (sv1a < sv0)
3659 	    sv0 = sv1a;
3660       if (sv1b < sv0)
3661 	    sv0 = sv1b;
3662       if (sv0b < sv0)
3663 	    sv0 = sv0b;
3664 
3665       if (sv1 > 0) {
3666 	    tmp |= 0x80;
3667 	    tmp |= sv1 << 4;
3668       } else {
3669 	      /* Set the MSB when both arguments MSBs are set. This
3670 		 can only happen if both one strengths are zero. */
3671 	    tmp |= (a.value_&b.value_)&0x80;
3672 	    tmp |= (-sv1) << 4;
3673       }
3674 
3675       if (sv0 > 0) {
3676 	    tmp |= 0x08;
3677 	    tmp |= sv0;
3678       } else {
3679 	    tmp |= (-sv0);
3680       }
3681 
3682       vvp_scalar_t res;
3683       res.value_ = tmp;
3684 
3685 	/* Canonicalize the HiZ value. */
3686       if ((res.value_&0x77) == 0)
3687 	    res.value_ = 0;
3688 
3689       return res;
3690 }
3691 
3692 unsigned vvp_switch_strength_map[2][8] = {
3693       {  // non-resistive
3694 	    0, /* High impedance   --> High impedance   */
3695 	    1, /* Small capacitor  --> Small capacitor  */
3696 	    2, /* Medium capacitor --> Medium capacitor */
3697 	    3, /* Weak drive       --> Weak drive       */
3698 	    4, /* Large capacitor  --> Large capacitor  */
3699 	    5, /* Pull drive       --> Pull drive       */
3700 	    6, /* Strong drive     --> Strong drive     */
3701 	    6  /* Supply drive     --> Strong drive     */
3702       },
3703       {  // resistive
3704 	    0, /* High impedance   --> High impedance   */
3705 	    1, /* Small capacitor  --> Small capacitor  */
3706 	    1, /* Medium capacitor --> Small capacitor  */
3707 	    2, /* Weak drive       --> Medium capacitor */
3708 	    2, /* Large capacitor  --> Medium capacitor */
3709 	    3, /* Pull drive       --> Weak drive       */
3710 	    5, /* Strong drive     --> Pull drive       */
3711 	    5  /* Supply drive     --> Pull drive       */
3712       }
3713 };
3714 
reduce4(const vvp_vector8_t & that)3715 vvp_vector4_t reduce4(const vvp_vector8_t&that)
3716 {
3717       vvp_vector4_t out (that.size());
3718       for (unsigned idx = 0 ;  idx < out.size() ;  idx += 1)
3719 	    out.set_bit(idx, that.value(idx).value());
3720 
3721       return out;
3722 }
3723 
compare_gtge(const vvp_vector4_t & lef,const vvp_vector4_t & rig,vvp_bit4_t out_if_equal)3724 vvp_bit4_t compare_gtge(const vvp_vector4_t&lef, const vvp_vector4_t&rig,
3725 			vvp_bit4_t out_if_equal)
3726 {
3727       unsigned min_size = lef.size();
3728       if (rig.size() < min_size)
3729 	    min_size = rig.size();
3730 
3731 	// If one of the inputs is nil, treat is as all X values, and
3732 	// that makes the result BIT4_X.
3733       if (min_size == 0)
3734 	    return BIT4_X;
3735 
3736 	// As per the IEEE1364 definition of >, >=, < and <=, if there
3737 	// are any X or Z values in either of the operand vectors,
3738 	// then the result of the compare is BIT4_X.
3739 
3740 	// Check for X/Z in the left operand
3741       if (lef.has_xz())
3742 	    return BIT4_X;
3743 
3744 	// Check for X/Z in the right operand
3745       if (rig.has_xz())
3746 	    return BIT4_X;
3747 
3748       for (unsigned idx = lef.size() ; idx > rig.size() ;  idx -= 1) {
3749 	    if (lef.value(idx-1) == BIT4_1)
3750 		  return BIT4_1;
3751       }
3752 
3753       for (unsigned idx = rig.size() ; idx > lef.size() ;  idx -= 1) {
3754 	    if (rig.value(idx-1) == BIT4_1)
3755 		  return BIT4_0;
3756       }
3757 
3758       for (unsigned idx = min_size ; idx > 0 ;  idx -= 1) {
3759 	    vvp_bit4_t lv = lef.value(idx-1);
3760 	    vvp_bit4_t rv = rig.value(idx-1);
3761 
3762 	    if (lv == rv)
3763 		  continue;
3764 
3765 	    if (lv == BIT4_1)
3766 		  return BIT4_1;
3767 	    else
3768 		  return BIT4_0;
3769       }
3770 
3771       return out_if_equal;
3772 }
3773 
compare_gtge_signed(const vvp_vector4_t & a,const vvp_vector4_t & b,vvp_bit4_t out_if_equal)3774 vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
3775 			       const vvp_vector4_t&b,
3776 			       vvp_bit4_t out_if_equal)
3777 {
3778       assert(a.size() == b.size());
3779 
3780       unsigned sign_idx = a.size()-1;
3781       vvp_bit4_t a_sign = a.value(sign_idx);
3782       vvp_bit4_t b_sign = b.value(sign_idx);
3783 
3784       if (bit4_is_xz(a_sign))
3785 	    return BIT4_X;
3786       if (bit4_is_xz(b_sign))
3787 	    return BIT4_X;
3788 
3789       if (a_sign == b_sign)
3790 	    return compare_gtge(a, b, out_if_equal);
3791 
3792       if (a.has_xz())
3793 	    return BIT4_X;
3794 
3795       if (b.has_xz())
3796 	    return BIT4_X;
3797 
3798       if(a_sign == BIT4_0)
3799 	    return BIT4_1;
3800       else
3801 	    return BIT4_0;
3802 }
3803