Cast expressions from logic to bool.

Handle assignments from logic to bool variables by inserting
the proper cast expression nodes.
This commit is contained in:
Stephen Williams 2010-10-19 19:09:06 -07:00
parent b80dbeee11
commit b081818a90
8 changed files with 75 additions and 0 deletions

View File

@ -2265,6 +2265,12 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
ivl_assert(*this, rv->expr_width() >= wid);
}
if (lv->expr_type() == IVL_VT_BOOL && rv->expr_type() != IVL_VT_BOOL) {
if (debug_elaborate)
cerr << get_fileline() << ": debug: Cast expression to int2" << endl;
rv = cast_to_int2(rv);
}
NetAssign*cur = new NetAssign(lv, rv);
cur->set_line(*this);
@ -3562,6 +3568,14 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
rexp->set_width(lwid, true);
rexp = pad_to_width(rexp, lwid, *this);
if (ltype==IVL_VT_BOOL && rexp->expr_type()!=IVL_VT_BOOL) {
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "Cast force rvalue to int2" << endl;
}
rexp = cast_to_int2(rexp);
}
dev = new NetForce(lval, rexp);
if (debug_elaborate) {

View File

@ -176,6 +176,14 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src)
return tmp;
}
NetExpr* cast_to_int2(NetExpr*expr)
{
NetECast*cast = new NetECast('2', expr);
cast->set_line(*expr);
cast->cast_signed(expr->has_sign());
return cast;
}
/*
* Add a signed constant to an existing expression. Generate a new
* NetEBAdd node that has the input expression and an expression made

View File

@ -78,6 +78,8 @@ extern NetNet*cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid)
extern NetNet*cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid);
extern NetNet*cast_to_real(Design*des, NetScope*scope, NetNet*src);
extern NetExpr*cast_to_int2(NetExpr*expr);
/*
* Take the input expression and return a variation that assures that
* the expression is 1-bit wide and logical. This reflects the needs

View File

@ -3125,6 +3125,21 @@ static struct vector_info draw_unary_expr(ivl_expr_t expr, unsigned wid)
local_count += 1;
break;
case '2': /* Cast logic to bool */
assert(ivl_expr_value(sub) == IVL_VT_LOGIC);
res = draw_eval_expr_wid(sub, wid, 0);
/* Handle special case that value is 0 or 1. */
if (res.base == 0 || res.base == 1)
break;
if (res.base == 2 || res.base == 2) {
res.base = 0;
break;
}
fprintf(vvp_out, " %%cast2 %d, %d, %u;\n", res.base, res.base, res.wid);
break;
case 'i': /* Cast a real value to an integer. */
assert(ivl_expr_value(sub) == IVL_VT_REAL);
word = draw_eval_real(sub);

View File

@ -64,6 +64,7 @@ extern bool of_CASSIGN_LINK(vthread_t thr, vvp_code_t code);
extern bool of_CASSIGN_V(vthread_t thr, vvp_code_t code);
extern bool of_CASSIGN_WR(vthread_t thr, vvp_code_t code);
extern bool of_CASSIGN_X0(vthread_t thr, vvp_code_t code);
extern bool of_CAST2(vthread_t thr, vvp_code_t code);
extern bool of_CMPIS(vthread_t thr, vvp_code_t code);
extern bool of_CMPIU(vthread_t thr, vvp_code_t code);
extern bool of_CMPS(vthread_t thr, vvp_code_t code);

View File

@ -107,6 +107,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%cassign/v",of_CASSIGN_V,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
{ "%cassign/wr",of_CASSIGN_WR,2,{OA_FUNC_PTR,OA_BIT1, OA_NONE} },
{ "%cassign/x0",of_CASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
{ "%cast2", of_CAST2, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/s", of_CMPS, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/wr", of_CMPWR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },

View File

@ -217,6 +217,12 @@ cassign port (port-1) of the signal functor instead of the normal
assign port (port-0), so the signal responds differently. See
"VARIABLE STATEMENTS" and "NET STATEMENTS" in the README.txt file.
* %cast2 <dst>, <src>, <wid>
Convert the source vector, of type logic, to a bool vector by
changing all the X and Z bits to 0. The source and destinations may
overlap.
* %cmp/u <bit-l>, <bit-r>, <wid>
* %cmp/s <bit-l>, <bit-r>, <wid>

View File

@ -1385,6 +1385,34 @@ bool of_CASSIGN_X0(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_CAST2(vthread_t thr, vvp_code_t cp)
{
unsigned dst = cp->bit_idx[0];
unsigned src = cp->bit_idx[1];
unsigned wid = cp->number;
thr_check_addr(thr, dst+wid-1);
thr_check_addr(thr, src+wid-1);
vvp_vector4_t res;
switch (src) {
case 0:
case 2:
case 3:
res = vvp_vector4_t(wid, BIT4_0);
break;
case 1:
res = vvp_vector4_t(wid, BIT4_1);
break;
default:
res = vector2_to_vector4(vvp_vector2_t(vthread_bits_to_vector(thr, src, wid)), wid);
break;
}
thr->bits4.set_vec(dst, res);
return true;
}
bool of_CMPS(vthread_t thr, vvp_code_t cp)
{
vvp_bit4_t eq = BIT4_1;