Elaborate parameters, tasks and functions in packages.

Get the elaboration to happen all the way to the ivl_target
interface.
This commit is contained in:
Stephen Williams 2013-04-06 17:38:36 -07:00
parent b122ec2a1a
commit 44cd9158e8
9 changed files with 157 additions and 35 deletions

View File

@ -827,6 +827,9 @@ class PECallFunction : public PExpr {
unsigned test_width_method_(Design*des, NetScope*scope,
width_mode_t&mode);
NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned expr_wid, unsigned flags) const;
unsigned elaborate_arguments_(Design*des, NetScope*scope,
NetFuncDef*def, bool need_const,
std::vector<NetExpr*>&parms,

View File

@ -38,6 +38,8 @@ class PPackage : public PScopeExtra, public LineInfo {
~PPackage();
bool elaborate_scope(Design*des, NetScope*scope);
bool elaborate_sig(Design*des, NetScope*scope) const;
bool elaborate(Design*des, NetScope*scope) const;
void pform_dump(std::ostream&out) const;
};

View File

@ -1786,7 +1786,22 @@ NetExpr* PECallFunction::elaborate_expr_pkg_(Design*des, NetScope*scope,
<< "." << endl;
}
return 0;
// Find the package that contains this definition, and use the
// package scope as the search starting point for the function
// definition.
NetScope*pscope = des->find_package(package_->pscope_name());
ivl_assert(*this, pscope);
NetFuncDef*def = des->find_function(pscope, path_);
ivl_assert(*this, def);
NetScope*dscope = def->scope();
ivl_assert(*this, dscope);
if (! check_call_matches_definition_(des, dscope))
return 0;
return elaborate_base_(des, scope, dscope, expr_wid, flags);
}
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
@ -1851,9 +1866,20 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
scope->is_const_func(false);
}
return elaborate_base_(des, scope, dscope, expr_wid, flags);
}
NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned expr_wid, unsigned flags) const
{
if (! check_call_matches_definition_(des, dscope))
return 0;
NetFuncDef*def = dscope->func_def();
bool need_const = NEED_CONST & flags;
unsigned parms_count = parms_.size();
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;

View File

@ -552,7 +552,9 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
}
collect_scope_parameters_(des, scope, parameters);
collect_scope_localparams_(des, scope, localparams);
elaborate_scope_funcs(des, scope, funcs);
elaborate_scope_tasks(des, scope, tasks);
return true;
}

View File

@ -29,6 +29,7 @@
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
@ -166,7 +167,13 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
continue;
}
(*cur).second->elaborate_sig(des, fscope);
if (debug_elaborate) {
cerr << cur->second->get_fileline() << ": elaborate_sig_funcs: "
<< "Elaborate function " << use_name
<< " in " << scope_path(fscope) << endl;
}
cur->second->elaborate_sig(des, fscope);
}
}
@ -193,6 +200,22 @@ static void elaborate_sig_classes(Design*des, NetScope*scope,
}
}
bool PPackage::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
flag = elaborate_sig_wires_(des, scope) && flag;
// After all the wires are elaborated, we are free to
// elaborate the ports of the tasks defined within this
// module. Run through them now.
elaborate_sig_funcs(des, scope, funcs);
elaborate_sig_tasks(des, scope, tasks);
return flag;
}
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;

View File

