diff --git a/eval_tree.cc b/eval_tree.cc index af2382380..80bcb867e 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -1507,26 +1507,29 @@ NetExpr*NetETernary::blended_arguments_(const NetExpr*te, const NetExpr*fe) cons return rc; } -NetExpr* NetEUnary::eval_tree_real_() +NetExpr* NetEUnary::eval_tree_real_(const NetExpr*ex) const { - NetECReal*val= dynamic_cast (expr_), *res; + const NetECReal*val= dynamic_cast (ex); if (val == 0) return 0; + double res_val = val->value().as_double(); switch (op_) { case '+': - res = new NetECReal(val->value()); - ivl_assert(*this, res); break; case '-': - res = new NetECReal(-(val->value())); - ivl_assert(*this, res); + res_val = -res_val; + break; + + case 'm': + if (res_val < 0.0) res_val = -res_val; break; default: return 0; } - + NetECReal *res = new NetECReal( verireal(res_val) ); + ivl_assert(*this, res); res->set_line(*this); if (debug_eval_tree) @@ -1539,9 +1542,14 @@ NetExpr* NetEUnary::eval_tree_real_() NetExpr* NetEUnary::eval_tree() { eval_expr(expr_); - if (expr_type() == IVL_VT_REAL) return eval_tree_real_(); + return eval_arguments_(expr_); +} - NetEConst*rval = dynamic_cast(expr_); +NetExpr* NetEUnary::eval_arguments_(const NetExpr*ex) const +{ + if (expr_type() == IVL_VT_REAL) return eval_tree_real_(ex); + + const NetEConst*rval = dynamic_cast(ex); if (rval == 0) return 0; verinum val = rval->value(); @@ -1563,6 +1571,17 @@ NetExpr* NetEUnary::eval_tree() } break; + case 'm': + if (!val.is_defined()) { + for (unsigned idx = 0 ; idx < val.len() ; idx += 1) + val.set(idx, verinum::Vx); + } else if (val.is_negative()) { + verinum tmp (verinum::V0, val.len()); + tmp.has_sign(val.has_sign()); + val = verinum(tmp - val, val.len()); + } + break; + case '~': /* Bitwise not is even simpler than logical not. Just invert all the bits of the operand and @@ -1604,11 +1623,11 @@ NetExpr* NetEUBits::eval_tree() return NetEUnary::eval_tree(); } -NetEConst* NetEUReduce::eval_tree_real_() +NetEConst* NetEUReduce::eval_tree_real_(const NetExpr*ex) const { ivl_assert(*this, op_ == '!'); - NetECReal*val= dynamic_cast (expr_); + const NetECReal*val= dynamic_cast (ex); if (val == 0) return 0; verinum::V res = val->value().as_double() == 0.0 ? verinum::V1 : @@ -1628,9 +1647,14 @@ NetEConst* NetEUReduce::eval_tree_real_() NetEConst* NetEUReduce::eval_tree() { eval_expr(expr_); - if (expr_type() == IVL_VT_REAL) return eval_tree_real_(); + return eval_arguments_(expr_); +} - NetEConst*rval = dynamic_cast(expr_); +NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const +{ + if (expr_type() == IVL_VT_REAL) return eval_tree_real_(ex); + + const NetEConst*rval = dynamic_cast(ex); if (rval == 0) return 0; verinum val = rval->value(); diff --git a/net_func_eval.cc b/net_func_eval.cc index 1187e9433..827e98a5d 100644 --- a/net_func_eval.cc +++ b/net_func_eval.cc @@ -293,6 +293,14 @@ NetExpr* NetEConst::evaluate_function(const LineInfo&, return res; } +NetExpr* NetECReal::evaluate_function(const LineInfo&, + map&) const +{ + NetECReal*res = new NetECReal(value_); + res->set_line(*this); + return res; +} + NetExpr* NetESelect::evaluate_function(const LineInfo&loc, map&context_map) const { @@ -372,6 +380,17 @@ NetExpr* NetETernary::evaluate_function(const LineInfo&loc, return res; } +NetExpr* NetEUnary::evaluate_function(const LineInfo&loc, + map&context_map) const +{ + NetExpr*val = expr_->evaluate_function(loc, context_map); + if (val == 0) return 0; + + NetExpr*res = eval_arguments_(val); + delete val; + return res; +} + NetExpr* NetEUFunc::evaluate_function(const LineInfo&loc, map&context_map) const { diff --git a/netlist.h b/netlist.h index 7c08f1061..9d97165bd 100644 --- a/netlist.h +++ b/netlist.h @@ -1943,6 +1943,8 @@ class NetECReal : public NetExpr { virtual void dump(ostream&) const; virtual NetECReal* dup_expr() const; + virtual NetExpr*evaluate_function(const LineInfo&loc, + std::map&ctx) const; virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*); virtual NexusSet* nex_input(bool rem_out = true); @@ -4100,6 +4102,8 @@ class NetEUnary : public NetExpr { virtual NetEUnary* dup_expr() const; virtual NetExpr* eval_tree(); + virtual NetExpr* evaluate_function(const LineInfo&loc, + std::map&ctx) const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual ivl_variable_type_t expr_type() const; @@ -4112,7 +4116,8 @@ class NetEUnary : public NetExpr { NetExpr* expr_; private: - virtual NetExpr* eval_tree_real_(); + virtual NetExpr* eval_arguments_(const NetExpr*ex) const; + virtual NetExpr* eval_tree_real_(const NetExpr*ex) const; }; class NetEUBits : public NetEUnary { @@ -4140,7 +4145,8 @@ class NetEUReduce : public NetEUnary { virtual ivl_variable_type_t expr_type() const; private: - virtual NetEConst* eval_tree_real_(); + virtual NetEConst* eval_arguments_(const NetExpr*ex) const; + virtual NetEConst* eval_tree_real_(const NetExpr*ex) const; }; class NetECast : public NetEUnary {