Fix synthesis of signal and part select to keep signed/unsigned type.

If a signal has been cast to a different type, synthesis needs to
reflect the expression type, not the base signal type.

If a part select selects the entire signal, unless otherwise cast,
the expression is unsigned, regardless of the base signal type.

This fixes the additional issues reported in issue #1099.
This commit is contained in:
Martin Whitaker 2024-02-25 21:48:39 +00:00
parent 3624a54f7f
commit fc29e51e41
1 changed files with 30 additions and 4 deletions

View File

@ -1259,9 +1259,22 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
// padding.) If this was for an actual part select that at // padding.) If this was for an actual part select that at
// this point the output vector_width is exactly right, and we // this point the output vector_width is exactly right, and we
// are done. // are done.
if (sub->vector_width() == expr_width()) if (sub->vector_width() == expr_width()) {
if (sub->get_signed() == has_sign())
return sub; return sub;
// If the signal and expression type don't match, we
// need to add an intermediate signal to reflect that.
auto tmp_vec = new netvector_t(sub->data_type(), sub->vector_width() - 1, 0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT,
tmp_vec);
tmp->set_line(*this);
tmp->local_flag(true);
connect(sub->pin(0), tmp->pin(0));
return tmp;
}
netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0); netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0);
net_vec->set_signed(has_sign()); net_vec->set_signed(has_sign());
NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet*net = new NetNet(scope, scope->local_symbol(),
@ -1423,9 +1436,22 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
return tmp; return tmp;
} }
if (word_ == 0) if (word_ == 0) {
if (net_->get_signed() == has_sign())
return net_; return net_;
// If the signal has been cast to a different type, we
// need to add an intermediate signal to reflect that.
auto tmp_vec = new netvector_t(net_->data_type(), net_->vector_width() - 1, 0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT,
tmp_vec);
tmp->set_line(*this);
tmp->local_flag(true);
connect(net_->pin(0), tmp->pin(0));
return tmp;
}
netvector_t*tmp_vec = new netvector_t(net_->data_type(), netvector_t*tmp_vec = new netvector_t(net_->data_type(),
net_->vector_width()-1, 0); net_->vector_width()-1, 0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),