diff --git a/eval_tree.cc b/eval_tree.cc index e4f792989..bb63ba09c 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -2001,7 +2001,11 @@ NetExpr* NetEUFunc::eval_tree() NetFuncDef*def = func_->func_def(); ivl_assert(*this, def); - NetExpr*res = def->evaluate_function(*this, parms_); + vectorargs(parms_.size()); + for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) + args[idx] = parms_[idx]->dup_expr(); + + NetExpr*res = def->evaluate_function(*this, args); return res; } diff --git a/net_func_eval.cc b/net_func_eval.cc index 82a9bb863..35f481acb 100644 --- a/net_func_eval.cc +++ b/net_func_eval.cc @@ -42,13 +42,12 @@ NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vectordup_expr(); perm_string aname = ports_[idx]->name(); - context_map[aname] = tmp; + context_map[aname] = args[idx]; if (debug_eval_tree) { cerr << loc.get_fileline() << ": debug: " - << " input " << aname << " = " << *tmp << endl; + << " input " << aname << " = " << *args[idx] << endl; } } @@ -203,6 +202,27 @@ bool NetBlock::evaluate_function(const LineInfo&loc, return flag; } +bool NetCondit::evaluate_function(const LineInfo&loc, + map&context_map) const +{ + NetExpr*cond = expr_->evaluate_function(loc, context_map); + if (cond == 0) + return false; + + NetEConst*cond_const = dynamic_cast (cond); + ivl_assert(loc, cond_const); + + long val = cond_const->value().as_long(); + delete cond; + + if (val) + // The condition is true, so evaluate the if clause + return (if_ == 0) || if_->evaluate_function(loc, context_map); + else + // The condition is false, so evaluate the else clause + return (else_ == 0) || else_->evaluate_function(loc, context_map); +} + bool NetWhile::evaluate_function(const LineInfo&loc, map&context_map) const { @@ -405,3 +425,17 @@ NetExpr* NetETernary::evaluate_function(const LineInfo&loc, delete fval; return res; } + +NetExpr* NetEUFunc::evaluate_function(const LineInfo&loc, + map&context_map) const +{ + NetFuncDef*def = func_->func_def(); + ivl_assert(*this, def); + + vectorargs(parms_.size()); + for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) + args[idx] = parms_[idx]->evaluate_function(loc, context_map); + + NetExpr*res = def->evaluate_function(*this, args); + return res; +} diff --git a/netlist.h b/netlist.h index 8c95994e3..12a0384d0 100644 --- a/netlist.h +++ b/netlist.h @@ -2671,6 +2671,8 @@ class NetCondit : public NetProc { virtual int match_proc(struct proc_match_t*); virtual void dump(ostream&, unsigned ind) const; virtual DelayType delay_type() const; + virtual bool evaluate_function(const LineInfo&loc, + map&ctx) const; private: NetExpr* expr_; @@ -3225,6 +3227,9 @@ class NetEUFunc : public NetExpr { virtual NetEUFunc*dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true); virtual NetExpr* eval_tree(); + virtual NetExpr*evaluate_function(const LineInfo&loc, + std::map&ctx) const; + virtual NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root); private: