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;
}
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;
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<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;
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<NetECReal*> (expr_);
const NetECReal*val= dynamic_cast<const NetECReal*> (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<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;
verinum val = rval->value();

View File

@ -293,6 +293,14 @@ NetExpr* NetEConst::evaluate_function(const LineInfo&,
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,
map<perm_string,NetExpr*>&context_map) const
{
@ -372,6 +380,17 @@ NetExpr* NetETernary::evaluate_function(const LineInfo&loc,
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,
map<perm_string,NetExpr*>&context_map) const
{

View File

@ -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<perm_string,NetExpr*>&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<perm_string,NetExpr*>&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 {