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
21 # include "compiler.h"
26 # include "ivl_assert.h"
28 NetExpr
* NetExpr::eval_tree(int prune_to_width
)
34 * Some of the derived classes can be evaluated by the compiler, this
35 * method provides the common aid of evaluating the parameter
38 void NetEBinary::eval_sub_tree_()
40 NetExpr
*tmp
= left_
->eval_tree();
45 tmp
= right_
->eval_tree();
52 bool NetEBinary::get_real_arguments_(verireal
&lval
, verireal
&rval
)
54 switch (left_
->expr_type()) {
56 NetECReal
*lc
= dynamic_cast<NetECReal
*> (left_
);
57 if (lc
== 0) return false;
64 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
65 if (lc
== 0) return false;
66 verinum tmp
= lc
->value();
67 lval
= verireal(tmp
.as_long());
75 switch (right_
->expr_type()) {
77 NetECReal
*rc
= dynamic_cast<NetECReal
*> (right_
);
78 if (rc
== 0) return 0;
85 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
86 if (rc
== 0) return 0;
87 verinum tmp
= rc
->value();
88 rval
= verireal(tmp
.as_long());
100 NetExpr
* NetEBAdd::eval_tree(int prune_to_width
)
104 if (left_
->expr_type() == IVL_VT_REAL
|| right_
->expr_type()==IVL_VT_REAL
)
105 return eval_tree_real_();
107 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
108 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
110 /* If both operands are constant, then replace the entire
111 expression with a constant value. */
112 if (lc
!= 0 && rc
!= 0) {
113 verinum lval
= lc
->value();
114 verinum rval
= rc
->value();
128 /* Result might have known width. */
130 if (debug_eval_tree
) {
131 cerr
<< get_line() << ": debug: Evaluate expr=" << *this
132 << " --- prune=" << prune_to_width
<< endl
;
134 unsigned lwid
= lc
->expr_width();
135 unsigned rwid
= rc
->expr_width();
136 unsigned wid
= (rwid
> lwid
) ? rwid
: lwid
;
137 if (prune_to_width
< 0)
139 verinum val2
=verinum(val
,wid
);
143 return new NetEConst(val
);
146 /* Try to combine a right constant value with the right
147 constant value of a sub-expression add. For example, the
148 expression (a + 2) - 1 can be rewritten as a + 1. */
150 NetEBAdd
*se
= dynamic_cast<NetEBAdd
*>(left_
);
151 lc
= se
? dynamic_cast<NetEConst
*>(se
->right_
) : 0;
153 if (lc
!= 0 && rc
!= 0) {
155 verinum lval
= lc
->value();
156 verinum rval
= rc
->value();
159 if (op_
== se
->op_
) {
160 /* (a + lval) + rval --> a + (rval+lval) */
161 /* (a - lval) - rval --> a - (rval+lval) */
164 /* (a - lval) + rval --> a + (rval-lval) */
165 /* (a + lval) - rval --> a - (rval-lval) */
169 NetEConst
*tmp
= new NetEConst(val
);
170 left_
= se
->left_
->dup_expr();
174 /* We've changed the subexpression, but the result is
175 still not constant, so return nil here anyhow. */
179 /* Nothing more to be done, the value is not constant. */
183 NetECReal
* NetEBAdd::eval_tree_real_()
187 bool flag
= get_real_arguments_(lval
, rval
);
194 res_val
= lval
+ rval
;
197 res_val
= lval
- rval
;
200 ivl_assert(*this, 0);
203 NetECReal
*res
= new NetECReal( res_val
);
204 res
->set_line(*this);
208 NetEConst
* NetEBBits::eval_tree(int prune_to_width
)
212 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
213 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
215 /* Notice the special case where one of the operands is 0 and
216 this is a bitwise &. If this happens, then the result is
218 if ((op() == '&') && lc
&& (lc
->value() == verinum(0))) {
219 verinum
res (verinum::V0
, expr_width());
220 return new NetEConst(res
);
223 if ((op() == '&') && rc
&& (rc
->value() == verinum(0))) {
224 verinum
res (verinum::V0
, expr_width());
225 return new NetEConst(res
);
228 if (lc
== 0) return 0;
229 if (rc
== 0) return 0;
231 verinum lval
= lc
->value();
232 verinum rval
= rc
->value();
234 unsigned lwid
= lc
->expr_width();
235 if (lwid
== 0) lwid
= lval
.len();
237 unsigned rwid
= rc
->expr_width();
238 if (rwid
== 0) rwid
= rval
.len();
240 unsigned wid
= expr_width();
242 wid
= (rwid
> lwid
)? rwid
: lwid
;
244 verinum
res (verinum::V0
, wid
);
255 if (cnt
> wid
) cnt
= wid
;
256 if (cnt
> rwid
) cnt
= rwid
;
257 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
258 res
.set(idx
, lval
.get(idx
) | rval
.get(idx
));
261 for (unsigned idx
= lwid
; idx
< rwid
; idx
+= 1)
262 res
.set(idx
, rval
.get(idx
));
265 for (unsigned idx
= rwid
; idx
< lwid
; idx
+= 1)
266 res
.set(idx
, lval
.get(idx
));
273 if (cnt
> wid
) cnt
= wid
;
274 if (cnt
> rwid
) cnt
= rwid
;
275 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
276 res
.set(idx
, lval
.get(idx
) & rval
.get(idx
));
283 if (cnt
> wid
) cnt
= wid
;
284 if (cnt
> rwid
) cnt
= rwid
;
285 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
286 res
.set(idx
, lval
.get(idx
) ^ rval
.get(idx
));
289 for (unsigned idx
= lwid
; idx
< rwid
; idx
+= 1)
290 res
.set(idx
, rval
.get(idx
));
293 for (unsigned idx
= rwid
; idx
< lwid
; idx
+= 1)
294 res
.set(idx
, lval
.get(idx
));
303 return new NetEConst(res
);
307 NetEConst
* NetEBComp::eval_less_()
309 NetEConst
*r
= dynamic_cast<NetEConst
*>(right_
);
310 if (r
== 0) return 0;
312 verinum rv
= r
->value();
313 if (! rv
.is_defined()) {
314 verinum
result(verinum::Vx
, 1);
315 return new NetEConst(result
);
319 /* Detect the case where the right side is greater than or
320 equal to the largest value the left side can possibly
321 have. Use the width of the left expression as all 1's to
322 calculate the maximum possible width for the left_
323 expression. This test only works of the compare is
325 if (! (rv
.has_sign() || left_
->has_sign())) {
327 assert(left_
->expr_width() > 0);
328 verinum
lv (verinum::V1
, left_
->expr_width());
330 verinum
result(verinum::V1
, 1);
331 return new NetEConst(result
);
335 /* Now go on to the normal test of the values. */
336 NetEConst
*l
= dynamic_cast<NetEConst
*>(left_
);
337 if (l
== 0) return 0;
338 verinum lv
= l
->value();
339 if (! lv
.is_defined()) {
340 verinum
result(verinum::Vx
, 1);
341 return new NetEConst(result
);
344 if (lv
.has_sign() && rv
.has_sign()) {
345 if (lv
.as_long() < rv
.as_long()) {
346 verinum
result(verinum::V1
, 1);
347 return new NetEConst(result
);
350 if (lv
.as_ulong() < rv
.as_ulong()) {
351 verinum
result(verinum::V1
, 1);
352 return new NetEConst(result
);
356 verinum
result(verinum::V0
, 1);
357 return new NetEConst(result
);
360 NetEConst
* NetEBComp::eval_leeq_real_()
366 switch (left_
->expr_type()) {
368 rtmp
= dynamic_cast<NetECReal
*> (left_
);
372 lv
= rtmp
->value().as_double();
376 vtmp
= dynamic_cast<NetEConst
*> (left_
);
380 lv
= vtmp
->value().as_long();
388 switch (right_
->expr_type()) {
390 rtmp
= dynamic_cast<NetECReal
*> (right_
);
394 rv
= rtmp
->value().as_double();
398 vtmp
= dynamic_cast<NetEConst
*> (right_
);
402 rv
= vtmp
->value().as_long();
409 verinum
result((lv
<= rv
)? verinum::V1
: verinum::V0
, 1);
410 vtmp
= new NetEConst(result
);
411 vtmp
->set_line(*this);
416 NetEConst
* NetEBComp::eval_leeq_()
418 if (right_
->expr_type() == IVL_VT_REAL
)
419 return eval_leeq_real_();
420 if (left_
->expr_type() == IVL_VT_REAL
)
421 return eval_leeq_real_();
423 NetEConst
*r
= dynamic_cast<NetEConst
*>(right_
);
424 if (r
== 0) return 0;
426 verinum rv
= r
->value();
427 if (! rv
.is_defined()) {
428 verinum
result(verinum::Vx
, 1);
429 return new NetEConst(result
);
432 if (left_
->expr_width() == 0) {
433 cerr
<< get_line() << ": internal error: Something wrong "
434 << "with the left side width of <= ?" << endl
;
435 cerr
<< get_line() << ": : " << *this << endl
;
438 /* Detect the case where the right side is greater that or
439 equal to the largest value the left side can possibly
441 assert(left_
->expr_width() > 0);
442 verinum
lv (verinum::V1
, left_
->expr_width());
444 verinum
result(verinum::V1
, 1);
445 return new NetEConst(result
);
448 /* Now go on to the normal test of the values. */
449 NetEConst
*l
= dynamic_cast<NetEConst
*>(left_
);
450 if (l
== 0) return 0;
452 if (! lv
.is_defined()) {
453 verinum
result(verinum::Vx
, 1);
454 return new NetEConst(result
);
457 if (lv
.has_sign() && rv
.has_sign()) {
458 if (lv
.as_long() <= rv
.as_long()) {
459 verinum
result(verinum::V1
, 1);
460 return new NetEConst(result
);
463 if (lv
.as_ulong() <= rv
.as_ulong()) {
464 verinum
result(verinum::V1
, 1);
465 return new NetEConst(result
);
469 verinum
result(verinum::V0
, 1);
470 return new NetEConst(result
);
473 NetEConst
* NetEBComp::eval_gt_()
475 if ((left_
->expr_type() == IVL_VT_REAL
)
476 && (right_
->expr_type() == IVL_VT_REAL
)) {
478 NetECReal
*tmpl
= dynamic_cast<NetECReal
*>(left_
);
482 NetECReal
*tmpr
= dynamic_cast<NetECReal
*>(right_
);
486 double ll
= tmpl
->value().as_double();
487 double rr
= tmpr
->value().as_double();
489 verinum
result ((ll
> rr
)? verinum::V1
: verinum::V0
, 1, true);
490 return new NetEConst(result
);
493 NetEConst
*l
= dynamic_cast<NetEConst
*>(left_
);
494 if (l
== 0) return 0;
496 verinum lv
= l
->value();
497 if (! lv
.is_defined()) {
498 verinum
result(verinum::Vx
, 1);
499 return new NetEConst(result
);
502 /* Check for the special case where we know, simply by the
503 limited width of the right expression, that it cannot
504 possibly be false. */
505 if (right_
->expr_width() > 0) {
506 verinum
rv (verinum::V1
, right_
->expr_width());
508 verinum
result(verinum::V1
, 1);
509 return new NetEConst(result
);
513 /* Compare with a real value. Do it as double precision. */
514 if (right_
->expr_type() == IVL_VT_REAL
) {
515 NetECReal
*tmp
= dynamic_cast<NetECReal
*>(right_
);
519 double rr
= tmp
->value().as_double();
520 double ll
= lv
.has_sign()? lv
.as_long() : lv
.as_ulong();
522 verinum
result ((ll
> rr
)? verinum::V1
: verinum::V0
, 1, true);
523 return new NetEConst(result
);
526 /* Now go on to the normal test of the values. */
527 NetEConst
*r
= dynamic_cast<NetEConst
*>(right_
);
528 if (r
== 0) return 0;
529 verinum rv
= r
->value();
530 if (! rv
.is_defined()) {
531 verinum
result(verinum::Vx
, 1);
532 return new NetEConst(result
);
535 if (lv
.has_sign() && rv
.has_sign() && (lv
.as_long() > rv
.as_long())) {
536 verinum
result(verinum::V1
, 1);
537 return new NetEConst(result
);
540 if (lv
.as_ulong() > rv
.as_ulong()) {
541 verinum
result(verinum::V1
, 1);
542 return new NetEConst(result
);
545 verinum
result(verinum::V0
, 1);
546 return new NetEConst(result
);
549 NetEConst
* NetEBComp::eval_gteq_()
551 if ((left_
->expr_type() == IVL_VT_REAL
)
552 && (right_
->expr_type() == IVL_VT_REAL
)) {
554 NetECReal
*tmpl
= dynamic_cast<NetECReal
*>(left_
);
558 NetECReal
*tmpr
= dynamic_cast<NetECReal
*>(right_
);
562 double ll
= tmpl
->value().as_double();
563 double rr
= tmpr
->value().as_double();
565 verinum
result ((ll
>= rr
)? verinum::V1
: verinum::V0
, 1, true);
566 return new NetEConst(result
);
569 NetEConst
*l
= dynamic_cast<NetEConst
*>(left_
);
570 if (l
== 0) return 0;
572 verinum lv
= l
->value();
573 if (! lv
.is_defined()) {
574 verinum
result(verinum::Vx
, 1);
575 return new NetEConst(result
);
578 /* Detect the case where the left side is greater than the
579 largest value the right side can possibly have. */
580 if (right_
->expr_type() == IVL_VT_LOGIC
) {
581 assert(right_
->expr_width() > 0);
582 verinum
rv (verinum::V1
, right_
->expr_width());
584 verinum
result(verinum::V1
, 1);
585 return new NetEConst(result
);
589 /* Compare with a real value. Do it as double precision. */
590 if (right_
->expr_type() == IVL_VT_REAL
) {
591 NetECReal
*tmp
= dynamic_cast<NetECReal
*>(right_
);
595 double rr
= tmp
->value().as_double();
596 double ll
= lv
.has_sign()? lv
.as_long() : lv
.as_ulong();
598 verinum
result ((ll
>= rr
)? verinum::V1
: verinum::V0
, 1, true);
599 return new NetEConst(result
);
602 /* Now go on to the normal test of the values. */
603 NetEConst
*r
= dynamic_cast<NetEConst
*>(right_
);
604 if (r
== 0) return 0;
605 verinum rv
= r
->value();
606 if (! rv
.is_defined()) {
607 verinum
result(verinum::Vx
, 1);
608 return new NetEConst(result
);
611 if (lv
.has_sign() && rv
.has_sign()) {
613 if (lv
.as_long() >= rv
.as_long()) {
614 verinum
result(verinum::V1
, 1);
615 return new NetEConst(result
);
619 if (lv
.as_ulong() >= rv
.as_ulong()) {
620 verinum
result(verinum::V1
, 1);
621 return new NetEConst(result
);
625 verinum
result(verinum::V0
, 1);
626 return new NetEConst(result
);
629 NetEConst
* NetEBComp::eval_eqeq_(bool ne_flag
)
631 NetEConst
*l
= dynamic_cast<NetEConst
*>(left_
);
632 if (l
== 0) return 0;
633 NetEConst
*r
= dynamic_cast<NetEConst
*>(right_
);
634 if (r
== 0) return 0;
636 const verinum
&lv
= l
->value();
637 const verinum
&rv
= r
->value();
639 const verinum::V eq_res
= ne_flag
? verinum::V0
: verinum::V1
;
640 const verinum::V ne_res
= ne_flag
? verinum::V1
: verinum::V0
;
642 verinum::V res
= eq_res
;
643 unsigned top
= lv
.len();
647 for (unsigned idx
= 0 ; idx
< top
; idx
+= 1) {
649 switch (lv
.get(idx
)) {
660 switch (rv
.get(idx
)) {
671 if (res
== verinum::Vx
)
674 if (rv
.get(idx
) != lv
.get(idx
))
678 if (res
!= verinum::Vx
) {
679 verinum::V lpad
= verinum::V0
;
680 verinum::V rpad
= verinum::V0
;
682 if (lv
.has_sign() && lv
.get(lv
.len()-1) == verinum::V1
)
684 if (rv
.has_sign() && rv
.get(rv
.len()-1) == verinum::V1
)
687 for (unsigned idx
= top
; idx
< lv
.len() ; idx
+= 1)
688 switch (lv
.get(idx
)) {
696 if (res
!= verinum::Vx
&& rpad
!= verinum::V0
)
701 if (res
!= verinum::Vx
&& rpad
!= verinum::V1
)
709 for (unsigned idx
= top
; idx
< rv
.len() ; idx
+= 1)
710 switch (rv
.get(idx
)) {
718 if (res
!= verinum::Vx
&& lpad
!= verinum::V0
)
723 if (res
!= verinum::Vx
&& lpad
!= verinum::V1
)
732 return new NetEConst(verinum(res
));
735 NetEConst
* NetEBComp::eval_eqeqeq_()
737 NetEConst
*l
= dynamic_cast<NetEConst
*>(left_
);
738 if (l
== 0) return 0;
739 NetEConst
*r
= dynamic_cast<NetEConst
*>(right_
);
740 if (r
== 0) return 0;
742 const verinum
&lv
= l
->value();
743 const verinum
&rv
= r
->value();
745 verinum::V res
= verinum::V1
;
747 unsigned cnt
= lv
.len();
751 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
752 if (lv
.get(idx
) != rv
.get(idx
))
755 for (unsigned idx
= cnt
; idx
< lv
.len() ; idx
+= 1)
756 if (lv
.get(idx
) != verinum::V0
)
759 for (unsigned idx
= cnt
; idx
< rv
.len() ; idx
+= 1)
760 if (rv
.get(idx
) != verinum::V0
)
763 return new NetEConst(verinum(res
, 1));
766 NetEConst
* NetEBComp::eval_neeqeq_()
768 NetEConst
*tmp
= eval_eqeqeq_();
774 if (tmp
->value().get(0) == verinum::V0
)
775 res
= new NetEConst(verinum(verinum::V1
,1));
777 res
= new NetEConst(verinum(verinum::V0
,1));
783 NetEConst
* NetEBComp::eval_tree(int prune_to_width
)
788 case 'E': // Case equality (===)
789 return eval_eqeqeq_();
791 case 'e': // Equality (==)
792 return eval_eqeq_(false);
800 case 'N': // Case inequality (!==)
801 return eval_neeqeq_();
803 case 'n': // not-equal (!=)
804 return eval_eqeq_(true);
806 case '<': // Less than
809 case '>': // Greater then
818 * The NetEBDiv operator includes the / and % operators. First evaluate
819 * the sub-expressions, then perform the required operation.
821 NetExpr
* NetEBDiv::eval_tree(int prune_to_width
)
825 if (expr_type() == IVL_VT_REAL
) {
826 NetECReal
*lc
= dynamic_cast<NetECReal
*>(left_
);
827 if (lc
== 0) return 0;
829 verireal lval
= lc
->value();
831 if (NetECReal
*rc
= dynamic_cast<NetECReal
*>(right_
)) {
833 verireal rval
= rc
->value();
837 tmp
= new NetECReal(lval
/ rval
);
841 tmp
= new NetECReal(lval
% rval
);
845 tmp
->set_line(*this);
848 } else if (NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
)) {
851 verinum rval
= rc
->value();
855 tmp
= new NetECReal(lval
/ rval
);
859 tmp
= new NetECReal(lval
% rval
);
863 tmp
->set_line(*this);
870 assert(expr_type() == IVL_VT_LOGIC
);
871 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
872 if (lc
== 0) return 0;
873 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
874 if (rc
== 0) return 0;
876 verinum lval
= lc
->value();
877 verinum rval
= rc
->value();
881 return new NetEConst(lval
/ rval
);
884 return new NetEConst(lval
% rval
);
891 NetEConst
* NetEBLogic::eval_tree(int prune_to_width
)
894 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
895 if (lc
== 0) return 0;
896 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
897 if (rc
== 0) return 0;
899 verinum::V lv
= verinum::V0
;
900 verinum::V rv
= verinum::V0
;
902 verinum v
= lc
->value();
903 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
904 if (v
.get(idx
) == verinum::V1
)
907 if (lv
== verinum::V0
)
908 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
909 if (v
.get(idx
) != verinum::V0
)
913 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
914 if (v
.get(idx
) == verinum::V1
)
917 if (rv
== verinum::V0
)
918 for (unsigned idx
= 0 ; idx
< v
.len() ; idx
+= 1)
919 if (v
.get(idx
) != verinum::V0
)
924 case 'a': { // Logical AND (&&)
925 if ((lv
== verinum::V0
) || (rv
== verinum::V0
))
928 else if ((lv
== verinum::V1
) && (rv
== verinum::V1
))
937 case 'o': { // Logical OR (||)
938 if ((lv
== verinum::V1
) || (rv
== verinum::V1
))
941 else if ((lv
== verinum::V0
) && (rv
== verinum::V0
))
954 return new NetEConst(verinum(res
, 1));
958 NetExpr
* NetEBMult::eval_tree_real_()
963 bool flag
= get_real_arguments_(lval
, rval
);
964 if (! flag
) return 0;
967 NetECReal
*res
= new NetECReal(lval
* rval
);
968 res
->set_line(*this);
972 NetExpr
* NetEBMult::eval_tree(int prune_to_width
)
976 if (expr_type() == IVL_VT_REAL
)
977 return eval_tree_real_();
979 assert(expr_type() == IVL_VT_LOGIC
);
981 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
982 if (lc
== 0) return 0;
983 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
984 if (rc
== 0) return 0;
986 verinum lval
= lc
->value();
987 verinum rval
= rc
->value();
989 return new NetEConst(lval
* rval
);
992 NetExpr
* NetEBPow::eval_tree_real_()
997 bool flag
= get_real_arguments_(lval
, rval
);
998 if (! flag
) return 0;
1000 NetECReal
*res
= new NetECReal( pow(lval
,rval
) );
1001 res
->set_line(*this);
1005 NetExpr
* NetEBPow::eval_tree(int prune_to_width
)
1009 if (expr_type() == IVL_VT_REAL
)
1010 return eval_tree_real_();
1012 assert(expr_type() == IVL_VT_LOGIC
);
1014 NetEConst
*lc
= dynamic_cast<NetEConst
*>(left_
);
1015 if (lc
== 0) return 0;
1016 NetEConst
*rc
= dynamic_cast<NetEConst
*>(right_
);
1017 if (rc
== 0) return 0;
1019 verinum lval
= lc
->value();
1020 verinum rval
= rc
->value();
1022 return new NetEConst( pow(lval
,rval
) );
1027 * Evaluate the shift operator if possible. For this to work, both
1028 * operands must be constant.
1030 NetEConst
* NetEBShift::eval_tree(int prune_to_width
)
1033 NetEConst
*re
= dynamic_cast<NetEConst
*>(right_
);
1037 NetEConst
*le
= dynamic_cast<NetEConst
*>(left_
);
1043 verinum rv
= re
->value();
1044 verinum lv
= le
->value();
1046 /* Make an early estimate of the expression width. */
1047 unsigned wid
= expr_width();
1049 if (rv
.is_defined()) {
1051 unsigned shift
= rv
.as_ulong();
1053 if (debug_eval_tree
) {
1054 cerr
<< get_line() << ": debug: "
1055 << "Evaluate " << lv
<< "<<" << op() << ">> "
1056 << rv
<< ", wid=" << wid
<< ", shift=" << shift
1057 << ", lv.has_len()=" << lv
.has_len() << endl
;
1060 if ((wid
== 0) || ! lv
.has_len()) {
1061 /* If the caller doesn't care what the width is,
1062 then calcuate a width from the trimmed left
1063 expression, plus the shift. This avoids
1068 wid
= lv
.len() + shift
;
1071 if (prune_to_width
> 0 && wid
> (unsigned)prune_to_width
)
1072 wid
= prune_to_width
;
1075 verinum::V pad
= verinum::V0
;
1076 if (op() == 'R' && has_sign()) {
1077 pad
= lv
[lv
.len()-1];
1079 verinum
nv (pad
, wid
, lv
.has_len());
1081 if (op() == 'r' || op() == 'R') {
1085 if (shift
>= lv
.len())
1087 else if (cnt
> (lv
.len()-shift
))
1088 cnt
= (lv
.len()-shift
);
1089 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
1090 nv
.set(idx
, lv
[idx
+shift
]);
1096 if (shift
>= nv
.len())
1098 else if (cnt
> (nv
.len()-shift
))
1099 cnt
= nv
.len() - shift
;
1101 for (unsigned idx
= 0 ; idx
< cnt
; idx
+= 1)
1102 nv
.set(idx
+shift
, lv
[idx
]);
1105 res
= new NetEConst(nv
);
1109 wid
= left_
->expr_width();
1111 verinum
nv (verinum::Vx
, wid
);
1112 res
= new NetEConst(nv
);
1118 NetEConst
* NetEConcat::eval_tree(int prune_to_width
)
1120 unsigned repeat_val
= repeat();
1121 unsigned local_errors
= 0;
1123 if (debug_eval_tree
) {
1124 cerr
<< get_line() << ": debug: Evaluate expr=" << *this
1125 << ", prune_to_width=" << prune_to_width
<< endl
;
1129 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1) {
1131 // Parameter not here? This is an error, but presumably
1132 // already caught and we are here just to catch more.
1133 if (parms_
[idx
] == 0)
1137 // If this parameter is already a constant, all is well
1139 if (dynamic_cast<NetEConst
*>(parms_
[idx
])) {
1140 gap
+= parms_
[idx
]->expr_width();
1144 // Finally, try to evaluate the parameter expression
1145 // that is here. If I succeed, reset the parameter to
1146 // the evaluated value.
1147 assert(parms_
[idx
]);
1148 NetExpr
*expr
= parms_
[idx
]->eval_tree(0);
1153 if (! expr
->has_width()) {
1154 cerr
<< get_line() << ": error: concatenation "
1155 << "operand has indefinite width: "
1156 << *parms_
[idx
] << endl
;
1158 } else if (expr
->expr_width() == 0) {
1159 cerr
<< expr
->get_line() << ": internal error: "
1160 << "Operand of concatenation has no width: "
1165 gap
+= expr
->expr_width();
1170 if (local_errors
> 0)
1173 // Handle the special case that the repeat expression is
1174 // zero. In this case, just return a 0 value with the expected
1176 if (repeat_val
== 0) {
1177 verinum
val (verinum::V0
, expr_width());
1178 NetEConst
*res
= new NetEConst(val
);
1179 res
->set_width(val
.len());
1183 // At this point, the "gap" is the width of a single repeat of
1184 // the concatenation. The total width of the result is the gap
1185 // times the repeat count.
1186 verinum
val (verinum::Vx
, repeat_val
* gap
);
1188 // build up the result from least significant to most.
1191 bool is_string_flag
= true;
1192 for (unsigned idx
= parms_
.count() ; idx
> 0 ; idx
-= 1) {
1193 NetEConst
*expr
= dynamic_cast<NetEConst
*>(parms_
[idx
-1]);
1197 verinum tmp
= expr
->value();
1198 for (unsigned bit
= 0; bit
< tmp
.len(); bit
+= 1, cur
+= 1)
1199 for (unsigned rep
= 0 ; rep
< repeat_val
; rep
+= 1)
1200 val
.set(rep
*gap
+cur
, tmp
[bit
]);
1202 is_string_flag
= is_string_flag
&& tmp
.is_string();
1205 /* If all the values were strings, then re-stringify this
1206 constant. This might be useful information in the code
1207 generator or other optimizer steps. */
1208 if (is_string_flag
) {
1209 val
= verinum(val
.as_string());
1212 NetEConst
*res
= new NetEConst(val
);
1213 res
->set_width(val
.len());
1217 NetExpr
* NetEParam::eval_tree(int prune_to_width
)
1220 assert(scope_
== 0);
1224 if (debug_elaborate
) {
1225 cerr
<< get_line() << ": debug: evaluating expression: "
1230 const NetExpr
*expr_msb
;
1231 const NetExpr
*expr_lsb
;
1232 const NetExpr
*expr
= scope_
->get_parameter(name_
, expr_msb
, expr_lsb
);
1234 cerr
<< get_line() << ": internal error: Unable to match "
1235 << "parameter " << name_
<< " in scope "
1236 << scope_path(scope_
) << endl
;
1242 NetExpr
*nexpr
= expr
->dup_expr();
1245 // If the parameter that I refer to is already evaluated, then
1246 // return the constant value.
1247 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(nexpr
)) {
1248 verinum val
= tmp
->value();
1249 NetEConstParam
*ptmp
= new NetEConstParam(scope_
, name_
, val
);
1250 ptmp
->set_line(*this);
1255 if (NetECReal
*tmp
= dynamic_cast<NetECReal
*>(nexpr
)) {
1256 verireal val
= tmp
->value();
1257 NetECRealParam
*ptmp
= new NetECRealParam(scope_
, name_
, val
);
1258 ptmp
->set_line(*this);
1263 // Try to evaluate the expression. If I cannot, then the
1264 // expression is not a constant expression and I fail here.
1265 NetExpr
*res
= nexpr
->eval_tree();
1267 cerr
<< get_line() << ": internal error: Unable to evaluate "
1268 << "parameter " << name_
<< " expression: "
1274 // The result can be saved as the value of the parameter for
1275 // future reference, and return a copy to the caller.
1276 scope_
->replace_parameter(name_
, res
);
1278 /* Return as a result a NetEConstParam or NetECRealParam
1279 object, depending on the type of the expression. */
1281 switch (res
->expr_type()) {
1285 { NetEConst
*tmp
= dynamic_cast<NetEConst
*>(res
);
1287 cerr
<< get_line() << ": internal error: parameter "
1288 << name_
<< " evaluates to incomprehensible "
1289 << *res
<< "." << endl
;
1295 verinum val
= tmp
->value();
1296 NetEConstParam
*ptmp
= new NetEConstParam(scope_
, name_
, val
);
1302 { NetECReal
*tmp
= dynamic_cast<NetECReal
*>(res
);
1304 cerr
<< get_line() << ": internal error: parameter "
1305 << name_
<< " evaluates to incomprehensible "
1306 << *res
<< "." << endl
;
1312 verireal val
= tmp
->value();
1313 NetECRealParam
*ptmp
= new NetECRealParam(scope_
, name_
, val
);
1324 NetEConst
* NetESelect::eval_tree(int prune_to_width
)
1326 NetEConst
*expr
= dynamic_cast<NetEConst
*>(expr_
);
1328 NetExpr
*tmp
= expr_
->eval_tree();
1334 expr
= dynamic_cast<NetEConst
*>(expr_
);
1339 NetEConst
*base
= dynamic_cast<NetEConst
*>(base_
);
1341 NetExpr
*tmp
= base_
->eval_tree();
1347 base
= dynamic_cast<NetEConst
*>(base_
);
1353 bval
= base
->value().as_long();
1359 verinum eval
= expr
->value();
1360 verinum
oval (verinum::V0
, expr_width(), true);
1362 verinum::V pad_bit
= verinum::Vx
;
1365 /* If the base is NULL (different from 0) the this
1366 select is here for sign extension. So calculate a
1367 proper pad bit. Extend x or z or 0, and sign extend 1
1368 if this is signed. */
1369 unsigned top
= expr
->expr_width()-1;
1371 pad_bit
= eval
.get(top
);
1372 if (pad_bit
==verinum::V1
&& !has_sign())
1373 pad_bit
= verinum::V0
;
1376 for (unsigned long idx
= 0 ; idx
< expr_width() ; idx
+= 1) {
1377 if ((bval
>= 0) && ((unsigned long) bval
< eval
.len()))
1378 oval
.set(idx
, eval
.get(bval
));
1380 oval
.set(idx
, pad_bit
);
1385 NetEConst
*res
= new NetEConst(oval
);
1391 * A ternary expression evaluation is controlled by the condition
1392 * expression. If the condition evaluates to true or false, then
1393 * return the evaluated true or false expression. If the condition
1394 * evaluates to x or z, then merge the constant bits of the true and
1395 * false expressions.
1397 NetExpr
* NetETernary::eval_tree(int prune_to_width
)
1402 if (0 == dynamic_cast<NetEConst
*>(cond_
)) {
1403 tmp
= cond_
->eval_tree();
1411 if (0 == dynamic_cast<NetEConst
*>(true_val_
)) {
1412 tmp
= true_val_
->eval_tree();
1420 if (0 == dynamic_cast<NetEConst
*>(false_val_
)) {
1421 tmp
= false_val_
->eval_tree();
1429 NetEConst
*c
= dynamic_cast<NetEConst
*>(cond_
);
1433 /* Check the boolean value of the constant condition
1434 expression. Note that the X case is handled explicitly, so
1435 we must differentiate. */
1437 verinum cond_value
= c
->value();
1438 bool true_flag
= false;
1439 bool x_flag
= false;
1441 for (unsigned idx
= 0 ; idx
< cond_value
.len() ; idx
+= 1) {
1442 switch (cond_value
.get(idx
)) {
1454 /* If the condition is 1 or 0, return the true or false
1455 expression. Try to evaluate the expression down as far as
1459 if (debug_eval_tree
) {
1460 cerr
<< get_line() << ": debug: Evaluate ternary with "
1461 << "constant condition value: " << c
->value() << endl
;
1462 cerr
<< get_line() << ": : Selecting true case: "
1463 << *true_val_
<< endl
;
1465 return true_val_
->dup_expr();
1469 if (debug_eval_tree
) {
1470 cerr
<< get_line() << ": debug: Evaluate ternary with "
1471 << "constant condition value: " << c
->value() << endl
;
1472 cerr
<< get_line() << ": : Selecting false case: "
1473 << *true_val_
<< endl
;
1475 return false_val_
->dup_expr();
1478 /* Here we have a more complex case. We need to evaluate both
1479 expressions down to constants then compare the values to
1480 build up a constant result. */
1482 NetEConst
*t
= dynamic_cast<NetEConst
*>(true_val_
);
1487 NetEConst
*f
= dynamic_cast<NetEConst
*>(false_val_
);
1492 unsigned tsize
= t
->expr_width();
1493 unsigned fsize
= f
->expr_width();
1494 /* Size of the result is the size of the widest operand. */
1495 unsigned rsize
= tsize
> fsize
? tsize
: fsize
;
1497 verinum
val (verinum::V0
, rsize
);
1498 for (unsigned idx
= 0 ; idx
< rsize
; idx
+= 1) {
1499 verinum::V tv
= idx
< tsize
? t
->value().get(idx
) : verinum::V0
;
1500 verinum::V fv
= idx
< rsize
? f
->value().get(idx
) : verinum::V0
;
1505 val
.set(idx
, verinum::Vx
);
1508 if (debug_eval_tree
) {
1509 cerr
<< get_line() << ": debug: Evaluate ternary with "
1510 << "constant condition value: " << c
->value() << endl
;
1511 cerr
<< get_line() << ": : Blending cases to get "
1515 NetEConst
*rc
= new NetEConst(val
);
1516 rc
->set_line(*this);
1520 void NetEUnary::eval_expr_()
1523 if (dynamic_cast<NetEConst
*>(expr_
))
1526 NetExpr
*oper
= expr_
->eval_tree();
1534 NetEConst
* NetEUnary::eval_tree(int prune_to_width
)
1537 NetEConst
*rval
= dynamic_cast<NetEConst
*>(expr_
);
1541 verinum val
= rval
->value();
1546 /* Unary + is a no-op. */
1547 return new NetEConst(val
);
1550 if (val
.is_defined()) {
1552 verinum
tmp (verinum::V0
, val
.len());
1553 tmp
.has_sign(val
.has_sign());
1557 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1558 val
.set(idx
, verinum::Vx
);
1561 return new NetEConst(val
);
1565 /* Bitwise not is even simpler then logical
1566 not. Just invert all the bits of the operand and
1567 make the new value with the same dimensions. */
1568 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1569 switch (val
.get(idx
)) {
1571 val
.set(idx
, verinum::V1
);
1574 val
.set(idx
, verinum::V0
);
1577 val
.set(idx
, verinum::Vx
);
1580 return new NetEConst(val
);
1591 NetEConst
* NetEUBits::eval_tree(int prune_to_width
)
1593 return NetEUnary::eval_tree(prune_to_width
);
1596 NetEConst
* NetEUReduce::eval_tree(int prune_to_width
)
1599 NetEConst
*rval
= dynamic_cast<NetEConst
*>(expr_
);
1603 verinum val
= rval
->value();
1609 /* Evaluate the unary logical not by first scanning
1610 the operand value for V1 and Vx bits. If we find
1611 any V1 bits we know that the value is TRUE, so
1612 the result of ! is V0. If there are no V1 bits
1613 but there are some Vx/Vz bits, the result is
1614 unknown. Otherwise, the result is V1. */
1615 unsigned v1
= 0, vx
= 0;
1616 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1) {
1617 switch (val
.get(idx
)) {
1629 res
= v1
? verinum::V0
: (vx
? verinum::Vx
: verinum::V1
);
1635 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1636 res
= res
& val
.get(idx
);
1642 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1643 res
= res
| val
.get(idx
);
1648 /* Reduction XOR. */
1649 unsigned ones
= 0, unknown
= 0;
1650 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1651 switch (val
.get(idx
)) {
1663 return new NetEConst(verinum(verinum::Vx
,1,true));
1665 return new NetEConst(verinum(verinum::V1
,1,true));
1666 return new NetEConst(verinum(verinum::V0
,1,true));
1673 return new NetEConst(verinum(res
, 1));