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,
|
||||
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(<ype);
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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_; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue