diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index a54ff5b7d..7bc1dcdb2 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -642,7 +642,7 @@ static int draw_task(ivl_scope_t scope, ivl_scope_t parent) /* * Create an empty VHDL entity for a Verilog module. */ -static void create_skeleton_entity_for(ivl_scope_t scope) +static void create_skeleton_entity_for(ivl_scope_t scope, int depth) { assert(ivl_scope_type(scope) == IVL_SCT_MODULE); @@ -658,7 +658,7 @@ static void create_skeleton_entity_for(ivl_scope_t scope) // 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, "FromVerilog"); - vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch); + vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch, depth); // Build a comment to add to the entity/architecture ostringstream ss; @@ -676,13 +676,16 @@ static void create_skeleton_entity_for(ivl_scope_t scope) * A first pass through the hierarchy: create VHDL entities for * each unique Verilog module type. */ -static int draw_skeleton_scope(ivl_scope_t scope, void *_parent) +static int draw_skeleton_scope(ivl_scope_t scope, void *_unused) { - debug_msg("Initial visit to scope %s", ivl_scope_name(scope)); + static int depth = 0; + + debug_msg("Initial visit to scope %s at depth %d", + ivl_scope_name(scope), depth); switch (ivl_scope_type(scope)) { case IVL_SCT_MODULE: - create_skeleton_entity_for(scope); + create_skeleton_entity_for(scope, depth); break; case IVL_SCT_GENERATE: error("No translation for generate statements yet"); @@ -694,8 +697,11 @@ static int draw_skeleton_scope(ivl_scope_t scope, void *_parent) // The other scope types are expanded later on break; } - - return ivl_scope_children(scope, draw_skeleton_scope, scope); + + ++depth; + int rc = ivl_scope_children(scope, draw_skeleton_scope, NULL); + --depth; + return rc; } static int draw_all_signals(ivl_scope_t scope, void *_parent) diff --git a/tgt-vhdl/vhdl.cc b/tgt-vhdl/vhdl.cc index e3ab25fe9..3701ac31e 100644 --- a/tgt-vhdl/vhdl.cc +++ b/tgt-vhdl/vhdl.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -210,13 +211,21 @@ extern "C" int target_design(ivl_design_t des) << "-- Icarus Verilog VHDL Code Generator " VERSION " (" VERSION_TAG ")" << endl << endl; + // If the user passed -pdepth=N then only emit entities with + // depth < N + // I.e. -pdepth=1 emits only the top-level entity + // If max_depth is zero then all entities will be emitted + // (This is handy since it means we can use atoi ;-) + int max_depth = std::atoi(ivl_design_flag(des, "depth")); + // Make sure we only emit one example of each type of entity set seen_entities; for (entity_list_t::iterator it = g_entities.begin(); it != g_entities.end(); ++it) { - if (seen_entities.find((*it)->get_name()) == seen_entities.end()) { + if (seen_entities.find((*it)->get_name()) == seen_entities.end() + && (max_depth == 0 || (*it)->depth < max_depth)) { (*it)->emit(outfile); seen_entities.insert((*it)->get_name()); } diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index c610e10c5..65314de9d 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -87,8 +87,8 @@ vhdl_scope *vhdl_scope::get_parent() const } vhdl_entity::vhdl_entity(const char *name, const char *derived_from, - vhdl_arch *arch) - : name_(name), arch_(arch), derived_from_(derived_from) + vhdl_arch *arch, int depth) + : depth(depth), name_(name), arch_(arch), derived_from_(derived_from) { arch->get_scope()->set_parent(&ports_); } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index d7f30c43c..45c5687ee 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -797,7 +797,7 @@ private: class vhdl_entity : public vhdl_element { public: vhdl_entity(const char *name, const char *derived_from, - vhdl_arch *arch); + vhdl_arch *arch, int depth=0); virtual ~vhdl_entity(); void emit(std::ostream &of, int level=0) const; @@ -807,6 +807,11 @@ public: const std::string &get_derived_from() const { return derived_from_; } vhdl_scope *get_scope() { return &ports_; } + + // Each entity has an associated depth which is how deep in + // the Verilog module hierarchy it was found + // This is used to limit the maximum depth of modules emitted + const int depth; private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture