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