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