diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 948b15259..3a6cf7744 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -31,8 +31,14 @@ */ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) { + + // Create a new process and store it in the entity's + // architecture. This needs to be done first or the + // parent link won't be valid (and draw_stmt needs this + // to add information to the architecture) vhdl_process *vhdl_proc = new vhdl_process(); - + ent->get_arch()->add_stmt(vhdl_proc); + ivl_statement_t stmt = ivl_process_stmt(proc); int rc = draw_stmt(vhdl_proc, stmt); if (rc != 0) @@ -55,9 +61,6 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) ss << ivl_scope_tname(scope); vhdl_proc->set_comment(ss.str()); - // Store it in the entity's architecture - ent->get_arch()->add_stmt(vhdl_proc); - return 0; } diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index d05e6209b..9d97a75c9 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -39,7 +39,8 @@ */ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) { - require_package("std.textio"); + // Add the package requirement to the containing entity + proc->get_parent()->get_parent()->requires_package("std.textio"); const char *display_line = "Verilog_Display_Line"; @@ -53,10 +54,10 @@ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) // TODO: Write the data into the line - // Write_Line(Output, Verilog_Display_Line) + // WriteLine(Output, Verilog_Display_Line) vhdl_var_ref *output_ref = new vhdl_var_ref("Output"); vhdl_var_ref *line_ref = new vhdl_var_ref(display_line); - vhdl_pcall_stmt *write_line = new vhdl_pcall_stmt("Write_Line"); + vhdl_pcall_stmt *write_line = new vhdl_pcall_stmt("WriteLine"); write_line->add_expr(output_ref); write_line->add_expr(line_ref); proc->add_stmt(write_line); diff --git a/tgt-vhdl/vhdl.cc b/tgt-vhdl/vhdl.cc index 09e56b6c2..d060f979d 100644 --- a/tgt-vhdl/vhdl.cc +++ b/tgt-vhdl/vhdl.cc @@ -33,11 +33,6 @@ static int g_errors = 0; // Total number of errors encountered static entity_list_t g_entities; // All entities to emit -typedef std::string package_name_t; -typedef std::list require_list_t; - -static require_list_t g_requires; // External packages required - /* * Called when an unrecoverable problem is encountered. @@ -78,21 +73,6 @@ void remember_entity(vhdl_entity* ent) g_entities.push_back(ent); } -/* - * Add a package to the list of packages that should be - * use-ed at the start of the program. - */ -void require_package(const char *name) -{ - package_name_t pname(name); - require_list_t::iterator it; - for (it = g_requires.begin(); it != g_requires.end(); ++it) { - if (*it == pname) - return; - } - g_requires.push_back(pname); -} - extern "C" int target_design(ivl_design_t des) { ivl_scope_t *roots; @@ -108,14 +88,6 @@ extern "C" int target_design(ivl_design_t des) const char *ofname = ivl_design_flag(des, "-o"); std::ofstream outfile(ofname); - // Write all the required packages (and libraries?) - //outfile << "library ieee;" << std::endl; - for (require_list_t::iterator it = g_requires.begin(); - it != g_requires.end(); - ++it) - outfile << "use " << *it << ".all;" << std::endl; - outfile << std::endl; - for (entity_list_t::iterator it = g_entities.begin(); it != g_entities.end(); ++it) diff --git a/tgt-vhdl/vhdl_element.cc b/tgt-vhdl/vhdl_element.cc index 7f9ce9b4c..c2e4a6b7d 100644 --- a/tgt-vhdl/vhdl_element.cc +++ b/tgt-vhdl/vhdl_element.cc @@ -102,7 +102,7 @@ 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; } vhdl_entity::~vhdl_entity() @@ -110,8 +110,29 @@ 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); +} + void vhdl_entity::emit(std::ofstream &of, int level) const { + for (std::list::const_iterator it = uses_.begin(); + it != uses_.end(); + ++it) + of << "use " << *it << ".all;" << std::endl; + of << std::endl; + emit_comment(of, level); of << "entity " << name_ << " is"; // ...ports... @@ -123,7 +144,7 @@ void vhdl_entity::emit(std::ofstream &of, int level) const } vhdl_arch::vhdl_arch(const char *entity, const char *name) - : name_(name), entity_(entity) + : parent_(NULL), name_(name), entity_(entity) { } @@ -136,6 +157,7 @@ vhdl_arch::~vhdl_arch() void vhdl_arch::add_stmt(vhdl_conc_stmt *stmt) { + stmt->parent_ = this; stmts_.push_back(stmt); } @@ -144,6 +166,12 @@ void vhdl_arch::add_decl(vhdl_decl *decl) decls_.push_back(decl); } +vhdl_entity *vhdl_arch::get_parent() const +{ + assert(parent_); + return parent_; +} + void vhdl_arch::emit(std::ofstream &of, int level) const { emit_comment(of, level); @@ -173,6 +201,12 @@ bool vhdl_arch::have_declared_component(const std::string &name) const return false; } +vhdl_arch *vhdl_conc_stmt::get_parent() const +{ + assert(parent_); + return parent_; +} + vhdl_process::vhdl_process(const char *name) : name_(name) { diff --git a/tgt-vhdl/vhdl_element.hh b/tgt-vhdl/vhdl_element.hh index ab0646597..553dcb013 100644 --- a/tgt-vhdl/vhdl_element.hh +++ b/tgt-vhdl/vhdl_element.hh @@ -26,6 +26,7 @@ #include class vhdl_entity; +class vhdl_arch; /* * Any VHDL syntax element. Each element can also contain a comment. @@ -98,8 +99,14 @@ 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; @@ -236,6 +243,7 @@ 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="Behavioural"); virtual ~vhdl_arch(); @@ -244,7 +252,9 @@ public: bool have_declared_component(const std::string &name) const; void add_decl(vhdl_decl *decl); void add_stmt(vhdl_conc_stmt *stmt); + vhdl_entity *get_parent() const; private: + vhdl_entity *parent_; conc_stmt_list_t stmts_; decl_list_t decls_; std::string name_, entity_; @@ -265,12 +275,13 @@ public: void emit(std::ofstream &of, int level=0) const; vhdl_arch *get_arch() const { return arch_; } const std::string &get_name() const { return name_; } - + void requires_package(const char *spec); const std::string &get_derived_from() const { return derived_from_; } private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture std::string derived_from_; + std::list uses_; }; typedef std::list entity_list_t; diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index 35027bec1..3612f426a 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -16,7 +16,6 @@ int draw_stmt(vhdl_process *proc, ivl_statement_t stmt); void remember_entity(vhdl_entity *ent); vhdl_entity *find_entity(const std::string &tname); -void require_package(const char *name); #endif /* #ifndef INC_VHDL_TARGET_H */