From abb03632dd8ef796d4541a9efa42f505f777577d Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 31 Mar 2011 18:50:48 -0700 Subject: [PATCH] Basic elaboration of vhdl component instantiations. This gets us as far as emiting a component instantiation. Very little error checking/elaboration is done, so there is room for improvement, but this is a working stub. --- vhdlpp/architec.cc | 16 ++++++++++++++++ vhdlpp/architec.h | 18 ++++++++++++++++++ vhdlpp/architec_emit.cc | 17 +++++++++++++++++ vhdlpp/debug.cc | 12 ++++++++++++ vhdlpp/parse.y | 42 ++++++++++++++++++++++++++++++++--------- vhdlpp/parse_types.h | 41 ++++++++++++++++++++++++++++++++++++++++ vhdlpp/parse_wrap.h | 1 + 7 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 vhdlpp/parse_types.h diff --git a/vhdlpp/architec.cc b/vhdlpp/architec.cc index cacee181a..446766d72 100644 --- a/vhdlpp/architec.cc +++ b/vhdlpp/architec.cc @@ -19,6 +19,7 @@ # include "architec.h" # include "expression.h" +# include "parse_types.h" using namespace std; @@ -57,3 +58,18 @@ SignalAssignment::~SignalAssignment() delete *cur; } } + +ComponentInstantiation::ComponentInstantiation(perm_string i, perm_string c, + list*ports) +: iname_(i), cname_(c) +{ + while (! ports->empty()) { + named_expr_t*cur = ports->front(); + ports->pop_front(); + port_map_[cur->name()] = cur->expr(); + } +} + +ComponentInstantiation::~ComponentInstantiation() +{ +} diff --git a/vhdlpp/architec.h b/vhdlpp/architec.h index 9b25bc2ad..176bf0f05 100644 --- a/vhdlpp/architec.h +++ b/vhdlpp/architec.h @@ -29,6 +29,7 @@ class Entity; class Expression; class ExpName; class Signal; +class named_expr_t; /* * The Architecture class carries the contents (name, statements, @@ -106,4 +107,21 @@ class SignalAssignment : public Architecture::Statement { std::list rval_; }; +class ComponentInstantiation : public Architecture::Statement { + + public: + ComponentInstantiation(perm_string iname, perm_string cname, + std::list*ports); + ~ComponentInstantiation(); + + int emit(ostream&out, Entity*entity, Architecture*arc); + virtual void dump(ostream&out) const; + + private: + perm_string iname_; + perm_string cname_; + + std::map port_map_; +}; + #endif diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index 888e1fad7..7809de885 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -70,3 +70,20 @@ int SignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc) return errors; } +int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc) +{ + int errors = 0; + + out << cname_ << " " << iname_ << "("; + const char*comma = ""; + for (map::iterator cur = port_map_.begin() + ; cur != port_map_.end() ; ++cur) { + out << comma << "." << cur->first << "("; + errors += cur->second->emit(out, ent, arc); + out << ")"; + comma = ", "; + } + out << ");" << endl; + + return errors; +} diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 5357e8651..295144804 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -136,6 +136,18 @@ void SignalAssignment::dump(ostream&out) const } } +void ComponentInstantiation::dump(ostream&out) const +{ + out << " Component Instantiation file=" << get_fileline() << endl; + + for (map::const_iterator cur = port_map_.begin() + ; cur != port_map_.end() ; ++cur) { + out << " " << cur->first << " => ..." << endl; + cur->second->dump(out, 10); + } + +} + void Expression::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Expression [" << typeid(*this).name() << "]" diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 72a4c8036..cea3be383 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -34,6 +34,7 @@ # include # include # include +# include "parse_types.h" # include inline void FILE_NAME(LineInfo*tmp, const struct yyltype&where) @@ -89,6 +90,9 @@ static map block_components; Expression*expr; std::list* expr_list; + named_expr_t*named_expr; + std::list*named_expr_list; + const VType* vtype; std::list* interface_list; @@ -149,6 +153,9 @@ static map block_components; %type waveform waveform_elements +%type association_element +%type association_list port_map_aspect port_map_aspect_opt + %type subtype_indication %type identifier_opt logical_name suffix @@ -213,12 +220,24 @@ architecture_statement_part ; association_element - : name ARROW name + : IDENTIFIER ARROW name + { named_expr_t*tmp = new named_expr_t(lex_strings.make($1), $3); + delete[]$1; + $$ = tmp; + } ; association_list : association_list ',' association_element + { std::list*tmp = $1; + tmp->push_back($3); + $$ = tmp; + } | association_element + { std::list*tmp = new std::list; + tmp->push_back($1); + $$ = tmp; + } ; //TODO: this list is only a sketch @@ -314,16 +333,19 @@ component_configuration ; component_instantiation_statement - : IDENTIFIER ':' IDENTIFIER port_map_aspect_opt ';' - { sorrymsg(@1, "Component instantiation statements are not supported.\n"); + : IDENTIFIER ':' K_component_opt IDENTIFIER port_map_aspect_opt ';' + { perm_string iname = lex_strings.make($1); + perm_string cname = lex_strings.make($4); + ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $5); + FILE_NAME(tmp, @1); delete[]$1; - delete[]$3; - $$ = 0; + delete[]$4; + $$ = tmp; } - | IDENTIFIER ':' IDENTIFIER error ';' + | IDENTIFIER ':' K_component_opt IDENTIFIER error ';' { errormsg(@4, "Errors in component instantiation.\n"); delete[]$1; - delete[]$3; + delete[]$4; $$ = 0; } ; @@ -793,11 +815,12 @@ port_clause_opt : port_clause {$$ = $1;} | {$$ = 0;} ; port_map_aspect : K_port K_map '(' association_list ')' + { $$ = $4; } ; port_map_aspect_opt - : port_map_aspect - | + : port_map_aspect { $$ = $1; } + | { $$ = 0; } ; prefix @@ -1017,6 +1040,7 @@ waveform_element /* Some keywords are optional in some contexts. In all such cases, a similar rule is used, as described here. */ K_architecture_opt : K_architecture | ; +K_component_opt : K_component | ; K_configuration_opt: K_configuration| ; K_entity_opt : K_entity | ; K_package_opt : K_package | ; diff --git a/vhdlpp/parse_types.h b/vhdlpp/parse_types.h new file mode 100644 index 000000000..71120d7d1 --- /dev/null +++ b/vhdlpp/parse_types.h @@ -0,0 +1,41 @@ +#ifndef __parse_types_H +#define __parse_types_H +/* + * Copyright (c) 2011 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +# include "StringHeap.h" +class Expression; + +class named_expr_t { + + public: + named_expr_t (perm_string n, Expression*e) : name_(n), expr_(e) { } + + perm_string name() const { return name_; } + Expression* expr() const { return expr_; } + private: + perm_string name_; + Expression* expr_; + + private: // Not implemented + named_expr_t(const named_expr_t&); + named_expr_t& operator = (const named_expr_t&); +}; + +#endif diff --git a/vhdlpp/parse_wrap.h b/vhdlpp/parse_wrap.h index 797441159..31812bf8c 100644 --- a/vhdlpp/parse_wrap.h +++ b/vhdlpp/parse_wrap.h @@ -30,6 +30,7 @@ # include "vhdlreal.h" # include "architec.h" # include "expression.h" +# include "parse_types.h" class VType;