Make %t with real values use specified width if given.
[iverilog.git] / eval_tree.cc
blob9c6dfe97642c5417f50b0e6c112dec309f3d84b4
1 /*
2 * Copyright (c) 1999-2003 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: eval_tree.cc,v 1.77 2007/06/02 03:42:12 steve Exp $"
21 #endif
23 # include "config.h"
24 # include "compiler.h"
26 # include <iostream>
28 # include "netlist.h"
29 # include "ivl_assert.h"
31 NetExpr* NetExpr::eval_tree(int prune_to_width)
33 return 0;
37 * Some of the derived classes can be evaluated by the compiler, this
38 * method provides the common aid of evaluating the parameter
39 * expressions.
41 void NetEBinary::eval_sub_tree_()
43 NetExpr*tmp = left_->eval_tree();
44 if (tmp) {
45 delete left_;
46 left_ = tmp;
48 tmp = right_->eval_tree();
49 if (tmp){
50 delete right_;
51 right_ = tmp;
55 bool NetEBinary::get_real_arguments_(verireal&lval, verireal&rval)
57 switch (left_->expr_type()) {
58 case IVL_VT_REAL: {
59 NetECReal*lc = dynamic_cast<NetECReal*> (left_);
60 if (lc == 0) return false;
61 lval = lc->value();
62 break;
65 case IVL_VT_BOOL:
66 case IVL_VT_LOGIC: {
67 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
68 if (lc == 0) return false;
69 verinum tmp = lc->value();
70 lval = verireal(tmp.as_long());
71 break;
74 default:
75 assert(0);
78 switch (right_->expr_type()) {
79 case IVL_VT_REAL: {
80 NetECReal*rc = dynamic_cast<NetECReal*> (right_);
81 if (rc == 0) return 0;
82 rval = rc->value();
83 break;
86 case IVL_VT_BOOL:
87 case IVL_VT_LOGIC: {
88 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
89 if (rc == 0) return 0;
90 verinum tmp = rc->value();
91 rval = verireal(tmp.as_long());
92 break;
95 default:
96 assert(0);
100 return true;
103 NetExpr* NetEBAdd::eval_tree(int prune_to_width)
105 eval_sub_tree_();
107 if (left_->expr_type() == IVL_VT_REAL || right_->expr_type()==IVL_VT_REAL)
108 return eval_tree_real_();
110 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
111 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
113 /* If both operands are constant, then replace the entire
114 expression with a constant value. */
115 if (lc != 0 && rc != 0) {
116 verinum lval = lc->value();
117 verinum rval = rc->value();
119 verinum val;
120 switch (op_) {
121 case '+':
122 val = lval + rval;
123 break;
124 case '-':
125 val = lval - rval;
126 break;
127 default:
128 return 0;
131 /* Result might have known width. */
132 if (has_width()) {
133 if (debug_eval_tree) {
134 cerr << get_line() << ": debug: Evaluate expr=" << *this
135 << " --- prune=" << prune_to_width << endl;
137 unsigned lwid = lc->expr_width();
138 unsigned rwid = rc->expr_width();
139 unsigned wid = (rwid > lwid) ? rwid : lwid;
140 if (prune_to_width < 0)
141 wid += 1;
142 verinum val2=verinum(val,wid);
143 val=val2;
146 return new NetEConst(val);
149 /* Try to combine a right constant value with the right
150 constant value of a sub-expression add. For example, the
151 expression (a + 2) - 1 can be rewritten as a + 1. */
153 NetEBAdd*se = dynamic_cast<NetEBAdd*>(left_);
154 lc = se? dynamic_cast<NetEConst*>(se->right_) : 0;
156 if (lc != 0 && rc != 0) {
157 assert(se != 0);
158 verinum lval = lc->value();
159 verinum rval = rc->value();
161 verinum val;
162 if (op_ == se->op_) {
163 /* (a + lval) + rval --> a + (rval+lval) */
164 /* (a - lval) - rval --> a - (rval+lval) */
165 val = rval + lval;
166 } else {
167 /* (a - lval) + rval --> a + (rval-lval) */
168 /* (a + lval) - rval --> a - (rval-lval) */
169 val = rval - lval;
172 NetEConst*tmp = new NetEConst(val);
173 left_ = se->left_->dup_expr();
174 delete se;
175 delete right_;
176 right_ = tmp;
177 /* We've changed the subexpression, but the result is
178 still not constant, so return nil here anyhow. */
179 return 0;
182 /* Nothing more to be done, the value is not constant. */
183 return 0;
186 NetECReal* NetEBAdd::eval_tree_real_()
188 verireal lval;
189 verireal rval;
190 bool flag = get_real_arguments_(lval, rval);
191 if (!flag) return 0;
193 verireal res_val;
195 switch (op()) {
196 case '+':
197 res_val = lval + rval;
198 break;
199 case '-':
200 res_val = lval - rval;
201 break;
202 default:
203 ivl_assert(*this, 0);
206 NetECReal*res = new NetECReal( res_val );
207 res->set_line(*this);
208 return res;
211 NetEConst* NetEBBits::eval_tree(int prune_to_width)
213 eval_sub_tree_();
215 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
216 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
218 /* Notice the special case where one of the operands is 0 and
219 this is a bitwise &. If this happens, then the result is
220 known to be 0. */
221 if ((op() == '&') && lc && (lc->value() == verinum(0))) {
222 verinum res (verinum::V0, expr_width());
223 return new NetEConst(res);
226 if ((op() == '&') && rc && (rc->value() == verinum(0))) {
227 verinum res (verinum::V0, expr_width());
228 return new NetEConst(res);
231 if (lc == 0) return 0;
232 if (rc == 0) return 0;
234 verinum lval = lc->value();
235 verinum rval = rc->value();
237 unsigned lwid = lc->expr_width();
238 if (lwid == 0) lwid = lval.len();
240 unsigned rwid = rc->expr_width();
241 if (rwid == 0) rwid = rval.len();
243 unsigned wid = expr_width();
244 if (wid == 0)
245 wid = (rwid > lwid)? rwid : lwid;
247 verinum res (verinum::V0, wid);
249 if (lwid > wid)
250 lwid = wid;
251 if (rwid > wid)
252 rwid = wid;
254 switch (op()) {
256 case '|': {
257 unsigned cnt = lwid;
258 if (cnt > wid) cnt = wid;
259 if (cnt > rwid) cnt = rwid;
260 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
261 res.set(idx, lval.get(idx) | rval.get(idx));
263 if (lwid < rwid)
264 for (unsigned idx = lwid ; idx < rwid ; idx += 1)
265 res.set(idx, rval.get(idx));
267 if (rwid < lwid)
268 for (unsigned idx = rwid ; idx < lwid ; idx += 1)
269 res.set(idx, lval.get(idx));
271 break;
274 case '&': {
275 unsigned cnt = lwid;
276 if (cnt > wid) cnt = wid;
277 if (cnt > rwid) cnt = rwid;
278 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
279 res.set(idx, lval.get(idx) & rval.get(idx));
281 break;
284 case '^': {
285 unsigned cnt = lwid;
286 if (cnt > wid) cnt = wid;
287 if (cnt > rwid) cnt = rwid;
288 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
289 res.set(idx, lval.get(idx) ^ rval.get(idx));
291 if (lwid < rwid)
292 for (unsigned idx = lwid ; idx < rwid ; idx += 1)
293 res.set(idx, rval.get(idx));
295 if (rwid < lwid)
296 for (unsigned idx = rwid ; idx < lwid ; idx += 1)
297 res.set(idx, lval.get(idx));
299 break;
302 default:
303 return 0;
306 return new NetEConst(res);
310 NetEConst* NetEBComp::eval_less_()
312 NetEConst*r = dynamic_cast<NetEConst*>(right_);
313 if (r == 0) return 0;
315 verinum rv = r->value();
316 if (! rv.is_defined()) {
317 verinum result(verinum::Vx, 1);
318 return new NetEConst(result);
322 /* Detect the case where the right side is greater than or
323 equal to the largest value the left side can possibly
324 have. Use the width of the left expression as all 1's to
325 calculate the maximum possible width for the left_
326 expression. This test only works of the compare is
327 unsigned. */
328 if (! (rv.has_sign() || left_->has_sign())) {
330 assert(left_->expr_width() > 0);
331 verinum lv (verinum::V1, left_->expr_width());
332 if (lv < rv) {
333 verinum result(verinum::V1, 1);
334 return new NetEConst(result);
338 /* Now go on to the normal test of the values. */
339 NetEConst*l = dynamic_cast<NetEConst*>(left_);
340 if (l == 0) return 0;
341 verinum lv = l->value();
342 if (! lv.is_defined()) {
343 verinum result(verinum::Vx, 1);
344 return new NetEConst(result);
347 if (lv.has_sign() && rv.has_sign()) {
348 if (lv.as_long() < rv.as_long()) {
349 verinum result(verinum::V1, 1);
350 return new NetEConst(result);
352 } else {
353 if (lv.as_ulong() < rv.as_ulong()) {
354 verinum result(verinum::V1, 1);
355 return new NetEConst(result);
359 verinum result(verinum::V0, 1);
360 return new NetEConst(result);
363 NetEConst* NetEBComp::eval_leeq_real_()
365 NetEConst*vtmp;
366 NetECReal*rtmp;
367 double lv, rv;
369 switch (left_->expr_type()) {
370 case IVL_VT_REAL:
371 rtmp = dynamic_cast<NetECReal*> (left_);
372 if (rtmp == 0)
373 return 0;
375 lv = rtmp->value().as_double();
376 break;
378 case IVL_VT_LOGIC:
379 vtmp = dynamic_cast<NetEConst*> (left_);
380 if (vtmp == 0)
381 return 0;
383 lv = vtmp->value().as_long();
384 break;
386 default:
387 assert(0);
391 switch (right_->expr_type()) {
392 case IVL_VT_REAL:
393 rtmp = dynamic_cast<NetECReal*> (right_);
394 if (rtmp == 0)
395 return 0;
397 rv = rtmp->value().as_double();
398 break;
400 case IVL_VT_LOGIC:
401 vtmp = dynamic_cast<NetEConst*> (right_);
402 if (vtmp == 0)
403 return 0;
405 rv = vtmp->value().as_long();
406 break;
408 default:
409 assert(0);
412 verinum result((lv <= rv)? verinum::V1 : verinum::V0, 1);
413 vtmp = new NetEConst(result);
414 vtmp->set_line(*this);
416 return vtmp;
419 NetEConst* NetEBComp::eval_leeq_()
421 if (right_->expr_type() == IVL_VT_REAL)
422 return eval_leeq_real_();
423 if (left_->expr_type() == IVL_VT_REAL)
424 return eval_leeq_real_();
426 NetEConst*r = dynamic_cast<NetEConst*>(right_);
427 if (r == 0) return 0;
429 verinum rv = r->value();
430 if (! rv.is_defined()) {
431 verinum result(verinum::Vx, 1);
432 return new NetEConst(result);
435 if (left_->expr_width() == 0) {
436 cerr << get_line() << ": internal error: Something wrong "
437 << "with the left side width of <= ?" << endl;
438 cerr << get_line() << ": : " << *this << endl;
441 /* Detect the case where the right side is greater that or
442 equal to the largest value the left side can possibly
443 have. */
444 assert(left_->expr_width() > 0);
445 verinum lv (verinum::V1, left_->expr_width());
446 if (lv <= rv) {
447 verinum result(verinum::V1, 1);
448 return new NetEConst(result);
451 /* Now go on to the normal test of the values. */
452 NetEConst*l = dynamic_cast<NetEConst*>(left_);
453 if (l == 0) return 0;
454 lv = l->value();
455 if (! lv.is_defined()) {
456 verinum result(verinum::Vx, 1);
457 return new NetEConst(result);
460 if (lv.has_sign() && rv.has_sign()) {
461 if (lv.as_long() <= rv.as_long()) {
462 verinum result(verinum::V1, 1);
463 return new NetEConst(result);
465 } else {
466 if (lv.as_ulong() <= rv.as_ulong()) {
467 verinum result(verinum::V1, 1);
468 return new NetEConst(result);
472 verinum result(verinum::V0, 1);
473 return new NetEConst(result);
476 NetEConst* NetEBComp::eval_gt_()
478 if ((left_->expr_type() == IVL_VT_REAL)
479 && (right_->expr_type() == IVL_VT_REAL)) {
481 NetECReal*tmpl = dynamic_cast<NetECReal*>(left_);
482 if (tmpl == 0)
483 return 0;
485 NetECReal*tmpr = dynamic_cast<NetECReal*>(right_);
486 if (tmpr == 0)
487 return 0;
489 double ll = tmpl->value().as_double();
490 double rr = tmpr->value().as_double();
492 verinum result ((ll > rr)? verinum::V1 : verinum::V0, 1, true);
493 return new NetEConst(result);
496 NetEConst*l = dynamic_cast<NetEConst*>(left_);
497 if (l == 0) return 0;
499 verinum lv = l->value();
500 if (! lv.is_defined()) {
501 verinum result(verinum::Vx, 1);
502 return new NetEConst(result);
505 /* Check for the special case where we know, simply by the
506 limited width of the right expression, that it cannot
507 possibly be false. */
508 if (right_->expr_width() > 0) {
509 verinum rv (verinum::V1, right_->expr_width());
510 if (lv > rv) {
511 verinum result(verinum::V1, 1);
512 return new NetEConst(result);
516 /* Compare with a real value. Do it as double precision. */
517 if (right_->expr_type() == IVL_VT_REAL) {
518 NetECReal*tmp = dynamic_cast<NetECReal*>(right_);
519 if (tmp == 0)
520 return 0;
522 double rr = tmp->value().as_double();
523 double ll = lv.has_sign()? lv.as_long() : lv.as_ulong();
525 verinum result ((ll > rr)? verinum::V1 : verinum::V0, 1, true);
526 return new NetEConst(result);
529 /* Now go on to the normal test of the values. */
530 NetEConst*r = dynamic_cast<NetEConst*>(right_);
531 if (r == 0) return 0;
532 verinum rv = r->value();
533 if (! rv.is_defined()) {
534 verinum result(verinum::Vx, 1);
535 return new NetEConst(result);
538 if (lv.has_sign() && rv.has_sign() && (lv.as_long() > rv.as_long())) {
539 verinum result(verinum::V1, 1);
540 return new NetEConst(result);
543 if (lv.as_ulong() > rv.as_ulong()) {
544 verinum result(verinum::V1, 1);
545 return new NetEConst(result);
548 verinum result(verinum::V0, 1);
549 return new NetEConst(result);
552 NetEConst* NetEBComp::eval_gteq_()
554 if ((left_->expr_type() == IVL_VT_REAL)
555 && (right_->expr_type() == IVL_VT_REAL)) {
557 NetECReal*tmpl = dynamic_cast<NetECReal*>(left_);
558 if (tmpl == 0)
559 return 0;
561 NetECReal*tmpr = dynamic_cast<NetECReal*>(right_);
562 if (tmpr == 0)
563 return 0;
565 double ll = tmpl->value().as_double();
566 double rr = tmpr->value().as_double();
568 verinum result ((ll >= rr)? verinum::V1 : verinum::V0, 1, true);
569 return new NetEConst(result);
572 NetEConst*l = dynamic_cast<NetEConst*>(left_);
573 if (l == 0) return 0;
575 verinum lv = l->value();
576 if (! lv.is_defined()) {
577 verinum result(verinum::Vx, 1);
578 return new NetEConst(result);
581 /* Detect the case where the left side is greater than the
582 largest value the right side can possibly have. */
583 if (right_->expr_type() == IVL_VT_LOGIC) {
584 assert(right_->expr_width() > 0);
585 verinum rv (verinum::V1, right_->expr_width());
586 if (lv >= rv) {
587 verinum result(verinum::V1, 1);
588 return new NetEConst(result);
592 /* Compare with a real value. Do it as double precision. */
593 if (right_->expr_type() == IVL_VT_REAL) {
594 NetECReal*tmp = dynamic_cast<NetECReal*>(right_);
595 if (tmp == 0)
596 return 0;
598 double rr = tmp->value().as_double();
599 double ll = lv.has_sign()? lv.as_long() : lv.as_ulong();
601 verinum result ((ll >= rr)? verinum::V1 : verinum::V0, 1, true);
602 return new NetEConst(result);
605 /* Now go on to the normal test of the values. */
606 NetEConst*r = dynamic_cast<NetEConst*>(right_);
607 if (r == 0) return 0;
608 verinum rv = r->value();
609 if (! rv.is_defined()) {
610 verinum result(verinum::Vx, 1);
611 return new NetEConst(result);
614 if (lv.has_sign() && rv.has_sign()) {
616 if (lv.as_long() >= rv.as_long()) {
617 verinum result(verinum::V1, 1);
618 return new NetEConst(result);
620 } else {
622 if (lv.as_ulong() >= rv.as_ulong()) {
623 verinum result(verinum::V1, 1);
624 return new NetEConst(result);
628 verinum result(verinum::V0, 1);
629 return new NetEConst(result);
632 NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
634 NetEConst*l = dynamic_cast<NetEConst*>(left_);
635 if (l == 0) return 0;
636 NetEConst*r = dynamic_cast<NetEConst*>(right_);
637 if (r == 0) return 0;
639 const verinum&lv = l->value();
640 const verinum&rv = r->value();
642 const verinum::V eq_res = ne_flag? verinum::V0 : verinum::V1;
643 const verinum::V ne_res = ne_flag? verinum::V1 : verinum::V0;
645 verinum::V res = eq_res;
646 unsigned top = lv.len();
647 if (rv.len() < top)
648 top = rv.len();
650 for (unsigned idx = 0 ; idx < top ; idx += 1) {
652 switch (lv.get(idx)) {
654 case verinum::Vx:
655 case verinum::Vz:
656 res = verinum::Vx;
657 break;
659 default:
660 break;
663 switch (rv.get(idx)) {
665 case verinum::Vx:
666 case verinum::Vz:
667 res = verinum::Vx;
668 break;
670 default:
671 break;
674 if (res == verinum::Vx)
675 break;
677 if (rv.get(idx) != lv.get(idx))
678 res = ne_res;
681 if (res != verinum::Vx) {
682 verinum::V lpad = verinum::V0;
683 verinum::V rpad = verinum::V0;
685 if (lv.has_sign() && lv.get(lv.len()-1) == verinum::V1)
686 lpad = verinum::V1;
687 if (rv.has_sign() && rv.get(rv.len()-1) == verinum::V1)
688 rpad = verinum::V1;
690 for (unsigned idx = top ; idx < lv.len() ; idx += 1)
691 switch (lv.get(idx)) {
693 case verinum::Vx:
694 case verinum::Vz:
695 res = verinum::Vx;
696 break;
698 case verinum::V0:
699 if (res != verinum::Vx && rpad != verinum::V0)
700 res = ne_res;
701 break;
703 case verinum::V1:
704 if (res != verinum::Vx && rpad != verinum::V1)
705 res = ne_res;
706 break;
708 default:
709 break;
712 for (unsigned idx = top ; idx < rv.len() ; idx += 1)
713 switch (rv.get(idx)) {
715 case verinum::Vx:
716 case verinum::Vz:
717 res = verinum::Vx;
718 break;
720 case verinum::V0:
721 if (res != verinum::Vx && lpad != verinum::V0)
722 res = ne_res;
723 break;
725 case verinum::V1:
726 if (res != verinum::Vx && lpad != verinum::V1)
727 res = ne_res;
728 break;
730 default:
731 break;
735 return new NetEConst(verinum(res));
738 NetEConst* NetEBComp::eval_eqeqeq_()
740 NetEConst*l = dynamic_cast<NetEConst*>(left_);
741 if (l == 0) return 0;
742 NetEConst*r = dynamic_cast<NetEConst*>(right_);
743 if (r == 0) return 0;
745 const verinum&lv = l->value();
746 const verinum&rv = r->value();
748 verinum::V res = verinum::V1;
750 unsigned cnt = lv.len();
751 if (cnt > rv.len())
752 cnt = rv.len();
754 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
755 if (lv.get(idx) != rv.get(idx))
756 res = verinum::V0;
758 for (unsigned idx = cnt ; idx < lv.len() ; idx += 1)
759 if (lv.get(idx) != verinum::V0)
760 res = verinum::V0;
762 for (unsigned idx = cnt ; idx < rv.len() ; idx += 1)
763 if (rv.get(idx) != verinum::V0)
764 res = verinum::V0;
766 return new NetEConst(verinum(res, 1));
769 NetEConst* NetEBComp::eval_neeqeq_()
771 NetEConst*tmp = eval_eqeqeq_();
772 if (tmp == 0)
773 return 0;
775 NetEConst*res;
777 if (tmp->value().get(0) == verinum::V0)
778 res = new NetEConst(verinum(verinum::V1,1));
779 else
780 res = new NetEConst(verinum(verinum::V0,1));
782 delete tmp;
783 return res;
786 NetEConst* NetEBComp::eval_tree(int prune_to_width)
788 eval_sub_tree_();
790 switch (op_) {
791 case 'E': // Case equality (===)
792 return eval_eqeqeq_();
794 case 'e': // Equality (==)
795 return eval_eqeq_(false);
797 case 'G': // >=
798 return eval_gteq_();
800 case 'L': // <=
801 return eval_leeq_();
803 case 'N': // Case inequality (!==)
804 return eval_neeqeq_();
806 case 'n': // not-equal (!=)
807 return eval_eqeq_(true);
809 case '<': // Less than
810 return eval_less_();
812 case '>': // Greater then
813 return eval_gt_();
815 default:
816 return 0;
821 * The NetEBDiv operator includes the / and % operators. First evaluate
822 * the sub-expressions, then perform the required operation.
824 NetExpr* NetEBDiv::eval_tree(int prune_to_width)
826 eval_sub_tree_();
828 if (expr_type() == IVL_VT_REAL) {
829 NetECReal*lc = dynamic_cast<NetECReal*>(left_);
830 if (lc == 0) return 0;
832 verireal lval = lc->value();
834 if (NetECReal*rc = dynamic_cast<NetECReal*>(right_)) {
835 NetECReal*tmp = 0;
836 verireal rval = rc->value();
838 switch (op_) {
839 case '/':
840 tmp = new NetECReal(lval / rval);
841 break;
843 case '%':
844 tmp = new NetECReal(lval % rval);
847 assert(tmp);
848 tmp->set_line(*this);
849 return tmp;
851 } else if (NetEConst*rc = dynamic_cast<NetEConst*>(right_)) {
853 NetECReal*tmp = 0;
854 verinum rval = rc->value();
856 switch (op_) {
857 case '/':
858 tmp = new NetECReal(lval / rval);
859 break;
861 case '%':
862 tmp = new NetECReal(lval % rval);
865 assert(tmp);
866 tmp->set_line(*this);
867 return tmp;
872 } else {
873 assert(expr_type() == IVL_VT_LOGIC);
874 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
875 if (lc == 0) return 0;
876 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
877 if (rc == 0) return 0;
879 verinum lval = lc->value();
880 verinum rval = rc->value();
882 switch (op_) {
883 case '/':
884 return new NetEConst(lval / rval);
886 case '%':
887 return new NetEConst(lval % rval);
891 return 0;
894 NetEConst* NetEBLogic::eval_tree(int prune_to_width)
896 eval_sub_tree_();
897 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
898 if (lc == 0) return 0;
899 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
900 if (rc == 0) return 0;
902 verinum::V lv = verinum::V0;
903 verinum::V rv = verinum::V0;
905 verinum v = lc->value();
906 for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
907 if (v.get(idx) == verinum::V1)
908 lv = verinum::V1;
910 if (lv == verinum::V0)
911 for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
912 if (v.get(idx) != verinum::V0)
913 lv = verinum::Vx;
915 v = rc->value();
916 for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
917 if (v.get(idx) == verinum::V1)
918 rv = verinum::V1;
920 if (rv == verinum::V0)
921 for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
922 if (v.get(idx) != verinum::V0)
923 rv = verinum::Vx;
925 verinum::V res;
926 switch (op_) {
927 case 'a': { // Logical AND (&&)
928 if ((lv == verinum::V0) || (rv == verinum::V0))
929 res = verinum::V0;
931 else if ((lv == verinum::V1) && (rv == verinum::V1))
932 res = verinum::V1;
934 else
935 res = verinum::Vx;
937 break;
940 case 'o': { // Logical OR (||)
941 if ((lv == verinum::V1) || (rv == verinum::V1))
942 res = verinum::V1;
944 else if ((lv == verinum::V0) && (rv == verinum::V0))
945 res = verinum::V0;
947 else
948 res = verinum::Vx;
950 break;
953 default:
954 return 0;
957 return new NetEConst(verinum(res, 1));
961 NetExpr* NetEBMult::eval_tree_real_()
963 verireal lval;
964 verireal rval;
966 bool flag = get_real_arguments_(lval, rval);
967 if (! flag) return 0;
970 NetECReal*res = new NetECReal(lval * rval);
971 res->set_line(*this);
972 return res;
975 NetExpr* NetEBMult::eval_tree(int prune_to_width)
977 eval_sub_tree_();
979 if (expr_type() == IVL_VT_REAL)
980 return eval_tree_real_();
982 assert(expr_type() == IVL_VT_LOGIC);
984 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
985 if (lc == 0) return 0;
986 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
987 if (rc == 0) return 0;
989 verinum lval = lc->value();
990 verinum rval = rc->value();
992 return new NetEConst(lval * rval);
995 NetExpr* NetEBPow::eval_tree_real_()
997 verireal lval;
998 verireal rval;
1000 bool flag = get_real_arguments_(lval, rval);
1001 if (! flag) return 0;
1003 NetECReal*res = new NetECReal( pow(lval,rval) );
1004 res->set_line(*this);
1005 return res;
1008 NetExpr* NetEBPow::eval_tree(int prune_to_width)
1010 eval_sub_tree_();
1012 if (expr_type() == IVL_VT_REAL)
1013 return eval_tree_real_();
1015 assert(expr_type() == IVL_VT_LOGIC);
1017 NetEConst*lc = dynamic_cast<NetEConst*>(left_);
1018 if (lc == 0) return 0;
1019 NetEConst*rc = dynamic_cast<NetEConst*>(right_);
1020 if (rc == 0) return 0;
1022 verinum lval = lc->value();
1023 verinum rval = rc->value();
1025 return new NetEConst( pow(lval,rval) );
1030 * Evaluate the shift operator if possible. For this to work, both
1031 * operands must be constant.
1033 NetEConst* NetEBShift::eval_tree(int prune_to_width)
1035 eval_sub_tree_();
1036 NetEConst*re = dynamic_cast<NetEConst*>(right_);
1037 if (re == 0)
1038 return 0;
1040 NetEConst*le = dynamic_cast<NetEConst*>(left_);
1041 if (le == 0)
1042 return 0;
1044 NetEConst*res;
1046 verinum rv = re->value();
1047 verinum lv = le->value();
1049 /* Make an early estimate of the expression width. */
1050 unsigned wid = expr_width();
1052 if (rv.is_defined()) {
1054 unsigned shift = rv.as_ulong();
1056 if (debug_eval_tree) {
1057 cerr << get_line() << ": debug: "
1058 << "Evaluate " << lv << "<<" << op() << ">> "
1059 << rv << ", wid=" << wid << ", shift=" << shift
1060 << ", lv.has_len()=" << lv.has_len() << endl;
1063 if ((wid == 0) || ! lv.has_len()) {
1064 /* If the caller doesn't care what the width is,
1065 then calcuate a width from the trimmed left
1066 expression, plus the shift. This avoids
1067 data loss. */
1068 lv = trim_vnum(lv);
1069 wid = lv.len();
1070 if (op() == 'l')
1071 wid = lv.len() + shift;
1074 if (prune_to_width > 0 && wid > (unsigned)prune_to_width)
1075 wid = prune_to_width;
1077 assert(wid);
1078 verinum nv (verinum::V0, wid, lv.has_len());
1080 if (op() == 'r') {
1081 unsigned cnt = wid;
1082 if (cnt > nv.len())
1083 cnt = nv.len();
1084 if (shift >= lv.len())
1085 cnt = 0;
1086 else if (cnt > (lv.len()-shift))
1087 cnt = (lv.len()-shift);
1088 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
1089 nv.set(idx, lv[idx+shift]);
1091 } else {
1092 unsigned cnt = wid;
1093 if (cnt > lv.len())
1094 cnt = lv.len();
1095 if (shift >= nv.len())
1096 cnt = 0;
1097 else if (cnt > (nv.len()-shift))
1098 cnt = nv.len() - shift;
1100 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
1101 nv.set(idx+shift, lv[idx]);
1104 res = new NetEConst(nv);
1106 } else {
1107 if (wid == 0)
1108 wid = left_->expr_width();
1110 verinum nv (verinum::Vx, wid);
1111 res = new NetEConst(nv);
1114 return res;
1117 NetEConst* NetEConcat::eval_tree(int prune_to_width)
1119 unsigned repeat_val = repeat();
1120 unsigned local_errors = 0;
1122 if (debug_eval_tree) {
1123 cerr << get_line() << ": debug: Evaluate expr=" << *this
1124 << ", prune_to_width=" << prune_to_width << endl;
1127 unsigned gap = 0;
1128 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
1130 // Parameter not here? This is an error, but presumably
1131 // already caught and we are here just to catch more.
1132 if (parms_[idx] == 0)
1133 continue;
1136 // If this parameter is already a constant, all is well
1137 // so go on.
1138 if (dynamic_cast<NetEConst*>(parms_[idx])) {
1139 gap += parms_[idx]->expr_width();
1140 continue;
1143 // Finally, try to evaluate the parameter expression
1144 // that is here. If I succeed, reset the parameter to
1145 // the evaluated value.
1146 assert(parms_[idx]);
1147 NetExpr*expr = parms_[idx]->eval_tree(0);
1148 if (expr) {
1149 delete parms_[idx];
1150 parms_[idx] = expr;
1152 if (! expr->has_width()) {
1153 cerr << get_line() << ": error: concatenation "
1154 << "operand has indefinite width: "
1155 << *parms_[idx] << endl;
1156 local_errors += 1;
1157 } else if (expr->expr_width() == 0) {
1158 cerr << expr->get_line() << ": internal error: "
1159 << "Operand of concatenation has no width: "
1160 << *expr << endl;
1161 local_errors += 1;
1164 gap += expr->expr_width();
1169 if (local_errors > 0)
1170 return 0;
1172 // Handle the special case that the repeat expression is
1173 // zero. In this case, just return a 0 value with the expected
1174 // width.
1175 if (repeat_val == 0) {
1176 verinum val (verinum::V0, expr_width());
1177 NetEConst*res = new NetEConst(val);
1178 res->set_width(val.len());
1179 return res;
1182 // At this point, the "gap" is the width of a single repeat of
1183 // the concatenation. The total width of the result is the gap
1184 // times the repeat count.
1185 verinum val (verinum::Vx, repeat_val * gap);
1187 // build up the result from least significant to most.
1189 unsigned cur = 0;
1190 bool is_string_flag = true;
1191 for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
1192 NetEConst*expr = dynamic_cast<NetEConst*>(parms_[idx-1]);
1193 if (expr == 0)
1194 return 0;
1196 verinum tmp = expr->value();
1197 for (unsigned bit = 0; bit < tmp.len(); bit += 1, cur += 1)
1198 for (unsigned rep = 0 ; rep < repeat_val ; rep += 1)
1199 val.set(rep*gap+cur, tmp[bit]);
1201 is_string_flag = is_string_flag && tmp.is_string();
1204 /* If all the values were strings, then re-stringify this
1205 constant. This might be useful information in the code
1206 generator or other optimizer steps. */
1207 if (is_string_flag) {
1208 val = verinum(val.as_string());
1211 NetEConst*res = new NetEConst(val);
1212 res->set_width(val.len());
1213 return res;
1216 NetExpr* NetEParam::eval_tree(int prune_to_width)
1218 if (des_ == 0) {
1219 assert(scope_ == 0);
1220 return 0;
1223 if (debug_elaborate) {
1224 cerr << get_line() << ": debug: evaluating expression: "
1225 << *this << endl;
1228 assert(scope_);
1229 const NetExpr*expr_msb;
1230 const NetExpr*expr_lsb;
1231 const NetExpr*expr = scope_->get_parameter(name_, expr_msb, expr_lsb);
1232 if (expr == 0) {
1233 cerr << get_line() << ": internal error: Unable to match "
1234 << "parameter " << name_ << " in scope "
1235 << scope_path(scope_) << endl;
1236 return 0;
1239 assert(expr);
1241 NetExpr*nexpr = expr->dup_expr();
1242 assert(nexpr);
1244 // If the parameter that I refer to is already evaluated, then
1245 // return the constant value.
1246 if (NetEConst*tmp = dynamic_cast<NetEConst*>(nexpr)) {
1247 verinum val = tmp->value();
1248 NetEConstParam*ptmp = new NetEConstParam(scope_, name_, val);
1249 ptmp->set_line(*this);
1250 delete nexpr;
1251 return ptmp;
1254 if (NetECReal*tmp = dynamic_cast<NetECReal*>(nexpr)) {
1255 verireal val = tmp->value();
1256 NetECRealParam*ptmp = new NetECRealParam(scope_, name_, val);
1257 ptmp->set_line(*this);
1258 delete nexpr;
1259 return ptmp;
1262 // Try to evaluate the expression. If I cannot, then the
1263 // expression is not a constant expression and I fail here.
1264 NetExpr*res = nexpr->eval_tree();
1265 if (res == 0) {
1266 cerr << get_line() << ": internal error: Unable to evaluate "
1267 << "parameter " << name_ << " expression: "
1268 << *nexpr << endl;
1269 delete nexpr;
1270 return 0;
1273 // The result can be saved as the value of the parameter for
1274 // future reference, and return a copy to the caller.
1275 scope_->replace_parameter(name_, res);
1277 /* Return as a result a NetEConstParam or NetECRealParam
1278 object, depending on the type of the expression. */
1280 switch (res->expr_type()) {
1282 case IVL_VT_BOOL:
1283 case IVL_VT_LOGIC:
1284 { NetEConst*tmp = dynamic_cast<NetEConst*>(res);
1285 if (tmp == 0) {
1286 cerr << get_line() << ": internal error: parameter "
1287 << name_ << " evaluates to incomprehensible "
1288 << *res << "." << endl;
1289 return 0;
1292 assert(tmp);
1294 verinum val = tmp->value();
1295 NetEConstParam*ptmp = new NetEConstParam(scope_, name_, val);
1297 return ptmp;
1300 case IVL_VT_REAL:
1301 { NetECReal*tmp = dynamic_cast<NetECReal*>(res);
1302 if (tmp == 0) {
1303 cerr << get_line() << ": internal error: parameter "
1304 << name_ << " evaluates to incomprehensible "
1305 << *res << "." << endl;
1306 return 0;
1309 assert(tmp);
1311 verireal val = tmp->value();
1312 NetECRealParam*ptmp = new NetECRealParam(scope_, name_, val);
1314 return ptmp;
1317 default:
1318 assert(0);
1319 return 0;
1323 NetEConst* NetESelect::eval_tree(int prune_to_width)
1325 NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
1326 if (expr == 0) {
1327 NetExpr*tmp = expr_->eval_tree();
1328 if (tmp != 0) {
1329 delete expr_;
1330 expr_ = tmp;
1333 expr = dynamic_cast<NetEConst*>(expr_);
1336 long bval = 0;
1337 if (base_) {
1338 NetEConst*base = dynamic_cast<NetEConst*>(base_);
1339 if (base == 0) {
1340 NetExpr*tmp = base_->eval_tree();
1341 if (tmp != 0) {
1342 delete base_;
1343 base_ = tmp;
1346 base = dynamic_cast<NetEConst*>(base_);
1349 if (base == 0)
1350 return 0;
1352 bval = base->value().as_long();
1355 if (expr == 0)
1356 return 0;
1358 verinum eval = expr->value();
1359 verinum oval (verinum::V0, expr_width(), true);
1361 verinum::V pad_bit = verinum::Vx;
1362 if (base_ == 0) {
1364 /* If the base is NULL (different from 0) the this
1365 select is here for sign extension. So calculate a
1366 proper pad bit. Extend x or z or 0, and sign extend 1
1367 if this is signed. */
1368 unsigned top = expr->expr_width()-1;
1370 pad_bit = eval.get(top);
1371 if (pad_bit==verinum::V1 && !has_sign())
1372 pad_bit = verinum::V0;
1375 for (unsigned long idx = 0 ; idx < expr_width() ; idx += 1) {
1376 if ((bval >= 0) && ((unsigned long) bval < eval.len()))
1377 oval.set(idx, eval.get(bval));
1378 else
1379 oval.set(idx, pad_bit);
1381 bval += 1;
1384 NetEConst*res = new NetEConst(oval);
1385 return res;
1390 * A ternary expression evaluation is controlled by the condition
1391 * expression. If the condition evaluates to true or false, then
1392 * return the evaluated true or false expression. If the condition
1393 * evaluates to x or z, then merge the constant bits of the true and
1394 * false expressions.
1396 NetExpr* NetETernary::eval_tree(int prune_to_width)
1398 NetExpr*tmp;
1400 assert(cond_);
1401 if (0 == dynamic_cast<NetEConst*>(cond_)) {
1402 tmp = cond_->eval_tree();
1403 if (tmp != 0) {
1404 delete cond_;
1405 cond_ = tmp;
1409 assert(true_val_);
1410 if (0 == dynamic_cast<NetEConst*>(true_val_)) {
1411 tmp = true_val_->eval_tree();
1412 if (tmp != 0) {
1413 delete true_val_;
1414 true_val_ = tmp;
1418 assert(false_val_);
1419 if (0 == dynamic_cast<NetEConst*>(false_val_)) {
1420 tmp = false_val_->eval_tree();
1421 if (tmp != 0) {
1422 delete false_val_;
1423 false_val_ = tmp;
1428 NetEConst*c = dynamic_cast<NetEConst*>(cond_);
1429 if (c == 0)
1430 return 0;
1432 /* Check the boolean value of the constant condition
1433 expression. Note that the X case is handled explicitly, so
1434 we must differentiate. */
1436 verinum cond_value = c->value();
1437 bool true_flag = false;
1438 bool x_flag = false;
1440 for (unsigned idx = 0 ; idx < cond_value.len() ; idx += 1) {
1441 switch (cond_value.get(idx)) {
1442 case verinum::V1:
1443 true_flag = true;
1444 break;
1445 case verinum::V0:
1446 break;
1447 default:
1448 x_flag = true;
1453 /* If the condition is 1 or 0, return the true or false
1454 expression. Try to evaluate the expression down as far as
1455 we can. */
1457 if (true_flag) {
1458 if (debug_eval_tree) {
1459 cerr << get_line() << ": debug: Evaluate ternary with "
1460 << "constant condition value: " << c->value() << endl;
1461 cerr << get_line() << ": : Selecting true case: "
1462 << *true_val_ << endl;
1464 return true_val_->dup_expr();
1467 if (! x_flag) {
1468 if (debug_eval_tree) {
1469 cerr << get_line() << ": debug: Evaluate ternary with "
1470 << "constant condition value: " << c->value() << endl;
1471 cerr << get_line() << ": : Selecting false case: "
1472 << *true_val_ << endl;
1474 return false_val_->dup_expr();
1477 /* Here we have a more complex case. We need to evaluate both
1478 expressions down to constants then compare the values to
1479 build up a constant result. */
1481 NetEConst*t = dynamic_cast<NetEConst*>(true_val_);
1482 if (t == 0)
1483 return 0;
1486 NetEConst*f = dynamic_cast<NetEConst*>(false_val_);
1487 if (f == 0)
1488 return 0;
1491 unsigned tsize = t->expr_width();
1492 unsigned fsize = f->expr_width();
1493 /* Size of the result is the size of the widest operand. */
1494 unsigned rsize = tsize > fsize? tsize : fsize;
1496 verinum val (verinum::V0, rsize);
1497 for (unsigned idx = 0 ; idx < rsize ; idx += 1) {
1498 verinum::V tv = idx < tsize? t->value().get(idx) : verinum::V0;
1499 verinum::V fv = idx < rsize? f->value().get(idx) : verinum::V0;
1501 if (tv == fv)
1502 val.set(idx, tv);
1503 else
1504 val.set(idx, verinum::Vx);
1507 if (debug_eval_tree) {
1508 cerr << get_line() << ": debug: Evaluate ternary with "
1509 << "constant condition value: " << c->value() << endl;
1510 cerr << get_line() << ": : Blending cases to get "
1511 << val << endl;
1514 NetEConst*rc = new NetEConst(val);
1515 rc->set_line(*this);
1516 return rc;
1519 void NetEUnary::eval_expr_()
1521 assert(expr_);
1522 if (dynamic_cast<NetEConst*>(expr_))
1523 return;
1525 NetExpr*oper = expr_->eval_tree();
1526 if (oper == 0)
1527 return;
1529 delete expr_;
1530 expr_ = oper;
1533 NetEConst* NetEUnary::eval_tree(int prune_to_width)
1535 eval_expr_();
1536 NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
1537 if (rval == 0)
1538 return 0;
1540 verinum val = rval->value();
1542 switch (op_) {
1544 case '+':
1545 /* Unary + is a no-op. */
1546 return new NetEConst(val);
1548 case '-': {
1549 if (val.is_defined()) {
1551 verinum tmp (verinum::V0, val.len());
1552 tmp.has_sign(val.has_sign());
1553 val = tmp - val;
1555 } else {
1556 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
1557 val.set(idx, verinum::Vx);
1560 return new NetEConst(val);
1563 case '~': {
1564 /* Bitwise not is even simpler then logical
1565 not. Just invert all the bits of the operand and
1566 make the new value with the same dimensions. */
1567 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
1568 switch (val.get(idx)) {
1569 case verinum::V0:
1570 val.set(idx, verinum::V1);
1571 break;
1572 case verinum::V1:
1573 val.set(idx, verinum::V0);
1574 break;
1575 default:
1576 val.set(idx, verinum::Vx);
1579 return new NetEConst(val);
1582 case '!':
1583 assert(0);
1584 default:
1585 return 0;
1590 NetEConst* NetEUBits::eval_tree(int prune_to_width)
1592 return NetEUnary::eval_tree(prune_to_width);
1595 NetEConst* NetEUReduce::eval_tree(int prune_to_width)
1597 eval_expr_();
1598 NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
1599 if (rval == 0)
1600 return 0;
1602 verinum val = rval->value();
1603 verinum::V res;
1605 switch (op_) {
1607 case '!': {
1608 /* Evaluate the unary logical not by first scanning
1609 the operand value for V1 and Vx bits. If we find
1610 any V1 bits we know that the value is TRUE, so
1611 the result of ! is V0. If there are no V1 bits
1612 but there are some Vx/Vz bits, the result is
1613 unknown. Otherwise, the result is V1. */
1614 unsigned v1 = 0, vx = 0;
1615 for (unsigned idx = 0 ; idx < val.len() ; idx += 1) {
1616 switch (val.get(idx)) {
1617 case verinum::V0:
1618 break;
1619 case verinum::V1:
1620 v1 += 1;
1621 break;
1622 default:
1623 vx += 1;
1624 break;
1628 res = v1? verinum::V0 : (vx? verinum::Vx : verinum::V1);
1629 break;
1632 case '&': {
1633 res = verinum::V1;
1634 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
1635 res = res & val.get(idx);
1636 break;
1639 case '|': {
1640 res = verinum::V0;
1641 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
1642 res = res | val.get(idx);
1643 break;
1646 case '^': {
1647 /* Reduction XOR. */
1648 unsigned ones = 0, unknown = 0;
1649 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
1650 switch (val.get(idx)) {
1651 case verinum::V0:
1652 break;
1653 case verinum::V1:
1654 ones += 1;
1655 break;
1656 default:
1657 unknown += 1;
1658 break;
1661 if (unknown)
1662 return new NetEConst(verinum(verinum::Vx,1,true));
1663 if (ones%2)
1664 return new NetEConst(verinum(verinum::V1,1,true));
1665 return new NetEConst(verinum(verinum::V0,1,true));
1668 default:
1669 return 0;
1672 return new NetEConst(verinum(res, 1));