VHDL fix concatenation of std_logics

This fixes an assertion failure when taking a slice of
the result of concatenating several single-element vectors.
This commit is contained in:
Nick Gasson 2009-01-24 18:37:00 +00:00 committed by Stephen Williams
parent 2107125545
commit 308688f190
4 changed files with 23 additions and 17 deletions

View File

@ -195,6 +195,16 @@ vhdl_expr *vhdl_expr::resize(int newwidth)
rtype = vhdl_type::nsigned(newwidth);
else if (type_->get_name() == VHDL_TYPE_UNSIGNED)
rtype = vhdl_type::nunsigned(newwidth);
else if (type_->get_name() == VHDL_TYPE_STD_LOGIC) {
// Pad it with zeros
vhdl_expr* zeros = new vhdl_const_bits(string(newwidth - 1, '0').c_str(),
newwidth - 1, false, true);
vhdl_binop_expr* concat =
new vhdl_binop_expr(zeros, VHDL_BINOP_CONCAT, this,
vhdl_type::nunsigned(newwidth));
return concat;
}
else
return this; // Doesn't make sense to resize non-vector type

View File

@ -348,20 +348,16 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
static int tmp_count = 0;
ostringstream ss;
ss << "Verilog_Assign_Tmp_" << tmp_count++;
string tmpname = ss.str();
proc->get_scope()->add_decl
(new vhdl_var_decl(tmpname.c_str(), new vhdl_type(*rhs->get_type())));
vhdl_decl* tmp_decl = new vhdl_var_decl(ss.str(), rhs->get_type());
proc->get_scope()->add_decl(tmp_decl);
vhdl_var_ref *tmp_ref =
new vhdl_var_ref(tmpname.c_str(), new vhdl_type(*rhs->get_type()));
container->add_stmt(new vhdl_assign_stmt(tmp_ref, rhs));
container->add_stmt(new vhdl_assign_stmt(tmp_decl->make_ref(), rhs));
list<vhdl_var_ref*>::iterator it;
int width_so_far = 0;
for (it = lvals.begin(); it != lvals.end(); ++it) {
vhdl_var_ref *tmp_rhs =
new vhdl_var_ref(tmpname.c_str(), new vhdl_type(*rhs->get_type()));
vhdl_var_ref *tmp_rhs = tmp_decl->make_ref();
int lval_width = (*it)->get_type()->get_width();
vhdl_expr *slice_base = new vhdl_const_int(width_so_far);

View File

@ -501,13 +501,10 @@ void vhdl_var_ref::set_slice(vhdl_expr *s, int w)
vhdl_type_name_t tname = type_->get_name();
if (tname == VHDL_TYPE_ARRAY) {
type_ = new vhdl_type(*type_->get_base());
type_ = type_->get_base();
}
else {
assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED);
if (type_)
delete type_;
if (w > 0)
type_ = new vhdl_type(tname, w);
@ -578,10 +575,11 @@ void vhdl_assign_stmt::emit(std::ostream &of, int level) const
of << ";";
}
vhdl_const_bits::vhdl_const_bits(const char *value, int width, bool issigned)
vhdl_const_bits::vhdl_const_bits(const char *value, int width, bool issigned,
bool qualify)
: vhdl_expr(issigned ? vhdl_type::nsigned(width)
: vhdl_type::nunsigned(width), true),
qualified_(false),
qualified_(qualify),
signed_(issigned)
{
// Can't rely on value being NULL-terminated
@ -608,8 +606,9 @@ void vhdl_const_bits::emit(std::ostream &of, int level) const
// If it's a width we can write in hex, prefer that over binary
size_t bits = value_.size();
if (!signed_ && !has_meta_bits() && bits <= 64 && bits % 4 == 0) {
int64_t ival = bits_to_int();
int64_t ival = bits_to_int();
if ((!signed_ || ival >= 0)
&& !has_meta_bits() && bits <= 64 && bits % 4 == 0) {
of << "X\"" << hex << setfill('0') << setw(bits / 4) << ival;
}
else {

View File

@ -173,7 +173,8 @@ private:
class vhdl_const_bits : public vhdl_expr {
public:
vhdl_const_bits(const char *value, int width, bool issigned);
vhdl_const_bits(const char *value, int width, bool issigned,
bool qualify=false);
void emit(std::ostream &of, int level) const;
const std::string &get_value() const { return value_; }
vhdl_expr *to_integer();