Correctly generate signed/unsigned types
This commit is contained in:
parent
181a53d3ed
commit
449cd0a76e
|
|
@ -49,6 +49,8 @@ static vhdl_var_ref *translate_signal(ivl_expr_t e)
|
|||
const vhdl_decl *decl = ent->get_arch()->get_decl(strip_var(renamed));
|
||||
assert(decl);
|
||||
|
||||
std::cout << "ref: " << renamed << " width=" << decl->get_type()->get_width() << std::endl;
|
||||
|
||||
vhdl_type *type = new vhdl_type(*decl->get_type());
|
||||
|
||||
return new vhdl_var_ref(renamed, type);
|
||||
|
|
@ -59,7 +61,8 @@ static vhdl_var_ref *translate_signal(ivl_expr_t e)
|
|||
*/
|
||||
static vhdl_expr *translate_number(ivl_expr_t e)
|
||||
{
|
||||
return new vhdl_const_bits(ivl_expr_bits(e), ivl_expr_width(e));
|
||||
return new vhdl_const_bits(ivl_expr_bits(e), ivl_expr_width(e),
|
||||
ivl_expr_signed(e) != 0);
|
||||
}
|
||||
|
||||
static vhdl_expr *translate_unary(ivl_expr_t e)
|
||||
|
|
@ -127,14 +130,24 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
|
|||
int rwidth = rhs->get_type()->get_width();
|
||||
|
||||
// May need to resize the left or right hand side
|
||||
if (lwidth < rwidth)
|
||||
int opwidth;
|
||||
if (lwidth < rwidth) {
|
||||
rhs = rhs->cast(lhs->get_type());
|
||||
else if (rwidth < lwidth)
|
||||
opwidth = lwidth;
|
||||
}
|
||||
else if (rwidth < lwidth) {
|
||||
lhs = lhs->cast(rhs->get_type());
|
||||
opwidth = rwidth;
|
||||
}
|
||||
else
|
||||
opwidth = lwidth;
|
||||
|
||||
std::cout << "lwidth=" << lwidth << " rwidth=" << rwidth << std::endl;
|
||||
|
||||
// For === and !== we need to compare std_logic_vectors
|
||||
// rather than signeds
|
||||
vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR);
|
||||
int msb = ivl_expr_width(e) - 1;
|
||||
vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR, opwidth-1, 0);
|
||||
bool vectorop =
|
||||
(lhs->get_type()->get_name() == VHDL_TYPE_SIGNED
|
||||
|| lhs->get_type()->get_name() == VHDL_TYPE_UNSIGNED) &&
|
||||
|
|
@ -190,12 +203,7 @@ vhdl_expr *translate_select(ivl_expr_t e)
|
|||
return NULL;
|
||||
|
||||
// Hack: resize it to the correct size
|
||||
vhdl_type *rtype = vhdl_type::nsigned(ivl_expr_width(e));
|
||||
vhdl_fcall *resize = new vhdl_fcall("Resize", rtype);
|
||||
resize->add_expr(from);
|
||||
resize->add_expr(new vhdl_const_int(ivl_expr_width(e)));
|
||||
|
||||
return resize;
|
||||
return from->resize(ivl_expr_width(e));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -135,8 +135,10 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope)
|
|||
vhdl_type *sig_type;
|
||||
if (width == 1)
|
||||
sig_type = vhdl_type::std_logic();
|
||||
else
|
||||
else if (ivl_signal_signed(sig))
|
||||
sig_type = vhdl_type::nsigned(width);
|
||||
else
|
||||
sig_type = vhdl_type::nunsigned(width);
|
||||
|
||||
remember_signal(sig, arch->get_parent());
|
||||
|
||||
|
|
|
|||
|
|
@ -462,6 +462,11 @@ vhdl_expr::~vhdl_expr()
|
|||
*/
|
||||
vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
||||
{
|
||||
std::cout << "Cast: from=" << type_->get_string()
|
||||
<< " (" << type_->get_width() << ") "
|
||||
<< " to=" << to->get_string() << " ("
|
||||
<< to->get_width() << ")" << std::endl;
|
||||
|
||||
if (to->get_name() == type_->get_name()) {
|
||||
if (to->get_width() == type_->get_width())
|
||||
return this; // Identical
|
||||
|
|
@ -481,10 +486,14 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
|||
return conv;
|
||||
}
|
||||
else {
|
||||
vhdl_expr *tocast = this;
|
||||
if (to->get_width() != type_->get_width())
|
||||
tocast = resize(to->get_width());
|
||||
|
||||
vhdl_fcall *conv =
|
||||
new vhdl_fcall(to->get_string().c_str(), new vhdl_type(*to));
|
||||
conv->add_expr(this);
|
||||
|
||||
conv->add_expr(tocast);
|
||||
|
||||
return conv;
|
||||
}
|
||||
}
|
||||
|
|
@ -598,9 +607,14 @@ void vhdl_assign_stmt::emit(std::ofstream &of, int level) const
|
|||
of << ";";
|
||||
}
|
||||
|
||||
vhdl_const_bits::vhdl_const_bits(const char *value, int width)
|
||||
: vhdl_expr(vhdl_type::nsigned(width), true), qualified_(false)
|
||||
vhdl_const_bits::vhdl_const_bits(const char *value, int width, bool issigned)
|
||||
: vhdl_expr(issigned ? vhdl_type::nsigned(width)
|
||||
: vhdl_type::nunsigned(width), true),
|
||||
qualified_(false),
|
||||
signed_(issigned)
|
||||
{
|
||||
std::cout << (issigned ? "signed" : "unsigned") << " bits" << std::endl;
|
||||
|
||||
// Can't rely on value being NULL-terminated
|
||||
while (width--)
|
||||
value_.push_back(*value++);
|
||||
|
|
@ -643,7 +657,10 @@ vhdl_expr *vhdl_const_bits::cast(const vhdl_type *to)
|
|||
|
||||
void vhdl_const_bits::emit(std::ofstream &of, int level) const
|
||||
{
|
||||
of << (qualified_ ? "signed'(\"" : "\"");
|
||||
if (qualified_)
|
||||
of << (signed_ ? "signed" : "unsigned") << "'(\"";
|
||||
else
|
||||
of << "\"";
|
||||
|
||||
// The bits appear to be in reverse order
|
||||
std::string::const_reverse_iterator it;
|
||||
|
|
|
|||
|
|
@ -127,13 +127,13 @@ private:
|
|||
|
||||
class vhdl_const_bits : public vhdl_expr {
|
||||
public:
|
||||
vhdl_const_bits(const char *value, int width);
|
||||
vhdl_const_bits(const char *value, int width, bool issigned);
|
||||
void emit(std::ofstream &of, int level) const;
|
||||
const std::string &get_value() const { return value_; }
|
||||
vhdl_expr *cast(const vhdl_type *to);
|
||||
private:
|
||||
std::string value_;
|
||||
bool qualified_;
|
||||
bool qualified_, signed_;
|
||||
};
|
||||
|
||||
class vhdl_const_bit : public vhdl_expr {
|
||||
|
|
|
|||
Loading…
Reference in New Issue