@ -4876,6 +4876,19 @@ static void elaborate_classes(Design*des, NetScope*scope,
}
}
bool PPackage::elaborate(Design*des, NetScope*scope) const
{
bool result_flag = true;
// Elaborate function methods, and...
elaborate_functions(des, scope, funcs);
// Elaborate task methods.
elaborate_tasks(des, scope, tasks);
return result_flag;
}
/*
* When a module is instantiated, it creates the scope then uses this
* method to elaborate the contents of the module.
@ -5122,11 +5135,6 @@ bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const
return result_flag;
}
struct root_elem {
Module *mod;
NetScope *scope;
};
class elaborate_package_t : public elaborator_work_item_t {
public:
elaborate_package_t(Design*d, NetScope*scope, PPackage*p)
@ -5298,9 +5306,21 @@ bool Design::check_proc_delay() const
* for each root, does the whole elaboration sequence, and fills in
* the resulting Design.
*/
struct pack_elem {
PPackage*pack;
NetScope*scope;
};
struct root_elem {
Module *mod;
NetScope *scope;
};
Design* elaborate(list<perm_string>roots)
{
svector<root_elem*> root_elems(roots.size());
vector<struct root_elem> root_elems(roots.size());
vector<struct pack_elem> pack_elems(pform_packages.size());
bool rc = true;
unsigned i = 0;
@ -5310,6 +5330,7 @@ Design* elaborate(list<perm_string>roots)
// Elaborate the packages. Package elaboration is simpler
// because there are fewer sub-scopes involved.
i = 0;
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
; pac != pform_packages.end() ; ++ pac) {
@ -5318,9 +5339,14 @@ Design* elaborate(list<perm_string>roots)
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
des->elaboration_work_list.push_back(es);
pack_elems[i].pack = pac->second;
pack_elems[i].scope = scope;
i += 1;
}
// Scan the root modules by name, and elaborate their scopes.
i = 0;
for (list<perm_string>::const_iterator root = roots.begin()
; root != roots.end() ; ++ root ) {
@ -5353,10 +5379,9 @@ Design* elaborate(list<perm_string>roots)
// Save this scope, along with its definition, in the
// "root_elems" list for later passes.
struct root_elem *r = new struct root_elem;
r->mod = rmod;
r->scope = scope;
root_elems[i++] = r;
root_elems[i].mod = rmod;
root_elems[i].scope = scope;
i += 1;
// Arrange for these scopes to be elaborated as root
// scopes. Create an "elaborate_root_scope" object to
@ -5413,23 +5438,36 @@ Design* elaborate(list<perm_string>roots)
// what we need to elaborate signals and memories. This pass
// creates all the NetNet and NetMemory objects for declared
// objects.
for (i = 0; i < root_elems.count(); i++) {
for (i = 0; i < pack_elems.size(); i += 1) {
PPackage*pack = pack_elems[i].pack;
NetScope*scope= pack_elems[i].scope;
Module *rmod = root_elems[i]->mod;
NetScope *scope = root_elems[i]->scope;
if (! pack->elaborate_sig(des, scope)) {
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << pack->pscope_name()
<< ": elaborate_sig failed!!!" << endl;
}
delete des;
return 0;
}
}
for (i = 0; i < root_elems.size(); i++) {
Module *rmod = root_elems[i].mod;
NetScope *scope = root_elems[i].scope;
scope->set_num_ports( rmod->port_count() );
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": port elaboration root "
<< rmod->port_count() << " ports" << endl;
}
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": port elaboration root "
<< rmod->port_count() << " ports" << endl;
}
if (! rmod->elaborate_sig(des, scope)) {
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": elaborate_sig failed!!!" << endl;
}
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": elaborate_sig failed!!!" << endl;
}
delete des;
return 0;
}
@ -5461,12 +5499,17 @@ Design* elaborate(list<perm_string>roots)
// Now that the structure and parameters are taken care of,
// run through the pform again and generate the full netlist.
for (i = 0; i < root_elems.count(); i++) {
Module *rmod = root_elems[i]->mod;
NetScope *scope = root_elems[i]->scope;
for (i = 0; i < pack_elems.size(); i += 1) {
PPackage*pkg = pack_elems[i].pack;
NetScope*scope = pack_elems[i].scope;
rc &= pkg->elaborate(des, scope);
}
for (i = 0; i < root_elems.size(); i++) {
Module *rmod = root_elems[i].mod;
NetScope *scope = root_elems[i].scope;
rc &= rmod->elaborate(des, scope);
delete root_elems[i];
}
if (rc == false) {

18
emit.cc
View File

@ -436,6 +436,7 @@ bool NetScope::emit_defs(struct target_t*tgt) const
bool flag = true;
switch (type_) {
case PACKAGE:
case MODULE:
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; ++ cur )
@ -470,11 +471,17 @@ int Design::emit(struct target_t*tgt) const
if (tgt->start_design(this) == false)
return -2;
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
(*scope)->emit_scope(tgt);
// enumerate package scopes
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope) {
scope->second->emit_scope(tgt);
}
// enumerate root scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); ++ scope ) {
(*scope)->emit_scope(tgt);
}
// emit nodes
bool nodes_rc = true;
@ -494,6 +501,9 @@ int Design::emit(struct target_t*tgt) const
// emit task and function definitions
bool tasks_rc = true;
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope )
tasks_rc &= scope->second->emit_defs(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); ++ scope )
tasks_rc &= (*scope)->emit_defs(tgt);

View File

@ -400,9 +400,15 @@ void NetScope::run_defparams_later(Design*des)
void Design::evaluate_parameters()
{
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
for (map<perm_string,NetScope*>::const_iterator cur = packages_.begin()
; cur != packages_.end() ; ++ cur) {
cur->second->evaluate_parameters(this);
}
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end() ; ++ scope ) {
(*scope)->evaluate_parameters(this);
}
}
void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)

View File

@ -259,6 +259,13 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
return scope;
}
for (size_t idx = 0; idx < des.packages.size(); idx += 1) {
assert(des.packages[idx]);
ivl_scope_t scope = find_scope_from_root(des.packages[idx], cur);
if (scope)
return scope;
}
for (map<const NetScope*,ivl_scope_t>::iterator idx = des.classes.begin()
; idx != des.classes.end() ; ++ idx) {
ivl_scope_t scope = find_scope_from_root(idx->second, cur);