diff --git a/elab_expr.cc b/elab_expr.cc index 11ac12dcc..8b322831b 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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" diff --git a/expr_synth.cc b/expr_synth.cc index 28f6d449f..2ac96bbfb 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -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) { diff --git a/ivl_target.h b/ivl_target.h index 58c27e424..159ff7dac 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -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. diff --git a/netlist.h b/netlist.h index 931b9fe74..65d803ccb 100644 --- a/netlist.h +++ b/netlist.h @@ -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_; diff --git a/t-dll-api.cc b/t-dll-api.cc index d5ab959ea..c68a61f32 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -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_; diff --git a/t-dll.cc b/t-dll.cc index d09536f01..d41359bbd 100644 --- a/t-dll.cc +++ b/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; } diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 13da6f4d2..21c27df08 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -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]); }