vhdlpp: VType::get_width() uses information from Scope to determine the type width.

This commit is contained in:
Maciej Suminski 2015-03-02 14:33:26 +01:00
parent 9128eb67b9
commit e33b8b4dde
5 changed files with 34 additions and 41 deletions

View File

@ -668,11 +668,11 @@ class ExpName : public Expression {
bool try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
list<index_t*>&indices, int&data_size);
bool check_const_array_workaround_(const VTypeArray*arr, list<index_t*>&indices,
int&data_size) const;
bool check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope,
list<index_t*>&indices, int&data_size) const;
bool check_const_record_workaround_(const VTypeRecord*rec, list<index_t*>&indices,
int&data_size) const;
bool check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope,
list<index_t*>&indices, int&data_size) const;
int emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope,
const list<index_t*>&indices, int field_size);

View File

@ -771,7 +771,7 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(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<const VTypeArray*>(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<const VTypeDef*>(type)) {
@ -790,23 +790,26 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
const VTypeRecord*rec = dynamic_cast<const VTypeRecord*>(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<index_t*>&indices, int&data_size) const
ScopeBase*scope, list<index_t*>&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<index_t*>&indices, int&data_size) const
ScopeBase*scope, list<index_t*>&indices, int&data_size) const
{
int tmp_offset = 0;
const vector<VTypeRecord::element_t*>& 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<const VTypeArray*>(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;

View File

@ -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") {

View File

@ -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 << "<nil>";
}
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<element_t*>::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;

View File

@ -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;