Use signed rather than std_logic_vector

Arithmetic operators now working correctly
This commit is contained in:
Nick Gasson 2008-06-14 18:03:25 +01:00
parent 919c1d695c
commit 2fb57805ea
5 changed files with 46 additions and 25 deletions

View File

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

View File

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

View File

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

View File

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

View File

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