diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index f2e312f8a..63bde19e1 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -767,7 +767,7 @@ int ExpString::emit_as_array_(ostream& out, Entity*, Architecture*, const VTypeA int errors = 0; assert(arr->dimensions() == 1); - const VTypePrimitive*etype = dynamic_cast (arr->element_type()); + const VTypePrimitive*etype = dynamic_cast (arr->basic_type()); assert(etype); // Detect the special case that this is an array of diff --git a/vhdlpp/expression_stream.cc b/vhdlpp/expression_stream.cc index 901bfab9e..a37fea2ed 100644 --- a/vhdlpp/expression_stream.cc +++ b/vhdlpp/expression_stream.cc @@ -29,6 +29,9 @@ void ExpAggregate::write_to_stream(ostream&fd) fd << "("; for (vector::const_iterator cur = elements_.begin() ; cur != elements_.end() ; ++cur) { + if(cur != elements_.begin()) + fd << ", "; + (*cur)->write_to_stream(fd); } fd << ")"; @@ -41,7 +44,8 @@ void ExpAggregate::element_t::write_to_stream(ostream&fd) const (*cur)->write_to_stream(fd); } - fd << "=>"; + if(!fields_.empty()) + fd << "=>"; val_->write_to_stream(fd); } @@ -112,9 +116,14 @@ void ExpAttribute::write_to_stream(ostream&) ivl_assert(*this, !"Not supported"); } -void ExpBitstring::write_to_stream(ostream&) +void ExpBitstring::write_to_stream(ostream&fd) { - ivl_assert(*this, !"Not supported"); + fd << "\""; + for(vector::const_iterator it = value_.begin(); + it != value_.end(); ++it) { + fd << *it; + } + fd << "\""; } void ExpCharacter::write_to_stream(ostream&fd) @@ -198,9 +207,14 @@ void ExpRelation::write_to_stream(ostream&) ivl_assert(*this, !"Not supported"); } -void ExpString::write_to_stream(ostream&) +void ExpString::write_to_stream(ostream&fd) { - ivl_assert(*this, !"Not supported"); + fd << "\""; + for(vector::const_iterator it = value_.begin(); + it != value_.end(); ++it) { + fd << *it; + } + fd << "\""; } void ExpUAbs::write_to_stream(ostream&fd) diff --git a/vhdlpp/package.cc b/vhdlpp/package.cc index d3d4a8b06..68c8acee1 100644 --- a/vhdlpp/package.cc +++ b/vhdlpp/package.cc @@ -66,21 +66,6 @@ void Package::write_to_stream(ostream&fd) const fd << "type " << cur->first << ";" << endl; } - for (map::const_iterator cur = cur_constants_.begin() - ; cur != cur_constants_.end() ; ++ cur) { - if (cur->second==0 || cur->second->typ==0) { - fd << "-- const " << cur->first - << " has errors." << endl; - continue; - } - - fd << "constant " << cur->first << ": "; - cur->second->typ->write_to_stream(fd); - fd << " := "; - cur->second->val->write_to_stream(fd); - fd << ";" << endl; - } - for (map::const_iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { @@ -108,6 +93,21 @@ void Package::write_to_stream(ostream&fd) const fd << ";" << endl; } + for (map::const_iterator cur = cur_constants_.begin() + ; cur != cur_constants_.end() ; ++ cur) { + if (cur->second==0 || cur->second->typ==0) { + fd << "-- const " << cur->first + << " has errors." << endl; + continue; + } + + fd << "constant " << cur->first << ": "; + cur->second->typ->write_to_stream(fd); + fd << " := "; + cur->second->val->write_to_stream(fd); + fd << ";" << endl; + } + for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++cur) { cur->second->write_to_stream(fd); diff --git a/vhdlpp/package_emit.cc b/vhdlpp/package_emit.cc index 2cc3b91fb..db302cbad 100644 --- a/vhdlpp/package_emit.cc +++ b/vhdlpp/package_emit.cc @@ -52,18 +52,18 @@ int Package::emit_package(ostream&fd) const fd << " ;" << endl; } - for (map::const_iterator cur = use_constants_.begin() - ; cur != use_constants_.end() ; ++cur) { - fd << "localparam \\" << cur->first << " = "; - errors += cur->second->val->emit_package(fd); - fd << ";" << endl; - } - for (map::const_iterator cur = cur_constants_.begin() - ; cur != cur_constants_.end() ; ++cur) { - fd << "localparam " << cur->first << " = "; - errors += cur->second->val->emit_package(fd); - fd << ";" << endl; - } + //for (map::const_iterator cur = use_constants_.begin() + //; cur != use_constants_.end() ; ++cur) { + //fd << "localparam \\" << cur->first << " = "; + //errors += cur->second->val->emit_package(fd); + //fd << ";" << endl; + //} + //for (map::const_iterator cur = cur_constants_.begin() + //; cur != cur_constants_.end() ; ++cur) { + //fd << "localparam " << cur->first << " = "; + //errors += cur->second->val->emit_package(fd); + //fd << ";" << endl; + //} for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++ cur) { diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 0372d4925..906395f67 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -685,7 +685,7 @@ composite_type_definition /* unbounded_array_definition IEEE 1076-2008 P5.3.2.1 */ | K_array '(' index_subtype_definition_list ')' K_of subtype_indication { std::list r; - r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type + r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type VTypeArray*tmp = new VTypeArray($6, &r); $$ = tmp; } diff --git a/vhdlpp/parse_misc.cc b/vhdlpp/parse_misc.cc index 3956b4a1a..734443d3e 100644 --- a/vhdlpp/parse_misc.cc +++ b/vhdlpp/parse_misc.cc @@ -70,7 +70,7 @@ void bind_architecture_to_entity(const char*ename, Architecture*arch) static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, ScopeBase* /* scope */, Expression*array_left, - bool /* downto*/ , + bool downto, Expression*array_right) { const VType*base_type = parse_type_by_name(lex_strings.make(base_name)); @@ -82,7 +82,8 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n assert(array_left==0 || array_right!=0); - // unfold typedef, if it is the case + // unfold typedef, there might be VTypeArray inside + const VType*origin_type = base_type; const VTypeDef*type_def = dynamic_cast (base_type); if (type_def) { base_type = type_def->peek_definition(); @@ -97,9 +98,13 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n // For now, I only know how to handle 1 dimension assert(base_array->dimensions() == 1); - range[0] = VTypeArray::range_t(array_left, array_right); + range[0] = VTypeArray::range_t(array_left, array_right, downto); - VTypeArray*subtype = new VTypeArray(base_array->element_type(), range, base_array->signed_vector()); + // use typedef as the element type if possible + const VType*element = type_def ? origin_type : base_array->element_type(); + + VTypeArray*subtype = new VTypeArray(element, range, + base_array->signed_vector()); return subtype; } diff --git a/vhdlpp/vsignal.cc b/vhdlpp/vsignal.cc index d03dae459..c9d77c56e 100644 --- a/vhdlpp/vsignal.cc +++ b/vhdlpp/vsignal.cc @@ -50,10 +50,7 @@ void SigVarBase::elaborate_init_expr(Entity*ent, Architecture*arc) init_expr_ = bitstring; } else { - ExpAggregate*aggr = dynamic_cast(init_expr_); - if(aggr) { - aggr->elaborate_expr(ent, arc, peek_type()); - } + init_expr_->elaborate_expr(ent, arc, peek_type()); } } } diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 7c0875f44..208482877 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -88,7 +88,8 @@ VTypeArray::VTypeArray(const VType*element, std::list*r, bool sv) r->pop_front(); Expression*msb = curp->msb(); Expression*lsb = curp->lsb(); - ranges_[idx] = range_t(msb, lsb); + bool dir = curp->is_downto(); + ranges_[idx] = range_t(msb, lsb, dir); } } @@ -97,14 +98,28 @@ VTypeArray::~VTypeArray() { } -size_t VTypeArray::dimensions() const +const VType* VTypeArray::basic_type(bool typedef_allowed) const { - return ranges_.size(); -} + const VType*t = etype_; + const VTypeDef*tdef = NULL; + bool progress = false; -const VType* VTypeArray::element_type() const -{ - return etype_; + do { + progress = false; + + if((tdef = dynamic_cast(t))) { + t = tdef->peek_definition(); + } + + if(const VTypeArray*arr = dynamic_cast(t)) { + t = arr->element_type(); + progress = true; + } else if(tdef) { // return the typedef if it does not define an array + t = typedef_allowed ? tdef : tdef->peek_definition(); + } + } while(progress); + + return t; } void VTypeArray::show(ostream&out) const diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 0fce73145..09a44231d 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -173,17 +173,19 @@ class VTypeArray : public VType { public: class range_t { public: - range_t() : msb_(0), lsb_(0) { } - range_t(Expression*m, Expression*l) : msb_(m), lsb_(l) { } + range_t(Expression*m = NULL, Expression*l = NULL, bool dir = true) : + msb_(m), lsb_(l), direction_(dir) { } - bool is_box() const { return msb_==0 && lsb_==0; } + inline bool is_box() const { return msb_==0 && lsb_==0; } + inline bool is_downto() const { return direction_; } - Expression* msb() const { return msb_; } - Expression* lsb() const { return lsb_; } + inline Expression* msb() const { return msb_; } + inline Expression* lsb() const { return lsb_; } private: Expression* msb_; Expression* lsb_; + bool direction_; }; public: @@ -195,13 +197,20 @@ class VTypeArray : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - size_t dimensions() const; + inline size_t dimensions() const { return ranges_.size(); }; const range_t&dimension(size_t idx) const { return ranges_[idx]; } - bool signed_vector() const { return signed_flag_; } + inline bool signed_vector() const { return signed_flag_; } - const VType* element_type() const; + // returns the type of element held in the array + inline const VType* element_type() const { return etype_; } + + // returns the basic type of element held in the array + // (unfolds typedefs and multidimensional arrays) + // typedef_allowed decides if VTypeDef can be returned or should + // it be unfolded + const VType* basic_type(bool typedef_allowed = true) const; int emit_def(std::ostream&out, perm_string name) const; int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; @@ -210,6 +219,7 @@ class VTypeArray : public VType { bool can_be_packed() const { return etype_->can_be_packed(); } private: + void write_range_to_stream_(std::ostream&fd) const; const VType*etype_; std::vector ranges_; @@ -240,6 +250,7 @@ class VTypeEnum : public VType { VTypeEnum(const std::list*names); ~VTypeEnum(); + void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; int emit_def(std::ostream&out, perm_string name) const; diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index a723dbda5..9dc17b5f2 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -60,12 +60,8 @@ int VTypeArray::emit_def(ostream&out, perm_string name) const { int errors = 0; - const VTypeArray*cur = this; - while (const VTypeArray*sub = dynamic_cast (cur->etype_)) { - cur = sub; - } + const VType*raw_base = basic_type(); - const VType*raw_base = cur->etype_; const VTypePrimitive*base = dynamic_cast (raw_base); if (base) { diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index 987582dbc..1392a6c50 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -42,45 +42,52 @@ void VTypeArray::write_to_stream(ostream&fd) const if (etype_ == &primitive_STDLOGIC) { fd << "std_logic_vector"; if (! ranges_.empty() && ! ranges_[0].is_box()) { - assert(ranges_.size() < 2); - fd << " ("; - if (ranges_[0].msb()) - ranges_[0].msb()->write_to_stream(fd); - else - fd << "<>"; - fd << " downto "; - if (ranges_[0].lsb()) - ranges_[0].lsb()->write_to_stream(fd); - else - fd << "<>"; - fd << ") "; + write_range_to_stream_(fd); } return; } - fd << "array "; + bool typedefed = false; + if(const VTypeDef*tdef = dynamic_cast(etype_)) { + tdef->write_to_stream(fd); + typedefed = true; + } else { + fd << "array "; + } + if (! ranges_.empty()) { assert(ranges_.size() < 2); if (ranges_[0].is_box()) { fd << "(INTEGER range <>) "; } else { - assert(ranges_[0].msb() && ranges_[0].lsb()); - fd << "("; - if (ranges_[0].msb()) - ranges_[0].msb()->write_to_stream(fd); - else - fd << "<>"; - fd << " downto "; - if (ranges_[0].lsb()) - ranges_[0].lsb()->write_to_stream(fd); - else - fd << "<>"; - fd << ") "; + write_range_to_stream_(fd); } } - fd << "of "; - etype_->write_to_stream(fd); + if(!typedefed) { + fd << "of "; + etype_->write_to_stream(fd); + } +} + +void VTypeArray::write_range_to_stream_(std::ostream&fd) const +{ + assert(ranges_.size() < 2); + assert(ranges_[0].msb() && ranges_[0].lsb()); + + fd << "("; + if (ranges_[0].msb()) + ranges_[0].msb()->write_to_stream(fd); + else + fd << "<>"; + + fd << (ranges_[0].is_downto() ? " downto " : " to "); + + if (ranges_[0].lsb()) + ranges_[0].lsb()->write_to_stream(fd); + else + fd << "<>"; + fd << ") "; } void VTypeDef::write_type_to_stream(ostream&fd) const @@ -148,3 +155,18 @@ void VTypeRecord::element_t::write_to_stream(ostream&fd) const fd << name_ << ": "; type_->write_to_stream(fd); } + +void VTypeEnum::write_to_stream(std::ostream&fd) const +{ + fd << "("; + for (vector::const_iterator it = names_.begin(); + it != names_.end(); ++it) { + if(it != names_.begin()) + fd << ","; + + fd << *it; + + } + fd << ")"; +} +