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)
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
20 #ident "$Id: eval_tree.cc,v 1.77 2007/06/02 03:42:12 steve Exp $"
24 # include "compiler.h"
29 # include "ivl_assert.h"
31 NetExpr
* NetExpr::eval_tree(int prune_to_width
)
37 * Some of the derived classes can be evaluated by the compiler, this
38 * method provides the common aid of evaluating the parameter
41 void NetEBinary::eval_sub_tree_()
43 NetExpr
*tmp
= left_
->eval_tree();
48 tmp
= right_
->eval_tree();
55 bool NetEBinary::get_real_arguments_(verireal
&lval
, verireal
&rval
)
57 switch (left_
->expr_type()) {
59 NetECReal
*lc
= dynamic_cast<NetECReal
*> (left_
);
60 if (lc
== 0) return false;
67 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
68 if (lc
== 0) return false;
69 verinum tmp
= lc
->value();
70 lval
= verireal(tmp
.as_long());
78 switch (right_
->expr_type()) {
80 NetECReal
*rc
= dynamic_cast<NetECReal
*> (right_
);
81 if (rc
== 0) return 0;
88 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
89 if (rc
== 0) return 0;
90 verinum tmp
= rc
->value();
91 rval
= verireal(tmp
.as_long());
103 NetExpr
* NetEBAdd::eval_tree(int prune_to_width
)
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();
131 /* Result might have known 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)
142 verinum val2
=verinum(val
,wid
);
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) {
158 verinum lval
= lc
->value();
159 verinum rval
= rc
->value();
162 if (op_
== se
->op_
) {
163 /* (a + lval) + rval --> a + (rval+lval) */
164 /* (a - lval) - rval --> a - (rval+lval) */
167 /* (a - lval) + rval --> a + (rval-lval) */
168 /* (a + lval) - rval --> a - (rval-lval) */
172 NetEConst
*tmp
= new NetEConst(val
);
173 left_
= se
->left_
->dup_expr();
177 /* We've changed the subexpression, but the result is
178 still not constant, so return nil here anyhow. */
182 /* Nothing more to be done, the value is not constant. */
186 NetECReal
* NetEBAdd::eval_tree_real_()
190 bool flag
= get_real_arguments_(lval
, rval
);
197 res_val
= lval
+ rval
;
200 res_val
= lval
- rval
;
203 ivl_assert(*this, 0);
206 NetECReal
*res
= new NetECReal( res_val
);
207 res
->set_line(*this);
211 NetEConst
* NetEBBits::eval_tree(int prune_to_width
)
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
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();
245 wid
= (rwid
> lwid
)? rwid
: lwid
;
247 verinum
res (verinum::V0
, wid
);
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
));
264 for (unsigned idx
= lwid
; idx
< rwid
; idx
+= 1)
265 res
.set(idx
, rval
.get(idx
));
268 for (unsigned idx
= rwid
; idx
< lwid
; idx
+= 1)
269 res
.set(idx
, lval
.get(idx
));
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
));
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
));
292 for (unsigned idx
= lwid
; idx
< rwid
; idx
+= 1)
293 res
.set(idx
, rval
.get(idx
));
296 for (unsigned idx
= rwid
; idx
< lwid
; idx
+= 1)
297 res
.set(idx
, lval
.get(idx
));
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
328 if (! (rv
.has_sign() || left_
->has_sign())) {
330 assert(left_
->expr_width() > 0);
331 verinum
lv (verinum::V1
, left_
->expr_width());
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
);
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_()
369 switch (left_
->expr_type()) {
371 rtmp
= dynamic_cast<NetECReal
*> (left_
);
375 lv
= rtmp
->value().as_double();
379 vtmp
= dynamic_cast<NetEConst
*> (left_
);
383 lv
= vtmp
->value().as_long();
391 switch (right_
->expr_type()) {
393 rtmp
= dynamic_cast<NetECReal
*> (right_
);
397 rv
= rtmp
->value().as_double();
401 vtmp
= dynamic_cast<NetEConst
*> (right_
);
405 rv
= vtmp
->value().as_long();
412 verinum
result((lv
<= rv
)? verinum::V1
: verinum::V0
, 1);
413 vtmp
= new NetEConst(result
);
414 vtmp
->set_line(*this);
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
444 assert(left_
->expr_width() > 0);
445 verinum
lv (verinum::V1
, left_
->expr_width());
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;
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
);
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_
);
485 NetECReal
*tmpr
= dynamic_cast<NetECReal
*>(right_
);
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());
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_
);
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_
);
561 NetECReal
*tmpr
= dynamic_cast<NetECReal
*>(right_
);
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());
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_
);
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
);
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();
650 for (unsigned idx
= 0 ; idx
< top
; idx
+= 1) {
652 switch (lv
.get(idx
)) {
663 switch (rv
.get(idx
)) {
674 if (res
== verinum::Vx
)
677 if (rv
.get(idx
) != lv
.get(idx
))
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
)
687 if (rv
.has_sign() && rv
.get(rv
.len()-1) == verinum::V1
)
690 for (unsigned idx
= top
; idx
< lv
.len() ; idx
+= 1)
691 switch (lv
.get(idx
)) {
699 if (res
!= verinum::Vx
&& rpad
!= verinum::V0
)
704 if (res
!= verinum::Vx
&& rpad
!= verinum::V1
)
712 for (unsigned idx
= top
; idx
< rv
.len() ; idx
+= 1)
713 switch (rv
.get(idx
)) {
721 if (res
!= verinum::Vx
&& lpad
!= verinum::V0
)
726 if (res
!= verinum::Vx
&& lpad
!= verinum::V1
)
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();
754 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
755 if (lv
.get(idx
) != rv
.get(idx
))
758 for (unsigned idx
= cnt
; idx
< lv
.len() ; idx
+= 1)
759 if (lv
.get(idx
) != verinum::V0
)
762 for (unsigned idx
= cnt
; idx
< rv
.len() ; idx
+= 1)
763 if (rv
.get(idx
) != verinum::V0
)
766 return new NetEConst(verinum(res
, 1));
769 NetEConst
* NetEBComp::eval_neeqeq_()
771 NetEConst
*tmp
= eval_eqeqeq_();
777 if (tmp
->value().get(0) == verinum::V0
)
778 res
= new NetEConst(verinum(verinum::V1
,1));
780 res
= new NetEConst(verinum(verinum::V0
,1));
786 NetEConst
* NetEBComp::eval_tree(int prune_to_width
)
791 case 'E': // Case equality (===)
792 return eval_eqeqeq_();
794 case 'e': // Equality (==)
795 return eval_eqeq_(false);
803 case 'N': // Case inequality (!==)
804 return eval_neeqeq_();
806 case 'n': // not-equal (!=)
807 return eval_eqeq_(true);
809 case '<': // Less than
812 case '>': // Greater then
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
)
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_
)) {
836 verireal rval
= rc
->value();
840 tmp
= new NetECReal(lval
/ rval
);
844 tmp
= new NetECReal(lval
% rval
);
848 tmp
->set_line(*this);
851 } else if (NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
)) {
854 verinum rval
= rc
->value();
858 tmp
= new NetECReal(lval
/ rval
);
862 tmp
= new NetECReal(lval
% rval
);
866 tmp
->set_line(*this);
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();
884 return new NetEConst(lval
/ rval
);
887 return new NetEConst(lval
% rval
);
894 NetEConst
* NetEBLogic::eval_tree(int prune_to_width
)
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
)
910 if (lv
== verinum::V0
)
911 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
912 if (v
.get(idx
) != verinum::V0
)
916 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
917 if (v
.get(idx
) == verinum::V1
)
920 if (rv
== verinum::V0
)
921 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
922 if (v
.get(idx
) != verinum::V0
)
927 case 'a': { // Logical AND (&&)
928 if ((lv
== verinum::V0
) || (rv
== verinum::V0
))
931 else if ((lv
== verinum::V1
) && (rv
== verinum::V1
))
940 case 'o': { // Logical OR (||)
941 if ((lv
== verinum::V1
) || (rv
== verinum::V1
))
944 else if ((lv
== verinum::V0
) && (rv
== verinum::V0
))
957 return new NetEConst(verinum(res
, 1));
961 NetExpr
* NetEBMult::eval_tree_real_()
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);
975 NetExpr
* NetEBMult::eval_tree(int prune_to_width
)
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_()
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);
1008 NetExpr
* NetEBPow::eval_tree(int prune_to_width
)
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
)
1036 NetEConst
*re
= dynamic_cast<NetEConst
*>(right_
);
1040 NetEConst
*le
= dynamic_cast<NetEConst
*>(left_
);
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
1071 wid
= lv
.len() + shift
;
1074 if (prune_to_width
> 0 && wid
> (unsigned)prune_to_width
)
1075 wid
= prune_to_width
;
1078 verinum
nv (verinum::V0
, wid
, lv
.has_len());
1084 if (shift
>= lv
.len())
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
]);
1095 if (shift
>= nv
.len())
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
);
1108 wid
= left_
->expr_width();
1110 verinum
nv (verinum::Vx
, wid
);
1111 res
= new NetEConst(nv
);
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
;
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)
1136 // If this parameter is already a constant, all is well
1138 if (dynamic_cast<NetEConst
*>(parms_
[idx
])) {
1139 gap
+= parms_
[idx
]->expr_width();
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);
1152 if (! expr
->has_width()) {
1153 cerr
<< get_line() << ": error: concatenation "
1154 << "operand has indefinite width: "
1155 << *parms_
[idx
] << endl
;
1157 } else if (expr
->expr_width() == 0) {
1158 cerr
<< expr
->get_line() << ": internal error: "
1159 << "Operand of concatenation has no width: "
1164 gap
+= expr
->expr_width();
1169 if (local_errors
> 0)
1172 // Handle the special case that the repeat expression is
1173 // zero. In this case, just return a 0 value with the expected
1175 if (repeat_val
== 0) {
1176 verinum
val (verinum::V0
, expr_width());
1177 NetEConst
*res
= new NetEConst(val
);
1178 res
->set_width(val
.len());
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.
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]);
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());
1216 NetExpr
* NetEParam::eval_tree(int prune_to_width
)
1219 assert(scope_
== 0);
1223 if (debug_elaborate
) {
1224 cerr
<< get_line() << ": debug: evaluating expression: "
1229 const NetExpr
*expr_msb
;
1230 const NetExpr
*expr_lsb
;
1231 const NetExpr
*expr
= scope_
->get_parameter(name_
, expr_msb
, expr_lsb
);
1233 cerr
<< get_line() << ": internal error: Unable to match "
1234 << "parameter " << name_
<< " in scope "
1235 << scope_path(scope_
) << endl
;
1241 NetExpr
*nexpr
= expr
->dup_expr();
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);
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);
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();
1266 cerr
<< get_line() << ": internal error: Unable to evaluate "
1267 << "parameter " << name_
<< " expression: "
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()) {
1284 { NetEConst
*tmp
= dynamic_cast<NetEConst
*>(res
);
1286 cerr
<< get_line() << ": internal error: parameter "
1287 << name_
<< " evaluates to incomprehensible "
1288 << *res
<< "." << endl
;
1294 verinum val
= tmp
->value();
1295 NetEConstParam
*ptmp
= new NetEConstParam(scope_
, name_
, val
);
1301 { NetECReal
*tmp
= dynamic_cast<NetECReal
*>(res
);
1303 cerr
<< get_line() << ": internal error: parameter "
1304 << name_
<< " evaluates to incomprehensible "
1305 << *res
<< "." << endl
;
1311 verireal val
= tmp
->value();
1312 NetECRealParam
*ptmp
= new NetECRealParam(scope_
, name_
, val
);
1323 NetEConst
* NetESelect::eval_tree(int prune_to_width
)
1325 NetEConst
*expr
= dynamic_cast<NetEConst
*>(expr_
);
1327 NetExpr
*tmp
= expr_
->eval_tree();
1333 expr
= dynamic_cast<NetEConst
*>(expr_
);
1338 NetEConst
*base
= dynamic_cast<NetEConst
*>(base_
);
1340 NetExpr
*tmp
= base_
->eval_tree();
1346 base
= dynamic_cast<NetEConst
*>(base_
);
1352 bval
= base
->value().as_long();
1358 verinum eval
= expr
->value();
1359 verinum
oval (verinum::V0
, expr_width(), true);
1361 verinum::V pad_bit
= verinum::Vx
;
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
));
1379 oval
.set(idx
, pad_bit
);
1384 NetEConst
*res
= new NetEConst(oval
);
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
)
1401 if (0 == dynamic_cast<NetEConst
*>(cond_
)) {
1402 tmp
= cond_
->eval_tree();
1410 if (0 == dynamic_cast<NetEConst
*>(true_val_
)) {
1411 tmp
= true_val_
->eval_tree();
1419 if (0 == dynamic_cast<NetEConst
*>(false_val_
)) {
1420 tmp
= false_val_
->eval_tree();
1428 NetEConst
*c
= dynamic_cast<NetEConst
*>(cond_
);
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
)) {
1453 /* If the condition is 1 or 0, return the true or false
1454 expression. Try to evaluate the expression down as far as
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();
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_
);
1486 NetEConst
*f
= dynamic_cast<NetEConst
*>(false_val_
);
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
;
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 "
1514 NetEConst
*rc
= new NetEConst(val
);
1515 rc
->set_line(*this);
1519 void NetEUnary::eval_expr_()
1522 if (dynamic_cast<NetEConst
*>(expr_
))
1525 NetExpr
*oper
= expr_
->eval_tree();
1533 NetEConst
* NetEUnary::eval_tree(int prune_to_width
)
1536 NetEConst
*rval
= dynamic_cast<NetEConst
*>(expr_
);
1540 verinum val
= rval
->value();
1545 /* Unary + is a no-op. */
1546 return new NetEConst(val
);
1549 if (val
.is_defined()) {
1551 verinum
tmp (verinum::V0
, val
.len());
1552 tmp
.has_sign(val
.has_sign());
1556 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1557 val
.set(idx
, verinum::Vx
);
1560 return new NetEConst(val
);
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
)) {
1570 val
.set(idx
, verinum::V1
);
1573 val
.set(idx
, verinum::V0
);
1576 val
.set(idx
, verinum::Vx
);
1579 return new NetEConst(val
);
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
)
1598 NetEConst
*rval
= dynamic_cast<NetEConst
*>(expr_
);
1602 verinum val
= rval
->value();
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
)) {
1628 res
= v1
? verinum::V0
: (vx
? verinum::Vx
: verinum::V1
);
1634 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1635 res
= res
& val
.get(idx
);
1641 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1642 res
= res
| val
.get(idx
);
1647 /* Reduction XOR. */
1648 unsigned ones
= 0, unknown
= 0;
1649 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1650 switch (val
.get(idx
)) {
1662 return new NetEConst(verinum(verinum::Vx
,1,true));
1664 return new NetEConst(verinum(verinum::V1
,1,true));
1665 return new NetEConst(verinum(verinum::V0
,1,true));
1672 return new NetEConst(verinum(res
, 1));