1 // Copyright 2017-2019 VMware, Inc.
2 // SPDX-License-Identifier: BSD-2-Clause
3 //
4 // The BSD-2 license (the License) set forth below applies to all parts of the
5 // Cascade project.  You may not use this file except in compliance with the
6 // License.
7 //
8 // BSD-2 License
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this
14 // list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the following disclaimer in the documentation
18 // and/or other materials provided with the distribution.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include "verilog/analyze/evaluate.h"
32 
33 using namespace std;
34 
35 namespace cascade {
36 
Evaluate()37 Evaluate::Evaluate() {
38   feof_ = nullptr;
39   fopen_ = nullptr;
40 }
41 
set_feof_handler(FeofHandler h)42 Evaluate& Evaluate::set_feof_handler(FeofHandler h) {
43   feof_ = h;
44   return *this;
45 }
46 
set_fopen_handler(FopenHandler h)47 Evaluate& Evaluate::set_fopen_handler(FopenHandler h) {
48   fopen_ = h;
49   return *this;
50 }
51 
get_arity(const Identifier * id)52 vector<size_t> Evaluate::get_arity(const Identifier* id) {
53   const auto* r = Resolve().get_resolution(id);
54   assert(r != nullptr);
55 
56   // Variable references are always scalar
57   if (id != r) {
58     return vector<size_t>();
59   }
60   // Otherwise, iterate over the declaration to determine arity
61   vector<size_t> res;
62   for (auto i = r->begin_dim(), ie = r->end_dim(); i != ie; ++i) {
63     const auto rng = get_range(*i);
64     res.push_back((rng.first-rng.second)+1);
65   }
66   return res;
67 }
68 
get_msb(const Identifier * id)69 size_t Evaluate::get_msb(const Identifier* id) {
70   const auto* r = Resolve().get_resolution(id);
71   assert(r != nullptr);
72   const auto* p = r->get_parent();
73   assert((p != nullptr) && (p->is_subclass_of(Node::Tag::declaration)));
74   const auto* d = static_cast<const Declaration*>(p);
75   return d->is_null_dim() ? 0 : get_range(d->get_dim()).first;
76 }
77 
get_lsb(const Identifier * id)78 size_t Evaluate::get_lsb(const Identifier* id) {
79   const auto* r = Resolve().get_resolution(id);
80   assert(r != nullptr);
81   const auto* p = r->get_parent();
82   assert((p != nullptr) && (p->is_subclass_of(Node::Tag::declaration)));
83   const auto* d = static_cast<const Declaration*>(p);
84   return d->is_null_dim() ? 0 : get_range(d->get_dim()).second;
85 }
86 
get_width(const Expression * e)87 size_t Evaluate::get_width(const Expression* e) {
88   if (e->bit_val_.empty()) {
89     init(const_cast<Expression*>(e));
90   }
91   return e->bit_val_[0].size();
92 }
93 
get_type(const Expression * e)94 Bits::Type Evaluate::get_type(const Expression* e) {
95   if (e->bit_val_.empty()) {
96     init(const_cast<Expression*>(e));
97   }
98   return e->bit_val_[0].get_type();
99 }
100 
get_value(const Expression * e)101 const Bits& Evaluate::get_value(const Expression* e) {
102   if (e->bit_val_.empty()) {
103     init(const_cast<Expression*>(e));
104   }
105   if (e->get_flag<0>()) {
106     const_cast<Expression*>(e)->accept(this);
107     const_cast<Expression*>(e)->set_flag<0>(false);
108   }
109   return e->bit_val_[0];
110 }
111 
get_array_value(const Identifier * i)112 const Vector<Bits>& Evaluate::get_array_value(const Identifier* i) {
113   if (i->bit_val_.empty()) {
114     init(const_cast<Identifier*>(i));
115   }
116   if (i->get_flag<0>()) {
117     const_cast<Identifier*>(i)->accept(this);
118     const_cast<Identifier*>(i)->set_flag<0>(false);
119   }
120   return i->bit_val_;
121 }
122 
get_range(const Expression * e)123 pair<size_t, size_t> Evaluate::get_range(const Expression* e) {
124   if (e->is(Node::Tag::range_expression)) {
125     const auto* re = static_cast<const RangeExpression*>(e);
126     if (e->get_flag<0>()) {
127       const auto upper = get_value(re->get_upper()).to_uint();
128       const auto lower = get_value(re->get_lower()).to_uint();
129       switch (re->get_type()) {
130         case RangeExpression::Type::CONSTANT:
131           const_cast<RangeExpression*>(re)->vupper_ = upper;
132           const_cast<RangeExpression*>(re)->vlower_ = lower;
133           break;
134         case RangeExpression::Type::PLUS:
135           const_cast<RangeExpression*>(re)->vupper_ = upper+lower-1;
136           const_cast<RangeExpression*>(re)->vlower_ = upper;
137           break;
138         case RangeExpression::Type::MINUS:
139           const_cast<RangeExpression*>(re)->vupper_ = upper;
140           const_cast<RangeExpression*>(re)->vlower_ = upper-lower+1;
141           break;
142         default:
143           assert(false);
144           break;
145       }
146       const_cast<RangeExpression*>(re)->set_flag<0>(false);
147     }
148     return make_pair(re->vupper_, re->vlower_);
149   }
150   const auto idx = get_value(e).to_uint();
151   return make_pair(idx, idx);
152 }
153 
assign_value(const Identifier * id,const Bits & val)154 bool Evaluate::assign_value(const Identifier* id, const Bits& val) {
155   // Find the variable that we're referring to.
156   const auto* r = Resolve().get_resolution(id);
157   assert(r != nullptr);
158   if (r->bit_val_.empty()) {
159     init(const_cast<Identifier*>(r));
160   }
161 
162   // Calculate its index
163   const auto dres = dereference(r, id);
164   const auto idx = static_cast<size_t>(get<0>(dres));
165 
166   // Corner Case: Ignore writes to out of range indices
167   if (idx >= r->bit_val_.size()) {
168     return false;
169   }
170   // Simple Case: Full Assignment
171   if (get<1>(dres) == -1) {
172     if (!r->bit_val_[idx].eq(val)) {
173       const_cast<Identifier*>(r)->bit_val_[idx].assign(val);
174       flag_changed(r);
175       return true;
176     }
177     return false;
178   }
179   // Corner Case: Ignore writes to bit ranges which are entirely out of range
180   if (static_cast<size_t>(get<2>(dres)) >= get_width(r)) {
181     return false;
182   }
183   // Partial Case: Write as much as possible to a partially valid range
184   const auto msb = min(static_cast<size_t>(get<1>(dres)), get_width(r)-1);
185   const auto lsb = min(static_cast<size_t>(get<2>(dres)), get_width(r)-1);
186   if (!r->bit_val_[idx].eq(msb, lsb, val)) {
187     const_cast<Identifier*>(r)->bit_val_[idx].assign(msb, lsb, val);
188     flag_changed(r);
189     return true;
190   }
191   return false;
192 }
193 
assign_array_value(const Identifier * id,const Vector<Bits> & val)194 void Evaluate::assign_array_value(const Identifier* id, const Vector<Bits>& val) {
195   if (id->bit_val_.empty()) {
196     init(const_cast<Identifier*>(id));
197   }
198 
199   // Find the variable that we're referring to.
200   const auto* r = Resolve().get_resolution(id);
201   assert(r != nullptr);
202   if (r->bit_val_.empty()) {
203     init(const_cast<Identifier*>(r));
204   }
205 
206   // Perform the assignment. This method is never invoked along the critical
207   // path. There's no need to short-circuit after performing an equality check.
208   assert(val.size() == id->bit_val_.size());
209   for (size_t i = 0, ie = id->bit_val_.size(); i < ie; ++i) {
210     const_cast<Identifier*>(r)->bit_val_[i].assign(val[i]);
211   }
212   flag_changed(r);
213 }
214 
dereference(const Identifier * r,const Identifier * i)215 tuple<size_t,int,int> Evaluate::dereference(const Identifier* r, const Identifier* i) {
216   // Nothing to do if this is a scalar variable
217   if (r->empty_dim()) {
218     const auto rng = i->empty_dim() ?
219       make_pair<size_t, size_t>(-1,-1) :
220       get_range(i->front_dim());
221     return make_tuple(0, rng.first, rng.second);
222   }
223 
224   // Otherwise, i had better have at most one more dimension than r
225   assert(i->size_dim() - r->size_dim() <= 1);
226 
227   // Iterators
228   auto iitr = i->begin_dim();
229   auto ritr = r->begin_dim();
230   // The index we're looking for
231   size_t idx = 0;
232   // Multiplier for multi-dimensional arrays
233   if (r->bit_val_.empty()) {
234     init(const_cast<Identifier*>(r));
235   }
236   size_t mul = r->bit_val_.size();
237 
238   // Walk along subscripts
239   for (auto re = r->end_dim(); ritr != re; ++iitr, ++ritr) {
240     assert((*ritr)->is(Node::Tag::range_expression));
241     assert(!(*iitr)->is(Node::Tag::range_expression));
242 
243     const auto rval = get_range(*ritr);
244     const auto ival = get_value(*iitr).to_uint();
245 
246     mul /= ((rval.first-rval.second)+1);
247     idx += mul * ival;
248   }
249   const auto rng = (iitr == i->end_dim()) ?
250     make_pair<size_t, size_t>(-1,-1) :
251     get_range(*iitr);
252   return make_tuple(idx, rng.first, rng.second);
253 }
254 
assign_value(const Identifier * id,size_t idx,int msb,int lsb,const Bits & val)255 bool Evaluate::assign_value(const Identifier* id, size_t idx, int msb, int lsb, const Bits& val) {
256   if (id->bit_val_.empty()) {
257     init(const_cast<Identifier*>(id));
258   }
259 
260   // Corner Case: Ignore writes to out of bounds indices
261   if (idx >= id->bit_val_.size()) {
262     return false;
263   }
264   // Fast Path: Single bit assignments are easy to check
265   if (msb == -1) {
266     if (!id->bit_val_[idx].eq(val)) {
267       const_cast<Identifier*>(id)->bit_val_[idx].assign(val);
268       flag_changed(id);
269       return true;
270     }
271     return false;
272   }
273   // Corner Case: Ignore writes to bit ranges which are completely out of bounds
274   else if (static_cast<size_t>(lsb) >= get_width(id)) {
275     return false;
276   }
277   // Partial Case: Perform as much of the assignment as possible
278   const auto m = min(static_cast<size_t>(msb), get_width(id)-1);
279   const auto l = min(static_cast<size_t>(lsb), get_width(id)-1);
280   if (!id->bit_val_[idx].eq(m, l, val)) {
281     const_cast<Identifier*>(id)->bit_val_[idx].assign(m, l, val);
282     flag_changed(id);
283     return true;
284   }
285   return false;
286 }
287 
flag_changed(const Identifier * id)288 void Evaluate::flag_changed(const Identifier* id) {
289   for (auto i = Resolve().use_begin(id), ie = Resolve().use_end(id); i != ie; ++i) {
290     const_cast<Expression*>(*i)->set_flag<0>(true);
291   }
292   const_cast<Identifier*>(id)->set_flag<0>(false);
293 }
294 
flag_changed(const FeofExpression * fe)295 void Evaluate::flag_changed(const FeofExpression* fe) {
296   for (const Node* n = fe; n->is_subclass_of(Node::Tag::expression); n = n->get_parent()) {
297     const auto* e = static_cast<const Expression*>(n);
298     const_cast<Expression*>(e)->set_flag<0>(true);
299   }
300 }
301 
invalidate(const Expression * e)302 void Evaluate::invalidate(const Expression* e) {
303   const auto* root = get_root(e);
304   Invalidate i;
305   const_cast<Node*>(root)->accept(&i);
306 }
307 
edit(BinaryExpression * be)308 void Evaluate::edit(BinaryExpression* be) {
309   switch (be->get_op()) {
310     case BinaryExpression::Op::PLUS:
311       be->bit_val_[0].arithmetic_plus(get_value(be->get_lhs()), get_value(be->get_rhs()));
312       break;
313     case BinaryExpression::Op::MINUS:
314       be->bit_val_[0].arithmetic_minus(get_value(be->get_lhs()), get_value(be->get_rhs()));
315       break;
316     case BinaryExpression::Op::TIMES:
317       be->bit_val_[0].arithmetic_multiply(get_value(be->get_lhs()), get_value(be->get_rhs()));
318       break;
319     case BinaryExpression::Op::DIV:
320       be->bit_val_[0].arithmetic_divide(get_value(be->get_lhs()), get_value(be->get_rhs()));
321       break;
322     case BinaryExpression::Op::MOD:
323       be->bit_val_[0].arithmetic_mod(get_value(be->get_lhs()), get_value(be->get_rhs()));
324       break;
325     // NOTE: These are equivalent because we don't support x and z
326     case BinaryExpression::Op::EEEQ:
327     case BinaryExpression::Op::EEQ:
328       be->bit_val_[0].logical_eq(get_value(be->get_lhs()), get_value(be->get_rhs()));
329       break;
330     // NOTE: These are equivalent because we don't support x and z
331     case BinaryExpression::Op::BEEQ:
332     case BinaryExpression::Op::BEQ:
333       be->bit_val_[0].logical_ne(get_value(be->get_lhs()), get_value(be->get_rhs()));
334       break;
335     case BinaryExpression::Op::AAMP:
336       be->bit_val_[0].logical_and(get_value(be->get_lhs()), get_value(be->get_rhs()));
337       break;
338     case BinaryExpression::Op::PPIPE:
339       be->bit_val_[0].logical_or(get_value(be->get_lhs()), get_value(be->get_rhs()));
340       break;
341     case BinaryExpression::Op::TTIMES:
342       be->bit_val_[0].arithmetic_pow(get_value(be->get_lhs()), get_value(be->get_rhs()));
343       break;
344     case BinaryExpression::Op::LT:
345       be->bit_val_[0].logical_lt(get_value(be->get_lhs()), get_value(be->get_rhs()));
346       break;
347     case BinaryExpression::Op::LEQ:
348       be->bit_val_[0].logical_lte(get_value(be->get_lhs()), get_value(be->get_rhs()));
349       break;
350     case BinaryExpression::Op::GT:
351       be->bit_val_[0].logical_gt(get_value(be->get_lhs()), get_value(be->get_rhs()));
352       break;
353     case BinaryExpression::Op::GEQ:
354       be->bit_val_[0].logical_gte(get_value(be->get_lhs()), get_value(be->get_rhs()));
355       break;
356     case BinaryExpression::Op::AMP:
357       be->bit_val_[0].bitwise_and(get_value(be->get_lhs()), get_value(be->get_rhs()));
358       break;
359     case BinaryExpression::Op::PIPE:
360       be->bit_val_[0].bitwise_or(get_value(be->get_lhs()), get_value(be->get_rhs()));
361       break;
362     case BinaryExpression::Op::CARAT:
363       be->bit_val_[0].bitwise_xor(get_value(be->get_lhs()), get_value(be->get_rhs()));
364       break;
365     case BinaryExpression::Op::TCARAT:
366       be->bit_val_[0].bitwise_xnor(get_value(be->get_lhs()), get_value(be->get_rhs()));
367       break;
368     case BinaryExpression::Op::LLT:
369       be->bit_val_[0].bitwise_sll(get_value(be->get_lhs()), get_value(be->get_rhs()));
370       break;
371     case BinaryExpression::Op::LLLT:
372       be->bit_val_[0].bitwise_sal(get_value(be->get_lhs()), get_value(be->get_rhs()));
373       break;
374     case BinaryExpression::Op::GGT:
375       be->bit_val_[0].bitwise_slr(get_value(be->get_lhs()), get_value(be->get_rhs()));
376       break;
377     case BinaryExpression::Op::GGGT:
378       be->bit_val_[0].bitwise_sar(get_value(be->get_lhs()), get_value(be->get_rhs()));
379       break;
380 
381     default:
382       assert(false);
383       break;
384   }
385 }
386 
edit(ConditionalExpression * ce)387 void Evaluate::edit(ConditionalExpression* ce) {
388   if (get_value(ce->get_cond()).to_bool()) {
389     ce->bit_val_[0].assign(get_value(ce->get_lhs()));
390   } else {
391     ce->bit_val_[0].assign(get_value(ce->get_rhs()));
392   }
393 }
394 
edit(FeofExpression * fe)395 void Evaluate::edit(FeofExpression* fe) {
396   // Relies on target-specific logic:
397   if (feof_ != nullptr) {
398     fe->bit_val_[0].set(0, feof_(this, fe));
399   } else {
400     fe->bit_val_[0].set(0, true);
401   }
402 }
403 
edit(FopenExpression * fe)404 void Evaluate::edit(FopenExpression* fe) {
405   // Relies on target-specific logic:
406   if (fopen_ != nullptr) {
407     fe->bit_val_[0].assign(Bits(32, fopen_(this, fe)));
408   } else {
409     fe->bit_val_[0].assign(Bits(32, 0));
410   }
411 }
412 
edit(Concatenation * c)413 void Evaluate::edit(Concatenation* c) {
414   auto i = c->begin_exprs();
415   c->bit_val_[0].assign(get_value(*i++));
416   for (auto ie = c->end_exprs(); i != ie; ++i) {
417     c->bit_val_[0].concat(get_value(*i));
418   }
419 }
420 
edit(Identifier * id)421 void Evaluate::edit(Identifier* id) {
422   // Nothing to do if this is a self-reference
423   const auto* r = Resolve().get_resolution(id);
424   assert(r != nullptr);
425   if (r == id) {
426     return;
427   }
428   // Compute the index of this dereference
429   const auto dres = dereference(r, id);
430   const auto idx = static_cast<size_t>(get<0>(dres));
431 
432   // Corner Case: Ignore reads from out of bounds indices
433   if (idx >= get_array_value(r).size()) {
434     return;
435   }
436   // Simple Case: Full value assignment
437   else if (get<1>(dres) == -1) {
438     id->bit_val_[0].assign(get_array_value(r)[idx]);
439   }
440   // Partial Case: Ignore reads from bit ranges which are out of bounds
441   else {
442     const auto msb = min(static_cast<size_t>(get<1>(dres)), get_width(r)-1);
443     const auto lsb = min(static_cast<size_t>(get<2>(dres)), get_width(r)-1);
444     id->bit_val_[0].assign(get_array_value(r)[idx], msb, lsb);
445   }
446 }
447 
edit(MultipleConcatenation * mc)448 void Evaluate::edit(MultipleConcatenation* mc) {
449   const auto lhs = get_value(mc->get_expr()).to_uint();
450   mc->bit_val_[0].assign(get_value(mc->get_concat()));
451   for (size_t i = 1; i < lhs; ++i) {
452     mc->bit_val_[0].concat(mc->get_concat()->bit_val_[0]);
453   }
454 }
455 
edit(Number * n)456 void Evaluate::edit(Number* n) {
457   // Does nothing. We assigned a value to this expression in init.
458   (void) n;
459 }
460 
edit(String * s)461 void Evaluate::edit(String* s) {
462   // Does nothing. We assigned a value to this expression in init.
463   (void) s;
464 }
465 
edit(UnaryExpression * ue)466 void Evaluate::edit(UnaryExpression* ue) {
467   switch (ue->get_op()) {
468     case UnaryExpression::Op::PLUS:
469       ue->bit_val_[0].arithmetic_plus(get_value(ue->get_lhs()));
470       break;
471     case UnaryExpression::Op::MINUS:
472       ue->bit_val_[0].arithmetic_minus(get_value(ue->get_lhs()));
473       break;
474     case UnaryExpression::Op::BANG:
475       ue->bit_val_[0].logical_not(get_value(ue->get_lhs()));
476       break;
477     case UnaryExpression::Op::TILDE:
478       ue->bit_val_[0].bitwise_not(get_value(ue->get_lhs()));
479       break;
480     case UnaryExpression::Op::AMP:
481       ue->bit_val_[0].reduce_and(get_value(ue->get_lhs()));
482       break;
483     case UnaryExpression::Op::TAMP:
484       ue->bit_val_[0].reduce_nand(get_value(ue->get_lhs()));
485       break;
486     case UnaryExpression::Op::PIPE:
487       ue->bit_val_[0].reduce_or(get_value(ue->get_lhs()));
488       break;
489     case UnaryExpression::Op::TPIPE:
490       ue->bit_val_[0].reduce_nor(get_value(ue->get_lhs()));
491       break;
492     case UnaryExpression::Op::CARAT:
493       ue->bit_val_[0].reduce_xor(get_value(ue->get_lhs()));
494       break;
495     case UnaryExpression::Op::TCARAT:
496       ue->bit_val_[0].reduce_xnor(get_value(ue->get_lhs()));
497       break;
498     default:
499       assert(false);
500       break;
501   }
502 }
503 
get_root(const Expression * e) const504 const Node* Evaluate::get_root(const Expression* e) const {
505   // Walk up the AST until we find something other than an expression.  Our
506   // goal is to find the root of the expression subtree containing e.
507   //
508   // We treat assignments as subtrees. We also treat expressions inside of
509   // identifier and id subscripts, declaration subscripts, and the multiplier
510   // in multiple concatenations as subtrees. This will simplify some things in
511   // a few places where we'll want to compute a final context-determined value
512   // during self-determination.
513   const Node* root = nullptr;
514   for (root = e; ; root = root->get_parent()) {
515     // Subscripts inside of identifiers
516     if (root->is_subclass_of(Node::Tag::expression) && root->get_parent()->is(Node::Tag::identifier)) {
517       return root;
518     }
519     // Ranges inside of declarations
520     else if (root->is(Node::Tag::range_expression) && root->get_parent()->is_subclass_of(Node::Tag::declaration)) {
521       return root;
522     }
523     // Variables inside of declarations
524     else if (root->get_parent()->is_subclass_of(Node::Tag::declaration)) {
525       return root->get_parent();
526     }
527     // Continuous, non-blocking, or blocking assigns
528     else if (root->get_parent()->is(Node::Tag::continuous_assign) ||
529         root->get_parent()->is(Node::Tag::blocking_assign) ||
530         root->get_parent()->is(Node::Tag::nonblocking_assign) ||
531         root->get_parent()->is(Node::Tag::variable_assign)) {
532       return root->get_parent();
533     }
534     // Multiple Concatenation
535     else if (root->get_parent()->is(Node::Tag::multiple_concatenation)) {
536       return root;
537     }
538     // Subscripts inside of ids
539     else if (root->get_parent()->is(Node::Tag::id)) {
540       return root;
541     }
542     else if (!root->get_parent()->is_subclass_of(Node::Tag::expression)) {
543       return root;
544     }
545   }
546   assert(false);
547   return nullptr;
548 }
549 
init(Expression * e)550 void Evaluate::init(Expression* e) {
551   // This function is on the critical path for most things Evaluate-related.
552   // It's slightly faster to put the guard around this method where it's used
553   // rather than here, since it avoids a nested function call on every
554   // invocation of get_value, assign_value, etc...
555 
556   // Find the root of this subtree
557   const auto* root = get_root(e);
558   // Use rules of self-determination to allocate bits, sizes, and signs
559   SelfDetermine sd(this);
560   const_cast<Node*>(root)->accept(&sd);
561   // Use the rules of context-determination to update sizes in some cases
562   ContextDetermine cd(this);
563   const_cast<Node*>(root)->accept(&cd);
564 }
565 
edit(BinaryExpression * be)566 void Evaluate::Invalidate::edit(BinaryExpression* be) {
567   be->bit_val_.clear();
568   be->set_flag<0>(true);
569   Editor::edit(be);
570 }
571 
edit(ConditionalExpression * ce)572 void Evaluate::Invalidate::edit(ConditionalExpression* ce) {
573   ce->bit_val_.clear();
574   ce->set_flag<0>(true);
575   Editor::edit(ce);
576 }
577 
edit(FeofExpression * fe)578 void Evaluate::Invalidate::edit(FeofExpression* fe) {
579   fe->bit_val_.clear();
580   fe->set_flag<0>(true);
581   Editor::edit(fe);
582 }
583 
edit(FopenExpression * fe)584 void Evaluate::Invalidate::edit(FopenExpression* fe) {
585   fe->bit_val_.clear();
586   fe->set_flag<0>(true);
587   Editor::edit(fe);
588 }
589 
edit(Concatenation * c)590 void Evaluate::Invalidate::edit(Concatenation* c) {
591   c->bit_val_.clear();
592   c->set_flag<0>(true);
593   Editor::edit(c);
594 }
595 
edit(Identifier * id)596 void Evaluate::Invalidate::edit(Identifier* id) {
597   id->bit_val_.clear();
598   id->set_flag<0>(true);
599   // Don't descend into a different subtree
600 }
601 
edit(MultipleConcatenation * mc)602 void Evaluate::Invalidate::edit(MultipleConcatenation* mc) {
603   mc->bit_val_.clear();
604   mc->set_flag<0>(true);
605   // Don't descend into a different subtree
606   mc->accept_concat(this);
607 }
608 
edit(Number * n)609 void Evaluate::Invalidate::edit(Number* n) {
610   // Reset this number to its default size and sign.
611   n->bit_val_[0].reinterpret_type(static_cast<Bits::Type>(n->Node::get_val<5,2>()));
612   n->bit_val_[0].resize(n->Node::get_val<7,25>());
613   n->set_flag<0>(true);
614 }
615 
edit(String * s)616 void Evaluate::Invalidate::edit(String* s) {
617   // Nowhere left to descend to. This is a primary.
618   s->bit_val_.clear();
619   s->set_flag<0>(true);
620 }
621 
edit(RangeExpression * re)622 void Evaluate::Invalidate::edit(RangeExpression* re) {
623   // Nowhere left to descend to. This is a primary.
624   re->vupper_ = -1;
625   re->vlower_ = -1;
626   re->set_flag<0>(true);
627 
628   re->accept_upper(this);
629   re->accept_lower(this);
630 }
631 
edit(UnaryExpression * ue)632 void Evaluate::Invalidate::edit(UnaryExpression* ue) {
633   ue->bit_val_.clear();
634   ue->set_flag<0>(true);
635   Editor::edit(ue);
636 }
637 
edit(LocalparamDeclaration * ld)638 void Evaluate::Invalidate::edit(LocalparamDeclaration* ld) {
639   ld->accept_id(this);
640   // Ignore dim: Don't descend into a different subtree
641   ld->accept_val(this);
642 }
643 
edit(NetDeclaration * nd)644 void Evaluate::Invalidate::edit(NetDeclaration* nd) {
645   nd->accept_id(this);
646   // Ignore dim: Don't descend into a different subtree
647 }
648 
edit(ParameterDeclaration * pd)649 void Evaluate::Invalidate::edit(ParameterDeclaration* pd) {
650   pd->accept_id(this);
651   // Ignore dim: Don't descend into a different subtree
652   pd->accept_val(this);
653 }
654 
edit(RegDeclaration * rd)655 void Evaluate::Invalidate::edit(RegDeclaration* rd) {
656   rd->accept_id(this);
657   // Ignore dim: Don't descend into a different subtree
658   rd->accept_val(this);
659 }
660 
SelfDetermine(Evaluate * eval)661 Evaluate::SelfDetermine::SelfDetermine(Evaluate* eval) {
662   eval_ = eval;
663 }
664 
edit(BinaryExpression * be)665 void Evaluate::SelfDetermine::edit(BinaryExpression* be) {
666   Editor::edit(be);
667 
668   size_t w = 0;
669   bool r = false;
670   bool s = false;
671   switch (be->get_op()) {
672     case BinaryExpression::Op::PLUS:
673     case BinaryExpression::Op::MINUS:
674     case BinaryExpression::Op::TIMES:
675     case BinaryExpression::Op::DIV:
676     case BinaryExpression::Op::MOD:
677       w = max(be->get_lhs()->bit_val_[0].size(), be->get_rhs()->bit_val_[0].size());
678       r = be->get_lhs()->bit_val_[0].is_real() || be->get_rhs()->bit_val_[0].is_real();
679       s = be->get_lhs()->bit_val_[0].is_signed() && be->get_rhs()->bit_val_[0].is_signed();
680       break;
681     case BinaryExpression::Op::AMP:
682     case BinaryExpression::Op::PIPE:
683     case BinaryExpression::Op::CARAT:
684     case BinaryExpression::Op::TCARAT:
685       w = max(be->get_lhs()->bit_val_[0].size(), be->get_rhs()->bit_val_[0].size());
686       break;
687     case BinaryExpression::Op::EEEQ:
688     case BinaryExpression::Op::BEEQ:
689     case BinaryExpression::Op::EEQ:
690     case BinaryExpression::Op::BEQ:
691     case BinaryExpression::Op::GT:
692     case BinaryExpression::Op::GEQ:
693     case BinaryExpression::Op::LT:
694     case BinaryExpression::Op::LEQ:
695     case BinaryExpression::Op::AAMP:
696     case BinaryExpression::Op::PPIPE:
697       w = 1;
698       break;
699     case BinaryExpression::Op::GGT:
700     case BinaryExpression::Op::LLT:
701       w = be->get_lhs()->bit_val_[0].size();
702       s = be->get_lhs()->bit_val_[0].is_signed();
703       break;
704     case BinaryExpression::Op::TTIMES:
705       w = be->get_lhs()->bit_val_[0].size();
706       break;
707     case BinaryExpression::Op::GGGT:
708     case BinaryExpression::Op::LLLT:
709       w = be->get_lhs()->bit_val_[0].size();
710       s = be->get_lhs()->bit_val_[0].is_signed();
711       break;
712     default:
713       assert(false);
714   }
715   be->bit_val_.push_back(Bits(w, 0));
716   if (r) {
717     be->bit_val_[0].reinterpret_type(Bits::Type::REAL);
718   } else if (s) {
719     be->bit_val_[0].reinterpret_type(Bits::Type::SIGNED);
720   }
721 }
722 
edit(ConditionalExpression * ce)723 void Evaluate::SelfDetermine::edit(ConditionalExpression* ce) {
724   Editor::edit(ce);
725 
726   // TODO(eschkufz) Are we sure that this is the right calculus for type?  I
727   // haven't been able to find anything to this point in the spec.
728   size_t w = max(ce->get_lhs()->bit_val_[0].size(), ce->get_rhs()->bit_val_[0].size());
729   const auto r = ce->get_lhs()->bit_val_[0].is_real() || ce->get_rhs()->bit_val_[0].is_real();
730   const auto s = ce->get_lhs()->bit_val_[0].is_signed() && ce->get_rhs()->bit_val_[0].is_signed();
731 
732   ce->bit_val_.push_back(Bits(w, 0));
733   if (r) {
734     ce->bit_val_[0].reinterpret_type(Bits::Type::REAL);
735   } else {
736     ce->bit_val_[0].reinterpret_type(Bits::Type::SIGNED);
737   }
738 }
739 
edit(FeofExpression * fe)740 void Evaluate::SelfDetermine::edit(FeofExpression* fe) {
741   Editor::edit(fe);
742 
743   // $eof() expressions return 1-bit unsigned flags
744   fe->bit_val_.push_back(Bits(1, 0));
745 }
746 
edit(FopenExpression * fe)747 void Evaluate::SelfDetermine::edit(FopenExpression* fe) {
748   Editor::edit(fe);
749 
750   // $fopen() expressions return 32-bit unsigned integer file values.
751   fe->bit_val_.push_back(Bits(32, 0));
752 }
753 
edit(Concatenation * c)754 void Evaluate::SelfDetermine::edit(Concatenation* c) {
755   Editor::edit(c);
756 
757   size_t w = 0;
758   for (auto i = c->begin_exprs(), ie = c->end_exprs(); i != ie; ++i) {
759     w += (*i)->bit_val_[0].size();
760   }
761   c->bit_val_.push_back(Bits(w, 0));
762 }
763 
edit(Identifier * id)764 void Evaluate::SelfDetermine::edit(Identifier* id) {
765   // Don't descend on dim. We treat it as a separate subtree.
766   const auto* r = Resolve().get_resolution(id);
767   assert(r != nullptr);
768 
769   size_t w = 0;
770   Bits::Type t = Bits::Type::UNSIGNED;
771   if (id->size_dim() == r->size_dim()) {
772     w = eval_->get_width(r);
773     t = eval_->get_type(r);
774   } else if (id->back_dim()->is(Node::Tag::range_expression)) {
775     auto* re = static_cast<RangeExpression*>(id->back_dim());
776     const auto lower = eval_->get_value(re->get_lower()).to_uint();
777     if (re->get_type() == RangeExpression::Type::CONSTANT) {
778       const auto upper = eval_->get_value(re->get_upper()).to_uint();
779       w = (upper-lower)+1;
780     } else {
781       w = lower;
782     }
783   } else {
784     w = 1;
785   }
786   id->bit_val_.push_back(Bits(w, 0));
787   id->bit_val_[0].reinterpret_type(t);
788 }
789 
edit(MultipleConcatenation * mc)790 void Evaluate::SelfDetermine::edit(MultipleConcatenation* mc) {
791   // Don't descend on expr, this is a separate expression tree.
792   mc->accept_concat(this);
793 
794   size_t w = eval_->get_value(mc->get_expr()).to_uint() * mc->get_concat()->bit_val_[0].size();
795   mc->bit_val_.push_back(Bits(w, 0));
796 }
797 
edit(Number * n)798 void Evaluate::SelfDetermine::edit(Number* n) {
799   // Does nothing. We already have the value of this expression stored along
800   // with its default size and type in the ast.
801   (void) n;
802 }
803 
edit(String * s)804 void Evaluate::SelfDetermine::edit(String* s) {
805   // Strings are always unsigned.
806   s->bit_val_.push_back(Bits(s->get_readable_val()));
807 }
808 
edit(UnaryExpression * ue)809 void Evaluate::SelfDetermine::edit(UnaryExpression* ue) {
810   Editor::edit(ue);
811 
812   size_t w = 0;
813   auto r = false;
814   auto s = false;
815   switch (ue->get_op()) {
816     case UnaryExpression::Op::PLUS:
817     case UnaryExpression::Op::MINUS:
818       w = ue->get_lhs()->bit_val_[0].size();
819       r = ue->get_lhs()->bit_val_[0].is_real();
820       s = ue->get_lhs()->bit_val_[0].is_signed();
821       break;
822     case UnaryExpression::Op::TILDE:
823       w = ue->get_lhs()->bit_val_[0].size();
824       break;
825     case UnaryExpression::Op::AMP:
826     case UnaryExpression::Op::TAMP:
827     case UnaryExpression::Op::PIPE:
828     case UnaryExpression::Op::TPIPE:
829     case UnaryExpression::Op::CARAT:
830     case UnaryExpression::Op::TCARAT:
831     case UnaryExpression::Op::BANG:
832       w = 1;
833       break;
834     default:
835      assert(false);
836   }
837   ue->bit_val_.push_back(Bits(w, 0));
838   if (r) {
839     ue->bit_val_[0].reinterpret_type(Bits::Type::REAL);
840   } else if (s) {
841     ue->bit_val_[0].reinterpret_type(Bits::Type::SIGNED);
842   }
843 }
844 
edit(GenvarDeclaration * gd)845 void Evaluate::SelfDetermine::edit(GenvarDeclaration* gd) {
846   // Don't descend on id, we handle it below
847 
848   // Genvars are treated as 32-bit signed integers
849   gd->get_id()->bit_val_.push_back(Bits(32, 0));
850   gd->get_id()->bit_val_[0].reinterpret_type(Bits::Type::SIGNED);
851 }
852 
edit(LocalparamDeclaration * ld)853 void Evaluate::SelfDetermine::edit(LocalparamDeclaration* ld) {
854   // Don't descend on id or dim (id we handle below, dim is a separate subtree)
855   ld->accept_val(this);
856   // Hold off on initial assignment until context-determination
857 }
858 
edit(NetDeclaration * nd)859 void Evaluate::SelfDetermine::edit(NetDeclaration* nd) {
860   // Don't descend on id or dim (id we handle below, dim is a separate subtree)
861 
862   // Calculate arity
863   size_t arity = 1;
864   for (auto i = nd->get_id()->begin_dim(), ie = nd->get_id()->end_dim(); i != ie; ++i) {
865     const auto rng = eval_->get_range(*i);
866     arity *= ((rng.first-rng.second)+1);
867   }
868   // Calculate width
869   size_t w = 1;
870   if (nd->is_non_null_dim()) {
871     const auto rng = eval_->get_range(nd->get_dim());
872     w = (rng.first-rng.second)+1;
873   }
874   // Allocate bits
875   nd->get_id()->bit_val_.resize(arity);
876   for (size_t i = 0; i < arity; ++i) {
877     nd->get_id()->bit_val_[i].resize(w);
878     if (nd->get_type() == Declaration::Type::UNTYPED) {
879       nd->get_id()->bit_val_[i].reinterpret_type(Bits::Type::UNSIGNED);
880     } else {
881       nd->get_id()->bit_val_[i].reinterpret_type(static_cast<Bits::Type>(nd->get_type()));
882     }
883   }
884 
885   // TODO(eschkufz) For whatever reason, we've chosen to materialize net
886   // declarations as declarations followed by continuous assigns. So there's no
887   // initial value to worry about here.
888 }
889 
edit(ParameterDeclaration * pd)890 void Evaluate::SelfDetermine::edit(ParameterDeclaration* pd) {
891   // Don't descend on id or dim (id we handle below, dim is a separate subtree)
892   pd->accept_val(this);
893   // Hold off on initial assignment until context-determination
894 }
895 
edit(RegDeclaration * rd)896 void Evaluate::SelfDetermine::edit(RegDeclaration* rd) {
897   // Don't descend on id or dim (id we handle below, dim is a separate subtree)
898   rd->accept_val(this);
899 
900   // Calculate arity
901   size_t arity = 1;
902   for (auto i = rd->get_id()->begin_dim(), ie = rd->get_id()->end_dim(); i != ie; ++i) {
903     const auto rng = eval_->get_range(*i);
904     arity *= ((rng.first-rng.second)+1);
905   }
906   // Calculate width
907   size_t w = 1;
908   if (rd->is_non_null_dim()) {
909     const auto rng = eval_->get_range(rd->get_dim());
910     w = (rng.first-rng.second)+1;
911   }
912   // Allocate bits:
913   rd->get_id()->bit_val_.resize(arity);
914   for (size_t i = 0; i < arity; ++i) {
915     rd->get_id()->bit_val_[i].resize(w);
916     if (rd->get_type() == Declaration::Type::UNTYPED) {
917       rd->get_id()->bit_val_[i].reinterpret_type(Bits::Type::UNSIGNED);
918     } else {
919       rd->get_id()->bit_val_[i].reinterpret_type(static_cast<Bits::Type>(rd->get_type()));
920     }
921   }
922 
923   // Hold off on initial assignment here. We may be doing some size extending
924   // in context-determination. We'll want to wait until then to compute the
925   // value of this variable.
926 }
927 
ContextDetermine(Evaluate * eval)928 Evaluate::ContextDetermine::ContextDetermine(Evaluate* eval) {
929   eval_ = eval;
930 }
931 
edit(BinaryExpression * be)932 void Evaluate::ContextDetermine::edit(BinaryExpression* be) {
933   size_t w = 0;
934   switch (be->get_op()) {
935     case BinaryExpression::Op::PLUS:
936     case BinaryExpression::Op::MINUS:
937     case BinaryExpression::Op::TIMES:
938     case BinaryExpression::Op::DIV:
939     case BinaryExpression::Op::MOD:
940       // Both operands are context determined
941       if (!be->get_lhs()->bit_val_[0].is_real()) {
942         be->get_lhs()->bit_val_[0].resize(be->bit_val_[0].size());
943       }
944       if (!be->get_rhs()->bit_val_[0].is_real()) {
945         be->get_rhs()->bit_val_[0].resize(be->bit_val_[0].size());
946       }
947       break;
948     case BinaryExpression::Op::AMP:
949     case BinaryExpression::Op::PIPE:
950     case BinaryExpression::Op::CARAT:
951     case BinaryExpression::Op::TCARAT:
952       // Both operands are context determined
953       be->get_lhs()->bit_val_[0].resize(be->bit_val_[0].size());
954       be->get_rhs()->bit_val_[0].resize(be->bit_val_[0].size());
955       break;
956     case BinaryExpression::Op::EEEQ:
957     case BinaryExpression::Op::BEEQ:
958     case BinaryExpression::Op::EEQ:
959     case BinaryExpression::Op::BEQ:
960     case BinaryExpression::Op::GT:
961     case BinaryExpression::Op::GEQ:
962     case BinaryExpression::Op::LT:
963     case BinaryExpression::Op::LEQ:
964       // Operands are sort-of context determined. They affect each other
965       // independently of what's going on here.
966       w = max(eval_->get_width(be->get_lhs()), eval_->get_width(be->get_rhs()));
967       if (!be->get_lhs()->bit_val_[0].is_real()) {
968         be->get_lhs()->bit_val_[0].resize(w);
969       }
970       if (!be->get_rhs()->bit_val_[0].is_real()) {
971         be->get_rhs()->bit_val_[0].resize(w);
972       }
973       break;
974     case BinaryExpression::Op::AAMP:
975     case BinaryExpression::Op::PPIPE:
976       // Both operands are self-determined
977       break;
978     case BinaryExpression::Op::GGT:
979     case BinaryExpression::Op::LLT:
980     case BinaryExpression::Op::TTIMES:
981     case BinaryExpression::Op::GGGT:
982     case BinaryExpression::Op::LLLT:
983       // The right-hand side of these expressions is self-determined
984       be->get_lhs()->bit_val_[0].resize(be->bit_val_[0].size());
985       break;
986     default:
987       assert(false);
988   }
989 
990   Editor::edit(be);
991 }
992 
edit(ConditionalExpression * ce)993 void Evaluate::ContextDetermine::edit(ConditionalExpression* ce) {
994   // Conditions are self-determined
995   if (!ce->get_lhs()->bit_val_[0].is_real()) {
996     ce->get_lhs()->bit_val_[0].resize(ce->bit_val_[0].size());
997   }
998   if (!ce->get_rhs()->bit_val_[0].is_real()) {
999     ce->get_rhs()->bit_val_[0].resize(ce->bit_val_[0].size());
1000   }
1001   Editor::edit(ce);
1002 }
1003 
edit(FeofExpression * fe)1004 void Evaluate::ContextDetermine::edit(FeofExpression* fe) {
1005   // Nothing to do here. Feof doesn't determine the size or type of its
1006   // argument.
1007   (void) fe;
1008 }
1009 
edit(FopenExpression * fe)1010 void Evaluate::ContextDetermine::edit(FopenExpression* fe) {
1011   // Nothing to do here. Fopen doesn't determine the size or type of its
1012   // argument.
1013   (void) fe;
1014 }
1015 
edit(Identifier * id)1016 void Evaluate::ContextDetermine::edit(Identifier* id) {
1017   // Nothing to do here. The only expressions we can reach from here are subscripts,
1018   // which we treat as separate subtrees.
1019   (void) id;
1020 }
1021 
edit(MultipleConcatenation * mc)1022 void Evaluate::ContextDetermine::edit(MultipleConcatenation* mc) {
1023   // Don't descend on expr, this is a separate expression tree.
1024   mc->accept_concat(this);
1025 }
1026 
edit(Number * n)1027 void Evaluate::ContextDetermine::edit(Number* n) {
1028   // Nothing left to do here. This is a primary with no nested expressions.
1029   (void) n;
1030 }
1031 
edit(String * s)1032 void Evaluate::ContextDetermine::edit(String* s) {
1033   // Nothing left to do here. This is a primary with no nested expressions.
1034   (void) s;
1035 }
1036 
edit(UnaryExpression * ue)1037 void Evaluate::ContextDetermine::edit(UnaryExpression* ue) {
1038   switch (ue->get_op()) {
1039     case UnaryExpression::Op::PLUS:
1040     case UnaryExpression::Op::MINUS:
1041     case UnaryExpression::Op::TILDE:
1042       ue->get_lhs()->bit_val_[0].resize(ue->bit_val_[0].size());
1043       break;
1044     case UnaryExpression::Op::AMP:
1045     case UnaryExpression::Op::TAMP:
1046     case UnaryExpression::Op::PIPE:
1047     case UnaryExpression::Op::TPIPE:
1048     case UnaryExpression::Op::CARAT:
1049     case UnaryExpression::Op::TCARAT:
1050     case UnaryExpression::Op::BANG:
1051       // All operands are self-determined
1052       break;
1053     default:
1054      assert(false);
1055   }
1056 
1057   Editor::edit(ue);
1058 }
1059 
edit(ContinuousAssign * ca)1060 void Evaluate::ContextDetermine::edit(ContinuousAssign* ca) {
1061   // Identical implementations for continuous, blocking, non-blocking, and variable assigns
1062   if (ca->get_lhs()->bit_val_[0].size() > ca->get_rhs()->bit_val_[0].size()) {
1063     ca->get_rhs()->bit_val_[0].resize(ca->get_lhs()->bit_val_[0].size());
1064   }
1065   ca->accept_rhs(this);
1066 }
1067 
edit(GenvarDeclaration * gd)1068 void Evaluate::ContextDetermine::edit(GenvarDeclaration* gd) {
1069   // There's nothing left to do here. There's no rhs to worry about.
1070   (void) gd;
1071 }
1072 
edit(LocalparamDeclaration * ld)1073 void Evaluate::ContextDetermine::edit(LocalparamDeclaration* ld) {
1074   // Parameters don't impose constraints on their rhs
1075   ld->accept_val(this);
1076   // But they inherit size and width from their rhs according to some pretty
1077   // baroque rules.
1078   ld->get_id()->bit_val_.push_back(Bits(false));
1079   switch (ld->get_type()) {
1080     case Declaration::Type::UNSIGNED:
1081     case Declaration::Type::SIGNED:
1082       ld->get_id()->bit_val_[0].reinterpret_type(static_cast<Bits::Type>(ld->get_type()));
1083       if (ld->is_null_dim()) {
1084         ld->get_id()->bit_val_[0].resize(max(static_cast<size_t>(32), ld->get_val()->bit_val_[0].size()));
1085       } else {
1086         const auto rng = eval_->get_range(ld->get_dim());
1087         ld->get_id()->bit_val_[0].resize((rng.first-rng.second)+1);
1088       }
1089       break;
1090     case Declaration::Type::REAL:
1091       ld->get_id()->bit_val_[0].reinterpret_type(Bits::Type::REAL);
1092       ld->get_id()->bit_val_[0].resize(64);
1093       break;
1094     default:
1095       if (ld->is_null_dim()) {
1096         ld->get_id()->bit_val_[0].reinterpret_type(ld->get_val()->bit_val_[0].get_type());
1097         ld->get_id()->bit_val_[0].resize(ld->get_val()->bit_val_[0].size());
1098       } else {
1099         ld->get_id()->bit_val_[0].reinterpret_type(Bits::Type::UNSIGNED);
1100         const auto rng = eval_->get_range(ld->get_dim());
1101         ld->get_id()->bit_val_[0].resize((rng.first-rng.second)+1);
1102       }
1103       break;
1104   }
1105   // Now that we're all done, we can perform the initial assignment
1106   ld->get_id()->bit_val_[0].assign(eval_->get_value(ld->get_val()));
1107 }
1108 
edit(NetDeclaration * nd)1109 void Evaluate::ContextDetermine::edit(NetDeclaration* nd) {
1110   // There's nothing left to do here. There's no rhs to worry about.
1111   (void) nd;
1112 }
1113 
edit(ParameterDeclaration * pd)1114 void Evaluate::ContextDetermine::edit(ParameterDeclaration* pd) {
1115   // Parameters don't impose constraints on their rhs
1116   pd->accept_val(this);
1117   // But they inherit size and width from their rhs according to some pretty
1118   // baroque rules.
1119   pd->get_id()->bit_val_.push_back(Bits(false));
1120   switch (pd->get_type()) {
1121     case Declaration::Type::UNSIGNED:
1122     case Declaration::Type::SIGNED:
1123       pd->get_id()->bit_val_[0].reinterpret_type(static_cast<Bits::Type>(pd->get_type()));
1124       if (pd->is_null_dim()) {
1125         pd->get_id()->bit_val_[0].resize(max(static_cast<size_t>(32), pd->get_val()->bit_val_[0].size()));
1126       } else {
1127         const auto rng = eval_->get_range(pd->get_dim());
1128         pd->get_id()->bit_val_[0].resize((rng.first-rng.second)+1);
1129       }
1130       break;
1131     case Declaration::Type::REAL:
1132       pd->get_id()->bit_val_[0].reinterpret_type(Bits::Type::REAL);
1133       pd->get_id()->bit_val_[0].resize(64);
1134       break;
1135     default:
1136       if (pd->is_null_dim()) {
1137         pd->get_id()->bit_val_[0].reinterpret_type(pd->get_val()->bit_val_[0].get_type());
1138         pd->get_id()->bit_val_[0].resize(pd->get_val()->bit_val_[0].size());
1139       } else {
1140         pd->get_id()->bit_val_[0].reinterpret_type(Bits::Type::UNSIGNED);
1141         const auto rng = eval_->get_range(pd->get_dim());
1142         pd->get_id()->bit_val_[0].resize((rng.first-rng.second)+1);
1143       }
1144       break;
1145   }
1146   // Now that we're all done, we can perform the initial assignment
1147   pd->get_id()->bit_val_[0].assign(eval_->get_value(pd->get_val()));
1148 }
1149 
edit(RegDeclaration * rd)1150 void Evaluate::ContextDetermine::edit(RegDeclaration* rd) {
1151   // Nothing to do if there's no assignment happening here
1152   if (rd->is_null_val()) {
1153     return;
1154   }
1155   // The parser should guarantee that only scalar declarations
1156   // have initial values.
1157   assert(rd->get_id()->bit_val_.size() == 1);
1158 
1159   // Assignments impose larger sizes but not type constraints
1160   if (rd->get_id()->bit_val_[0].size() > rd->get_val()->bit_val_[0].size()) {
1161     rd->get_val()->bit_val_[0].resize(rd->get_id()->bit_val_[0].size());
1162   }
1163   rd->accept_val(this);
1164 
1165   // Now that we're context determined, we can perform initial assignment
1166   rd->get_id()->bit_val_[0].assign(eval_->get_value(rd->get_val()));
1167 }
1168 
edit(BlockingAssign * ba)1169 void Evaluate::ContextDetermine::edit(BlockingAssign* ba) {
1170   // Identical implementations for continuous, blocking, non-blocking, and variable assigns
1171   if (ba->get_lhs()->bit_val_[0].size() > ba->get_rhs()->bit_val_[0].size()) {
1172     ba->get_rhs()->bit_val_[0].resize(ba->get_lhs()->bit_val_[0].size());
1173   }
1174   ba->accept_rhs(this);
1175 }
1176 
edit(NonblockingAssign * na)1177 void Evaluate::ContextDetermine::edit(NonblockingAssign* na) {
1178   // Identical implementations for continuous, blocking, non-blocking, and variable assigns
1179   if (na->get_lhs()->bit_val_[0].size() > na->get_rhs()->bit_val_[0].size()) {
1180     na->get_rhs()->bit_val_[0].resize(na->get_lhs()->bit_val_[0].size());
1181   }
1182   na->accept_rhs(this);
1183 }
1184 
edit(VariableAssign * va)1185 void Evaluate::ContextDetermine::edit(VariableAssign* va) {
1186   // Assignments impose larger sizes but not type constraints
1187   if (va->get_lhs()->bit_val_[0].size() > va->get_rhs()->bit_val_[0].size()) {
1188     va->get_rhs()->bit_val_[0].resize(va->get_lhs()->bit_val_[0].size());
1189   }
1190   va->accept_rhs(this);
1191 }
1192 
1193 } // namespace cascade
1194