Extended constant function assignment operator support to real values.

Also output a "sorry" message if the LHS is a concatenation.
This commit is contained in:
Martin Whitaker 2016-02-22 23:31:35 +00:00
parent 74b8c04b91
commit f9f51db7ba
2 changed files with 55 additions and 4 deletions

View File

@ -209,6 +209,32 @@ bool NetProc::evaluate_function(const LineInfo&,
return false; return false;
} }
void NetAssign::eval_func_lval_op_real_(const LineInfo&loc,
verireal&lv, verireal&rv) const
{
switch (op_) {
case '+':
lv = lv + rv;
break;
case '-':
lv = lv - rv;
break;
case '*':
lv = lv * rv;
break;
case '/':
lv = lv / rv;
break;
case '%':
lv = lv % rv;
break;
default:
cerr << "Illegal assignment operator: "
<< human_readable_op(op_) << endl;
ivl_assert(loc, 0);
}
}
void NetAssign::eval_func_lval_op_(const LineInfo&loc, void NetAssign::eval_func_lval_op_(const LineInfo&loc,
verinum&lv, verinum&rv) const verinum&lv, verinum&rv) const
{ {
@ -267,7 +293,8 @@ void NetAssign::eval_func_lval_op_(const LineInfo&loc,
lv = lv >> rv.as_unsigned(); lv = lv >> rv.as_unsigned();
break; break;
default: default:
// illegal assignment operator cerr << "Illegal assignment operator: "
<< human_readable_op(op_) << endl;
ivl_assert(loc, 0); ivl_assert(loc, 0);
} }
lv = cast_to_width(lv, lv_width); lv = cast_to_width(lv, lv_width);
@ -334,8 +361,10 @@ bool NetAssign::eval_func_lval_(const LineInfo&loc,
ivl_assert(loc, base + lval->lwidth() <= old_lval->expr_width()); ivl_assert(loc, base + lval->lwidth() <= old_lval->expr_width());
NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval); NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval);
ivl_assert(loc, lval_const);
verinum lval_v = lval_const->value(); verinum lval_v = lval_const->value();
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result); NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
ivl_assert(loc, rval_const);
verinum rval_v = rval_const->value(); verinum rval_v = rval_const->value();
verinum lpart(verinum::Vx, lval->lwidth()); verinum lpart(verinum::Vx, lval->lwidth());
@ -354,18 +383,32 @@ bool NetAssign::eval_func_lval_(const LineInfo&loc,
delete rval_result; delete rval_result;
rval_result = new NetEConst(lval_v); rval_result = new NetEConst(lval_v);
} else { } else {
if (op_) { if (op_ == 0) {
rval_result = fix_assign_value(lval->sig(), rval_result);
} else if (dynamic_cast<NetECReal*>(rval_result)) {
NetECReal*lval_const = dynamic_cast<NetECReal*>(old_lval);
ivl_assert(loc, lval_const);
verireal lval_r = lval_const->value();
NetECReal*rval_const = dynamic_cast<NetECReal*>(rval_result);
ivl_assert(loc, rval_const);
verireal rval_r = rval_const->value();
eval_func_lval_op_real_(loc, lval_r, rval_r);
delete rval_result;
rval_result = new NetECReal(lval_r);
} else {
NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval); NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval);
ivl_assert(loc, lval_const);
verinum lval_v = lval_const->value(); verinum lval_v = lval_const->value();
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result); NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
ivl_assert(loc, rval_const);
verinum rval_v = rval_const->value(); verinum rval_v = rval_const->value();
eval_func_lval_op_(loc, lval_v, rval_v); eval_func_lval_op_(loc, lval_v, rval_v);
delete rval_result; delete rval_result;
rval_result = new NetEConst(lval_v); rval_result = new NetEConst(lval_v);
} else {
rval_result = fix_assign_value(lval->sig(), rval_result);
} }
} }
@ -404,6 +447,13 @@ bool NetAssign::evaluate_function(const LineInfo&loc,
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result); NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
ivl_assert(*this, rval_const); ivl_assert(*this, rval_const);
if (op_) {
cerr << get_fileline() << ": sorry: Assignment operators "
"inside a constant function are not currently "
"supported if the LHS is a concatenation." << endl;
return false;
}
verinum rval_full = rval_const->value(); verinum rval_full = rval_const->value();
delete rval_result; delete rval_result;

View File

@ -2881,6 +2881,7 @@ class NetAssign : public NetAssignBase {
map<perm_string,LocalVar>&ctx) const; map<perm_string,LocalVar>&ctx) const;
private: private:
void eval_func_lval_op_real_(const LineInfo&loc, verireal&lv, verireal&rv) const;
void eval_func_lval_op_(const LineInfo&loc, verinum&lv, verinum&rv) const; void eval_func_lval_op_(const LineInfo&loc, verinum&lv, verinum&rv) const;
bool eval_func_lval_(const LineInfo&loc, map<perm_string,LocalVar>&ctx, bool eval_func_lval_(const LineInfo&loc, map<perm_string,LocalVar>&ctx,
const NetAssign_*lval, NetExpr*rval_result) const; const NetAssign_*lval, NetExpr*rval_result) const;