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:
parent
74b8c04b91
commit
f9f51db7ba
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue