Fix signed/unsigned resizing
This commit is contained in:
parent
469036990a
commit
e5ef0d97bd
|
|
@ -88,20 +88,8 @@ static vhdl_expr *translate_unary(ivl_expr_t e)
|
|||
static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs,
|
||||
vhdl_binop_t op)
|
||||
{
|
||||
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) {
|
||||
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));
|
||||
vhdl_type *rtype = new vhdl_type(*lhs->get_type());
|
||||
return new vhdl_binop_expr(lhs, op, rhs, rtype);
|
||||
}
|
||||
|
||||
static vhdl_expr *translate_relation(vhdl_expr *lhs, vhdl_expr *rhs,
|
||||
|
|
@ -135,6 +123,15 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
|
|||
if (NULL == rhs)
|
||||
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
|
||||
// rather than signeds
|
||||
vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR);
|
||||
|
|
|
|||
|
|
@ -465,14 +465,8 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
|||
if (to->get_name() == type_->get_name()) {
|
||||
if (to->get_width() == type_->get_width())
|
||||
return this; // Identical
|
||||
else {
|
||||
vhdl_type *rtype = vhdl_type::nsigned(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
|
||||
return resize(to->get_width());
|
||||
}
|
||||
else if (to->get_name() == VHDL_TYPE_BOOLEAN) {
|
||||
// '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)
|
||||
{
|
||||
exprs_.push_back(e);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public:
|
|||
const vhdl_type *get_type() const { return type_; }
|
||||
bool constant() const { return isconst_; }
|
||||
virtual vhdl_expr *cast(const vhdl_type *to);
|
||||
virtual vhdl_expr *resize(int newwidth);
|
||||
private:
|
||||
vhdl_type *type_;
|
||||
bool isconst_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue