diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 30869c458..ce4c6c205 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -22,13 +22,57 @@ #include "vhdl_element.hh" #include +#include +#include + +/* + * Convert a Verilog process to VHDL and add it to the architecture + * of the given entity. + */ +static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) +{ + vhdl_process *vhdl_proc = new vhdl_process(); + + // TODO: Add statements + + // Add a comment indicating where it came from + ivl_scope_t scope = ivl_process_scope(proc); + const char *type = ivl_process_type(proc) == IVL_PR_INITIAL + ? "initial" : "always"; + std::ostringstream ss; + ss << "Generated from " << type << " process in scope "; + ss << ivl_scope_name(scope); + vhdl_proc->set_comment(ss.str()); + + // Store it in the entity's architecture + ent->get_arch()->add_stmt(vhdl_proc); + + return 0; +} int draw_process(ivl_process_t proc, void *cd) { ivl_scope_t scope = ivl_process_scope(proc); const char *scope_name = ivl_scope_name(scope); - std::cout << "process: scope " << scope_name << std::endl; - - return 0; + // A process should occur in a module scope, therefore it + // should have already been assigned a VHDL entity + assert(ivl_scope_type(scope) == IVL_SCT_MODULE); + vhdl_entity *ent = find_entity(ivl_scope_tname(scope)); + assert(ent != NULL); + + // If the scope this process belongs to is the same as the + // VHDL entity was generated from, then create a VHDL process + // from this Verilog process. This ensures that each process + // is translated at most once, no matter how many times it + // appears in the hierarchy. + if (ent->get_derived_from() == scope_name) { + std::cout << "New process encountered in " << scope_name << std::endl; + return generate_vhdl_process(ent, proc); + } + else { + std::cout << "Ignoring already seen process in "; + std::cout << scope_name << std::endl; + return 0; + } } diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index e761f58a8..641228bb3 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -35,12 +35,16 @@ static vhdl_entity *create_entity_for(ivl_scope_t scope) // The type name will become the entity name const char *tname = ivl_scope_tname(scope); + // Remember the scope name this entity was derived from so + // the correct processes can be added later + const char *derived_from = ivl_scope_name(scope); + // Verilog does not have the entity/architecture distinction // so we always create a pair and associate the architecture // with the entity for convenience (this also means that we // retain a 1-to-1 mapping of scope to VHDL element) vhdl_arch *arch = new vhdl_arch(tname); - vhdl_entity *ent = new vhdl_entity(tname, arch); + vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch); // Build a comment to add to the entity/architecture std::ostringstream ss; @@ -51,6 +55,9 @@ static vhdl_entity *create_entity_for(ivl_scope_t scope) arch->set_comment(ss.str()); ent->set_comment(ss.str()); + std::cout << "Generated entity " << tname; + std::cout << " from " << ivl_scope_name(scope) << std::endl; + remember_entity(ent); return ent; } @@ -67,10 +74,6 @@ static int draw_module(ivl_scope_t scope, ivl_scope_t parent) if (NULL == ent) ent = create_entity_for(scope); assert(ent); - - if (parent != NULL) { - std::cout << "parent " << ivl_scope_name(parent) << std::endl; - } return 0; } diff --git a/tgt-vhdl/vhdl.cc b/tgt-vhdl/vhdl.cc index 4e7e0e549..3eb64f98a 100644 --- a/tgt-vhdl/vhdl.cc +++ b/tgt-vhdl/vhdl.cc @@ -51,11 +51,11 @@ void error(const char *fmt, ...) /* * Find an entity given a type name. */ -vhdl_entity *find_entity(const char *tname) +vhdl_entity *find_entity(const std::string &tname) { entity_list_t::const_iterator it; for (it = g_entities.begin(); it != g_entities.end(); ++it) { - if (strcmp((*it)->get_name(), tname) == 0) + if ((*it)->get_name() == tname) return *it; } return NULL; diff --git a/tgt-vhdl/vhdl_element.cc b/tgt-vhdl/vhdl_element.cc index 5ee2ccb57..4d36a5f16 100644 --- a/tgt-vhdl/vhdl_element.cc +++ b/tgt-vhdl/vhdl_element.cc @@ -85,8 +85,9 @@ void vhdl_element::emit_comment(std::ofstream &of, int level) const //////// ENTITY //////// -vhdl_entity::vhdl_entity(const char *name, vhdl_arch *arch) - : name_(name), arch_(arch) +vhdl_entity::vhdl_entity(const char *name, const char *derived_from, + vhdl_arch *arch) + : name_(name), arch_(arch), derived_from_(derived_from) { } @@ -169,7 +170,7 @@ void vhdl_process::add_stmt(vhdl_seq_stmt* stmt) void vhdl_process::emit(std::ofstream &of, int level) const { emit_comment(of, level); - if (name_) + if (name_.size() > 0) of << name_ << ": "; of << "process is"; // TODO: sensitivity newline(of, level); diff --git a/tgt-vhdl/vhdl_element.hh b/tgt-vhdl/vhdl_element.hh index a7ace1012..e60127025 100644 --- a/tgt-vhdl/vhdl_element.hh +++ b/tgt-vhdl/vhdl_element.hh @@ -72,19 +72,20 @@ typedef std::list seq_stmt_list_t; */ class vhdl_process : public vhdl_conc_stmt { public: - vhdl_process(const char *name = NULL); + vhdl_process(const char *name = ""); virtual ~vhdl_process(); void emit(std::ofstream &of, int level) const; void add_stmt(vhdl_seq_stmt* stmt); private: seq_stmt_list_t stmts_; - const char *name_; + std::string name_; }; /* - * An architecture which implements an entity. + * An architecture which implements an entity. Entities are `derived' + * from instantiations of Verilog module scopes in the hierarchy. */ class vhdl_arch : public vhdl_element { public: @@ -95,7 +96,7 @@ public: void add_stmt(vhdl_conc_stmt* stmt); private: conc_stmt_list_t stmts_; - const char *name_, *entity_; + std::string name_, entity_; }; /* @@ -105,15 +106,19 @@ private: */ class vhdl_entity : public vhdl_element { public: - vhdl_entity(const char *name, vhdl_arch *arch); + vhdl_entity(const char *name, const char *derived_from, + vhdl_arch *arch); virtual ~vhdl_entity(); void emit(std::ofstream &of, int level=0) const; vhdl_arch *get_arch() const { return arch_; } - const char *get_name() const { return name_; } + const std::string &get_name() const { return name_; } + + const std::string &get_derived_from() const { return derived_from_; } private: - const char *name_; + std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture + std::string derived_from_; }; typedef std::list entity_list_t; diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index 5eabd8770..ec44ee95f 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -6,13 +6,15 @@ #include "vhdl_element.hh" +#include + void error(const char *fmt, ...); int draw_scope(ivl_scope_t scope, void *_parent); int draw_process(ivl_process_t net, void *cd); void remember_entity(vhdl_entity *ent); -vhdl_entity *find_entity(const char *tname); +vhdl_entity *find_entity(const std::string &tname); #endif /* #ifndef INC_VHDL_TARGET_H */