From ba36e47575942790a5b45ba8e9817ad19efb31ec Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 24 Jun 2008 18:12:00 +0100 Subject: [PATCH] Add new vhdl_scope class and refactor --- tgt-vhdl/vhdl_syntax.cc | 50 +++++++++++++++++++++++++++++++---------- tgt-vhdl/vhdl_syntax.hh | 32 +++++++++++++++++++------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 9740e5f08..485dfe425 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -25,6 +25,38 @@ #include #include +vhdl_scope::vhdl_scope() + : parent_(NULL) +{ + +} + +vhdl_scope::~vhdl_scope() +{ + delete_children(decls_); +} + +void vhdl_scope::add_decl(vhdl_decl *decl) +{ + decls_.push_back(decl); +} + +vhdl_decl *vhdl_scope::get_decl(const std::string &name) const +{ + decl_list_t::const_iterator it; + for (it = decls_.begin(); it != decls_.end(); ++it) { + if ((*it)->get_name() == name) + return *it; + } + + return parent_ ? parent_->get_decl(name) : NULL; +} + +bool vhdl_scope::have_declared(const std::string &name) const +{ + return get_decl(name) != NULL; +} + vhdl_entity::vhdl_entity(const char *name, const char *derived_from, vhdl_arch *arch) : name_(name), arch_(arch), derived_from_(derived_from) @@ -35,7 +67,6 @@ vhdl_entity::vhdl_entity(const char *name, const char *derived_from, vhdl_entity::~vhdl_entity() { delete arch_; - delete_children(ports_); } /* @@ -58,17 +89,12 @@ void vhdl_entity::requires_package(const char *spec) */ vhdl_decl *vhdl_entity::get_decl(const std::string &name) const { - decl_list_t::const_iterator it; - for (it = ports_.begin(); it != ports_.end(); ++it) { - if ((*it)->get_name() == name) - return *it; - } - return NULL; + return ports_.get_decl(name); } void vhdl_entity::add_port(vhdl_port_decl *decl) { - ports_.push_back(decl); + ports_.add_decl(decl); } void vhdl_entity::emit(std::ofstream &of, int level) const @@ -88,10 +114,10 @@ void vhdl_entity::emit(std::ofstream &of, int level) const emit_comment(of, level); of << "entity " << name_ << " is"; - if (ports_.size() > 0) { + if (!ports_.empty()) { newline(of, indent(level)); of << "port ("; - emit_children(of, ports_, indent(level), ";"); + emit_children(of, ports_.get_decls(), indent(level), ";"); of << ");"; } @@ -338,14 +364,14 @@ vhdl_component_decl::vhdl_component_decl(const char *name) /* * Create a component declaration for the given entity. */ -vhdl_component_decl *vhdl_component_decl::component_decl_for(const vhdl_entity *ent) +vhdl_component_decl *vhdl_component_decl::component_decl_for(vhdl_entity *ent) { assert(ent != NULL); vhdl_component_decl *decl = new vhdl_component_decl (ent->get_name().c_str()); - decl->ports_ = ent->get_ports(); + decl->ports_ = ent->get_scope()->get_decls(); return decl; } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 41e3d61b9..9ccca2781 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -24,6 +24,7 @@ #include "vhdl_element.hh" #include "vhdl_type.hh" +class vhdl_scope; class vhdl_entity; class vhdl_arch; @@ -438,7 +439,7 @@ typedef std::list decl_list_t; */ class vhdl_component_decl : public vhdl_decl { public: - static vhdl_component_decl *component_decl_for(const vhdl_entity *ent); + static vhdl_component_decl *component_decl_for(vhdl_entity *ent); void emit(std::ofstream &of, int level) const; private: @@ -521,11 +522,25 @@ private: /* - * Container for sequential statements. - * Verilog `initial' processes are used for variable - * initialisation whereas VHDL initialises variables in - * their declaration. + * Contains a list of declarations in a hierarchy. */ +class vhdl_scope { +public: + vhdl_scope(); + ~vhdl_scope(); + + void add_decl(vhdl_decl *decl); + vhdl_decl *get_decl(const std::string &name) const; + bool have_declared(const std::string &name) const; + + bool empty() const { return decls_.empty(); } + const decl_list_t &get_decls() const { return decls_; } +private: + decl_list_t decls_; + vhdl_scope *parent_; +}; + + class vhdl_process : public vhdl_conc_stmt { public: vhdl_process(const char *name = ""); @@ -587,16 +602,17 @@ public: void add_port(vhdl_port_decl *decl); vhdl_arch *get_arch() const { return arch_; } vhdl_decl *get_decl(const std::string &name) const; - const decl_list_t &get_ports() const { return ports_; } const std::string &get_name() const { return name_; } void requires_package(const char *spec); - const std::string &get_derived_from() const { return derived_from_; } + const std::string &get_derived_from() const { return derived_from_; } + + vhdl_scope *get_scope() { return &ports_; } private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture std::string derived_from_; string_list_t uses_; - decl_list_t ports_; + vhdl_scope ports_; }; typedef std::list entity_list_t;