Fix signed/unsigned resizing
This commit is contained in:
parent
469036990a
commit
e5ef0d97bd
|
|
@ -87,21 +87,9 @@ static vhdl_expr *translate_unary(ivl_expr_t e)
|
||||||
*/
|
*/
|
||||||
static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs,
|
static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs,
|
||||||
vhdl_binop_t op)
|
vhdl_binop_t op)
|
||||||
{
|
{
|
||||||
int lwidth = lhs->get_type()->get_width();
|
vhdl_type *rtype = new vhdl_type(*lhs->get_type());
|
||||||
int rwidth = rhs->get_type()->get_width();
|
return new vhdl_binop_expr(lhs, op, rhs, rtype);
|
||||||
|
|
||||||
// May need to resize the left or right hand side
|
|
||||||
if (lwidth < rwidth) {
|
|
||||||
lhs = lhs->cast(rhs->get_type());
|
|
||||||
lwidth = rwidth;
|
|
||||||
}
|
|
||||||
else if (rwidth < lwidth) {
|
|
||||||
rhs = rhs->cast(lhs->get_type());
|
|
||||||
rwidth = lwidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new vhdl_binop_expr(lhs, op, rhs, vhdl_type::nsigned(lwidth));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static vhdl_expr *translate_relation(vhdl_expr *lhs, vhdl_expr *rhs,
|
static vhdl_expr *translate_relation(vhdl_expr *lhs, vhdl_expr *rhs,
|
||||||
|
|
@ -134,6 +122,15 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
|
||||||
vhdl_expr *rhs = translate_expr(ivl_expr_oper2(e));
|
vhdl_expr *rhs = translate_expr(ivl_expr_oper2(e));
|
||||||
if (NULL == rhs)
|
if (NULL == rhs)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
int lwidth = lhs->get_type()->get_width();
|
||||||
|
int rwidth = rhs->get_type()->get_width();
|
||||||
|
|
||||||
|
// May need to resize the left or right hand side
|
||||||
|
if (lwidth < rwidth)
|
||||||
|
rhs = rhs->cast(lhs->get_type());
|
||||||
|
else if (rwidth < lwidth)
|
||||||
|
lhs = lhs->cast(rhs->get_type());
|
||||||
|
|
||||||
// For === and !== we need to compare std_logic_vectors
|
// For === and !== we need to compare std_logic_vectors
|
||||||
// rather than signeds
|
// rather than signeds
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope)
|
||||||
int nsigs = ivl_scope_sigs(scope);
|
int nsigs = ivl_scope_sigs(scope);
|
||||||
for (int i = 0; i < nsigs; i++) {
|
for (int i = 0; i < nsigs; i++) {
|
||||||
ivl_signal_t sig = ivl_scope_sig(scope, i);
|
ivl_signal_t sig = ivl_scope_sig(scope, i);
|
||||||
|
|
||||||
int width = ivl_signal_width(sig);
|
int width = ivl_signal_width(sig);
|
||||||
vhdl_type *sig_type;
|
vhdl_type *sig_type;
|
||||||
if (width == 1)
|
if (width == 1)
|
||||||
|
|
|
||||||
|
|
@ -465,14 +465,8 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
||||||
if (to->get_name() == type_->get_name()) {
|
if (to->get_name() == type_->get_name()) {
|
||||||
if (to->get_width() == type_->get_width())
|
if (to->get_width() == type_->get_width())
|
||||||
return this; // Identical
|
return this; // Identical
|
||||||
else {
|
else
|
||||||
vhdl_type *rtype = vhdl_type::nsigned(to->get_width());
|
return resize(to->get_width());
|
||||||
vhdl_fcall *resize = new vhdl_fcall("Resize", rtype);
|
|
||||||
resize->add_expr(this);
|
|
||||||
resize->add_expr(new vhdl_const_int(to->get_width()));
|
|
||||||
|
|
||||||
return resize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (to->get_name() == VHDL_TYPE_BOOLEAN) {
|
else if (to->get_name() == VHDL_TYPE_BOOLEAN) {
|
||||||
// '1' is true all else are false
|
// '1' is true all else are false
|
||||||
|
|
@ -495,6 +489,16 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vhdl_expr *vhdl_expr::resize(int newwidth)
|
||||||
|
{
|
||||||
|
vhdl_type *rtype = vhdl_type::nsigned(newwidth);
|
||||||
|
vhdl_fcall *resize = new vhdl_fcall("Resize", rtype);
|
||||||
|
resize->add_expr(this);
|
||||||
|
resize->add_expr(new vhdl_const_int(newwidth));
|
||||||
|
|
||||||
|
return resize;
|
||||||
|
}
|
||||||
|
|
||||||
void vhdl_expr_list::add_expr(vhdl_expr *e)
|
void vhdl_expr_list::add_expr(vhdl_expr *e)
|
||||||
{
|
{
|
||||||
exprs_.push_back(e);
|
exprs_.push_back(e);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ public:
|
||||||
const vhdl_type *get_type() const { return type_; }
|
const vhdl_type *get_type() const { return type_; }
|
||||||
bool constant() const { return isconst_; }
|
bool constant() const { return isconst_; }
|
||||||
virtual vhdl_expr *cast(const vhdl_type *to);
|
virtual vhdl_expr *cast(const vhdl_type *to);
|
||||||
|
virtual vhdl_expr *resize(int newwidth);
|
||||||
private:
|
private:
|
||||||
vhdl_type *type_;
|
vhdl_type *type_;
|
||||||
bool isconst_;
|
bool isconst_;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue