Fix signed/unsigned resizing

This commit is contained in:
Nick Gasson 2008-06-23 13:04:28 +01:00
parent 469036990a
commit e5ef0d97bd
4 changed files with 26 additions and 24 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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_;