From e33b8b4ddeeec00cf64dcb0f9ddff12cc68d9208 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 2 Mar 2015 14:33:26 +0100 Subject: [PATCH] vhdlpp: VType::get_width() uses information from Scope to determine the type width. --- vhdlpp/expression.h | 8 ++++---- vhdlpp/expression_emit.cc | 21 ++++++++++++--------- vhdlpp/expression_evaluate.cc | 19 +++++-------------- vhdlpp/vtype.cc | 15 +++++++-------- vhdlpp/vtype.h | 12 ++++++------ 5 files changed, 34 insertions(+), 41 deletions(-) diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 831f41a60..dd1ae6783 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -668,11 +668,11 @@ class ExpName : public Expression { bool try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope, list&indices, int&data_size); - bool check_const_array_workaround_(const VTypeArray*arr, list&indices, - int&data_size) const; + bool check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope, + list&indices, int&data_size) const; - bool check_const_record_workaround_(const VTypeRecord*rec, list&indices, - int&data_size) const; + bool check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope, + list&indices, int&data_size) const; int emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope, const list&indices, int field_size); diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 61f241490..7dee9ee47 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -771,7 +771,7 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*arr = dynamic_cast(type); assert(arr); - wrkand_required |= check_const_array_workaround_(arr, indices, data_size); + wrkand_required |= check_const_array_workaround_(arr, scope, indices, data_size); } if(prefix_.get() && scope->find_constant(prefix_->name_, type, exp)) { @@ -780,7 +780,7 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*arr = dynamic_cast(type); assert(arr); type = arr->element_type(); - data_size = type->get_width(); + data_size = type->get_width(scope); } while(const VTypeDef*type_def = dynamic_cast(type)) { @@ -790,23 +790,26 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeRecord*rec = dynamic_cast(type); assert(rec); - wrkand_required |= check_const_record_workaround_(rec, indices, data_size); + wrkand_required |= check_const_record_workaround_(rec, scope, indices, data_size); } return wrkand_required; } bool ExpName::check_const_array_workaround_(const VTypeArray*arr, - list&indices, int&data_size) const + ScopeBase*scope, list&indices, int&data_size) const { const VType*element = arr->element_type(); - data_size = element->get_width(); + data_size = element->get_width(scope); + if(data_size < 0) + return false; indices.push_back(new index_t(index_, new ExpInteger(data_size))); + return true; } bool ExpName::check_const_record_workaround_(const VTypeRecord*rec, - list&indices, int&data_size) const + ScopeBase*scope, list&indices, int&data_size) const { int tmp_offset = 0; const vector& elements = rec->get_elements(); @@ -818,7 +821,7 @@ bool ExpName::check_const_record_workaround_(const VTypeRecord*rec, if(el->peek_name() == name_) { const VType*type = el->peek_type(); - int tmp_field = type->get_width(); + int tmp_field = type->get_width(scope); if(tmp_field < 0) return false; @@ -828,13 +831,13 @@ bool ExpName::check_const_record_workaround_(const VTypeRecord*rec, if(index_) { const VTypeArray*arr = dynamic_cast(type); assert(arr); - return check_const_array_workaround_(arr, indices, data_size); + return check_const_array_workaround_(arr, scope, indices, data_size); } return true; } - int w = el->peek_type()->get_width(); + int w = el->peek_type()->get_width(scope); if(w < 0) return false; diff --git a/vhdlpp/expression_evaluate.cc b/vhdlpp/expression_evaluate.cc index b81b6a30d..2d498c020 100644 --- a/vhdlpp/expression_evaluate.cc +++ b/vhdlpp/expression_evaluate.cc @@ -33,7 +33,6 @@ bool Expression::evaluate(Entity*, ScopeBase*scope, int64_t&val) const return evaluate(scope, val); } - bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const { int64_t val1, val2; @@ -113,20 +112,12 @@ bool ExpAttribute::evaluate(ScopeBase*scope, int64_t&val) const } if(name_ == "length") { - int64_t size = 1; - for (size_t idx = 0 ; idx < arr->dimensions() ; idx += 1) { - const VTypeArray::range_t&dim = arr->dimension(idx); - int64_t msb_val, lsb_val; + int64_t size = arr->get_width(scope); - if(dim.is_box()) - return false; - - dim.msb()->evaluate(scope, msb_val); - dim.lsb()->evaluate(scope, lsb_val); - - size *= 1 + labs(msb_val - lsb_val); - } - val = size; + if(size > 0) + val = size; + else + return false; } else if(name_ == "left") { arr->dimension(0).msb()->evaluate(scope, val); } else if(name_ == "right") { diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index f91d994b2..7a6581148 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -79,13 +79,12 @@ void VTypePrimitive::show(ostream&out) const } } -int VTypePrimitive::get_width() const +int VTypePrimitive::get_width(ScopeBase*) const { switch(type_) { case BOOLEAN: case BIT: case STDLOGIC: - case REAL: return 1; case INTEGER: @@ -196,7 +195,7 @@ void VTypeArray::show(ostream&out) const out << ""; } -int VTypeArray::get_width() const +int VTypeArray::get_width(ScopeBase*scope) const { int64_t size = 1; @@ -208,16 +207,16 @@ int VTypeArray::get_width() const if(dim.is_box()) return -1; - if(!dim.msb()->evaluate(NULL, msb_val)) + if(!dim.msb()->evaluate(scope, msb_val)) return -1; - if(!dim.lsb()->evaluate(NULL, lsb_val)) + if(!dim.lsb()->evaluate(scope, lsb_val)) return -1; size *= 1 + labs(msb_val - lsb_val); } - return element_type()->get_width() * size; + return element_type()->get_width(scope) * size; } bool VTypeArray::is_unbounded() const { @@ -325,13 +324,13 @@ void VTypeRecord::show(ostream&out) const write_to_stream(out); } -int VTypeRecord::get_width() const +int VTypeRecord::get_width(ScopeBase*scope) const { int width = 0; for(vector::const_iterator it = elements_.begin(); it != elements_.end(); ++it) { - int w = (*it)->peek_type()->get_width(); + int w = (*it)->peek_type()->get_width(scope); if(w < 0) return -1; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 1819ea31c..47683b637 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -103,7 +103,7 @@ class VType { // Returns the type width in bits or negative number if it is impossible // to evaluate. - virtual int get_width() const { return -1; } + virtual int get_width(ScopeBase*) const { return -1; } private: friend struct decl_t; @@ -166,7 +166,7 @@ class VTypePrimitive : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - int get_width() const; + int get_width(ScopeBase*scope) const; type_t type() const { return type_; } @@ -227,7 +227,7 @@ class VTypeArray : public VType { void write_to_stream(std::ostream&fd) const; void write_type_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - int get_width() const; + int get_width(ScopeBase*scope) const; inline size_t dimensions() const { return ranges_.size(); }; const range_t&dimension(size_t idx) const @@ -301,7 +301,7 @@ class VTypeEnum : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - int get_width() const { return 32; } + int get_width(ScopeBase*) const { return 32; } int emit_def(std::ostream&out, perm_string name) const; @@ -341,7 +341,7 @@ class VTypeRecord : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - int get_width() const; + int get_width(ScopeBase*scope) const; int emit_def(std::ostream&out, perm_string name) const; bool can_be_packed() const { return true; } @@ -373,7 +373,7 @@ class VTypeDef : public VType { void write_to_stream(std::ostream&fd) const; void write_type_to_stream(std::ostream&fd) const; - int get_width() const { return type_->get_width(); } + int get_width(ScopeBase*scope) const { return type_->get_width(scope); } int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; int emit_def(std::ostream&out, perm_string name) const;