Start improving performace of VHDL hierarchy generation

This should prune a large amount of the visits to scopes
in the hierarchy. In particular, only one instance of each
scope type should be visited.
This commit is contained in:
Nick Gasson 2009-01-17 12:00:32 +00:00 committed by Stephen Williams
parent 4b114ff783
commit 3c2080e502
4 changed files with 97 additions and 7 deletions

View File

@ -86,6 +86,11 @@ int draw_process(ivl_process_t proc, void *cd)
{
ivl_scope_t scope = ivl_process_scope(proc);
if (!is_default_scope_instance(scope)) {
debug_msg("Ignoring process in %s", ivl_scope_name(scope));
return 0;
}
debug_msg("Translating process in %s (%s:%d)",
ivl_scope_name(scope), ivl_process_file(proc),
ivl_process_lineno(proc));

View File

@ -25,6 +25,8 @@
#include <sstream>
#include <cassert>
#include <cstring>
#include <set>
#include <algorithm>
static string make_safe_name(ivl_signal_t sig);
@ -40,6 +42,49 @@ void set_active_entity(vhdl_entity *ent)
g_active_entity = ent;
}
/*
* Set of scopes that are treated as the default examples of
* that type. Any other scopes of the same type are ignored.
*/
typedef set<ivl_scope_t> default_scopes_t;
static default_scopes_t g_default_scopes;
/*
* True if two scopes have the same type name.
*/
static bool same_scope_type_name(ivl_scope_t a, ivl_scope_t b)
{
return strcmp(ivl_scope_tname(a), ivl_scope_tname(b)) == 0;
}
/*
* True if we have already seen a scope with this type before.
* If the result is `false' then s is stored in the set of seen
* scopes.
*/
static bool seen_this_scope_type(ivl_scope_t s)
{
debug_msg("Seen scope type? %s", ivl_scope_tname(s));
if (find_if(g_default_scopes.begin(), g_default_scopes.end(),
bind1st(ptr_fun(same_scope_type_name), s))
== g_default_scopes.end()) {
g_default_scopes.insert(s);
return false;
}
else
return true;
}
/*
* True if this scope is the default example of this scope type.
* All other instances of this scope type are ignored.
*/
bool is_default_scope_instance(ivl_scope_t s)
{
return find(g_default_scopes.begin(), g_default_scopes.end(), s)
!= g_default_scopes.end();
}
/*
* This represents the portion of a nexus that is visible within
* a VHDL scope. If that nexus portion does not contain a signal,
@ -176,8 +221,10 @@ void draw_nexus(ivl_nexus_t nexus)
ivl_signal_t sig;
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
vhdl_scope *scope = find_scope_for_signal(sig);
unsigned pin = ivl_nexus_ptr_pin(nexus_ptr);
link_scope_to_nexus_signal(priv, scope, sig, pin);
if (scope) {
unsigned pin = ivl_nexus_ptr_pin(nexus_ptr);
link_scope_to_nexus_signal(priv, scope, sig, pin);
}
nexus_signal_width = ivl_signal_width(sig);
}
@ -193,6 +240,9 @@ void draw_nexus(ivl_nexus_t nexus)
ivl_net_const_t con;
if ((log = ivl_nexus_ptr_log(nexus_ptr))) {
ivl_scope_t log_scope = ivl_logic_scope(log);
if (!is_default_scope_instance(log_scope))
continue;
vhdl_entity *ent = find_entity(ivl_scope_name(log_scope));
assert(ent);
@ -761,6 +811,11 @@ static int draw_skeleton_scope(ivl_scope_t scope, void *_unused)
{
static int depth = 0;
if (seen_this_scope_type(scope)) {
debug_msg("Ignoring scope: %s\n", ivl_scope_name(scope));
return 0;
}
debug_msg("Initial visit to scope %s at depth %d",
ivl_scope_name(scope), depth);
@ -787,6 +842,11 @@ static int draw_skeleton_scope(ivl_scope_t scope, void *_unused)
static int draw_all_signals(ivl_scope_t scope, void *_parent)
{
if (!is_default_scope_instance(scope)) {
debug_msg("Ignoring scope: %s\n", ivl_scope_name(scope));
return 0;
}
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
assert(ent);
@ -802,6 +862,12 @@ static int draw_all_signals(ivl_scope_t scope, void *_parent)
*/
static int draw_functions(ivl_scope_t scope, void *_parent)
{
if (!is_default_scope_instance(scope)) {
debug_msg("Ignoring scope: %s\n", ivl_scope_name(scope));
return 0;
}
ivl_scope_t parent = static_cast<ivl_scope_t>(_parent);
if (ivl_scope_type(scope) == IVL_SCT_FUNCTION) {
if (draw_function(scope, parent) != 0)
@ -823,6 +889,11 @@ static int draw_functions(ivl_scope_t scope, void *_parent)
*/
static int draw_constant_drivers(ivl_scope_t scope, void *_parent)
{
if (!is_default_scope_instance(scope)) {
debug_msg("Ignoring scope: %s\n", ivl_scope_name(scope));
return 0;
}
ivl_scope_children(scope, draw_constant_drivers, scope);
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
@ -877,6 +948,13 @@ static int draw_constant_drivers(ivl_scope_t scope, void *_parent)
static int draw_all_logic_and_lpm(ivl_scope_t scope, void *_parent)
{
if (!is_default_scope_instance(scope)) {
debug_msg("Ignoring scope: %s\n", ivl_scope_name(scope));
return 0;
}
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
assert(ent);
@ -893,9 +971,14 @@ static int draw_all_logic_and_lpm(ivl_scope_t scope, void *_parent)
}
static int draw_hierarchy(ivl_scope_t scope, void *_parent)
{
{
if (ivl_scope_type(scope) == IVL_SCT_MODULE && _parent) {
ivl_scope_t parent = static_cast<ivl_scope_t>(_parent);
if (!is_default_scope_instance(parent)) {
debug_msg("Ignoring scope: %s\n", ivl_scope_name(scope));
return 0;
}
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
assert(ent);
@ -946,7 +1029,7 @@ static int draw_hierarchy(ivl_scope_t scope, void *_parent)
}
int draw_scope(ivl_scope_t scope, void *_parent)
{
{
int rc = draw_skeleton_scope(scope, _parent);
if (rc != 0)
return rc;

View File

@ -157,9 +157,10 @@ void rename_signal(ivl_signal_t sig, const std::string &renamed)
vhdl_scope *find_scope_for_signal(ivl_signal_t sig)
{
assert(seen_signal_before(sig));
return g_known_signals[sig].scope;
if (seen_signal_before(sig))
return g_known_signals[sig].scope;
else
return NULL;
}
const std::string &get_renamed_signal(ivl_signal_t sig)

View File

@ -32,6 +32,7 @@ vhdl_entity *find_entity(const string &sname);
ivl_design_t get_vhdl_design();
vhdl_entity *get_active_entity();
void set_active_entity(vhdl_entity *ent);
bool is_default_scope_instance(ivl_scope_t s);
vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus);