Manage expression types for ternary a little better.
The true and false expression clauses must have compatible types, which are not necesarily identical. In particular, VT_BOOL and VT_LOGIC are compatible for the purposes of ternary arguments. The test in NetETernary::synthesize was incorrect. In the process, fix the type handling of NetConst objects to allow for IVL_VT_BOOL constants. This is information that the downstream may find useful, so should be handled correctly.
This commit is contained in:
parent
3d5998cd63
commit
804f5a94d5
|
|
@ -2148,8 +2148,8 @@ unsigned PETernary::test_width(Design*des, NetScope*scope,
|
|||
return max(tru_wid,fal_wid);
|
||||
}
|
||||
|
||||
static bool test_ternary_operand_compat(ivl_variable_type_t l,
|
||||
ivl_variable_type_t r)
|
||||
bool NetETernary::test_operand_compat(ivl_variable_type_t l,
|
||||
ivl_variable_type_t r)
|
||||
{
|
||||
if (l == IVL_VT_LOGIC && r == IVL_VT_BOOL)
|
||||
return true;
|
||||
|
|
@ -2245,7 +2245,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (! test_ternary_operand_compat(tru->expr_type(), fal->expr_type())) {
|
||||
if (! NetETernary::test_operand_compat(tru->expr_type(), fal->expr_type())) {
|
||||
cerr << get_fileline() << ": error: Data types "
|
||||
<< tru->expr_type() << " and "
|
||||
<< fal->expr_type() << " of ternary"
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope)
|
|||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width-1,0);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(IVL_VT_LOGIC);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
|
||||
connect(osig->pin(0), con->pin(0));
|
||||
|
|
@ -1097,13 +1097,18 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope)
|
|||
|
||||
if (csig == 0 || tsig == 0 || fsig == 0) return 0;
|
||||
|
||||
if (tsig->data_type() != fsig->data_type()) {
|
||||
cerr << get_fileline() << ": error: True and False clauses of "
|
||||
"ternary expression have different types." << endl;
|
||||
if (! NetETernary::test_operand_compat(tsig->data_type(),fsig->data_type())) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< " True and False clauses of ternary expression "
|
||||
<< " have incompatible types." << endl;
|
||||
cerr << get_fileline() << ": : True clause is: "
|
||||
<< tsig->data_type() << endl;
|
||||
<< tsig->data_type()
|
||||
<< " (" << true_val_->expr_type() << "): "
|
||||
<< *true_val_ << endl;
|
||||
cerr << get_fileline() << ": : False clause is: "
|
||||
<< fsig->data_type() << endl;
|
||||
<< fsig->data_type()
|
||||
<< " (" << false_val_->expr_type() << "): "
|
||||
<< *false_val_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
} else if (tsig->data_type() == IVL_VT_NO_TYPE) {
|
||||
|
|
|
|||
|
|
@ -502,7 +502,8 @@ extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx);
|
|||
* ivl_const_bits
|
||||
* This returns a pointer to an array of constant characters,
|
||||
* each byte a '0', '1', 'x' or 'z'. The array is *not* nul
|
||||
* terminated.
|
||||
* terminated. This value is only value if ivl_const_type is
|
||||
* IVL_VT_LOGIC or IVL_VT_BOOL. It returns nil otherwise.
|
||||
*
|
||||
* ivl_const_nex
|
||||
* Return the ivl_nexus_t of the output for the constant.
|
||||
|
|
|
|||
|
|
@ -3565,6 +3565,9 @@ class NetETernary : public NetExpr {
|
|||
virtual void dump(ostream&) const;
|
||||
virtual NetNet*synthesize(Design*, NetScope*scope);
|
||||
|
||||
public:
|
||||
static bool test_operand_compat(ivl_variable_type_t tru, ivl_variable_type_t fal);
|
||||
|
||||
private:
|
||||
NetExpr*cond_;
|
||||
NetExpr*true_val_;
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ extern "C" const char*ivl_const_bits(ivl_net_const_t net)
|
|||
assert(net);
|
||||
switch (net->type) {
|
||||
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
if (net->width_ <= sizeof(net->b.bit_))
|
||||
return net->b.bit_;
|
||||
|
|
|
|||
6
t-dll.cc
6
t-dll.cc
|
|
@ -2199,7 +2199,7 @@ bool dll_target::net_const(const NetConst*net)
|
|||
|
||||
struct ivl_net_const_s *obj = new struct ivl_net_const_s;
|
||||
|
||||
obj->type = IVL_VT_LOGIC;
|
||||
obj->type = IVL_VT_BOOL;
|
||||
|
||||
/* constants have a single vector output. */
|
||||
assert(net->pin_count() == 1);
|
||||
|
|
@ -2223,9 +2223,13 @@ bool dll_target::net_const(const NetConst*net)
|
|||
bits[idx] = '1';
|
||||
break;
|
||||
case verinum::Vx:
|
||||
if (obj->type == IVL_VT_BOOL)
|
||||
obj->type = IVL_VT_LOGIC;
|
||||
bits[idx] = 'x';
|
||||
break;
|
||||
case verinum::Vz:
|
||||
if (obj->type == IVL_VT_BOOL)
|
||||
obj->type = IVL_VT_LOGIC;
|
||||
bits[idx] = 'z';
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1058,8 +1058,10 @@ static void signal_nexus_const(ivl_signal_t sig,
|
|||
fprintf(out, " const-");
|
||||
|
||||
switch (ivl_const_type(con)) {
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
bits = ivl_const_bits(con);
|
||||
assert(bits);
|
||||
for (idx = 0 ; idx < width ; idx += 1) {
|
||||
fprintf(out, "%c", bits[width-idx-1]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue