Add support for unary operators in constant user functions.

This patch implements the evaluate_function method for the NetEUnary
and NetEUReduce classes.
This commit is contained in:
Martin Whitaker 2013-02-03 13:51:39 +00:00 committed by Cary R
parent 11f479e028
commit afd23d13d5
3 changed files with 64 additions and 15 deletions

View File

@ -1507,26 +1507,29 @@ NetExpr*NetETernary::blended_arguments_(const NetExpr*te, const NetExpr*fe) cons
return rc; return rc;
} }
NetExpr* NetEUnary::eval_tree_real_() NetExpr* NetEUnary::eval_tree_real_(const NetExpr*ex) const
{ {
NetECReal*val= dynamic_cast<NetECReal*> (expr_), *res; const NetECReal*val= dynamic_cast<const NetECReal*> (ex);
if (val == 0) return 0; if (val == 0) return 0;
double res_val = val->value().as_double();
switch (op_) { switch (op_) {
case '+': case '+':
res = new NetECReal(val->value());
ivl_assert(*this, res);
break; break;
case '-': case '-':
res = new NetECReal(-(val->value())); res_val = -res_val;
ivl_assert(*this, res); break;
case 'm':
if (res_val < 0.0) res_val = -res_val;
break; break;
default: default:
return 0; return 0;
} }
NetECReal *res = new NetECReal( verireal(res_val) );
ivl_assert(*this, res);
res->set_line(*this); res->set_line(*this);
if (debug_eval_tree) if (debug_eval_tree)
@ -1539,9 +1542,14 @@ NetExpr* NetEUnary::eval_tree_real_()
NetExpr* NetEUnary::eval_tree() NetExpr* NetEUnary::eval_tree()
{ {
eval_expr(expr_); eval_expr(expr_);
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(); return eval_arguments_(expr_);
}
NetEConst*rval = dynamic_cast<NetEConst*>(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<const NetEConst*>(ex);
if (rval == 0) return 0; if (rval == 0) return 0;
verinum val = rval->value(); verinum val = rval->value();
@ -1563,6 +1571,17 @@ NetExpr* NetEUnary::eval_tree()
} }
break; 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 '~': case '~':
/* Bitwise not is even simpler than logical /* Bitwise not is even simpler than logical
not. Just invert all the bits of the operand and not. Just invert all the bits of the operand and
@ -1604,11 +1623,11 @@ NetExpr* NetEUBits::eval_tree()
return NetEUnary::eval_tree(); return NetEUnary::eval_tree();
} }
NetEConst* NetEUReduce::eval_tree_real_() NetEConst* NetEUReduce::eval_tree_real_(const NetExpr*ex) const
{ {
ivl_assert(*this, op_ == '!'); ivl_assert(*this, op_ == '!');
NetECReal*val= dynamic_cast<NetECReal*> (expr_); const NetECReal*val= dynamic_cast<const NetECReal*> (ex);
if (val == 0) return 0; if (val == 0) return 0;
verinum::V res = val->value().as_double() == 0.0 ? verinum::V1 : verinum::V res = val->value().as_double() == 0.0 ? verinum::V1 :
@ -1628,9 +1647,14 @@ NetEConst* NetEUReduce::eval_tree_real_()
NetEConst* NetEUReduce::eval_tree() NetEConst* NetEUReduce::eval_tree()
{ {
eval_expr(expr_); eval_expr(expr_);
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(); return eval_arguments_(expr_);
}
NetEConst*rval = dynamic_cast<NetEConst*>(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<const NetEConst*>(ex);
if (rval == 0) return 0; if (rval == 0) return 0;
verinum val = rval->value(); verinum val = rval->value();

View File

@ -293,6 +293,14 @@ NetExpr* NetEConst::evaluate_function(const LineInfo&,
return res; return res;
} }
NetExpr* NetECReal::evaluate_function(const LineInfo&,
map<perm_string,NetExpr*>&) const
{
NetECReal*res = new NetECReal(value_);
res->set_line(*this);
return res;
}
NetExpr* NetESelect::evaluate_function(const LineInfo&loc, NetExpr* NetESelect::evaluate_function(const LineInfo&loc,
map<perm_string,NetExpr*>&context_map) const map<perm_string,NetExpr*>&context_map) const
{ {
@ -372,6 +380,17 @@ NetExpr* NetETernary::evaluate_function(const LineInfo&loc,
return res; return res;
} }
NetExpr* NetEUnary::evaluate_function(const LineInfo&loc,
map<perm_string,NetExpr*>&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, NetExpr* NetEUFunc::evaluate_function(const LineInfo&loc,
map<perm_string,NetExpr*>&context_map) const map<perm_string,NetExpr*>&context_map) const
{ {

View File

@ -1943,6 +1943,8 @@ class NetECReal : public NetExpr {
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetECReal* dup_expr() const; virtual NetECReal* dup_expr() const;
virtual NetExpr*evaluate_function(const LineInfo&loc,
std::map<perm_string,NetExpr*>&ctx) const;
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*); virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
virtual NexusSet* nex_input(bool rem_out = true); virtual NexusSet* nex_input(bool rem_out = true);
@ -4100,6 +4102,8 @@ class NetEUnary : public NetExpr {
virtual NetEUnary* dup_expr() const; virtual NetEUnary* dup_expr() const;
virtual NetExpr* eval_tree(); virtual NetExpr* eval_tree();
virtual NetExpr* evaluate_function(const LineInfo&loc,
std::map<perm_string,NetExpr*>&ctx) const;
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
@ -4112,7 +4116,8 @@ class NetEUnary : public NetExpr {
NetExpr* expr_; NetExpr* expr_;
private: 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 { class NetEUBits : public NetEUnary {
@ -4140,7 +4145,8 @@ class NetEUReduce : public NetEUnary {
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
private: 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 { class NetECast : public NetEUnary {