diff --git a/PExpr.h b/PExpr.h index 0076bc5b8..74cbccd74 100644 --- a/PExpr.h +++ b/PExpr.h @@ -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&parms, diff --git a/PPackage.h b/PPackage.h index 3e498d0c4..6bd01c9c8 100644 --- a/PPackage.h +++ b/PPackage.h @@ -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; }; diff --git a/elab_expr.cc b/elab_expr.cc index 27c081521..6494262a6 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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; diff --git a/elab_scope.cc b/elab_scope.cc index 70e8b4d97..48709b30e 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -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; } diff --git a/elab_sig.cc b/elab_sig.cc index 7d2871a34..7db92eb6e 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -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; diff --git a/elaborate.cc b/elaborate.cc index 5de506473..ffff583bb 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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(listroots) { - svector root_elems(roots.size()); + vector root_elems(roots.size()); + vector pack_elems(pform_packages.size()); bool rc = true; unsigned i = 0; @@ -5310,6 +5330,7 @@ Design* elaborate(listroots) // Elaborate the packages. Package elaboration is simpler // because there are fewer sub-scopes involved. + i = 0; for (map::iterator pac = pform_packages.begin() ; pac != pform_packages.end() ; ++ pac) { @@ -5318,9 +5339,14 @@ Design* elaborate(listroots) 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::const_iterator root = roots.begin() ; root != roots.end() ; ++ root ) { @@ -5353,10 +5379,9 @@ Design* elaborate(listroots) // 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(listroots) // 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 << "" << ": 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 << "" << ": debug: " << rmod->mod_name() - << ": port elaboration root " - << rmod->port_count() << " ports" << endl; - } + if (debug_elaborate) { + cerr << "" << ": debug: " << rmod->mod_name() + << ": port elaboration root " + << rmod->port_count() << " ports" << endl; + } if (! rmod->elaborate_sig(des, scope)) { - if (debug_elaborate) { - cerr << "" << ": debug: " << rmod->mod_name() - << ": elaborate_sig failed!!!" << endl; - } + if (debug_elaborate) { + cerr << "" << ": debug: " << rmod->mod_name() + << ": elaborate_sig failed!!!" << endl; + } delete des; return 0; } @@ -5461,12 +5499,17 @@ Design* elaborate(listroots) // 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) { diff --git a/emit.cc b/emit.cc index bc7d19eb6..cab1d30d5 100644 --- a/emit.cc +++ b/emit.cc @@ -436,6 +436,7 @@ bool NetScope::emit_defs(struct target_t*tgt) const bool flag = true; switch (type_) { + case PACKAGE: case MODULE: for (map::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::const_iterator scope = root_scopes_.begin(); - scope != root_scopes_.end(); ++ scope ) - (*scope)->emit_scope(tgt); + // enumerate package scopes + for (map::const_iterator scope = packages_.begin() + ; scope != packages_.end() ; ++ scope) { + scope->second->emit_scope(tgt); + } + // enumerate root scopes + for (list::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::const_iterator scope = packages_.begin() + ; scope != packages_.end() ; ++ scope ) + tasks_rc &= scope->second->emit_defs(tgt); for (list::const_iterator scope = root_scopes_.begin() ; scope != root_scopes_.end(); ++ scope ) tasks_rc &= (*scope)->emit_defs(tgt); diff --git a/net_design.cc b/net_design.cc index 5d0c5b9d9..8f89b003a 100644 --- a/net_design.cc +++ b/net_design.cc @@ -400,9 +400,15 @@ void NetScope::run_defparams_later(Design*des) void Design::evaluate_parameters() { - for (list::const_iterator scope = root_scopes_.begin(); - scope != root_scopes_.end(); ++ scope ) + for (map::const_iterator cur = packages_.begin() + ; cur != packages_.end() ; ++ cur) { + cur->second->evaluate_parameters(this); + } + + for (list::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) diff --git a/t-dll.cc b/t-dll.cc index 409b81c56..d7d4fb234 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -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::iterator idx = des.classes.begin() ; idx != des.classes.end() ; ++ idx) { ivl_scope_t scope = find_scope_from_root(idx->second, cur);