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,
vhdl_binop_t op)
{
{
int lwidth = lhs->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(),
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
if (lwidth < rwidth) {
vhdl_fcall *resize =
new vhdl_fcall("resize", vhdl_type::nunsigned(rwidth));
resize->add_expr(l_cast);
new vhdl_fcall("resize", vhdl_type::nsigned(rwidth));
resize->add_expr(lhs);
resize->add_expr(new vhdl_const_int(rwidth));
// l_cast = resize;
lhs = resize;
lwidth = rwidth;
}
else if (rwidth < lwidth) {
vhdl_fcall *resize =
new vhdl_fcall("resize", vhdl_type::nunsigned(lwidth));
resize->add_expr(r_cast);
new vhdl_fcall("resize", vhdl_type::nsigned(lwidth));
resize->add_expr(rhs);
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,
vhdl_type::nunsigned(lwidth));
return new vhdl_binop_expr(lhs, op, rhs, vhdl_type::nsigned(lwidth));
}
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);
vhdl_type *sig_type;
if (width > 0)
if (width == 1)
sig_type = vhdl_type::std_logic();
else
sig_type = vhdl_type::std_logic_vector(width-1, 0);
sig_type = vhdl_type::nsigned(width);
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
of << "library ieee;" << 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();
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_expr(vhdl_type::std_logic_vector(strlen(value)-1, 0)),
: vhdl_expr(vhdl_type::nsigned(strlen(value))),
value_(value)
{
}
vhdl_expr *vhdl_const_bits::cast(const vhdl_type *to)
{
{
if (to->get_name() == VHDL_TYPE_STD_LOGIC) {
// VHDL won't let us cast directly between a vector and
// 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
{
of << "std_logic_vector'(\"";
of << "signed'(\"";
// The bits appear to be in reverse order
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);
}
/*
* This is just the name of the type, without any parameters.
*/
std::string vhdl_type::get_string() const
{
switch (name_) {
case VHDL_TYPE_STD_LOGIC:
return std::string("std_logic");
case VHDL_TYPE_STD_LOGIC_VECTOR:
{
std::ostringstream ss;
ss << "std_logic_vector(" << msb_;
ss << " downto " << lsb_ << ")";
return ss.str();
}
return std::string("std_logic_vector");
case VHDL_TYPE_STRING:
return std::string("String");
case VHDL_TYPE_LINE:
@ -80,14 +78,38 @@ std::string vhdl_type::get_string() const
return std::string("Integer");
case VHDL_TYPE_BOOLEAN:
return std::string("Boolean");
case VHDL_TYPE_SIGNED:
return std::string("signed");
case VHDL_TYPE_UNSIGNED:
return std::string("unsigned");
default:
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
{
of << get_string();
of << get_decl_string();
}
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;
vhdl_type_name_t get_name() const { return name_; }
std::string get_string() const;
std::string get_decl_string() const;
int get_width() const { return msb_ - lsb_ + 1; }
int get_msb() const { return msb_; }
int get_lsb() const { return lsb_; }