Correctly generate signed/unsigned types

This commit is contained in:
Nick Gasson 2008-06-23 14:28:27 +01:00
parent 181a53d3ed
commit 449cd0a76e
4 changed files with 45 additions and 18 deletions

View File

@ -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));
}
/*

View File

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

View File

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

View File

@ -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 {