run scope elaboration as queued work items.

Putting scope elaboration into work queue items allows for handling
more complex processing order. The elaboration_work_list queue drives
the processing of elaborate_scope and parameter evaluation.
This commit is contained in:
Stephen Williams 2008-06-24 20:28:08 -07:00
parent 360be597a8
commit c810406195
2 changed files with 83 additions and 25 deletions

View File

@ -3775,6 +3775,50 @@ struct root_elem {
NetScope *scope;
};
class elaborate_root_scope_t : public elaborator_work_item_t {
public:
elaborate_root_scope_t(Design*des, NetScope*scope, Module*rmod)
: elaborator_work_item_t(des), scope_(scope), rmod_(rmod)
{ }
~elaborate_root_scope_t() { }
virtual void elaborate_runrun()
{
Module::replace_t stub;
if (! rmod_->elaborate_scope(des, scope_, stub))
des->errors += 1;
}
private:
NetScope*scope_;
Module*rmod_;
};
class top_defparams : public elaborator_work_item_t {
public:
top_defparams(Design*des)
: elaborator_work_item_t(des)
{ }
~top_defparams() { }
virtual void elaborate_runrun()
{
// This method recurses through the scopes, looking for
// defparam assignments to apply to the parameters in the
// various scopes. This needs to be done after all the scopes
// and basic parameters are taken care of because the defparam
// can assign to a parameter declared *after* it.
des->run_defparams();
// At this point, all parameter overrides are done. Scan the
// scopes and evaluate the parameters all the way down to
// constants.
des->evaluate_parameters();
}
};
/*
* This function is the root of all elaboration. The input is the list
* of root module names. The function locates the Module definitions
@ -3829,21 +3873,27 @@ Design* elaborate(list<perm_string>roots)
r->mod = rmod;
r->scope = scope;
root_elems[i++] = r;
// Arrange for these scopes to be elaborated as root
// scopes. Create an "elaborate_root_scope" object to
// contain the work item, and append it to the scope
// elaborations work list.
elaborator_work_item_t*es = new elaborate_root_scope_t(des, scope, rmod);
des->elaboration_work_list.push_back(es);
}
// Elaborate the instances of the root modules into the root
// scopes that we created. The elaborate_scope for each will
// recurse down the design, furtner elaborating sub-scope all
// the way down to the leaves.
for (i = 0; i < root_elems.count(); i += 1) {
Module*rmod = root_elems[i]->mod;
NetScope*scope = root_elems[i]->scope;
// After the work items for the root scope elaboration, push a
// work item to process the defparams.
des->elaboration_work_list.push_back(new top_defparams(des));
Module::replace_t stub;
if (! rmod->elaborate_scope(des, scope, stub)) {
delete des;
return 0;
}
// Run the work list of scope elaborations until the list is
// empty. This list is initially populated above where the
// initial root scopes are primed.
while (! des->elaboration_work_list.empty()) {
elaborator_work_item_t*tmp = des->elaboration_work_list.front();
des->elaboration_work_list.pop_front();
tmp->elaborate_runrun();
delete tmp;
}
// Errors already? Probably missing root modules. Just give up
@ -3851,19 +3901,6 @@ Design* elaborate(list<perm_string>roots)
if (des->errors > 0)
return des;
// This method recurses through the scopes, looking for
// defparam assignments to apply to the parameters in the
// various scopes. This needs to be done after all the scopes
// and basic parameters are taken care of because the defparam
// can assign to a parameter declared *after* it.
des->run_defparams();
// At this point, all parameter overrides are done. Scan the
// scopes and evaluate the parameters all the way down to
// constants.
des->evaluate_parameters();
// With the parameters evaluated down to constants, we have
// what we need to elaborate signals and memories. This pass
// creates all the NetNet and NetMemory objects for declared

View File

@ -3598,6 +3598,18 @@ class NetESignal : public NetExpr {
NetExpr*word_;
};
/*
* The Design object keeps a list of work items for processing
* elaboration. This is the type of those work items.
*/
struct elaborator_work_item_t {
explicit elaborator_work_item_t(Design*d)
: des(d) { }
virtual ~elaborator_work_item_t() { }
virtual void elaborate_runrun() =0;
protected:
Design*des;
};
/*
* This class contains an entire design. It includes processes and a
@ -3647,6 +3659,15 @@ class Design {
NetScope* find_scope(NetScope*, const std::list<hname_t>&path,
NetScope::TYPE type = NetScope::MODULE) const;
/* These members help manage elaboration of scopes. When we
get to a point in scope elaboration where we want to put
off a scope elaboration, an object of scope_elaboration_t
is pushed onto the scope_elaborations list. The scope
elaborator will go through this list elaborating scopes
until the list is empty. */
list<elaborator_work_item_t*>elaboration_work_list;
void run_elaboration_work(void);
// PARAMETERS
void run_defparams();