Fix implicit casts in assignments (part 2).

This patch adds support for implicit casts in module port connections
and in user task output assignments.
This commit is contained in:
Martin Whitaker 2013-02-25 22:13:05 +00:00 committed by Stephen Williams
parent 22769afd20
commit bc2a4c01c9
2 changed files with 43 additions and 3 deletions

View File

@ -1470,6 +1470,13 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
sig = cast_to_real(des, scope, sig);
}
// If we have a 4-state bit/vector signal driving a
// 2-state port then we convert the value to 2-state.
if ((sig->data_type() == IVL_VT_LOGIC ) &&
!prts.empty() && (prts[0]->data_type() == IVL_VT_BOOL )) {
sig = cast_to_int2(des, scope, sig,
sig->vector_width());
}
} else if (prts[0]->port_type() == NetNet::PINOUT) {
@ -1599,6 +1606,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
}
// If we have a 4-state bit/vector port driving a
// 2-state signal then we convert the value to 2-state.
if ((sig->data_type() == IVL_VT_BOOL ) &&
!prts.empty() && (prts[0]->data_type() == IVL_VT_LOGIC )) {
for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
prts[pidx]->port_type(NetNet::NOT_A_PORT);
prts[pidx] = cast_to_int2(des, scope, prts[pidx],
prts[pidx]->vector_width());
prts[pidx]->port_type(NetNet::POUTPUT);
}
}
// A real to real connection is not allowed for arrayed
// instances. You cannot have multiple real drivers.
if ((sig->data_type() == IVL_VT_REAL ) &&
@ -3233,8 +3252,28 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
if (lv == 0)
continue;
NetESignal*sig = new NetESignal(port);
NetExpr*rv = pad_to_width(sig, count_lval_width(lv), *this);
NetExpr*rv = new NetESignal(port);
/* Handle any implicit cast. */
unsigned lv_width = count_lval_width(lv);
if (lv->expr_type() != rv->expr_type()) {
switch (lv->expr_type()) {
case IVL_VT_REAL:
rv = cast_to_real(rv);
break;
case IVL_VT_BOOL:
rv = cast_to_int2(rv, lv_width);
break;
case IVL_VT_LOGIC:
rv = cast_to_int4(rv, lv_width);
break;
default:
/* Don't yet know how to handle this. */
ivl_assert(*this, 0);
break;
}
}
rv = pad_to_width(rv, lv_width, *this);
/* Generate the assignment statement. */
NetAssign*ass = new NetAssign(lv, rv);

View File

@ -82,7 +82,8 @@ NetNet* cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid)
if (src->data_type() == IVL_VT_BOOL)
return src;
netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, wid-1, 0);
netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, wid-1, 0,
src->get_signed());
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec);
tmp->set_line(*src);
tmp->local_flag(true);