From a33bbecc98b91941f9fdb38bf9482f12f8c25592 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 24 Apr 2015 17:00:21 +0200 Subject: [PATCH 1/9] vhdlpp: VTypeRange::write_to_stream uses to/downto depending on the range boundaries. --- vhdlpp/vtype.cc | 6 ++---- vhdlpp/vtype.h | 6 +++--- vhdlpp/vtype_stream.cc | 6 ++++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 17001977f..ee43570e7 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -273,11 +273,9 @@ void VTypeArray::evaluate_ranges(ScopeBase*scope) { } } -VTypeRange::VTypeRange(const VType*base, int64_t max_val, int64_t min_val) -: base_(base) +VTypeRange::VTypeRange(const VType*base, int64_t end_val, int64_t start_val) +: base_(base), end_(end_val), start_(start_val) { - max_ = max_val; - min_ = min_val; } VTypeRange::~VTypeRange() diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 5b00bc885..62b528240 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -275,10 +275,10 @@ class VTypeArray : public VType { class VTypeRange : public VType { public: - VTypeRange(const VType*base, int64_t max_val, int64_t min_val); + VTypeRange(const VType*base, int64_t end, int64_t start); ~VTypeRange(); - VType*clone() const { return new VTypeRange(base_->clone(), max_, min_); } + VType*clone() const { return new VTypeRange(base_->clone(), start_, end_); } // Get the type that is limited by the range. inline const VType* base_type() const { return base_; } @@ -289,7 +289,7 @@ class VTypeRange : public VType { private: const VType*base_; - int64_t max_, min_; + int64_t end_, start_; }; class VTypeEnum : public VType { diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index f625f190a..0ded586de 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -171,14 +171,16 @@ void VTypeRange::write_to_stream(ostream&fd) const // Detect some special cases that can be written as ieee or // standard types. if (const VTypePrimitive*tmp = dynamic_cast (base_)) { - if (min_==0 && max_==INT64_MAX && tmp->type()==VTypePrimitive::INTEGER) { + if (start_==0 && end_==INT64_MAX && tmp->type()==VTypePrimitive::INTEGER) { fd << "natural"; return; } } base_->write_to_stream(fd); - fd << " range " << min_ << " to " << max_; + fd << " range " << start_; + fd << (start_ < end_ ? " to " : " downto "); + fd << end_; } void VTypeRecord::write_to_stream(ostream&fd) const From ddc204391ee0829bd6b182cec193488b567a454b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 24 Apr 2015 17:01:11 +0200 Subject: [PATCH 2/9] vhdlpp: Add 'sub' prefix for subtypes while emitting packages. --- vhdlpp/package.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vhdlpp/package.cc b/vhdlpp/package.cc index df8f60c41..167c8a279 100644 --- a/vhdlpp/package.cc +++ b/vhdlpp/package.cc @@ -74,6 +74,9 @@ void Package::write_to_stream(ostream&fd) const if (is_global_type(cur->first)) continue; + if(!dynamic_cast(cur->second)) + fd << "sub"; + fd << "type " << cur->first << " is "; cur->second->write_type_to_stream(fd); fd << "; -- imported" << endl; @@ -85,6 +88,9 @@ void Package::write_to_stream(ostream&fd) const if (is_global_type(cur->first)) continue; + if(!dynamic_cast(cur->second)) + fd << "sub"; + fd << "type " << cur->first << " is "; cur->second->write_type_to_stream(fd); fd << ";" << endl; From 515ab40ffe0b70a3d3d30df259e479e8675df5e0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 24 Apr 2015 17:15:51 +0200 Subject: [PATCH 3/9] vhdlpp: Special handling for string type emission. --- vhdlpp/vtype_stream.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index 0ded586de..2cf159db8 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -41,14 +41,16 @@ void VTypeArray::write_to_stream(ostream&fd) const // Special cases: std_logic_vector & string if (etype_ == &primitive_STDLOGIC) { fd << "std_logic_vector"; - if (! ranges_.empty() && ! ranges_[0].is_box()) { + if (!ranges_.empty() && !ranges_[0].is_box()) { + write_range_to_stream_(fd); + } + return; + } else if (etype_ == &primitive_CHARACTER) { + fd << "string"; + if (!ranges_.empty() && !ranges_[0].is_box()) { write_range_to_stream_(fd); } return; - } else if (etype_ == &primitive_CHARACTER && - ranges_.size() == 1 && ranges_[0].is_box()) { - fd << "string"; - return; } bool typedefed = false; @@ -104,6 +106,13 @@ void VTypeArray::write_type_to_stream(ostream&fd) const } return; } + else if (etype_ == &primitive_CHARACTER) { + fd << "string"; + if (! ranges_.empty() && ! ranges_[0].is_box()) { + write_range_to_stream_(fd); + } + return; + } fd << "array "; From 25458b8cc20dac76f7ba674e839ec3b11bbeeaa9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 8 May 2015 15:55:26 +0200 Subject: [PATCH 4/9] vhdlpp: inout direction for ports. --- vhdlpp/entity.h | 2 +- vhdlpp/entity_emit.cc | 8 ++++++-- vhdlpp/entity_stream.cc | 3 +++ vhdlpp/parse.y | 1 + vhdlpp/subprogram_emit.cc | 3 +++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/vhdlpp/entity.h b/vhdlpp/entity.h index b93d6a369..8c41e52ab 100644 --- a/vhdlpp/entity.h +++ b/vhdlpp/entity.h @@ -27,7 +27,7 @@ # include "StringHeap.h" # include "LineInfo.h" -typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t; +typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT, PORT_INOUT } port_mode_t; class Architecture; class Expression; diff --git a/vhdlpp/entity_emit.cc b/vhdlpp/entity_emit.cc index 268b36f7d..fd2077fdc 100644 --- a/vhdlpp/entity_emit.cc +++ b/vhdlpp/entity_emit.cc @@ -74,17 +74,21 @@ int Entity::emit(ostream&out) switch (port->mode) { case PORT_NONE: // Should not happen + cerr << get_fileline() << ": error: Undefined port direction." << endl; out << "NO_PORT " << port->name; break; case PORT_IN: out << "input "; - errors += decl.emit(out, port->name); break; case PORT_OUT: out << "output "; - errors += decl.emit(out, port->name); + break; + case PORT_INOUT: + out << "inout "; break; } + + errors += decl.emit(out, port->name); } cout << ")"; } diff --git a/vhdlpp/entity_stream.cc b/vhdlpp/entity_stream.cc index cd1e67334..dfde97c74 100644 --- a/vhdlpp/entity_stream.cc +++ b/vhdlpp/entity_stream.cc @@ -69,6 +69,9 @@ void ComponentBase::write_to_stream(ostream&fd) const case PORT_OUT: fd << "out "; break; + case PORT_INOUT: + fd << "inout "; + break; } item->type->write_to_stream(fd); diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 9e60453b1..0927022be 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -1584,6 +1584,7 @@ loop_statement mode : K_in { $$ = PORT_IN; } | K_out { $$ = PORT_OUT; } + | K_inout { $$ = PORT_INOUT; } ; mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ; diff --git a/vhdlpp/subprogram_emit.cc b/vhdlpp/subprogram_emit.cc index 5cb43e3a6..c2ae47cd8 100644 --- a/vhdlpp/subprogram_emit.cc +++ b/vhdlpp/subprogram_emit.cc @@ -50,6 +50,9 @@ int Subprogram::emit_package(ostream&fd) const case PORT_OUT: fd << "output "; break; + case PORT_INOUT: + fd << "inout "; + break; case PORT_NONE: fd << "inout /* PORT_NONE? */ "; break; From 9231ad51a41f3f81f2b4189c350410aec7ffe97a Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 16 May 2015 00:40:26 +0200 Subject: [PATCH 5/9] vhdlpp: generics without a default value are set to 1'bx. --- vhdlpp/entity_emit.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vhdlpp/entity_emit.cc b/vhdlpp/entity_emit.cc index fd2077fdc..62acac193 100644 --- a/vhdlpp/entity_emit.cc +++ b/vhdlpp/entity_emit.cc @@ -50,11 +50,14 @@ int Entity::emit(ostream&out) const InterfacePort*curp = *cur; if (cur != parms_.begin()) out << ", "; - out << "parameter \\" << curp->name << " "; + out << "parameter \\" << curp->name << " = "; if(curp->expr) { - out << "= "; errors += curp->expr->emit(out, this, 0); - } + } else { + // Unlike VHDL, Verilog module parameter port list + // elements are always assignments. Fill in the blank. + out << "1'bx"; + } } out << ") "; } From bb2e6782fa19a2f2dfba656b6b1766100bc7b1e3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 18 May 2015 17:32:09 +0200 Subject: [PATCH 6/9] Copy constructor for LineInfo. --- libmisc/LineInfo.cc | 5 +++++ libmisc/LineInfo.h | 1 + vhdlpp/expression.cc | 1 + 3 files changed, 7 insertions(+) diff --git a/libmisc/LineInfo.cc b/libmisc/LineInfo.cc index 753b24970..c0daaff14 100644 --- a/libmisc/LineInfo.cc +++ b/libmisc/LineInfo.cc @@ -27,6 +27,11 @@ LineInfo::LineInfo() { } +LineInfo::LineInfo(const LineInfo&that) : + file_(that.file_), lineno_(that.lineno_) +{ +} + LineInfo::~LineInfo() { } diff --git a/libmisc/LineInfo.h b/libmisc/LineInfo.h index b212bc959..4d4c6beda 100644 --- a/libmisc/LineInfo.h +++ b/libmisc/LineInfo.h @@ -36,6 +36,7 @@ using namespace std; class LineInfo { public: LineInfo(); + LineInfo(const LineInfo&that); virtual ~LineInfo(); // Get a fully formatted file/lineno diff --git a/vhdlpp/expression.cc b/vhdlpp/expression.cc index 77d80a4d6..949d568ae 100644 --- a/vhdlpp/expression.cc +++ b/vhdlpp/expression.cc @@ -311,6 +311,7 @@ ExpConditional::else_t::else_t(Expression*cond, std::list*tru) } ExpConditional::else_t::else_t(const else_t&other) +: LineInfo(other) { cond_ = other.cond_->clone(); for(std::list::const_iterator it = other.true_clause_.begin(); From bc83d2914a4b1ca58d665d8840bf204a1362074d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 20 May 2015 12:02:22 +0200 Subject: [PATCH 7/9] vhdlpp: Corrected an error message for attributes. --- vhdlpp/expression_evaluate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vhdlpp/expression_evaluate.cc b/vhdlpp/expression_evaluate.cc index b67cbd5da..54bf704b4 100644 --- a/vhdlpp/expression_evaluate.cc +++ b/vhdlpp/expression_evaluate.cc @@ -106,7 +106,7 @@ bool ExpAttribute::evaluate(ScopeBase*scope, int64_t&val) const const VTypeArray*arr = dynamic_cast(base_type); if (arr == 0) { cerr << endl << get_fileline() << ": error: " - << "Cannot apply the 'length attribute to non-array objects" + << "Cannot apply the '" << name_ << " attribute to non-array objects" << endl; ivl_assert(*this, false); return false; From 7aab315ce533cee5e9de781738ddeefc3ac3fb64 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 20 May 2015 17:30:07 +0200 Subject: [PATCH 8/9] vhdlpp: Allow assigning values to inout ports. --- vhdlpp/expression_elaborate.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index 5f54fc66a..30985fa53 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -112,7 +112,7 @@ int ExpName::elaborate_lval_(Entity*ent, ScopeBase*scope, bool is_sequ, ExpName* const VType*found_type = 0; if (const InterfacePort*cur = ent->find_port(name_)) { - if (cur->mode != PORT_OUT) { + if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) { cerr << get_fileline() << ": error: Assignment to " "input port " << name_ << "." << endl; return errors + 1; @@ -216,7 +216,7 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ) const VType*found_type = 0; if (const InterfacePort*cur = ent->find_port(name_)) { - if (cur->mode != PORT_OUT) { + if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) { cerr << get_fileline() << ": error: Assignment to " "input port " << name_ << "." << endl; return errors += 1; From 51d7237d5289d380d816a30df0340635aec16339 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 21 May 2015 01:25:34 +0200 Subject: [PATCH 9/9] vhdlpp: Display error message for undefined generic values. --- vhdlpp/architec_emit.cc | 16 ++++++++++++++++ vhdlpp/entity.h | 1 + 2 files changed, 17 insertions(+) diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index cf18cdd84..d0d3fb1ff 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -150,6 +150,22 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc) arc->set_cur_component(this); + if(ComponentBase*comp = arc->find_component(cname_)) { + const std::vector& generics = comp->get_generics(); + + if(generics.size() != generic_map_.size()) + // Display an error for generics that do not have neither + // default nor component specific value defined + for(vector::const_iterator it = generics.begin(); + it != generics.end(); ++it) { + if(!(*it)->expr && generic_map_.count((*it)->name) == 0) { + cerr << get_fileline() << ": generic " << (*it)->name << + "value is not defined" << endl; + ++errors; + } + } + } + out << cname_; if (! generic_map_.empty()) { out << " #("; diff --git a/vhdlpp/entity.h b/vhdlpp/entity.h index 8c41e52ab..5e183d1a5 100644 --- a/vhdlpp/entity.h +++ b/vhdlpp/entity.h @@ -63,6 +63,7 @@ class ComponentBase : public LineInfo { const InterfacePort* find_port(perm_string by_name) const; const InterfacePort* find_generic(perm_string by_name) const; + const std::vector& get_generics() const { return parms_; } // Declare the ports for the entity. The parser calls this // method with a list of interface elements that were parsed