Use signed rather than std_logic_vector
Arithmetic operators now working correctly
This commit is contained in:
parent
919c1d695c
commit
2fb57805ea
|
|
@ -79,7 +79,7 @@ static vhdl_expr *translate_unary(ivl_expr_t e)
|
||||||
*/
|
*/
|
||||||
static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs,
|
static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs,
|
||||||
vhdl_binop_t op)
|
vhdl_binop_t op)
|
||||||
{
|
{
|
||||||
int lwidth = lhs->get_type()->get_width();
|
int lwidth = lhs->get_type()->get_width();
|
||||||
int rwidth = rhs->get_type()->get_width();
|
int rwidth = rhs->get_type()->get_width();
|
||||||
|
|
||||||
|
|
@ -88,28 +88,25 @@ static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs,
|
||||||
vhdl_type rtype(VHDL_TYPE_UNSIGNED, rhs->get_type()->get_msb(),
|
vhdl_type rtype(VHDL_TYPE_UNSIGNED, rhs->get_type()->get_msb(),
|
||||||
rhs->get_type()->get_lsb());
|
rhs->get_type()->get_lsb());
|
||||||
|
|
||||||
vhdl_expr *l_cast = lhs->cast(<ype);
|
|
||||||
vhdl_expr *r_cast = lhs->cast(&rtype);
|
|
||||||
|
|
||||||
// May need to resize the left or right hand side
|
// May need to resize the left or right hand side
|
||||||
if (lwidth < rwidth) {
|
if (lwidth < rwidth) {
|
||||||
vhdl_fcall *resize =
|
vhdl_fcall *resize =
|
||||||
new vhdl_fcall("resize", vhdl_type::nunsigned(rwidth));
|
new vhdl_fcall("resize", vhdl_type::nsigned(rwidth));
|
||||||
resize->add_expr(l_cast);
|
resize->add_expr(lhs);
|
||||||
resize->add_expr(new vhdl_const_int(rwidth));
|
resize->add_expr(new vhdl_const_int(rwidth));
|
||||||
// l_cast = resize;
|
lhs = resize;
|
||||||
|
lwidth = rwidth;
|
||||||
}
|
}
|
||||||
else if (rwidth < lwidth) {
|
else if (rwidth < lwidth) {
|
||||||
vhdl_fcall *resize =
|
vhdl_fcall *resize =
|
||||||
new vhdl_fcall("resize", vhdl_type::nunsigned(lwidth));
|
new vhdl_fcall("resize", vhdl_type::nsigned(lwidth));
|
||||||
resize->add_expr(r_cast);
|
resize->add_expr(rhs);
|
||||||
resize->add_expr(new vhdl_const_int(lwidth));
|
resize->add_expr(new vhdl_const_int(lwidth));
|
||||||
//r_cast = resize;
|
rhs = resize;
|
||||||
|
rwidth = lwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return new vhdl_binop_expr(l_cast, op, r_cast,
|
return new vhdl_binop_expr(lhs, op, rhs, vhdl_type::nsigned(lwidth));
|
||||||
vhdl_type::nunsigned(lwidth));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static vhdl_expr *translate_binary(ivl_expr_t e)
|
static vhdl_expr *translate_binary(ivl_expr_t e)
|
||||||
|
|
|
||||||
|
|
@ -133,10 +133,10 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope)
|
||||||
|
|
||||||
int width = ivl_signal_width(sig);
|
int width = ivl_signal_width(sig);
|
||||||
vhdl_type *sig_type;
|
vhdl_type *sig_type;
|
||||||
if (width > 0)
|
if (width == 1)
|
||||||
sig_type = vhdl_type::std_logic();
|
sig_type = vhdl_type::std_logic();
|
||||||
else
|
else
|
||||||
sig_type = vhdl_type::std_logic_vector(width-1, 0);
|
sig_type = vhdl_type::nsigned(width);
|
||||||
|
|
||||||
remember_signal(sig, arch->get_parent());
|
remember_signal(sig, arch->get_parent());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ void vhdl_entity::emit(std::ofstream &of, int level) const
|
||||||
// might as well include it by default
|
// might as well include it by default
|
||||||
of << "library ieee;" << std::endl;
|
of << "library ieee;" << std::endl;
|
||||||
of << "use ieee.std_logic_1164.all;" << std::endl;
|
of << "use ieee.std_logic_1164.all;" << std::endl;
|
||||||
|
of << "use ieee.numeric_std.all;" << std::endl;
|
||||||
|
|
||||||
for (std::list<std::string>::const_iterator it = uses_.begin();
|
for (std::list<std::string>::const_iterator it = uses_.begin();
|
||||||
it != uses_.end();
|
it != uses_.end();
|
||||||
|
|
@ -547,14 +548,14 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_const_bits::vhdl_const_bits(const char *value)
|
vhdl_const_bits::vhdl_const_bits(const char *value)
|
||||||
: vhdl_expr(vhdl_type::std_logic_vector(strlen(value)-1, 0)),
|
: vhdl_expr(vhdl_type::nsigned(strlen(value))),
|
||||||
value_(value)
|
value_(value)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_expr *vhdl_const_bits::cast(const vhdl_type *to)
|
vhdl_expr *vhdl_const_bits::cast(const vhdl_type *to)
|
||||||
{
|
{
|
||||||
if (to->get_name() == VHDL_TYPE_STD_LOGIC) {
|
if (to->get_name() == VHDL_TYPE_STD_LOGIC) {
|
||||||
// VHDL won't let us cast directly between a vector and
|
// VHDL won't let us cast directly between a vector and
|
||||||
// a scalar type
|
// a scalar type
|
||||||
|
|
@ -571,7 +572,7 @@ 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 << "std_logic_vector'(\"";
|
of << "signed'(\"";
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
|
||||||
|
|
@ -58,18 +58,16 @@ vhdl_type *vhdl_type::nsigned(int width)
|
||||||
return new vhdl_type(VHDL_TYPE_SIGNED, width-1, 0);
|
return new vhdl_type(VHDL_TYPE_SIGNED, width-1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is just the name of the type, without any parameters.
|
||||||
|
*/
|
||||||
std::string vhdl_type::get_string() const
|
std::string vhdl_type::get_string() const
|
||||||
{
|
{
|
||||||
switch (name_) {
|
switch (name_) {
|
||||||
case VHDL_TYPE_STD_LOGIC:
|
case VHDL_TYPE_STD_LOGIC:
|
||||||
return std::string("std_logic");
|
return std::string("std_logic");
|
||||||
case VHDL_TYPE_STD_LOGIC_VECTOR:
|
case VHDL_TYPE_STD_LOGIC_VECTOR:
|
||||||
{
|
return std::string("std_logic_vector");
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "std_logic_vector(" << msb_;
|
|
||||||
ss << " downto " << lsb_ << ")";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
case VHDL_TYPE_STRING:
|
case VHDL_TYPE_STRING:
|
||||||
return std::string("String");
|
return std::string("String");
|
||||||
case VHDL_TYPE_LINE:
|
case VHDL_TYPE_LINE:
|
||||||
|
|
@ -80,14 +78,38 @@ std::string vhdl_type::get_string() const
|
||||||
return std::string("Integer");
|
return std::string("Integer");
|
||||||
case VHDL_TYPE_BOOLEAN:
|
case VHDL_TYPE_BOOLEAN:
|
||||||
return std::string("Boolean");
|
return std::string("Boolean");
|
||||||
|
case VHDL_TYPE_SIGNED:
|
||||||
|
return std::string("signed");
|
||||||
|
case VHDL_TYPE_UNSIGNED:
|
||||||
|
return std::string("unsigned");
|
||||||
default:
|
default:
|
||||||
return std::string("BadType");
|
return std::string("BadType");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The is the qualified name of the type.
|
||||||
|
*/
|
||||||
|
std::string vhdl_type::get_decl_string() const
|
||||||
|
{
|
||||||
|
switch (name_) {
|
||||||
|
case VHDL_TYPE_STD_LOGIC_VECTOR:
|
||||||
|
case VHDL_TYPE_UNSIGNED:
|
||||||
|
case VHDL_TYPE_SIGNED:
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << get_string() << "(" << msb_;
|
||||||
|
ss << " downto " << lsb_ << ")";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return get_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void vhdl_type::emit(std::ofstream &of, int level) const
|
void vhdl_type::emit(std::ofstream &of, int level) const
|
||||||
{
|
{
|
||||||
of << get_string();
|
of << get_decl_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb)
|
vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ public:
|
||||||
void emit(std::ofstream &of, int level) const;
|
void emit(std::ofstream &of, int level) const;
|
||||||
vhdl_type_name_t get_name() const { return name_; }
|
vhdl_type_name_t get_name() const { return name_; }
|
||||||
std::string get_string() const;
|
std::string get_string() const;
|
||||||
|
std::string get_decl_string() const;
|
||||||
int get_width() const { return msb_ - lsb_ + 1; }
|
int get_width() const { return msb_ - lsb_ + 1; }
|
||||||
int get_msb() const { return msb_; }
|
int get_msb() const { return msb_; }
|
||||||
int get_lsb() const { return lsb_; }
|
int get_lsb() const { return lsb_; }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue