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:
parent
2107125545
commit
308688f190
|
|
@ -195,6 +195,16 @@ vhdl_expr *vhdl_expr::resize(int newwidth)
|
||||||
rtype = vhdl_type::nsigned(newwidth);
|
rtype = vhdl_type::nsigned(newwidth);
|
||||||
else if (type_->get_name() == VHDL_TYPE_UNSIGNED)
|
else if (type_->get_name() == VHDL_TYPE_UNSIGNED)
|
||||||
rtype = vhdl_type::nunsigned(newwidth);
|
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
|
else
|
||||||
return this; // Doesn't make sense to resize non-vector type
|
return this; // Doesn't make sense to resize non-vector type
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,20 +348,16 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
|
||||||
static int tmp_count = 0;
|
static int tmp_count = 0;
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << "Verilog_Assign_Tmp_" << tmp_count++;
|
ss << "Verilog_Assign_Tmp_" << tmp_count++;
|
||||||
string tmpname = ss.str();
|
|
||||||
|
|
||||||
proc->get_scope()->add_decl
|
vhdl_decl* tmp_decl = new vhdl_var_decl(ss.str(), rhs->get_type());
|
||||||
(new vhdl_var_decl(tmpname.c_str(), new vhdl_type(*rhs->get_type())));
|
proc->get_scope()->add_decl(tmp_decl);
|
||||||
|
|
||||||
vhdl_var_ref *tmp_ref =
|
container->add_stmt(new vhdl_assign_stmt(tmp_decl->make_ref(), rhs));
|
||||||
new vhdl_var_ref(tmpname.c_str(), new vhdl_type(*rhs->get_type()));
|
|
||||||
container->add_stmt(new vhdl_assign_stmt(tmp_ref, rhs));
|
|
||||||
|
|
||||||
list<vhdl_var_ref*>::iterator it;
|
list<vhdl_var_ref*>::iterator it;
|
||||||
int width_so_far = 0;
|
int width_so_far = 0;
|
||||||
for (it = lvals.begin(); it != lvals.end(); ++it) {
|
for (it = lvals.begin(); it != lvals.end(); ++it) {
|
||||||
vhdl_var_ref *tmp_rhs =
|
vhdl_var_ref *tmp_rhs = tmp_decl->make_ref();
|
||||||
new vhdl_var_ref(tmpname.c_str(), new vhdl_type(*rhs->get_type()));
|
|
||||||
|
|
||||||
int lval_width = (*it)->get_type()->get_width();
|
int lval_width = (*it)->get_type()->get_width();
|
||||||
vhdl_expr *slice_base = new vhdl_const_int(width_so_far);
|
vhdl_expr *slice_base = new vhdl_const_int(width_so_far);
|
||||||
|
|
|
||||||
|
|
@ -501,13 +501,10 @@ void vhdl_var_ref::set_slice(vhdl_expr *s, int w)
|
||||||
|
|
||||||
vhdl_type_name_t tname = type_->get_name();
|
vhdl_type_name_t tname = type_->get_name();
|
||||||
if (tname == VHDL_TYPE_ARRAY) {
|
if (tname == VHDL_TYPE_ARRAY) {
|
||||||
type_ = new vhdl_type(*type_->get_base());
|
type_ = type_->get_base();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED);
|
assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED);
|
||||||
|
|
||||||
if (type_)
|
|
||||||
delete type_;
|
|
||||||
|
|
||||||
if (w > 0)
|
if (w > 0)
|
||||||
type_ = new vhdl_type(tname, w);
|
type_ = new vhdl_type(tname, w);
|
||||||
|
|
@ -578,10 +575,11 @@ void vhdl_assign_stmt::emit(std::ostream &of, int level) const
|
||||||
of << ";";
|
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_expr(issigned ? vhdl_type::nsigned(width)
|
||||||
: vhdl_type::nunsigned(width), true),
|
: vhdl_type::nunsigned(width), true),
|
||||||
qualified_(false),
|
qualified_(qualify),
|
||||||
signed_(issigned)
|
signed_(issigned)
|
||||||
{
|
{
|
||||||
// Can't rely on value being NULL-terminated
|
// 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
|
// If it's a width we can write in hex, prefer that over binary
|
||||||
size_t bits = value_.size();
|
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;
|
of << "X\"" << hex << setfill('0') << setw(bits / 4) << ival;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,8 @@ private:
|
||||||
|
|
||||||
class vhdl_const_bits : public vhdl_expr {
|
class vhdl_const_bits : public vhdl_expr {
|
||||||
public:
|
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;
|
void emit(std::ostream &of, int level) const;
|
||||||
const std::string &get_value() const { return value_; }
|
const std::string &get_value() const { return value_; }
|
||||||
vhdl_expr *to_integer();
|
vhdl_expr *to_integer();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue