From 9842035d899b7633772127a80ea22015302ce2b9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 16 Sep 2014 16:31:18 +0200 Subject: [PATCH 1/4] vhdlpp: Simplified the initalization for signals/variables. --- vhdlpp/vsignal.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/vhdlpp/vsignal.cc b/vhdlpp/vsignal.cc index c9d77c56e..e8bc87a35 100644 --- a/vhdlpp/vsignal.cc +++ b/vhdlpp/vsignal.cc @@ -37,21 +37,7 @@ SigVarBase::~SigVarBase() void SigVarBase::elaborate_init_expr(Entity*ent, Architecture*arc) { if(init_expr_) { - // convert the initializing string to bitstring if applicable - const ExpString*string = dynamic_cast(init_expr_); - if(string) { - const std::vector& val = string->get_value(); - char buf[val.size() + 1]; - std::copy(val.begin(), val.end(), buf); - buf[val.size()] = 0; - - ExpBitstring*bitstring = new ExpBitstring(buf); - delete init_expr_; - init_expr_ = bitstring; - } - else { init_expr_->elaborate_expr(ent, arc, peek_type()); - } } } From 54696e012753298e5acceef34fdaec24228cb9ab Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 17 Sep 2014 11:24:16 +0200 Subject: [PATCH 2/4] vhdlpp: Elaboration & emit support for aggregate initializer expressions in records. --- vhdlpp/expression.h | 3 +++ vhdlpp/expression_elaborate.cc | 45 ++++++++++++++++++++++++++++++++++ vhdlpp/expression_emit.cc | 26 ++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 2cf89b78c..df1b9bf81 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -283,7 +283,9 @@ class ExpAggregate : public Expression { private: int elaborate_expr_array_(Entity*ent, Architecture*arc, const VTypeArray*ltype); + int elaborate_expr_record_(Entity*ent, Architecture*arc, const VTypeRecord*ltype); int emit_array_(ostream&out, Entity*ent, Architecture*arc, const VTypeArray*ltype); + int emit_record_(ostream&out, Entity*ent, Architecture*arc, const VTypeRecord*ltype); private: // This is the elements as directly parsed. @@ -575,6 +577,7 @@ class ExpName : public Expression { bool symbolic_compare(const Expression*that) const; void dump(ostream&out, int indent = 0) const; const char* name() const; + inline perm_string peek_name() const { return name_; } void set_range(Expression*msb, Expression*lsb); diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index a53b7d23c..ce8dd6ab9 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -411,6 +411,9 @@ int ExpAggregate::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype if (const VTypeArray*larray = dynamic_cast(ltype)) { return elaborate_expr_array_(ent, arc, larray); } + else if(const VTypeRecord*lrecord = dynamic_cast(ltype)) { + return elaborate_expr_record_(ent, arc, lrecord); + } cerr << get_fileline() << ": internal error: I don't know how to elaborate aggregate expressions. type=" << typeid(*ltype).name() << endl; return 1; @@ -476,6 +479,48 @@ int ExpAggregate::elaborate_expr_array_(Entity*ent, Architecture*arc, const VTyp return errors; } +int ExpAggregate::elaborate_expr_record_(Entity*ent, Architecture*arc, const VTypeRecord*ltype) +{ + int errors = 0; + + aggregate_.resize(elements_.size()); + + // Translate the elements_ array to the aggregate_ array. In + // the target array, each expression is attached to a single + // choice. + for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) { + element_t*ecur = elements_[edx]; + + // it is invalid to have more than one choice in record assignment + ivl_assert(*this, ecur->count_choices() == 1); + + ecur->map_choices(&aggregate_[edx]); + } + + // Now run through the more convenient mapping and elaborate + // all the expressions that I find. + for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { + ivl_assert(*this, !aggregate_[idx].alias_flag); + + choice_t*ch = aggregate_[idx].choice; + ivl_assert(*this, !ch->others()); + + // Get the appropriate type for a field + const ExpName*field = dynamic_cast(ch->simple_expression(false)); + ivl_assert(*this, field); + + perm_string field_name = field->peek_name(); + const VTypeRecord::element_t*el = ltype->element_by_name(field_name); + + errors += aggregate_[idx].expr->elaborate_expr(ent, arc, el->peek_type()); + } + + // done with the obsolete elements_ vector. + elements_.clear(); + + return errors; +} + void ExpAggregate::element_t::map_choices(ExpAggregate::choice_element*dst) { for (size_t idx = 0 ; idx < fields_.size() ; idx += 1) { diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 63bde19e1..32778d8ea 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -95,6 +95,8 @@ int ExpAggregate::emit(ostream&out, Entity*ent, Architecture*arc) if (const VTypeArray*atype = dynamic_cast (use_type)) return emit_array_(out, ent, arc, atype); + else if (const VTypeRecord*arecord = dynamic_cast (use_type)) + return emit_record_(out, ent, arc, arecord); out << "/* " << get_fileline() << ": internal error: " << "I don't know how to elab/emit aggregate in " << typeid(use_type).name() @@ -271,6 +273,30 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V return errors; } +int ExpAggregate::emit_record_(ostream&out, Entity*ent, Architecture*arc, const VTypeRecord*ltype) +{ + int errors = 0; + + out << "{"; + + for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { + ivl_assert(*this, !aggregate_[idx].choice->others()); + ivl_assert(*this, !aggregate_[idx].choice->range_expressions()); + + Expression*val = aggregate_[idx].expr; + ivl_assert(*this, val); + + if(idx != 0) + out << ","; + + errors += val->emit(out, ent, arc); + } + + out << "}"; + + return errors; +} + int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; From 94abef195a8ab27fc2e5de1ef3cda614679cb13f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 17 Sep 2014 16:30:44 +0200 Subject: [PATCH 3/4] vhdlpp: Commented out named assignment for records. --- vhdlpp/expression_emit.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 32778d8ea..ac42aa94a 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -273,7 +273,7 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V return errors; } -int ExpAggregate::emit_record_(ostream&out, Entity*ent, Architecture*arc, const VTypeRecord*ltype) +int ExpAggregate::emit_record_(ostream&out, Entity*ent, Architecture*arc, const VTypeRecord*) { int errors = 0; @@ -283,12 +283,16 @@ int ExpAggregate::emit_record_(ostream&out, Entity*ent, Architecture*arc, const ivl_assert(*this, !aggregate_[idx].choice->others()); ivl_assert(*this, !aggregate_[idx].choice->range_expressions()); + //Expression*name = aggregate_[idx].choice->simple_expression(false); + //ivl_assert(*this, name); Expression*val = aggregate_[idx].expr; ivl_assert(*this, val); if(idx != 0) out << ","; + //errors += name->emit(out, ent, arc); + //out << ": "; errors += val->emit(out, ent, arc); } From f5dd2ac87e7f26497975a4728cec92341b145288 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 17 Sep 2014 16:32:56 +0200 Subject: [PATCH 4/4] vhdlpp: Aggregate expressions for records can be specified in any order. --- vhdlpp/expression_elaborate.cc | 20 +++++++++++--------- vhdlpp/vtype.cc | 8 ++++++-- vhdlpp/vtype.h | 3 +-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index ce8dd6ab9..1987be699 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -56,6 +56,10 @@ const VType* Expression::fit_type(Entity*ent, Architecture*arc, const VTypeArray const VType*ExpName::elaborate_adjust_type_with_range_(Entity*, Architecture*arc, const VType*type) { + // Unfold typedefs + while (const VTypeDef*tdef = dynamic_cast(type)) { + type = tdef->peek_definition(); + } if (const VTypeArray*array = dynamic_cast(type)) { if (index_ && !lsb_) { @@ -484,6 +488,8 @@ int ExpAggregate::elaborate_expr_record_(Entity*ent, Architecture*arc, const VTy int errors = 0; aggregate_.resize(elements_.size()); + choice_element tmp; + int idx; // Translate the elements_ array to the aggregate_ array. In // the target array, each expression is attached to a single @@ -494,24 +500,20 @@ int ExpAggregate::elaborate_expr_record_(Entity*ent, Architecture*arc, const VTy // it is invalid to have more than one choice in record assignment ivl_assert(*this, ecur->count_choices() == 1); - ecur->map_choices(&aggregate_[edx]); - } + ecur->map_choices(&tmp); + choice_t*ch = tmp.choice; - // Now run through the more convenient mapping and elaborate - // all the expressions that I find. - for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { - ivl_assert(*this, !aggregate_[idx].alias_flag); - - choice_t*ch = aggregate_[idx].choice; ivl_assert(*this, !ch->others()); + ivl_assert(*this, !tmp.alias_flag); // Get the appropriate type for a field const ExpName*field = dynamic_cast(ch->simple_expression(false)); ivl_assert(*this, field); perm_string field_name = field->peek_name(); - const VTypeRecord::element_t*el = ltype->element_by_name(field_name); + const VTypeRecord::element_t*el = ltype->element_by_name(field_name, &idx); + aggregate_[idx] = tmp; errors += aggregate_[idx].expr->elaborate_expr(ent, arc, el->peek_type()); } diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 208482877..a7f9233aa 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -205,13 +205,17 @@ void VTypeRecord::show(ostream&out) const write_to_stream(out); } -const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name) const +const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name, int*index) const { for (vector::const_iterator cur = elements_.begin() ; cur != elements_.end() ; ++cur) { element_t*curp = *cur; - if (curp->peek_name() == name) + if (curp->peek_name() == name) { + if (index) + *index = std::distance(elements_.begin(), cur); + return curp; + } } return 0; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 09a44231d..247af6b51 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -288,8 +288,7 @@ class VTypeRecord : public VType { int emit_def(std::ostream&out, perm_string name) const; bool can_be_packed() const { return true; } - - const element_t* element_by_name(perm_string name) const; + const element_t* element_by_name(perm_string name, int*index = NULL) const; private: std::vector elements_;