From 5d7558b5e0b467396c104cb5c45325f69648cb29 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Wed, 6 Mar 2013 18:28:43 +0000 Subject: [PATCH] Fix assigned vector size in constant user functions. When assigning to a bit/logic variable, the RHS expression value must be trimmed to match the size of the variable. --- net_func_eval.cc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/net_func_eval.cc b/net_func_eval.cc index b05f1df69..e7460baf2 100644 --- a/net_func_eval.cc +++ b/net_func_eval.cc @@ -25,6 +25,26 @@ using namespace std; +static NetExpr* fix_assign_value(const NetNet*lhs, NetExpr*rhs) +{ + NetEConst*ce = dynamic_cast(rhs); + if (ce == 0) return rhs; + + unsigned lhs_width = lhs->vector_width(); + unsigned rhs_width = rhs->expr_width(); + if (rhs_width < lhs_width) { + rhs = pad_to_width(rhs, lhs_width, *rhs); + } else if (rhs_width > lhs_width) { + verinum value(ce->value(), lhs_width); + ce = new NetEConst(value); + ce->set_line(*rhs); + delete rhs; + rhs = ce; + } + rhs->cast_signed(lhs->get_signed()); + return rhs; +} + NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vector&args) const { // Make the context map; @@ -43,7 +63,7 @@ NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vectorname(); - context_map[aname] = args[idx]; + context_map[aname] = fix_assign_value(ports_[idx], args[idx]); if (debug_eval_tree) { cerr << loc.get_fileline() << ": debug: " @@ -171,7 +191,7 @@ bool NetAssign::evaluate_function(const LineInfo&loc, delete rval_result; rval_result = new NetEConst(lval_v); } else { - rval_result->cast_signed(lval->sig()->get_signed()); + rval_result = fix_assign_value(lval->sig(), rval_result); } if (ptr->second)