From 63b1887ff27fd5bfd1c734b9590041d7e725f048 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 24 Jun 2008 18:52:25 +0100 Subject: [PATCH] Refactor code to use the new vhdl_scope class --- tgt-vhdl/display.cc | 7 +-- tgt-vhdl/lpm.cc | 6 +- tgt-vhdl/process.cc | 8 +-- tgt-vhdl/scope.cc | 37 ++++++------ tgt-vhdl/stmt.cc | 14 ++--- tgt-vhdl/vhdl_syntax.cc | 126 +++++++--------------------------------- tgt-vhdl/vhdl_syntax.hh | 26 +++------ tgt-vhdl/vhdl_target.h | 3 +- 8 files changed, 64 insertions(+), 163 deletions(-) diff --git a/tgt-vhdl/display.cc b/tgt-vhdl/display.cc index ad59d6c45..1b40c8c82 100644 --- a/tgt-vhdl/display.cc +++ b/tgt-vhdl/display.cc @@ -115,14 +115,11 @@ static void flush_string(std::ostringstream &ss, stmt_container *container) int draw_stask_display(vhdl_process *proc, stmt_container *container, ivl_statement_t stmt, bool newline) { - // Add the package requirement to the containing entity - proc->get_parent()->get_parent()->requires_package("std.textio"); - - if (!proc->have_declared_var(DISPLAY_LINE)) { + if (!proc->get_scope()->have_declared(DISPLAY_LINE)) { vhdl_var_decl *line_var = new vhdl_var_decl(DISPLAY_LINE, vhdl_type::line()); line_var->set_comment("For generating $display output"); - proc->add_decl(line_var); + proc->get_scope()->add_decl(line_var); } // Write the data into the line diff --git a/tgt-vhdl/lpm.cc b/tgt-vhdl/lpm.cc index 8778dff8a..3d67ddf93 100644 --- a/tgt-vhdl/lpm.cc +++ b/tgt-vhdl/lpm.cc @@ -25,15 +25,15 @@ static int draw_binop_lpm(vhdl_arch *arch, ivl_lpm_t lpm, vhdl_binop_t op) { - vhdl_expr *lhs = nexus_to_var_ref(arch, ivl_lpm_data(lpm, 0)); + vhdl_expr *lhs = nexus_to_var_ref(arch->get_scope(), ivl_lpm_data(lpm, 0)); if (NULL == lhs) return 1; - vhdl_expr *rhs = nexus_to_var_ref(arch, ivl_lpm_data(lpm, 1)); + vhdl_expr *rhs = nexus_to_var_ref(arch->get_scope(), ivl_lpm_data(lpm, 1)); if (NULL == rhs) return 1; - vhdl_var_ref *out = nexus_to_var_ref(arch, ivl_lpm_q(lpm, 0)); + vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm, 0)); if (NULL == out) return 1; diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 4d6ac6b8f..cc6ca855a 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -86,12 +86,12 @@ void blocking_assign_to(vhdl_process *proc, ivl_signal_t sig) // This is the first time a non-blocking assignment // has been made to this signal: create a variable // to shadow it. - if (!proc->have_declared_var(tmpname)) { - vhdl_decl *decl = proc->get_parent()->get_decl(var); + if (!proc->get_scope()->have_declared(tmpname)) { + vhdl_decl *decl = proc->get_scope()->get_decl(var); assert(decl); vhdl_type *type = new vhdl_type(*decl->get_type()); - proc->add_decl(new vhdl_var_decl(tmpname.c_str(), type)); + proc->get_scope()->add_decl(new vhdl_var_decl(tmpname.c_str(), type)); } rename_signal(sig, tmpname); @@ -110,7 +110,7 @@ void draw_blocking_assigns(vhdl_process *proc, stmt_container *container) for (it = g_assign_vars.begin(); it != g_assign_vars.end(); ++it) { std::string stripped(strip_var((*it).first)); - vhdl_decl *decl = proc->get_decl(stripped); + vhdl_decl *decl = proc->get_scope()->get_decl(stripped); assert(decl); vhdl_type *type = new vhdl_type(*decl->get_type()); diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 743202fb7..23dd95490 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -25,11 +25,12 @@ #include #include + /* - * Given a nexus and an architecture, find the first signal + * Given a nexus and an architecture scope, find the first signal * that is connected to the nexus, if there is one. */ -vhdl_var_ref *nexus_to_var_ref(vhdl_arch *arch, ivl_nexus_t nexus) +vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus) { int nptrs = ivl_nexus_ptrs(nexus); for (int i = 0; i < nptrs; i++) { @@ -39,7 +40,7 @@ vhdl_var_ref *nexus_to_var_ref(vhdl_arch *arch, ivl_nexus_t nexus) if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) { const char *signame = get_renamed_signal(sig).c_str(); - vhdl_decl *decl = arch->get_decl(signame); + vhdl_decl *decl = arch_scope->get_decl(signame); assert(decl); vhdl_type *type = new vhdl_type(*(decl->get_type())); @@ -67,7 +68,7 @@ static vhdl_expr *inputs_to_expr(vhdl_arch *arch, vhdl_binop_t op, int npins = ivl_logic_pins(log); for (int i = 1; i < npins; i++) { ivl_nexus_t input = ivl_logic_pin(log, i); - gate->add_expr(nexus_to_var_ref(arch, input)); + gate->add_expr(nexus_to_var_ref(arch->get_scope(), input)); } return gate; @@ -82,7 +83,7 @@ static vhdl_expr *input_to_expr(vhdl_arch *arch, vhdl_unaryop_t op, ivl_nexus_t input = ivl_logic_pin(log, 1); assert(input); - vhdl_expr *operand = nexus_to_var_ref(arch, input); + vhdl_expr *operand = nexus_to_var_ref(arch->get_scope(), input); return new vhdl_unaryop_expr(op, operand, vhdl_type::std_logic()); } @@ -98,7 +99,7 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope) // The output is always pin zero ivl_nexus_t output = ivl_logic_pin(log, 0); - vhdl_var_ref *lhs = nexus_to_var_ref(arch, output); + vhdl_var_ref *lhs = nexus_to_var_ref(arch->get_scope(), output); vhdl_expr *rhs = NULL; switch (ivl_logic_type(log)) { @@ -123,9 +124,9 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope) } /* - * Declare all signals for a scope in an architecture. + * Declare all signals and ports for a scope. */ -static void declare_signals(vhdl_arch *arch, ivl_scope_t scope) +static void declare_signals(vhdl_entity *ent, ivl_scope_t scope) { int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { @@ -140,7 +141,7 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope) else sig_type = vhdl_type::nunsigned(width); - remember_signal(sig, arch->get_parent()); + remember_signal(sig, ent); // Make sure the signal name conforms to VHDL naming rules std::string name(ivl_signal_basename(sig)); @@ -162,14 +163,14 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope) ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { case IVL_SIP_NONE: - arch->add_decl(new vhdl_signal_decl(name.c_str(), sig_type)); + ent->get_arch()->add_decl(new vhdl_signal_decl(name.c_str(), sig_type)); break; case IVL_SIP_INPUT: - arch->get_parent()->add_port + ent->get_scope()->add_decl (new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_IN)); break; case IVL_SIP_OUTPUT: - arch->get_parent()->add_port + ent->get_scope()->add_decl (new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_OUT)); if (ivl_signal_type(sig) == IVL_SIT_REG) { @@ -183,18 +184,18 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope) rename_signal(sig, newname.c_str()); vhdl_type *reg_type = new vhdl_type(*sig_type); - arch->add_decl(new vhdl_signal_decl(newname.c_str(), reg_type)); + ent->get_arch()->add_decl(new vhdl_signal_decl(newname.c_str(), reg_type)); // Create a concurrent assignment statement to // connect the register to the output - arch->add_stmt + ent->get_arch()->add_stmt (new vhdl_cassign_stmt (new vhdl_var_ref(name.c_str(), NULL), new vhdl_var_ref(newname.c_str(), NULL))); } break; case IVL_SIP_INOUT: - arch->get_parent()->add_port + ent->get_scope()->add_decl (new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_INOUT)); break; } @@ -231,10 +232,10 @@ static vhdl_entity *create_entity_for(ivl_scope_t scope) // retain a 1-to-1 mapping of scope to VHDL element) vhdl_arch *arch = new vhdl_arch(tname, "FromVerilog"); vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch); - + // Locate all the signals in this module and add them to // the architecture - declare_signals(arch, scope); + declare_signals(ent, scope); // Similarly, add all the primitive logic gates declare_logic(arch, scope); @@ -344,7 +345,7 @@ static int draw_module(ivl_scope_t scope, ivl_scope_t parent) assert(parent_arch != NULL); // Create a forward declaration for it - if (!parent_arch->have_declared_component(ent->get_name())) { + if (!parent_arch->have_declared(ent->get_name())) { vhdl_decl *comp_decl = vhdl_component_decl::component_decl_for(ent); parent_arch->add_decl(comp_decl); } diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index ff0375ac0..90d63c475 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -43,7 +43,7 @@ static int draw_stask_finish(vhdl_process *proc, stmt_container *container, { const char *use_vhpi = ivl_design_flag(get_vhdl_design(), "use-vhpi-finish"); if (strcmp(use_vhpi, "1") == 0) { - proc->get_parent()->get_parent()->requires_package("work.Verilog_Support"); + //get_active_entity()->requires_package("work.Verilog_Support"); container->add_stmt(new vhdl_pcall_stmt("work.Verilog_Support.Finish")); } else { @@ -121,7 +121,7 @@ static int draw_nbassign(vhdl_process *proc, stmt_container *container, if ((sig = ivl_lval_sig(lval))) { const char *signame = get_renamed_signal(sig).c_str(); - vhdl_decl *decl = proc->get_parent()->get_decl(signame); + vhdl_decl *decl = proc->get_scope()->get_decl(signame); assert(decl); vhdl_expr *rhs_raw = translate_expr(ivl_stmt_rval(stmt)); @@ -175,7 +175,7 @@ static int draw_assign(vhdl_process *proc, stmt_container *container, if ((sig = ivl_lval_sig(lval))) { const std::string signame(get_renamed_signal(sig)); - vhdl_decl *decl = proc->get_decl(signame); + vhdl_decl *decl = proc->get_scope()->get_decl(signame); assert(decl); vhdl_expr *rhs_raw = translate_expr(ivl_stmt_rval(stmt)); @@ -186,7 +186,7 @@ static int draw_assign(vhdl_process *proc, stmt_container *container, // As with non-blocking assignment, push constant assignments // into the initialisation if we can if (proc->is_initial() && ivl_signal_port(sig) == IVL_SIP_NONE - && rhs->constant() && !proc->have_declared_var(signame)) { + && rhs->constant() && !proc->get_scope()->have_declared(signame)) { decl->set_initial(rhs); // This signal may be used e.g. in a loop test so we need @@ -295,7 +295,7 @@ static int draw_delay(vhdl_process *proc, stmt_container *container, static void edge_detector(ivl_nexus_t nexus, vhdl_process *proc, vhdl_binop_expr *test, const char *type) { - vhdl_var_ref *ref = nexus_to_var_ref(proc->get_parent(), nexus); + vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope()->get_parent(), nexus); vhdl_fcall *detect = new vhdl_fcall(type, vhdl_type::boolean()); detect->add_expr(ref); test->add_expr(detect); @@ -334,7 +334,7 @@ static int draw_wait(vhdl_process *proc, stmt_container *container, // Only add this signal to the sensitivity if it's part // of the containing architecture (i.e. it has already // been declared) - if (proc->get_parent()->have_declared(signame)) { + if (proc->get_scope()->get_parent()->have_declared(signame)) { proc->add_sensitivity(signame); non_edges.push_back(signame); break; @@ -418,7 +418,7 @@ static int draw_case(vhdl_process *proc, stmt_container *container, // TODO: Check if this is already declared const char *tmp_name = "Verilog_Case_Ex"; vhdl_type *test_type = new vhdl_type(*test->get_type()); - proc->add_decl(new vhdl_var_decl(tmp_name, test_type)); + proc->get_scope()->add_decl(new vhdl_var_decl(tmp_name, test_type)); vhdl_var_ref *tmp_ref = new vhdl_var_ref(tmp_name, NULL); container->add_stmt(new vhdl_assign_stmt(tmp_ref, test)); diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 485dfe425..770e8db7d 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -57,11 +57,17 @@ bool vhdl_scope::have_declared(const std::string &name) const return get_decl(name) != NULL; } +vhdl_scope *vhdl_scope::get_parent() +{ + assert(parent_); + return parent_; +} + vhdl_entity::vhdl_entity(const char *name, const char *derived_from, vhdl_arch *arch) : name_(name), arch_(arch), derived_from_(derived_from) { - arch->parent_ = this; + arch->get_scope()->set_parent(&ports_); } vhdl_entity::~vhdl_entity() @@ -69,29 +75,6 @@ vhdl_entity::~vhdl_entity() delete arch_; } -/* - * Add a package to the list of `use' statements before - * the entity. - */ -void vhdl_entity::requires_package(const char *spec) -{ - std::string pname(spec); - std::list::iterator it; - for (it = uses_.begin(); it != uses_.end(); ++it) { - if (*it == pname) - return; - } - uses_.push_back(spec); -} - -/* - * Find a port declaration by name - */ -vhdl_decl *vhdl_entity::get_decl(const std::string &name) const -{ - return ports_.get_decl(name); -} - void vhdl_entity::add_port(vhdl_port_decl *decl) { ports_.add_decl(decl); @@ -104,11 +87,7 @@ void vhdl_entity::emit(std::ofstream &of, int level) const of << "library ieee;" << std::endl; of << "use ieee.std_logic_1164.all;" << std::endl; of << "use ieee.numeric_std.all;" << std::endl; - - for (std::list::const_iterator it = uses_.begin(); - it != uses_.end(); - ++it) - of << "use " << *it << ".all;" << std::endl; + of << "use std.textio.all;" << std::endl; of << std::endl; emit_comment(of, level); @@ -128,7 +107,7 @@ void vhdl_entity::emit(std::ofstream &of, int level) const } vhdl_arch::vhdl_arch(const char *entity, const char *name) - : parent_(NULL), name_(name), entity_(entity) + : name_(name), entity_(entity) { } @@ -136,24 +115,22 @@ vhdl_arch::vhdl_arch(const char *entity, const char *name) vhdl_arch::~vhdl_arch() { delete_children(stmts_); - delete_children(decls_); +} + +void vhdl_arch::add_stmt(vhdl_process *proc) +{ + proc->get_scope()->set_parent(&scope_); + stmts_.push_back(proc); } void vhdl_arch::add_stmt(vhdl_conc_stmt *stmt) { - stmt->parent_ = this; stmts_.push_back(stmt); } void vhdl_arch::add_decl(vhdl_decl *decl) { - decls_.push_back(decl); -} - -vhdl_entity *vhdl_arch::get_parent() const -{ - assert(parent_); - return parent_; + scope_.add_decl(decl); } void vhdl_arch::emit(std::ofstream &of, int level) const @@ -161,7 +138,7 @@ void vhdl_arch::emit(std::ofstream &of, int level) const emit_comment(of, level); of << "architecture " << name_ << " of " << entity_; of << " is"; - emit_children(of, decls_, level); + emit_children(of, scope_.get_decls(), level); of << "begin"; emit_children(of, stmts_, level); of << "end architecture;"; @@ -170,32 +147,7 @@ void vhdl_arch::emit(std::ofstream &of, int level) const vhdl_decl *vhdl_arch::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; - } - - // Maybe it's a port rather than an internal signal? - assert(parent_); - return parent_->get_decl(name); -} - -/* - * True if component `name' has already been declared in this - * architecture. This is a bit of hack, since it uses typeid - * to distinguish between components and other declarations. - */ -bool vhdl_arch::have_declared_component(const std::string &name) const -{ - std::string comp_typename(typeid(vhdl_component_decl).name()); - decl_list_t::const_iterator it; - for (it = decls_.begin(); it != decls_.end(); ++it) { - if (comp_typename == typeid(**it).name() - && (*it)->get_name() == name) - return true; - } - return false; + return scope_.get_decl(name); } /* @@ -204,14 +156,9 @@ bool vhdl_arch::have_declared_component(const std::string &name) const */ bool vhdl_arch::have_declared(const std::string &name) const { - return get_decl(name) != NULL; + return scope_.have_declared(name); } -vhdl_arch *vhdl_conc_stmt::get_parent() const -{ - assert(parent_); - return parent_; -} vhdl_process::vhdl_process(const char *name) : name_(name), initial_(false) @@ -219,44 +166,11 @@ vhdl_process::vhdl_process(const char *name) } -vhdl_process::~vhdl_process() -{ - delete_children(decls_); -} - -void vhdl_process::add_decl(vhdl_decl* decl) -{ - decls_.push_back(decl); -} - -vhdl_decl *vhdl_process::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; - } - - // Maybe it's a signal rather than a variable? - assert(get_parent()); - return get_parent()->get_decl(name); -} - void vhdl_process::add_sensitivity(const char *name) { sens_.push_back(name); } -bool vhdl_process::have_declared_var(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 true; - } - return false; -} - void vhdl_process::emit(std::ofstream &of, int level) const { // If there are no statements in the body, this process @@ -285,7 +199,7 @@ void vhdl_process::emit(std::ofstream &of, int level) const } of << "is"; - emit_children(of, decls_, level); + emit_children(of, scope_.get_decls(), level); of << "begin"; stmts_.emit(of, level); of << "end process;"; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 9ccca2781..72d9ce2d2 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -203,14 +203,8 @@ private: * processes. */ class vhdl_conc_stmt : public vhdl_element { - friend class vhdl_arch; // Can set its parent public: - vhdl_conc_stmt() : parent_(NULL) {} virtual ~vhdl_conc_stmt() {} - - vhdl_arch *get_parent() const; -private: - vhdl_arch *parent_; }; typedef std::list conc_stmt_list_t; @@ -532,9 +526,11 @@ public: void add_decl(vhdl_decl *decl); vhdl_decl *get_decl(const std::string &name) const; bool have_declared(const std::string &name) const; + vhdl_scope *get_parent(); bool empty() const { return decls_.empty(); } const decl_list_t &get_decls() const { return decls_; } + void set_parent(vhdl_scope *p) { parent_ = p; } private: decl_list_t decls_; vhdl_scope *parent_; @@ -544,19 +540,16 @@ private: class vhdl_process : public vhdl_conc_stmt { public: vhdl_process(const char *name = ""); - virtual ~vhdl_process(); void emit(std::ofstream &of, int level) const; stmt_container *get_container() { return &stmts_; } - void add_decl(vhdl_decl *decl); void add_sensitivity(const char *name); - bool have_declared_var(const std::string &name) const; - vhdl_decl *get_decl(const std::string &name) const; + vhdl_scope *get_scope() { return &scope_; } void set_initial(bool i) { initial_ = i; } bool is_initial() const { return initial_; } private: stmt_container stmts_; - decl_list_t decls_; + vhdl_scope scope_; std::string name_; string_list_t sens_; bool initial_; @@ -567,22 +560,20 @@ private: * An architecture which implements an entity. */ class vhdl_arch : public vhdl_element { - friend class vhdl_entity; // Can set its parent public: vhdl_arch(const char *entity, const char *name); virtual ~vhdl_arch(); void emit(std::ofstream &of, int level=0) const; - bool have_declared_component(const std::string &name) const; bool have_declared(const std::string &name) const; vhdl_decl *get_decl(const std::string &name) const; void add_decl(vhdl_decl *decl); + void add_stmt(vhdl_process *proc); void add_stmt(vhdl_conc_stmt *stmt); - vhdl_entity *get_parent() const; + vhdl_scope *get_scope() { return &scope_; } private: - vhdl_entity *parent_; conc_stmt_list_t stmts_; - decl_list_t decls_; + vhdl_scope scope_; std::string name_, entity_; }; @@ -601,9 +592,7 @@ public: void emit(std::ofstream &of, int level=0) const; void add_port(vhdl_port_decl *decl); vhdl_arch *get_arch() const { return arch_; } - vhdl_decl *get_decl(const std::string &name) const; const std::string &get_name() const { return name_; } - void requires_package(const char *spec); const std::string &get_derived_from() const { return derived_from_; } vhdl_scope *get_scope() { return &ports_; } @@ -611,7 +600,6 @@ private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture std::string derived_from_; - string_list_t uses_; vhdl_scope ports_; }; diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index cd12460ed..fbabc5e30 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -23,8 +23,9 @@ void remember_entity(vhdl_entity *ent); vhdl_entity *find_entity(const std::string &tname); ivl_design_t get_vhdl_design(); +vhdl_entity *get_active_entity(); -vhdl_var_ref *nexus_to_var_ref(vhdl_arch *arch, ivl_nexus_t nexus); +vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus); void remember_signal(ivl_signal_t sig, const vhdl_entity *ent); void rename_signal(ivl_signal_t sig, const std::string &renamed);