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:
parent
b80dbeee11
commit
b081818a90
14
elaborate.cc
14
elaborate.cc
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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} },
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue