1 #ifndef IVL_vvp_net_H
2 #define IVL_vvp_net_H
3 /*
4 * Copyright (c) 2004-2018 Stephen Williams (steve@icarus.com)
5 *
6 * This source code is free software; you can redistribute it
7 * and/or modify it in source code form under the terms of the GNU
8 * General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 # include "config.h"
23 # include "vpi_user.h"
24 # include "vvp_vpi_callback.h"
25 # include "permaheap.h"
26 # include "vvp_object.h"
27 # include <cstddef>
28 # include <cstdlib>
29 # include <cstring>
30 # include <string>
31 # include <new>
32 # include <cassert>
33
34 #ifdef HAVE_IOSFWD
35 # include <iosfwd>
36 #else
37 class ostream;
38 #endif
39
40 # include "ivl_alloc.h"
41
42 using namespace std;
43
44
45 /* Data types */
46 class vvp_scalar_t;
47
48 class vvp_vector2_t;
49 class vvp_vector4_t;
50 class vvp_vector8_t;
51
52 /* Basic netlist types. */
53 class vvp_net_t;
54 class vvp_net_fun_t;
55 class vvp_net_fil_t;
56
57 /* Core net function types. */
58 class vvp_fun_concat;
59 class vvp_fun_drive;
60 class vvp_fun_part;
61
62 class vvp_delay_t;
63
64 /*
65 * Storage for items declared in automatically allocated scopes (i.e. automatic
66 * tasks and functions). The first two slots in each context are reserved for
67 * linking to other contexts. The function that adds items to a context knows
68 * this, and allocates context indices accordingly.
69 */
70 typedef void**vvp_context_t;
71
72 typedef void*vvp_context_item_t;
73
vvp_allocate_context(unsigned nitem)74 inline vvp_context_t vvp_allocate_context(unsigned nitem)
75 {
76 return (vvp_context_t)malloc((2 + nitem) * sizeof(void*));
77 }
78
vvp_get_next_context(vvp_context_t context)79 inline vvp_context_t vvp_get_next_context(vvp_context_t context)
80 {
81 return (vvp_context_t)context[0];
82 }
83
vvp_set_next_context(vvp_context_t context,vvp_context_t next)84 inline void vvp_set_next_context(vvp_context_t context, vvp_context_t next)
85 {
86 context[0] = next;
87 }
88
vvp_get_stacked_context(vvp_context_t context)89 inline vvp_context_t vvp_get_stacked_context(vvp_context_t context)
90 {
91 return (vvp_context_t)context[1];
92 }
93
vvp_set_stacked_context(vvp_context_t context,vvp_context_t stack)94 inline void vvp_set_stacked_context(vvp_context_t context, vvp_context_t stack)
95 {
96 context[1] = stack;
97 }
98
vvp_get_context_item(vvp_context_t context,unsigned item_idx)99 inline vvp_context_item_t vvp_get_context_item(vvp_context_t context,
100 unsigned item_idx)
101 {
102 return (vvp_context_item_t)context[item_idx];
103 }
104
vvp_set_context_item(vvp_context_t context,unsigned item_idx,vvp_context_item_t item)105 inline void vvp_set_context_item(vvp_context_t context, unsigned item_idx,
106 vvp_context_item_t item)
107 {
108 context[item_idx] = item;
109 }
110
111 /*
112 * An "automatic" functor is one which may be associated with an automatically
113 * allocated scope item. This provides the infrastructure needed to allocate
114 * the state information for individual instances of the item.
115 */
116 struct automatic_hooks_s {
117
automatic_hooks_sautomatic_hooks_s118 automatic_hooks_s() {}
~automatic_hooks_sautomatic_hooks_s119 virtual ~automatic_hooks_s() {}
120
121 virtual void alloc_instance(vvp_context_t context) = 0;
122 virtual void reset_instance(vvp_context_t context) = 0;
123 #ifdef CHECK_WITH_VALGRIND
124 virtual void free_instance(vvp_context_t context) = 0;
125 #endif
126 };
127
128 /*
129 * This is the set of Verilog 4-value bit values. Scalars have this
130 * value along with strength, vectors are a collection of these
131 * values. The enumeration has fixed numeric values that can be
132 * expressed in 2 real bits, so that some of the internal classes can
133 * pack them tightly.
134 *
135 * WARNING: Many things rely on this encoding for the BIT4_* enumeration
136 * values, so accept that these values are cast in stone.
137 */
138 enum vvp_bit4_t {
139 BIT4_0 = 0,
140 BIT4_1 = 1,
141 BIT4_X = 3,
142 BIT4_Z = 2
143 };
144
145 /* Return an ASCII character that represents the vvp_bit4_t value. */
vvp_bit4_to_ascii(vvp_bit4_t a)146 inline char vvp_bit4_to_ascii(vvp_bit4_t a) { return "01zx"[a]; }
147
148 extern vvp_bit4_t add_with_carry(vvp_bit4_t a, vvp_bit4_t b, vvp_bit4_t&c);
149
150 extern vvp_bit4_t scalar_to_bit4(PLI_INT32 scalar);
151
152 /* Return TRUE if the bit is BIT4_X or BIT4_Z. The fast
153 implementation here relies on the encoding of vvp_bit4_t values. */
bit4_is_xz(vvp_bit4_t a)154 inline bool bit4_is_xz(vvp_bit4_t a) { return a >= 2; }
155
156 /* This function converts BIT4_Z to BIT4_X, but passes other values
157 unchanged. This fast implementation relies of the encoding of the
158 vvp_bit4_t values. In particular, the BIT4_X==3 and BIT4_Z==2 */
bit4_z2x(vvp_bit4_t a)159 inline vvp_bit4_t bit4_z2x(vvp_bit4_t a)
160 { return (vvp_bit4_t) ( (int)a | ((int)a >> 1) ); }
161
162 /* Some common boolean operators. These implement the Verilog rules
163 for 4-value bit operations. The fast implementations here rely
164 on the encoding of vvp_bit4_t values. */
165
166 // ~BIT4_0 --> BIT4_1
167 // ~BIT4_1 --> BIT4_0
168 // ~BIT4_X --> BIT4_X
169 // ~BIT4_Z --> BIT4_X
170 inline vvp_bit4_t operator ~ (vvp_bit4_t a)
171 { return bit4_z2x((vvp_bit4_t) (((int)a) ^ 1)); }
172
173 inline vvp_bit4_t operator | (vvp_bit4_t a, vvp_bit4_t b)
174 {
175 if (a==BIT4_1 || b==BIT4_1)
176 return BIT4_1;
177 return bit4_z2x( (vvp_bit4_t) ((int)a | (int)b) );
178 }
179
180 inline vvp_bit4_t operator & (vvp_bit4_t a, vvp_bit4_t b)
181 {
182 if (a==BIT4_0 || b==BIT4_0)
183 return BIT4_0;
184 return bit4_z2x( (vvp_bit4_t) ((int)a | (int)b) );
185 }
186
187
188 extern vvp_bit4_t operator ^ (vvp_bit4_t a, vvp_bit4_t b);
189 extern ostream& operator<< (ostream&o, vvp_bit4_t a);
190
191 /* Return >0, ==0 or <0 if the from-to transition represents a
192 posedge, no edge, or negedge. */
193 extern int edge(vvp_bit4_t from, vvp_bit4_t to);
194
195 /* Support for $countdrivers. */
update_driver_counts(vvp_bit4_t bit,unsigned counts[3])196 inline void update_driver_counts(vvp_bit4_t bit, unsigned counts[3])
197 {
198 switch (bit) {
199 case BIT4_0:
200 counts[0] += 1;
201 break;
202 case BIT4_1:
203 counts[1] += 1;
204 break;
205 case BIT4_X:
206 counts[2] += 1;
207 break;
208 default:
209 break;
210 }
211 }
212
213 /*
214 * Some of the instructions do wide addition to arrays of long. They
215 * use this add_with_carry function to help.
216 */
add_with_carry(unsigned long a,unsigned long b,unsigned long & carry)217 static inline unsigned long add_with_carry(unsigned long a, unsigned long b,
218 unsigned long&carry)
219 {
220 unsigned long tmp = b + carry;
221 unsigned long sum = a + tmp;
222 carry = 0;
223 if (tmp < b)
224 carry = 1;
225 if (sum < tmp)
226 carry = 1;
227 if (sum < a)
228 carry = 1;
229 return sum;
230 }
231
232 extern unsigned long multiply_with_carry(unsigned long a, unsigned long b,
233 unsigned long&carry);
234
235 /*
236 * This class represents scalar values collected into vectors. The
237 * vector values can be accessed individually, or treated as a
238 * unit. in any case, the elements of the vector are addressed from
239 * zero(LSB) to size-1(MSB).
240 *
241 * No strength values are stored here, if strengths are needed, use a
242 * collection of vvp_scalar_t objects instead.
243 */
244 class vvp_vector4_t {
245
246 friend vvp_vector4_t operator ~(const vvp_vector4_t&that);
247 friend class vvp_vector4array_t;
248 friend class vvp_vector4array_sa;
249 friend class vvp_vector4array_aa;
250
251 public:
252 static const vvp_vector4_t nil;
253
254 public:
255 explicit vvp_vector4_t(unsigned size =0, vvp_bit4_t bits =BIT4_X);
256
257 explicit vvp_vector4_t(unsigned size, double val);
258
259 // Construct a vector4 from the subvalue of another
260 // vector4. The width of the result is 'wid', and the bits are
261 // pulled from 'that' to implement the Verilog part select
262 // semantics. This means that part select beyond 'that'
263 // returns X bits.
264 explicit vvp_vector4_t(const vvp_vector4_t&that,
265 unsigned adr, unsigned wid);
266
267 vvp_vector4_t(const vvp_vector4_t&that);
268 vvp_vector4_t(const vvp_vector4_t&that, bool invert_flag);
269 vvp_vector4_t& operator= (const vvp_vector4_t&that);
270
271 ~vvp_vector4_t();
272
size()273 inline unsigned size() const { return size_; }
274 void resize(unsigned new_size, vvp_bit4_t pad_bit = BIT4_X);
275
276 // Get the bit at the specified address
277 vvp_bit4_t value(unsigned idx) const;
278 // Get the vector4 subvector starting at the address
279 vvp_vector4_t subvalue(unsigned idx, unsigned size) const;
280 // Get the 2-value bits for the subvector. This returns a new
281 // array of longs, or a nil pointer if an XZ bit was detected
282 // in the array.
283 unsigned long*subarray(unsigned idx, unsigned size, bool xz_to_0 =false) const;
284 void setarray(unsigned idx, unsigned size, const unsigned long*val);
285
286 // Set a 4-value bit or subvector into the vector. Return true
287 // if any bits of the vector change as a result of this operation.
288 void set_bit(unsigned idx, vvp_bit4_t val);
289 bool set_vec(unsigned idx, const vvp_vector4_t&that);
290
291 // Get the bits from another vector, but keep my size.
292 void copy_bits(const vvp_vector4_t&that);
293
294 // Move bits within this vector.
295 void mov(unsigned dst, unsigned src, unsigned cnt);
296
297 // Add that to this in the Verilog way.
298 void add(const vvp_vector4_t&that);
299
300 // Subtract that from this in the Verilog way.
301 void sub(const vvp_vector4_t&that);
302
303 // Multiply this by that in the Verilog way.
304 void mul(const vvp_vector4_t&that);
305
306 // Test that the vectors are exactly equal
307 bool eeq(const vvp_vector4_t&that) const;
308
309 // Test that the vectors are equal, with xz comparing as equal.
310 bool eq_xz(const vvp_vector4_t&that) const;
311
312 // Return true if there is an X or Z anywhere in the vector.
313 bool has_xz() const;
314
315 // Change all Z bits to X bits.
316 void change_z2x();
317
318 // Change all bits to X bits.
319 void set_to_x();
320
321 // Display the value into the buf as a string.
322 char*as_string(char*buf, size_t buf_len) const;
323
324 void invert();
325 vvp_vector4_t& operator &= (const vvp_vector4_t&that);
326 vvp_vector4_t& operator |= (const vvp_vector4_t&that);
327 vvp_vector4_t& operator += (int64_t);
328
329 private:
330 // Number of vvp_bit4_t bits that can be shoved into a word.
331 enum { BITS_PER_WORD = 8*sizeof(unsigned long) };
332 // The double value constructor requires that WORD_0_BBITS
333 // and WORD_1_BBITS have the same value!
334 #if SIZEOF_UNSIGNED_LONG == 8
335 enum { WORD_0_ABITS = 0x0000000000000000UL,
336 WORD_0_BBITS = 0x0000000000000000UL };
337 enum { WORD_1_ABITS = 0xFFFFFFFFFFFFFFFFUL,
338 WORD_1_BBITS = 0x0000000000000000UL };
339 enum { WORD_X_ABITS = 0xFFFFFFFFFFFFFFFFUL,
340 WORD_X_BBITS = 0xFFFFFFFFFFFFFFFFUL };
341 enum { WORD_Z_ABITS = 0x0000000000000000UL,
342 WORD_Z_BBITS = 0xFFFFFFFFFFFFFFFFUL };
343 #elif SIZEOF_UNSIGNED_LONG == 4
344 enum { WORD_0_ABITS = 0x00000000UL, WORD_0_BBITS = 0x00000000UL };
345 enum { WORD_1_ABITS = 0xFFFFFFFFUL, WORD_1_BBITS = 0x00000000UL };
346 enum { WORD_X_ABITS = 0xFFFFFFFFUL, WORD_X_BBITS = 0xFFFFFFFFUL };
347 enum { WORD_Z_ABITS = 0x00000000UL, WORD_Z_BBITS = 0xFFFFFFFFUL };
348 #else
349 #error "WORD_X_xBITS not defined for this architecture?"
350 #endif
351
352 // Initialize and operator= use this private method to copy
353 // the data from that object into this object.
354 void copy_from_(const vvp_vector4_t&that);
355 void copy_from_big_(const vvp_vector4_t&that);
356 void copy_inverted_from_(const vvp_vector4_t&that);
357
358 void allocate_words_(unsigned long inita, unsigned long initb);
359
360 // Values in the vvp_vector4_t are stored split across two
361 // arrays. For each bit in the vector, there is an abit and a
362 // bbit. the encoding of a vvp_vector4_t is:
363 //
364 // abit bbit
365 // ---- ----
366 // BIT4_0 0 0 (Note that for BIT4_0 and BIT4_1, the bbit
367 // BIT4_1 1 0 value is 0. This makes detecting XZ fast.)
368 // BIT4_X 1 1
369 // BIT4_Z 0 1
370
371 unsigned size_;
372 union {
373 unsigned long abits_val_;
374 unsigned long*abits_ptr_;
375 };
376 union {
377 unsigned long bbits_val_;
378 unsigned long*bbits_ptr_;
379 };
380 };
381
vvp_vector4_t(const vvp_vector4_t & that)382 inline vvp_vector4_t::vvp_vector4_t(const vvp_vector4_t&that)
383 {
384 copy_from_(that);
385 }
386
vvp_vector4_t(const vvp_vector4_t & that,bool invert_flag)387 inline vvp_vector4_t::vvp_vector4_t(const vvp_vector4_t&that, bool invert_flag)
388 {
389 if (invert_flag)
390 copy_inverted_from_(that);
391 else
392 copy_from_(that);
393 }
394
vvp_vector4_t(unsigned size__,vvp_bit4_t val)395 inline vvp_vector4_t::vvp_vector4_t(unsigned size__, vvp_bit4_t val)
396 : size_(size__)
397 {
398 /* note: this relies on the bit encoding for the vvp_bit4_t. */
399 static const unsigned long init_atable[4] = {
400 WORD_0_ABITS,
401 WORD_1_ABITS,
402 WORD_Z_ABITS,
403 WORD_X_ABITS };
404 static const unsigned long init_btable[4] = {
405 WORD_0_BBITS,
406 WORD_1_BBITS,
407 WORD_Z_BBITS,
408 WORD_X_BBITS };
409
410 allocate_words_(init_atable[val], init_btable[val]);
411 }
412
~vvp_vector4_t()413 inline vvp_vector4_t::~vvp_vector4_t()
414 {
415 if (size_ > BITS_PER_WORD) {
416 delete[] abits_ptr_;
417 // bbits_ptr_ actually points half-way into a
418 // double-length array started at abits_ptr_
419 }
420 }
421
422 inline vvp_vector4_t& vvp_vector4_t::operator= (const vvp_vector4_t&that)
423 {
424 if (this == &that)
425 return *this;
426
427 if (size_ > BITS_PER_WORD)
428 delete[] abits_ptr_;
429
430 copy_from_(that);
431
432 return *this;
433 }
434
copy_from_(const vvp_vector4_t & that)435 inline void vvp_vector4_t::copy_from_(const vvp_vector4_t&that)
436 {
437 size_ = that.size_;
438 if (size_ <= BITS_PER_WORD) {
439 abits_val_ = that.abits_val_;
440 bbits_val_ = that.bbits_val_;
441 } else {
442 copy_from_big_(that);
443 }
444 }
445
value(unsigned idx)446 inline vvp_bit4_t vvp_vector4_t::value(unsigned idx) const
447 {
448 if (idx >= size_)
449 return BIT4_X;
450
451 unsigned off;
452
453 unsigned long abits, bbits;
454 if (size_ > BITS_PER_WORD) {
455 unsigned wdx = idx / BITS_PER_WORD;
456 off = idx % BITS_PER_WORD;
457 abits = abits_ptr_[wdx];
458 bbits = bbits_ptr_[wdx];
459 } else {
460 off = idx;
461 abits = abits_val_;
462 bbits = bbits_val_;
463 }
464
465 abits >>= off;
466 bbits >>= off;
467 int tmp = ((bbits&1) << 1) + (abits&1);
468 // This cast works since b==1,a==1 is X and b==1,a==0 is Z.
469 return (vvp_bit4_t)tmp;
470 }
471
subvalue(unsigned adr,unsigned wid)472 inline vvp_vector4_t vvp_vector4_t::subvalue(unsigned adr, unsigned wid) const
473 {
474 return vvp_vector4_t(*this, adr, wid);
475 }
476
set_bit(unsigned idx,vvp_bit4_t val)477 inline void vvp_vector4_t::set_bit(unsigned idx, vvp_bit4_t val)
478 {
479 assert(idx < size_);
480
481 unsigned long off = idx % BITS_PER_WORD;
482 unsigned long mask = 1UL << off;
483
484 if (size_ > BITS_PER_WORD) {
485 unsigned wdx = idx / BITS_PER_WORD;
486 switch (val) {
487 case BIT4_0:
488 abits_ptr_[wdx] &= ~mask;
489 bbits_ptr_[wdx] &= ~mask;
490 break;
491 case BIT4_1:
492 abits_ptr_[wdx] |= mask;
493 bbits_ptr_[wdx] &= ~mask;
494 break;
495 case BIT4_X:
496 abits_ptr_[wdx] |= mask;
497 bbits_ptr_[wdx] |= mask;
498 break;
499 case BIT4_Z:
500 abits_ptr_[wdx] &= ~mask;
501 bbits_ptr_[wdx] |= mask;
502 break;
503 }
504 } else {
505 switch (val) {
506 case BIT4_0:
507 abits_val_ &= ~mask;
508 bbits_val_ &= ~mask;
509 break;
510 case BIT4_1:
511 abits_val_ |= mask;
512 bbits_val_ &= ~mask;
513 break;
514 case BIT4_X:
515 abits_val_ |= mask;
516 bbits_val_ |= mask;
517 break;
518 case BIT4_Z:
519 abits_val_ &= ~mask;
520 bbits_val_ |= mask;
521 break;
522 }
523 }
524 }
525
526 inline vvp_vector4_t operator ~ (const vvp_vector4_t&that)
527 {
528 vvp_vector4_t res (that, true);
529 return res;
530 }
531
532 extern ostream& operator << (ostream&, const vvp_vector4_t&);
533
534 extern vvp_bit4_t compare_gtge(const vvp_vector4_t&a,
535 const vvp_vector4_t&b,
536 vvp_bit4_t val_if_equal);
537 extern vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
538 const vvp_vector4_t&b,
539 vvp_bit4_t val_if_equal);
540 template <class T> extern T coerce_to_width(const T&that, unsigned width);
541
542 /*
543 * These functions extract the value of the vector as a native type,
544 * if possible, and return true to indicate success. If the vector has
545 * any X or Z bits, the resulting value will have 0 bits in their
546 * place (this follows the rules of Verilog conversions from vector4
547 * to real and integers) and the return value becomes false to
548 * indicate an error.
549 *
550 * The "is_arithmetic" flag true will cause a result to be entirely 0
551 * if any bits are X/Z. That is normally what you want if this value
552 * is in the midst of an arithmetic expression. If is_arithmetic=false
553 * then the X/Z bits will be replaced with 0 bits, and the return
554 * value will be "false", but the other bits will be transferred. This
555 * is what you want if you are doing "vpi_get_value", for example.
556 */
557 template <class T> extern bool vector4_to_value(const vvp_vector4_t&a, T&val,
558 bool is_signed,
559 bool is_arithmetic =true);
560
561 template <class T> extern bool vector4_to_value(const vvp_vector4_t&a,
562 bool&overflow_flag, T&val);
563
vector4_to_value(const vvp_vector4_t & a,T & val)564 template <class T> inline bool vector4_to_value(const vvp_vector4_t&a, T&val)
565 {
566 bool overflow_flag;
567 return vector4_to_value(a, overflow_flag, val);
568 }
569
570 extern bool vector4_to_value(const vvp_vector4_t&a, double&val, bool is_signed);
571
572 extern bool vector2_to_value(const vvp_vector2_t&a, int32_t&val, bool is_signed);
573
574 extern vvp_vector4_t vector4_from_text(const char*bits, unsigned wid);
575
576
577 /*
578 * vvp_vector4array_t
579 */
580 class vvp_vector4array_t {
581
582 public:
583 vvp_vector4array_t(unsigned width, unsigned words);
584 virtual ~vvp_vector4array_t();
585
width()586 unsigned width() const { return width_; }
words()587 unsigned words() const { return words_; }
588
589 virtual vvp_vector4_t get_word(unsigned idx) const = 0;
590 virtual void set_word(unsigned idx, const vvp_vector4_t&that) = 0;
591
592 protected:
593 struct v4cell {
594 union {
595 unsigned long abits_val_;
596 unsigned long*abits_ptr_;
597 };
598 union {
599 unsigned long bbits_val_;
600 unsigned long*bbits_ptr_;
601 };
602 };
603
604 vvp_vector4_t get_word_(v4cell*cell) const;
605 void set_word_(v4cell*cell, const vvp_vector4_t&that);
606
607 unsigned width_;
608 unsigned words_;
609
610 private: // Not implemented
611 vvp_vector4array_t(const vvp_vector4array_t&);
612 vvp_vector4array_t& operator = (const vvp_vector4array_t&);
613 };
614
615 /*
616 * Statically allocated vvp_vector4array_t
617 */
618 class vvp_vector4array_sa : public vvp_vector4array_t {
619
620 public:
621 vvp_vector4array_sa(unsigned width, unsigned words);
622 ~vvp_vector4array_sa();
623
624 vvp_vector4_t get_word(unsigned idx) const;
625 void set_word(unsigned idx, const vvp_vector4_t&that);
626
627 private:
628 v4cell* array_;
629 };
630
631 /*
632 * Automatically allocated vvp_vector4array_t
633 */
634 class vvp_vector4array_aa : public vvp_vector4array_t, public automatic_hooks_s {
635
636 public:
637 vvp_vector4array_aa(unsigned width, unsigned words);
638 ~vvp_vector4array_aa();
639
640 void alloc_instance(vvp_context_t context);
641 void reset_instance(vvp_context_t context);
642 #ifdef CHECK_WITH_VALGRIND
643 void free_instance(vvp_context_t context);
644 #endif
645
646 vvp_vector4_t get_word(unsigned idx) const;
647 void set_word(unsigned idx, const vvp_vector4_t&that);
648
649 private:
650 unsigned context_idx_;
651 };
652
653 /* vvp_vector2_t
654 */
655 class vvp_vector2_t {
656
657 friend vvp_vector2_t operator - (const vvp_vector2_t&);
658 friend vvp_vector2_t operator + (const vvp_vector2_t&,
659 const vvp_vector2_t&);
660 friend vvp_vector2_t operator * (const vvp_vector2_t&,
661 const vvp_vector2_t&);
662 friend bool operator > (const vvp_vector2_t&, const vvp_vector2_t&);
663 friend bool operator >= (const vvp_vector2_t&, const vvp_vector2_t&);
664 friend bool operator < (const vvp_vector2_t&, const vvp_vector2_t&);
665 friend bool operator <= (const vvp_vector2_t&, const vvp_vector2_t&);
666 friend bool operator == (const vvp_vector2_t&, const vvp_vector2_t&);
667
668 public:
669 vvp_vector2_t();
670 vvp_vector2_t(const vvp_vector2_t&);
671 vvp_vector2_t(const vvp_vector2_t&, unsigned newsize);
672 vvp_vector2_t(const vvp_vector2_t&, unsigned base, unsigned wid);
673 // Make a vvp_vector2_t from a vvp_vector4_t. If enable_NaN
674 // is true and there are X or Z bits, then the result becomes
675 // a NaN value. If enable_NaN is false then X or Z bits are
676 // converted to 0 as per the standard Verilog rules.
677 vvp_vector2_t(const vvp_vector4_t&that, bool allow_NaN = false);
678 // Make from a native long and a specified width.
679 vvp_vector2_t(unsigned long val, unsigned wid);
680 // Make with the width, and filled with 1 or 0 bits.
681 enum fill_t {FILL0, FILL1};
682 vvp_vector2_t(fill_t fill, unsigned wid);
683 ~vvp_vector2_t();
684
685 vvp_vector2_t&operator += (const vvp_vector2_t&that);
686 vvp_vector2_t&operator -= (const vvp_vector2_t&that);
687 vvp_vector2_t&operator <<= (unsigned shift);
688 vvp_vector2_t&operator >>= (unsigned shift);
689 vvp_vector2_t&operator = (const vvp_vector2_t&);
690
691 // Assign a vec4 to a vec2, using Verilog rules for converting
692 // XZ values to 0.
693 vvp_vector2_t&operator = (const vvp_vector4_t&);
694
695 bool is_NaN() const;
696 bool is_zero() const;
697 unsigned size() const;
698 int value(unsigned idx) const;
699 vvp_bit4_t value4(unsigned idx) const;
700 // Get the vector2 subvector starting at the address
701 vvp_vector2_t subvalue(unsigned idx, unsigned size) const;
702 void set_bit(unsigned idx, int bit);
703 void set_vec(unsigned idx, const vvp_vector2_t&that);
704 // Make the size just big enough to hold the first 1 bit.
705 void trim();
706 // Trim off extra 1 bit since this is representing a negative value.
707 // Always keep at least 32 bits.
708 void trim_neg();
709
710 private:
711 enum { BITS_PER_WORD = 8 * sizeof(unsigned long) };
712 unsigned long*vec_;
713 unsigned wid_;
714
715 private:
716 void copy_from_that_(const vvp_vector2_t&that);
717 void copy_from_that_(const vvp_vector4_t&that);
718 };
719
720 extern bool operator > (const vvp_vector2_t&, const vvp_vector2_t&);
721 extern bool operator >= (const vvp_vector2_t&, const vvp_vector2_t&);
722 extern bool operator < (const vvp_vector2_t&, const vvp_vector2_t&);
723 extern bool operator <= (const vvp_vector2_t&, const vvp_vector2_t&);
724 extern bool operator == (const vvp_vector2_t&, const vvp_vector2_t&);
725 extern vvp_vector2_t operator - (const vvp_vector2_t&);
726 extern vvp_vector2_t operator + (const vvp_vector2_t&, const vvp_vector2_t&);
727 extern vvp_vector2_t operator * (const vvp_vector2_t&, const vvp_vector2_t&);
728 extern vvp_vector2_t operator / (const vvp_vector2_t&, const vvp_vector2_t&);
729 extern vvp_vector2_t operator % (const vvp_vector2_t&, const vvp_vector2_t&);
730
731 vvp_vector2_t pow(const vvp_vector2_t&, vvp_vector2_t&);
732 extern vvp_vector4_t vector2_to_vector4(const vvp_vector2_t&, unsigned wid);
733
734 /* A c4string is of the form C4<...> where ... are bits. */
735 extern bool c4string_test(const char*str);
736 extern vvp_vector4_t c4string_to_vector4(const char*str);
737
738 /* A crstring is of the form Cr<...> where ... defines are real. */
739 extern bool crstring_test(const char*str);
740 extern double crstring_to_double(const char*str);
741
742 extern ostream& operator<< (ostream&, const vvp_vector2_t&);
743
vvp_vector2_t(const vvp_vector2_t & that)744 inline vvp_vector2_t::vvp_vector2_t(const vvp_vector2_t&that)
745 {
746 copy_from_that_(that);
747 }
748
vvp_vector2_t(const vvp_vector4_t & that,bool enable_NaN)749 inline vvp_vector2_t::vvp_vector2_t(const vvp_vector4_t&that, bool enable_NaN)
750 {
751 if (enable_NaN && that.has_xz()) {
752 vec_ = 0;
753 wid_ = 0;
754 return;
755 }
756 copy_from_that_(that);
757 }
758
~vvp_vector2_t()759 inline vvp_vector2_t::~vvp_vector2_t()
760 {
761 delete[] vec_;
762 }
763
764 /* Inline some of the vector2_t methods. */
size()765 inline unsigned vvp_vector2_t::size() const
766 {
767 return wid_;
768 }
769
value4(unsigned idx)770 inline vvp_bit4_t vvp_vector2_t::value4(unsigned idx) const
771 {
772 if (value(idx))
773 return BIT4_1;
774 else
775 return BIT4_0;
776 }
777
subvalue(unsigned base,unsigned wid)778 inline vvp_vector2_t vvp_vector2_t::subvalue(unsigned base, unsigned wid) const
779 {
780 return vvp_vector2_t(*this, base, wid);
781 }
782
783 /*
784 * This class represents a scalar value with strength. These are
785 * heavier than the simple vvp_bit4_t, but more information is
786 * carried by that weight.
787 *
788 * The strength values are as defined here:
789 * HiZ - 0
790 * Small - 1
791 * Medium - 2
792 * Weak - 3
793 * Large - 4
794 * Pull - 5
795 * Strong - 6
796 * Supply - 7
797 *
798 * There are two strengths for a value: strength0 and strength1. If
799 * the value is Z, then strength0 is the strength of the 0-value, and
800 * strength of the 1-value. If the value is 0 or 1, then the strengths
801 * are the range for that value.
802 */
803 class vvp_scalar_t {
804
805 friend vvp_scalar_t fully_featured_resolv_(vvp_scalar_t a, vvp_scalar_t b);
806
807 public:
808 // Make a HiZ value.
809 explicit vvp_scalar_t();
810
811 // Make an unambiguous value.
812 explicit vvp_scalar_t(vvp_bit4_t val, unsigned str0, unsigned str1);
813
814 // Get the vvp_bit4_t version of the value
815 vvp_bit4_t value() const;
816 unsigned strength0() const;
817 unsigned strength1() const;
818
eeq(vvp_scalar_t that)819 bool eeq(vvp_scalar_t that) const { return value_ == that.value_; }
is_hiz()820 bool is_hiz() const { return (value_ & 0x77) == 0; }
821
822 private:
823 // This class and the vvp_vector8_t class are closely related,
824 // so allow vvp_vector8_t access to the raw encoding so that
825 // it can do compact vectoring of vvp_scalar_t objects.
826 friend class vvp_vector8_t;
vvp_scalar_t(unsigned char val)827 explicit vvp_scalar_t(unsigned char val) : value_(val) { }
raw()828 unsigned char raw() const { return value_; }
829
830 private:
831 unsigned char value_;
832 };
833
vvp_scalar_t()834 inline vvp_scalar_t::vvp_scalar_t()
835 {
836 value_ = 0;
837 }
838
vvp_scalar_t(vvp_bit4_t val,unsigned str0,unsigned str1)839 inline vvp_scalar_t::vvp_scalar_t(vvp_bit4_t val, unsigned str0, unsigned str1)
840 {
841 assert(str0 <= 7);
842 assert(str1 <= 7);
843
844 if (str0 == 0 && str1 == 0) {
845 value_ = 0x00;
846 } else switch (val) {
847 case BIT4_0:
848 value_ = str0 | (str0<<4);
849 break;
850 case BIT4_1:
851 value_ = str1 | (str1<<4) | 0x88;
852 break;
853 case BIT4_X:
854 value_ = str0 | (str1<<4) | 0x80;
855 break;
856 case BIT4_Z:
857 value_ = 0x00;
858 break;
859 }
860 }
861
value()862 inline vvp_bit4_t vvp_scalar_t::value() const
863 {
864 if ((value_ & 0x77) == 0) {
865 return BIT4_Z;
866 } else switch (value_ & 0x88) {
867 case 0x00:
868 return BIT4_0;
869 case 0x88:
870 return BIT4_1;
871 default:
872 return BIT4_X;
873 }
874 }
875
876
resolve(vvp_scalar_t a,vvp_scalar_t b)877 inline vvp_scalar_t resolve(vvp_scalar_t a, vvp_scalar_t b)
878 {
879 extern vvp_scalar_t fully_featured_resolv_(vvp_scalar_t, vvp_scalar_t);
880
881 // If the value is HiZ, resolution is simply a matter of
882 // returning the *other* value.
883 if (a.is_hiz())
884 return b;
885 if (b.is_hiz())
886 return a;
887 // If the values are the identical, then resolution is simply
888 // returning *either* value.
889 if (a .eeq( b ))
890 return a;
891
892 return fully_featured_resolv_(a,b);
893 }
894
895 extern ostream& operator<< (ostream&, vvp_scalar_t);
896
897 /*
898 * This class is a way to carry vectors of strength modeled
899 * values. The 8 in the name is the number of possible distinct values
900 * a well defined bit may have. When you add in ambiguous values, the
901 * number of distinct values span the vvp_scalar_t.
902 *
903 * A vvp_vector8_t object can be created from a vvp_vector4_t and a
904 * strength value. The vvp_vector8_t bits have the values of the input
905 * vector, all with the strength specified. If no strength is
906 * specified, then the conversion from bit4 to a scalar will use the
907 * Verilog convention default of strong (6).
908 */
909 class vvp_vector8_t {
910
911 friend vvp_vector8_t part_expand(const vvp_vector8_t&, unsigned, unsigned);
912
913 public:
914 explicit vvp_vector8_t(unsigned size =0);
915 // Make a vvp_vector8_t from a vector4 and a specified
916 // strength.
917 explicit vvp_vector8_t(const vvp_vector4_t&that,
918 unsigned str0,
919 unsigned str1);
920 explicit vvp_vector8_t(const vvp_vector2_t&that,
921 unsigned str0,
922 unsigned str1);
923
924 ~vvp_vector8_t();
925
926 static const vvp_vector8_t nil;
927
928 public:
929
size()930 unsigned size() const { return size_; }
931 vvp_scalar_t value(unsigned idx) const;
932 vvp_vector8_t subvalue(unsigned adr, unsigned width) const;
933 void set_bit(unsigned idx, vvp_scalar_t val);
934 void set_vec(unsigned idx, const vvp_vector8_t&that);
935
936 // Test that the vectors are exactly equal
937 bool eeq(const vvp_vector8_t&that) const;
938
939 vvp_vector8_t(const vvp_vector8_t&that);
940 vvp_vector8_t& operator= (const vvp_vector8_t&that);
941
942 private:
943 unsigned size_;
944 union {
945 unsigned char*ptr_;
946 unsigned char val_[sizeof(void*)];
947 };
948 };
949
950 /* Resolve uses the default Verilog resolver algorithm to resolve
951 two drive vectors to a single output. */
resolve(const vvp_vector8_t & a,const vvp_vector8_t & b)952 inline vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b)
953 {
954 assert(a.size() == b.size());
955 vvp_vector8_t out (a.size());
956
957 for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
958 out.set_bit(idx, resolve(a.value(idx), b.value(idx)));
959 }
960
961 return out;
962 }
963
964 /* This lookup tabke implements the strength reduction implied by
965 Verilog standard switch devices. The major dimension selects
966 between non-resistive and resistive devices. */
967 extern unsigned vvp_switch_strength_map[2][8];
968
969 /* The reduce4 function converts a vector8 to a vector4, losing
970 strength information in the process. */
971 extern vvp_vector4_t reduce4(const vvp_vector8_t&that);
972 extern vvp_vector8_t part_expand(const vvp_vector8_t&a, unsigned wid, unsigned off);
973
974 /* A c8string is of the form C8<...> where ... are bits. */
975 extern bool c8string_test(const char*str);
976 extern vvp_vector8_t c8string_to_vector8(const char*str);
977
978 /* Print a vector8 value to a stream. */
979 extern ostream& operator<< (ostream&, const vvp_vector8_t&);
980
vvp_vector8_t(unsigned size__)981 inline vvp_vector8_t::vvp_vector8_t(unsigned size__)
982 : size_(size__)
983 {
984 if (size_ <= sizeof(val_)) {
985 memset(val_, 0, sizeof(val_));
986 } else {
987 ptr_ = new unsigned char[size_];
988 memset(ptr_, 0, size_);
989 }
990 }
991
~vvp_vector8_t()992 inline vvp_vector8_t::~vvp_vector8_t()
993 {
994 if (size_ > sizeof(val_))
995 delete[]ptr_;
996 }
997
value(unsigned idx)998 inline vvp_scalar_t vvp_vector8_t::value(unsigned idx) const
999 {
1000 assert(idx < size_);
1001 if (size_ <= sizeof(val_))
1002 return vvp_scalar_t(val_[idx]);
1003 else
1004 return vvp_scalar_t(ptr_[idx]);
1005 }
1006
set_bit(unsigned idx,vvp_scalar_t val)1007 inline void vvp_vector8_t::set_bit(unsigned idx, vvp_scalar_t val)
1008 {
1009 assert(idx < size_);
1010 if (size_ <= sizeof(val_))
1011 val_[idx] = val.raw();
1012 else
1013 ptr_[idx] = val.raw();
1014 }
1015
1016 // Exactly-equal for vvp_vector8_t is common and should be as tight
1017 // as possible.
eeq(const vvp_vector8_t & that)1018 inline bool vvp_vector8_t::eeq(const vvp_vector8_t&that) const
1019 {
1020 if (size_ != that.size_)
1021 return false;
1022 if (size_ == 0)
1023 return true;
1024
1025 if (size_ <= sizeof(val_))
1026 // This is equivalent to memcmp(val_, that.val_, sizeof val_)==0
1027 return ptr_ == that.ptr_;
1028 else
1029 return memcmp(ptr_, that.ptr_, size_) == 0;
1030 }
1031
1032 /*
1033 * This class implements a pointer that points to an item within a
1034 * target. The ptr() method returns a pointer to the vvp_net_t, and
1035 * the port() method returns a 0-3 value that selects the input within
1036 * the vvp_net_t. Use this pointer to point only to the inputs of
1037 * vvp_net_t objects. To point to vvp_net_t objects as a whole, use
1038 * vvp_net_t* pointers.
1039 *
1040 * Alert! Ugly details. Protective clothing recommended!
1041 * The vvp_net_ptr_t encodes the bits of a C pointer, and two bits of
1042 * port identifier into an unsigned long. This works only if vvp_net_t*
1043 * values are always aligned on 4-byte boundaries.
1044 */
1045 template <class T> class vvp_sub_pointer_t {
1046
1047 public:
vvp_sub_pointer_t()1048 vvp_sub_pointer_t() : bits_(0) { }
1049
vvp_sub_pointer_t(T * ptr__,unsigned port__)1050 vvp_sub_pointer_t(T*ptr__, unsigned port__)
1051 {
1052 bits_ = reinterpret_cast<uintptr_t> (ptr__);
1053 assert( (bits_ & 3) == 0 );
1054 assert( (port__ & ~3) == 0 );
1055 bits_ |= port__;
1056 }
1057
~vvp_sub_pointer_t()1058 ~vvp_sub_pointer_t() { }
1059
ptr()1060 T* ptr()
1061 { return reinterpret_cast<T*> (bits_ & ~3UL); }
1062
ptr()1063 const T* ptr() const
1064 { return reinterpret_cast<const T*> (bits_ & ~3UL); }
1065
port()1066 unsigned port() const { return bits_ & 3; }
1067
nil()1068 bool nil() const { return bits_ == 0; }
1069
1070 bool operator == (vvp_sub_pointer_t that) const { return bits_ == that.bits_; }
1071 bool operator != (vvp_sub_pointer_t that) const { return bits_ != that.bits_; }
1072
1073 private:
1074 uintptr_t bits_;
1075 };
1076
1077 typedef vvp_sub_pointer_t<vvp_net_t> vvp_net_ptr_t;
1078 template <class T> ostream& operator << (ostream&out, vvp_sub_pointer_t<T> val)
1079 { out << val.ptr() << "[" << val.port() << "]"; return out; }
1080
1081 /*
1082 * This is the basic unit of netlist connectivity. It is a fan-in of
1083 * up to 4 inputs, and output pointer, and a pointer to the node's
1084 * functionality.
1085 *
1086 * A net output that is non-nil points to the input of one of its
1087 * destination nets. If there are multiple destinations, then the
1088 * referenced input port points to the next input. For example:
1089 *
1090 * +--+--+--+--+---+
1091 * | | | | | . | Output from this vvp_net_t points to...
1092 * +--+--+--+--+-|-+
1093 * |
1094 * /
1095 * /
1096 * /
1097 * |
1098 * v
1099 * +--+--+--+--+---+
1100 * | | | | | . | ... the fourth input of this vvp_net_t, and...
1101 * +--+--+--+--+-|-+
1102 * | |
1103 * / .
1104 * / .
1105 * | .
1106 * v
1107 * +--+--+--+--+---+
1108 * | | | | | . | ... the third input of this vvp_net_t.
1109 * +--+--+--+--+-|-+
1110 *
1111 * Thus, the fan-in of a vvp_net_t node is limited to 4 inputs, but
1112 * the fan-out is unlimited.
1113 *
1114 * The vvp_send_*() functions take as input a vvp_net_ptr_t and follow
1115 * all the fan-out chain, delivering the specified value. The send_*()
1116 * methods of the vvp_net_t class are similar, but they follow the
1117 * output, possibly filtered, from the vvp_net_t.
1118 */
1119 class vvp_net_t {
1120 public:
1121 vvp_net_t();
1122
1123 #ifdef CHECK_WITH_VALGRIND
1124 vvp_net_t *pool;
1125 #endif
1126 vvp_net_ptr_t port[4];
1127 vvp_net_fun_t*fun;
1128 vvp_net_fil_t*fil;
1129
1130 public:
1131 // Connect the port to the output from this net.
1132 void link(vvp_net_ptr_t port);
1133 // Disconnect the port from the output of this net.
1134 void unlink(vvp_net_ptr_t port);
1135
1136 public: // Methods to propagate output from this node.
1137 void send_vec4(const vvp_vector4_t&val, vvp_context_t context);
1138 void send_vec8(const vvp_vector8_t&val);
1139 void send_real(double val, vvp_context_t context);
1140 void send_long(long val);
1141 void send_string(const std::string&val, vvp_context_t context);
1142 void send_object(vvp_object_t val, vvp_context_t context);
1143
1144 void send_vec4_pv(const vvp_vector4_t&val,
1145 unsigned base, unsigned wid, unsigned vwid,
1146 vvp_context_t context);
1147 void send_vec8_pv(const vvp_vector8_t&val,
1148 unsigned base, unsigned wid, unsigned vwid);
1149
1150
1151 public: // Methods to arrange for the output of this net to be forced.
1152
1153 // The intent is that all efforts at force are directed to
1154 // operate only on the vvp_net_t whose output is to be
1155 // forced. These methods then communicate the force to the
1156 // attached filter to set up the actual force.
1157 void force_vec4(const vvp_vector4_t&val, const vvp_vector2_t&mask);
1158 void force_vec8(const vvp_vector8_t&val, const vvp_vector2_t&mask);
1159 void force_real(double val, const vvp_vector2_t&mask);
1160
1161 public: // Method to support $countdrivers
1162 void count_drivers(unsigned idx, unsigned counts[4]);
1163
1164 private:
1165 vvp_net_ptr_t out_;
1166
1167 public: // Need a better new for these objects.
1168 static void* operator new(std::size_t size);
1169 static void operator delete(void*); // not implemented
1170 private: // not implemented
1171 static void* operator new[](std::size_t size);
1172 #if defined(__GNUC__)
1173 static void operator delete[](void*);
1174 #endif
1175 };
1176
1177 /*
1178 * Instances of this class represent the functionality of a
1179 * node. vvp_net_t objects hold pointers to the vvp_net_fun_t
1180 * associated with it. Objects of this type take inputs that arrive at
1181 * a port and perform some sort of action in response.
1182 *
1183 * Whenever a bit is delivered to a vvp_net_t object, the associated
1184 * vvp_net_fun_t::recv_*() method is invoked with the port pointer and
1185 * the bit value. The port pointer is used to figure out which exact
1186 * input receives the bit.
1187 *
1188 * In this context, a "bit" is the thing that arrives at a single
1189 * input. The bit may be a single data bit, a bit vector, various
1190 * sorts of numbers or aggregate objects.
1191 *
1192 * recv_vec4 is the most common way for a datum to arrive at a
1193 * port. The value is a vvp_vector4_t.
1194 *
1195 * Most nodes do not care about the specific strengths of bits, so the
1196 * default behavior for recv_vec8 and recv_vec8_pv is to reduce the
1197 * operand to a vvp_vector4_t and pass it on to the recv_vec4 or
1198 * recv_vec4_pv method.
1199 *
1200 * The recv_vec4, recv_vec4_pv, and recv_real methods are also
1201 * passed a context pointer. When the received bit has propagated
1202 * from a statically allocated node, this will be a null pointer.
1203 * When the received bit has propagated from an automatically
1204 * allocated node, this will be a pointer to the context that
1205 * contains the instance of that bit that has just been modified.
1206 * When the received bit was from a procedural assignment or from
1207 * a VPI set_value() operation, this will be a pointer to the
1208 * writable context associated with the currently running thread.
1209 */
1210 class vvp_net_fun_t {
1211
1212 public:
1213 vvp_net_fun_t();
1214 virtual ~vvp_net_fun_t();
1215
1216 virtual void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1217 vvp_context_t context);
1218 virtual void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
1219 virtual void recv_real(vvp_net_ptr_t port, double bit,
1220 vvp_context_t context);
1221 virtual void recv_long(vvp_net_ptr_t port, long bit);
1222 virtual void recv_string(vvp_net_ptr_t port, const std::string&bit,
1223 vvp_context_t context);
1224 virtual void recv_object(vvp_net_ptr_t port, vvp_object_t bit,
1225 vvp_context_t context);
1226
1227 // Part select variants of above
1228 virtual void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
1229 unsigned base, unsigned wid, unsigned vwid,
1230 vvp_context_t context);
1231 virtual void recv_vec8_pv(vvp_net_ptr_t p, const vvp_vector8_t&bit,
1232 unsigned base, unsigned wid, unsigned vwid);
1233 virtual void recv_long_pv(vvp_net_ptr_t port, long bit,
1234 unsigned base, unsigned wid);
1235
1236 // This method is called when the net is forced or
1237 // released. This is very rarely needed; island ports use it
1238 // to know that the net is being forced and that it needs to
1239 // do something about it.
1240 virtual void force_flag(bool run_now);
1241
1242 protected:
1243 void recv_vec4_pv_(vvp_net_ptr_t p, const vvp_vector4_t&bit,
1244 unsigned base, unsigned wid, unsigned vwid,
1245 vvp_context_t context);
1246 void recv_vec8_pv_(vvp_net_ptr_t p, const vvp_vector8_t&bit,
1247 unsigned base, unsigned wid, unsigned vwid);
1248
1249 public: // These objects are only permallocated.
new(std::size_t size)1250 static void* operator new(std::size_t size) { return heap_.alloc(size); }
1251 static void operator delete(void*); // not implemented
1252
heap_total()1253 static std::size_t heap_total() { return heap_.heap_total(); }
1254
1255 protected:
1256 static permaheap heap_;
1257
1258 private: // not implemented
1259 vvp_net_fun_t(const vvp_net_fun_t&);
1260 vvp_net_fun_t& operator= (const vvp_net_fun_t&);
1261 static void* operator new[](std::size_t size);
1262 static void operator delete[](void*);
1263 };
1264
1265 /*
1266 * A vvp_net_fil_t is a filter object that filters an output from a
1267 * vvp_net_t. The send_*() methods of the vvp_net_t object invoke the
1268 * filter of the output being transmitted. The filter function will
1269 * decide if this value is to be propagated, and how, and return a
1270 * prop_t enumeration to reflect the choice.
1271 *
1272 * The filter object also provides an implementation hooks for
1273 * force/release.
1274 */
1275 class vvp_net_fil_t : public vvp_vpi_callback {
1276
1277 public:
1278 vvp_net_fil_t();
1279 virtual ~vvp_net_fil_t();
1280
1281 public:
1282 enum prop_t { STOP=0, PROP, REPL };
1283
1284
1285 // These filter methods are used by the vvp_net_t::send_*()
1286 // methods to test the output (from the functor) bit value
1287 // against any force filters. If none of the bits are forced,
1288 // then the method returns PROP and the caller propagates the
1289 // bit value. If bits were changed by the force mask, then the
1290 // method returns REPL and the caller should propagate the rep
1291 // value instead. If the function returns STOP, then all the
1292 // output bits are filtered by the force mask and there is
1293 // nothing to propagate.
1294 virtual prop_t filter_vec4(const vvp_vector4_t&bit, vvp_vector4_t&rep,
1295 unsigned base, unsigned vwid);
1296 virtual prop_t filter_vec8(const vvp_vector8_t&val, vvp_vector8_t&rep,
1297 unsigned base, unsigned vwid);
1298 virtual prop_t filter_real(double&val);
1299 virtual prop_t filter_long(long&val);
1300 virtual prop_t filter_object(vvp_object_t&val);
1301 virtual prop_t filter_string(const std::string&val);
1302
1303 virtual void release(vvp_net_ptr_t ptr, bool net_flag) =0;
1304 virtual void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag) =0;
1305
1306 // The %force/link instruction needs a place to write the
1307 // source node of the force, so that subsequent %force and
1308 // %release instructions can undo the link as needed. */
1309 void force_link(vvp_net_t*dst, vvp_net_t*src);
1310 void force_unlink(void);
1311
1312 virtual unsigned filter_size() const =0;
1313
1314 public:
1315 // Support for force methods. These are called by the
1316 // vvp_net_t::force_* methods to set the force value and mask
1317 // for the filter.
1318 virtual void force_fil_vec4(const vvp_vector4_t&val, const vvp_vector2_t&mask) =0;
1319 virtual void force_fil_vec8(const vvp_vector8_t&val, const vvp_vector2_t&mask) =0;
1320 virtual void force_fil_real(double val, const vvp_vector2_t&mask) =0;
1321
1322 public: // These objects are only permallocated.
new(std::size_t size)1323 static void* operator new(std::size_t size) { return heap_.alloc(size); }
1324 static void operator delete(void*); // not implemented
1325
heap_total()1326 static size_t heap_total() { return heap_.heap_total(); }
1327
1328 private:
1329 static permaheap heap_;
1330
1331 private: // not implemented
1332 vvp_net_fil_t(const vvp_net_fil_t&);
1333 vvp_net_fil_t& operator= (const vvp_net_fil_t&);
1334 static void* operator new[](std::size_t size);
1335 static void operator delete[](void*);
1336
1337 protected:
1338 // Set bits of the filter force mask
1339 void force_mask(const vvp_vector2_t&mask);
1340 // Release the force on the bits set in the mask.
1341 void release_mask(const vvp_vector2_t&mask);
1342 // Test bits of the filter force mask;
1343 bool test_force_mask(unsigned bit) const;
1344 bool test_force_mask_is_zero() const;
1345
1346 // This template method is used by derived classes to process
1347 // the val through the force mask. The force value is the
1348 // currently forced value, and the buf is a value that this
1349 // method will use to hold a filtered value, if needed. This
1350 // method returns the replacement value into the "rep"
1351 // argument and returns a code indicating whether any changes
1352 // were made.
1353 template <class T> prop_t filter_mask_(const T&val, const T&force, T&rep, unsigned addr);
1354 // This template method is similar to the above, but works for
1355 // native types that are not so expensive to edit in place.
1356 template <class T> prop_t filter_mask_(T&val, T force);
1357
1358 // These templates are similar to filter_mask_, but are
1359 // idempotent. Then do not trigger callbacks or otherwise
1360 // cause any local changes. These methods are used to test
1361 // arbitrary values against the force mask.
1362 template <class T> prop_t filter_input_mask_(const T&val, const T&force, T&rep) const;
1363
1364 private:
1365 // Mask of forced bits
1366 vvp_vector2_t force_mask_;
1367 // True if the next filter must propagate. Need this to allow
1368 // the forced value to get through.
1369 bool force_propagate_;
1370 // force link back.
1371 class vvp_net_t*force_link_;
1372 };
1373
1374 /* **** Some core net functions **** */
1375
1376 /* vvp_fun_concat
1377 * This node function creates vectors (vvp_vector4_t) from the
1378 * concatenation of the inputs. The inputs (4) may be vector or
1379 * vector8 objects, but they are reduced to vector4 values and
1380 * strength information lost.
1381 *
1382 * The expected widths of the input vectors must be given up front so
1383 * that the positions in the output vector (and also the size of the
1384 * output vector) can be worked out. The input vectors must match the
1385 * expected width.
1386 */
1387 class vvp_fun_concat : public vvp_net_fun_t {
1388
1389 public:
1390 vvp_fun_concat(unsigned w0, unsigned w1,
1391 unsigned w2, unsigned w3);
1392 ~vvp_fun_concat();
1393
1394 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1395 vvp_context_t context);
1396
1397 void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1398 unsigned base, unsigned wid, unsigned vwid,
1399 vvp_context_t);
1400 private:
1401 unsigned wid_[4];
1402 vvp_vector4_t val_;
1403 };
1404
1405 class vvp_fun_concat8 : public vvp_net_fun_t {
1406
1407 public:
1408 vvp_fun_concat8(unsigned w0, unsigned w1,
1409 unsigned w2, unsigned w3);
1410 ~vvp_fun_concat8();
1411
1412 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1413 vvp_context_t context);
1414 void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
1415
1416 void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1417 unsigned base, unsigned wid, unsigned vwid,
1418 vvp_context_t);
1419 void recv_vec8_pv(vvp_net_ptr_t p, const vvp_vector8_t&bit,
1420 unsigned base, unsigned wid, unsigned vwid);
1421
1422 private:
1423 unsigned wid_[4];
1424 vvp_vector8_t val_;
1425 };
1426
1427 /*
1428 * The vvp_fun_force class objects are net functors that use their input
1429 * to force the associated filter. They do not actually have an
1430 * output, they instead drive the force_* methods of the net filter.
1431 *
1432 * This functor is also special in that we know a priori that only
1433 * port-0 is used, so we can use ports 1-3 for local storage. See the
1434 * implementation of vvp_filter_wire_base::force_link in
1435 * vvp_net_sig.cc for details.
1436 */
1437 class vvp_fun_force : public vvp_net_fun_t {
1438
1439 public:
1440 vvp_fun_force();
1441 ~vvp_fun_force();
1442
1443 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1444 vvp_context_t context);
1445 void recv_real(vvp_net_ptr_t port, double bit, vvp_context_t);
1446 };
1447
1448 /* vvp_fun_repeat
1449 * This node function create vectors by repeating the input. The width
1450 * is the width of the output vector, and the repeat is the number of
1451 * times to repeat the input. The width of the input vector is
1452 * implicit from these values.
1453 */
1454 class vvp_fun_repeat : public vvp_net_fun_t {
1455
1456 public:
1457 vvp_fun_repeat(unsigned width, unsigned repeat);
1458 ~vvp_fun_repeat();
1459
1460 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1461 vvp_context_t context);
1462
1463 private:
1464 unsigned wid_;
1465 unsigned rep_;
1466 };
1467
1468 /* vvp_fun_drive
1469 * This node function takes an input vvp_vector4_t as input, and
1470 * repeats that value as a vvp_vector8_t with all the bits given the
1471 * strength of the drive. This is the way vvp_scalar8_t objects are
1472 * created. Input 0 is the value to be driven (vvp_vector4_t) and
1473 * inputs 1 and two are the strength0 and strength1 values to use. The
1474 * strengths may be taken as constant values, or adjusted as longs
1475 * from the network.
1476 *
1477 * This functor only propagates vvp_vector8_t values.
1478 */
1479 class vvp_fun_drive : public vvp_net_fun_t {
1480
1481 public:
1482 vvp_fun_drive(unsigned str0 =6, unsigned str1 =6);
1483 ~vvp_fun_drive();
1484
1485 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1486 vvp_context_t context);
1487 //void recv_long(vvp_net_ptr_t port, long bit);
1488
1489 void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1490 unsigned base, unsigned wid, unsigned vwid,
1491 vvp_context_t);
1492 private:
1493 unsigned char drive0_;
1494 unsigned char drive1_;
1495 };
1496
1497 /*
1498 * EXTEND functors expand an input vector to the desired output
1499 * width. The extend_signed functor sign extends the input. If the
1500 * input is already wider than the desired output, then it is passed
1501 * unmodified.
1502 */
1503 class vvp_fun_extend_signed : public vvp_net_fun_t {
1504
1505 public:
1506 explicit vvp_fun_extend_signed(unsigned wid);
1507 ~vvp_fun_extend_signed();
1508
1509 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1510 vvp_context_t context);
1511
1512 void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1513 unsigned base, unsigned wid, unsigned vwid,
1514 vvp_context_t);
1515 private:
1516 unsigned width_;
1517 };
1518
1519 /*
1520 * Wide Functors:
1521 * Wide functors represent special devices that may have more than 4
1522 * input ports. These devices need a set of N/4 actual functors to
1523 * catch the inputs, and use another to deliver the output.
1524 *
1525 * vvp_wide_fun_t --+--> vvp_wide_fun_core --> ...
1526 * |
1527 * vvp_wide_fun_t --+
1528 * |
1529 * vvp_wide_fun_t --+
1530 *
1531 * There are enough input functors to take all the functor inputs, 4
1532 * per functor. These inputs deliver the changed input value to the
1533 * wide_fun_core, which carries the infrastructure for the thread. The
1534 * wide_fun_core is also a functor whose output is connected to the rest
1535 * of the netlist. This is where the result is delivered back to the
1536 * netlist.
1537 *
1538 * The vvp_wide_fun_core keeps a store of the inputs from all the
1539 * input functors, and makes them available to the derived class that
1540 * does the processing.
1541 */
1542
1543 class vvp_wide_fun_core : public vvp_net_fun_t {
1544
1545 public:
1546 vvp_wide_fun_core(vvp_net_t*net, unsigned nports);
1547 virtual ~vvp_wide_fun_core();
1548 // These objects are not perm allocated.
new(std::size_t size)1549 void* operator new(std::size_t size) { return ::new char[size]; }
delete(void * ptr)1550 void operator delete(void* ptr) { ::delete[]((char*)ptr); }
1551
1552 protected:
1553 void propagate_vec4(const vvp_vector4_t&bit, vvp_time64_t delay =0);
1554 void propagate_real(double bit, vvp_time64_t delay =0);
1555 unsigned port_count() const;
1556
1557 vvp_vector4_t& value(unsigned);
1558 double value_r(unsigned);
1559
1560 private:
1561 // the derived class implements this to receive an indication
1562 // that one of the port input values changed.
1563 virtual void recv_vec4_from_inputs(unsigned port) =0;
1564 virtual void recv_real_from_inputs(unsigned port);
1565
1566 friend class vvp_wide_fun_t;
1567 void dispatch_vec4_from_input_(unsigned port, vvp_vector4_t bit);
1568 void dispatch_real_from_input_(unsigned port, double bit);
1569
1570 private:
1571 // Back-point to the vvp_net_t that points to me.
1572 vvp_net_t*ptr_;
1573 // Structure to track the input values from the input functors.
1574 unsigned nports_;
1575 vvp_vector4_t*port_values_;
1576 double*port_rvalues_;
1577 };
1578
1579 /*
1580 * The job of the input functor is only to monitor inputs to the
1581 * function and pass them to the ufunc_core object. Each functor takes
1582 * up to 4 inputs, with the base the port number for the first
1583 * function input that this functor represents.
1584 */
1585 class vvp_wide_fun_t : public vvp_net_fun_t {
1586
1587 public:
1588 vvp_wide_fun_t(vvp_wide_fun_core*c, unsigned base);
1589 ~vvp_wide_fun_t();
1590
1591 void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
1592 vvp_context_t context);
1593 void recv_real(vvp_net_ptr_t port, double bit,
1594 vvp_context_t context);
1595
1596 void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
1597 unsigned base, unsigned wid, unsigned vwid,
1598 vvp_context_t context);
1599
1600 private:
1601 vvp_wide_fun_core*core_;
1602 unsigned port_base_;
1603 };
1604
1605
vvp_send_vec4(vvp_net_ptr_t ptr,const vvp_vector4_t & val,vvp_context_t context)1606 inline void vvp_send_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&val, vvp_context_t context)
1607 {
1608 while (class vvp_net_t*cur = ptr.ptr()) {
1609 vvp_net_ptr_t next = cur->port[ptr.port()];
1610
1611 if (cur->fun)
1612 cur->fun->recv_vec4(ptr, val, context);
1613
1614 ptr = next;
1615 }
1616 }
1617
1618 extern void vvp_send_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&val);
1619 extern void vvp_send_real(vvp_net_ptr_t ptr, double val,
1620 vvp_context_t context);
1621 extern void vvp_send_long(vvp_net_ptr_t ptr, long val);
1622 extern void vvp_send_long_pv(vvp_net_ptr_t ptr, long val,
1623 unsigned base, unsigned width);
1624
vvp_send_string(vvp_net_ptr_t ptr,const std::string & val,vvp_context_t context)1625 inline void vvp_send_string(vvp_net_ptr_t ptr, const std::string&val, vvp_context_t context)
1626 {
1627 while (vvp_net_t*cur = ptr.ptr()) {
1628 vvp_net_ptr_t next = cur->port[ptr.port()];
1629
1630 if (cur->fun)
1631 cur->fun->recv_string(ptr, val, context);
1632
1633 ptr = next;
1634 }
1635 }
1636
vvp_send_object(vvp_net_ptr_t ptr,vvp_object_t val,vvp_context_t context)1637 inline void vvp_send_object(vvp_net_ptr_t ptr, vvp_object_t val, vvp_context_t context)
1638 {
1639 while (vvp_net_t*cur = ptr.ptr()) {
1640 vvp_net_ptr_t next = cur->port[ptr.port()];
1641
1642 if (cur->fun)
1643 cur->fun->recv_object(ptr, val, context);
1644
1645 ptr = next;
1646 }
1647 }
1648
1649 /*
1650 * Part-vector versions of above functions. This function uses the
1651 * corresponding recv_vec4_pv method in the vvp_net_fun_t functor to
1652 * deliver parts of a vector.
1653 *
1654 * The ptr is the destination input port to write to.
1655 *
1656 * <val> is the vector to be written. The width of this vector must
1657 * exactly match the <wid> vector.
1658 *
1659 * The <base> is where in the receiver the bit vector is to be
1660 * written. This address is given in canonical units; 0 is the LSB, 1
1661 * is the next bit, and so on.
1662 *
1663 * The <vwid> is the width of the destination vector that this part is
1664 * part of. This is used by intermediate nodes, i.e. resolvers, to
1665 * know how wide to pad with Z, if it needs to transform the part to a
1666 * mirror of the destination vector.
1667 */
vvp_send_vec4_pv(vvp_net_ptr_t ptr,const vvp_vector4_t & val,unsigned base,unsigned wid,unsigned vwid,vvp_context_t context)1668 inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val,
1669 unsigned base, unsigned wid, unsigned vwid,
1670 vvp_context_t context)
1671 {
1672 while (class vvp_net_t*cur = ptr.ptr()) {
1673 vvp_net_ptr_t next = cur->port[ptr.port()];
1674
1675 if (cur->fun)
1676 cur->fun->recv_vec4_pv(ptr, val, base, wid, vwid, context);
1677
1678 ptr = next;
1679 }
1680 }
1681
vvp_send_vec8_pv(vvp_net_ptr_t ptr,const vvp_vector8_t & val,unsigned base,unsigned wid,unsigned vwid)1682 inline void vvp_send_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&val,
1683 unsigned base, unsigned wid, unsigned vwid)
1684 {
1685 while (class vvp_net_t*cur = ptr.ptr()) {
1686 vvp_net_ptr_t next = cur->port[ptr.port()];
1687
1688 if (cur->fun)
1689 cur->fun->recv_vec8_pv(ptr, val, base, wid, vwid);
1690
1691 ptr = next;
1692 }
1693 }
1694
send_vec4(const vvp_vector4_t & val,vvp_context_t context)1695 inline void vvp_net_t::send_vec4(const vvp_vector4_t&val, vvp_context_t context)
1696 {
1697 if (fil == 0) {
1698 vvp_send_vec4(out_, val, context);
1699 return;
1700 }
1701
1702 vvp_vector4_t rep;
1703 switch (fil->filter_vec4(val, rep, 0, val.size())) {
1704 case vvp_net_fil_t::STOP:
1705 break;
1706 case vvp_net_fil_t::PROP:
1707 vvp_send_vec4(out_, val, context);
1708 break;
1709 case vvp_net_fil_t::REPL:
1710 vvp_send_vec4(out_, rep, context);
1711 break;
1712 }
1713 }
1714
send_vec4_pv(const vvp_vector4_t & val,unsigned base,unsigned wid,unsigned vwid,vvp_context_t context)1715 inline void vvp_net_t::send_vec4_pv(const vvp_vector4_t&val,
1716 unsigned base, unsigned wid, unsigned vwid,
1717 vvp_context_t context)
1718 {
1719 if (fil == 0) {
1720 vvp_send_vec4_pv(out_, val, base, wid, vwid, context);
1721 return;
1722 }
1723
1724 assert(val.size() == wid);
1725 vvp_vector4_t rep;
1726 switch (fil->filter_vec4(val, rep, base, vwid)) {
1727 case vvp_net_fil_t::STOP:
1728 break;
1729 case vvp_net_fil_t::PROP:
1730 vvp_send_vec4_pv(out_, val, base, wid, vwid, context);
1731 break;
1732 case vvp_net_fil_t::REPL:
1733 vvp_send_vec4_pv(out_, rep, base, wid, vwid, context);
1734 break;
1735 }
1736 }
1737
send_vec8(const vvp_vector8_t & val)1738 inline void vvp_net_t::send_vec8(const vvp_vector8_t&val)
1739 {
1740 if (fil == 0) {
1741 vvp_send_vec8(out_, val);
1742 return;
1743 }
1744
1745 vvp_vector8_t rep;
1746 switch (fil->filter_vec8(val, rep, 0, val.size())) {
1747 case vvp_net_fil_t::STOP:
1748 break;
1749 case vvp_net_fil_t::PROP:
1750 vvp_send_vec8(out_, val);
1751 break;
1752 case vvp_net_fil_t::REPL:
1753 vvp_send_vec8(out_, rep);
1754 break;
1755 }
1756 }
1757
send_vec8_pv(const vvp_vector8_t & val,unsigned base,unsigned wid,unsigned vwid)1758 inline void vvp_net_t::send_vec8_pv(const vvp_vector8_t&val,
1759 unsigned base, unsigned wid, unsigned vwid)
1760 {
1761 if (fil == 0) {
1762 vvp_send_vec8_pv(out_, val, base, wid, vwid);
1763 return;
1764 }
1765
1766 assert(val.size() == wid);
1767 vvp_vector8_t rep;
1768 switch (fil->filter_vec8(val, rep, base, vwid)) {
1769 case vvp_net_fil_t::STOP:
1770 break;
1771 case vvp_net_fil_t::PROP:
1772 vvp_send_vec8_pv(out_, val, base, wid, vwid);
1773 break;
1774 case vvp_net_fil_t::REPL:
1775 vvp_send_vec8_pv(out_, rep, base, wid, vwid);
1776 break;
1777 }
1778 }
1779
send_real(double val,vvp_context_t context)1780 inline void vvp_net_t::send_real(double val, vvp_context_t context)
1781 {
1782 if (fil && ! fil->filter_real(val))
1783 return;
1784
1785 vvp_send_real(out_, val, context);
1786 }
1787
1788
send_string(const std::string & val,vvp_context_t context)1789 inline void vvp_net_t::send_string(const std::string&val, vvp_context_t context)
1790 {
1791 if (fil && !fil->filter_string(val))
1792 return;
1793
1794 vvp_send_string(out_, val, context);
1795 }
1796
1797
send_object(vvp_object_t val,vvp_context_t context)1798 inline void vvp_net_t::send_object(vvp_object_t val, vvp_context_t context)
1799 {
1800 if (fil && ! fil->filter_object(val))
1801 return;
1802
1803 vvp_send_object(out_, val, context);
1804 }
1805
1806
test_force_mask(unsigned bit)1807 inline bool vvp_net_fil_t::test_force_mask(unsigned bit) const
1808 {
1809 if (bit >= force_mask_.size())
1810 return false;
1811 if (force_mask_.value(bit))
1812 return true;
1813 else
1814 return false;
1815 }
1816
test_force_mask_is_zero(void)1817 inline bool vvp_net_fil_t::test_force_mask_is_zero(void) const
1818 {
1819 if (force_mask_.size() == 0)
1820 return true;
1821 if (force_mask_.is_zero())
1822 return true;
1823 return false;
1824 }
1825
1826 /*
1827 * Undefine the ivl_alloc.h definitions so they don't leak out of this file.
1828 */
1829 #undef malloc
1830 #undef realloc
1831 #undef calloc
1832 #undef __ivl_alloc_H
1833
1834 #endif /* IVL_vvp_net_H */
1835