From c5fee8bdb96ebdafb018be24e6606552ddc8c60c Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 30 Sep 2014 16:06:32 -0700 Subject: [PATCH] Elaborate root tasks/functions. --- PTask.h | 6 ++++ design_dump.cc | 6 ++++ elab_scope.cc | 80 ++++++++++++++++++++++++++++++++++++++------------ elab_sig.cc | 11 +++++++ elaborate.cc | 15 ++++++++++ main.cc | 10 +++++++ net_design.cc | 23 +++++++++++++++ net_scope.cc | 1 - netlist.h | 5 ++++ parse_api.h | 5 ++++ pform.cc | 21 +++++++++---- pform_dump.cc | 39 +++++++++++++++--------- 12 files changed, 183 insertions(+), 39 deletions(-) diff --git a/PTask.h b/PTask.h index b400381a9..1b636d05a 100644 --- a/PTask.h +++ b/PTask.h @@ -49,6 +49,12 @@ class PTaskFunc : public PScope, public LineInfo { // to the class type. inline class_type_t* method_of() const { return this_type_; } + + virtual void elaborate_sig(Design*des, NetScope*scope) const =0; + virtual void elaborate(Design*des, NetScope*scope) const =0; + + virtual void dump(std::ostream&, unsigned) const =0; + protected: // Elaborate the ports list. Write into the ports vector the // NetNet pointers for the ports, and write into the pdefs the diff --git a/design_dump.cc b/design_dump.cc index 113ce5bc0..7673b1598 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -1885,6 +1885,12 @@ void Design::dump(ostream&o) const cur->second->dump_scope(o); } + o << "$ROOT TASKS/FUNCTIONS:" << endl; + for (map::const_iterator cur = root_tasks_.begin() + ; cur != root_tasks_.end() ; ++ cur) { + cur->first->dump(o); + } + o << "SCOPES:" << endl; for (list::const_iterator scope = root_scopes_.begin(); scope != root_scopes_.end(); ++ scope ) { diff --git a/elab_scope.cc b/elab_scope.cc index 98d1718e3..b5890bb2f 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -559,6 +559,25 @@ static void elaborate_scope_events_(Design*des, NetScope*scope, } } +static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task) +{ + hname_t use_name( task->pscope_name() ); + + NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK); + task_scope->is_auto(task->is_auto()); + task_scope->set_line(task); + + if (scope==0) + des->add_root_task(task_scope, task); + + if (debug_scopes) { + cerr << task->get_fileline() << ": elaborate_scope_task: " + << "Elaborate task scope " << scope_path(task_scope) << endl; + } + + task->elaborate_scope(des, task_scope); +} + static void elaborate_scope_tasks(Design*des, NetScope*scope, const map&tasks) { @@ -600,19 +619,30 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope, des->errors += 1; } - NetScope*task_scope = new NetScope(scope, use_name, - NetScope::TASK); - task_scope->is_auto((*cur).second->is_auto()); - task_scope->set_line((*cur).second); - - if (debug_scopes) - cerr << cur->second->get_fileline() << ": debug: " - << "Elaborate task scope " << scope_path(task_scope) << endl; - (*cur).second->elaborate_scope(des, task_scope); + elaborate_scope_task(des, scope, cur->second); } } +static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task) +{ + hname_t use_name( task->pscope_name() ); + + NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC); + task_scope->is_auto(task->is_auto()); + task_scope->set_line(task); + + if (scope==0) + des->add_root_task(task_scope, task); + + if (debug_scopes) { + cerr << task->get_fileline() << ": elaborate_scope_func: " + << "Elaborate task scope " << scope_path(task_scope) << endl; + } + + task->elaborate_scope(des, task_scope); +} + static void elaborate_scope_funcs(Design*des, NetScope*scope, const map&funcs) { @@ -655,19 +685,33 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope, des->errors += 1; } - NetScope*func_scope = new NetScope(scope, use_name, - NetScope::FUNC); - func_scope->is_auto((*cur).second->is_auto()); - func_scope->set_line((*cur).second); - - if (debug_scopes) - cerr << cur->second->get_fileline() << ": debug: " - << "Elaborate function scope " << scope_path(func_scope) << endl; - (*cur).second->elaborate_scope(des, func_scope); + elaborate_scope_func(des, scope, cur->second); } } +void elaborate_rootscope_tasks(Design*des) +{ + for (map::iterator cur = pform_tasks.begin() + ; cur != pform_tasks.end() ; ++ cur) { + + if (PTask*task = dynamic_cast (cur->second)) { + elaborate_scope_task(des, 0, task); + continue; + } + + if (PFunction*func = dynamic_cast(cur->second)) { + elaborate_scope_func(des, 0, func); + continue; + } + + cerr << cur->second->get_fileline() << ": internal error: " + << "elabortae_rootscope_tasks does not understand " + << "this object," << endl; + des->errors += 1; + } +} + class generate_schemes_work_item_t : public elaborator_work_item_t { public: generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod) diff --git a/elab_sig.cc b/elab_sig.cc index 316748ed4..d12561c5e 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1316,4 +1316,15 @@ void Design::root_elaborate_sig(void) cur_class->elaborate_sig(this, cur_pclass); } + + for (map::iterator cur = root_tasks_.begin() + ; cur != root_tasks_.end() ; ++ cur) { + + if (debug_elaborate) { + cerr << cur->second->get_fileline() << ": root_elaborate_sig: " + << "Elaborate_sig for root task/func " << scope_path(cur->first) << endl; + } + + cur->second->elaborate_sig(this, cur->first); + } } diff --git a/elaborate.cc b/elaborate.cc index 409ebe759..50ecd8bc2 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -5989,6 +5989,18 @@ void Design::root_elaborate(void) PClass*cur_pclass = class_to_pclass_[cur_class]; cur_class->elaborate(this, cur_pclass); } + + for (map::iterator cur = root_tasks_.begin() + ; cur != root_tasks_.end() ; ++ cur) { + + if (debug_elaborate) { + cerr << cur->second->get_fileline() << ": Design::root_elaborate: " + << "Elaborate for root task/func " << scope_path(cur->first) << endl; + } + + cur->second->elaborate(this, cur->first); + } + } /* @@ -6022,6 +6034,9 @@ Design* elaborate(listroots) // Elaborate enum sets in $root scope. elaborate_rootscope_enumerations(des); + // Elaborate tasks and functions in $root scope. + elaborate_rootscope_tasks(des); + // Elaborate classes in $root scope. elaborate_rootscope_classes(des); diff --git a/main.cc b/main.cc index 3658ba512..21d7232b1 100644 --- a/main.cc +++ b/main.cc @@ -1019,6 +1019,16 @@ int main(int argc, char*argv[]) ; cur != disciplines.end() ; ++ cur ) { pform_dump(out, (*cur).second); } + out << "PFORM DUMP $ROOT TASKS/FUNCTIONS:" << endl; + for (map::iterator cur = pform_tasks.begin() + ; cur != pform_tasks.end() ; ++ cur) { + pform_dump(out, cur->second); + } + out << "PFORM DUMP $ROOT CLASSES:" << endl; + for (map::iterator cur = pform_classes.begin() + ; cur != pform_classes.end() ; ++ cur) { + pform_dump(out, cur->second); + } out << "PFORM DUMP PACKAGES:" << endl; for (map::iterator pac = pform_packages.begin() ; pac != pform_packages.end() ; ++ pac) { diff --git a/net_design.cc b/net_design.cc index cd162d6b2..9bea1d6d9 100644 --- a/net_design.cc +++ b/net_design.cc @@ -197,7 +197,25 @@ NetScope* Design::find_scope(const std::list&path) const tmp.pop_front(); } + } + for (map::const_iterator root = root_tasks_.begin() + ; root != root_tasks_.end() ; ++ root) { + + NetScope*cur = root->first; + if (path.front() != cur->fullname()) + continue; + + std::list tmp = path; + tmp.pop_front(); + + while (cur) { + if (tmp.empty()) return cur; + + cur = cur->child( tmp.front() ); + + tmp.pop_front(); + } } return 0; @@ -831,6 +849,11 @@ NetScope* Design::find_task(NetScope*scope, const pform_name_t&name) return 0; } +void Design::add_root_task(NetScope*tscope, PTaskFunc*tf) +{ + root_tasks_[tscope] = tf; +} + void Design::add_node(NetNode*net) { assert(net->design_ == 0); diff --git a/net_scope.cc b/net_scope.cc index f3044e9f4..1d8653e79 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -135,7 +135,6 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bo time_unit_ = 0; time_prec_ = 0; time_from_timescale_ = false; - assert(t==MODULE || t==PACKAGE || t==CLASS); } switch (t) { diff --git a/netlist.h b/netlist.h index 96e8ccc27..66e36201b 100644 --- a/netlist.h +++ b/netlist.h @@ -77,6 +77,7 @@ class NetEvWait; class PClass; class PExpr; class PFunction; +class PTaskFunc; struct enum_type_t; class netclass_t; class netdarray_t; @@ -4813,6 +4814,7 @@ class Design : public Definitions { // Tasks NetScope* find_task(NetScope*scope, const pform_name_t&name); + void add_root_task(NetScope*tscope, PTaskFunc*tf); // Find a class in the $root scope. void add_class(netclass_t*cl, PClass*pclass); @@ -4852,6 +4854,9 @@ class Design : public Definitions { // packages do not nest. std::mappackages_; + // Tasks in the $root scope + std::maproot_tasks_; + // Need this for elaboration of $root scope pclass objects. std::map class_to_pclass_; diff --git a/parse_api.h b/parse_api.h index d80948c2f..a698c3bee 100644 --- a/parse_api.h +++ b/parse_api.h @@ -30,6 +30,7 @@ class Design; class Module; class PClass; class PPackage; +class PTaskFunc; class PUdp; class data_type_t; struct enum_type_t; @@ -43,13 +44,17 @@ extern std::map pform_modules; extern std::map pform_primitives; extern std::map pform_typedefs; extern std::set pform_enum_sets; +extern std::map pform_tasks; extern std::map pform_classes; extern std::map pform_packages; +extern void pform_dump(std::ostream&out, const PClass*pac); extern void pform_dump(std::ostream&out, const PPackage*pac); +extern void pform_dump(std::ostream&out, const PTaskFunc*tf); extern void elaborate_rootscope_enumerations(Design*des); extern void elaborate_rootscope_classes(Design*des); +extern void elaborate_rootscope_tasks(Design*des); /* * This code actually invokes the parser to make modules. The first diff --git a/pform.cc b/pform.cc index da7bc964f..8d6e0bdcb 100644 --- a/pform.cc +++ b/pform.cc @@ -71,6 +71,11 @@ setpform_enum_sets; */ map pform_classes; +/* + * Task and function definitions in the $root scope go here. + */ +map pform_tasks; + std::string vlltype::get_fileline() const { ostringstream buf; @@ -371,16 +376,11 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) FILE_NAME(task, loc); PScopeExtra*scopex = find_nearest_scopex(lexical_scope); - if ((scopex == 0) && (generation_flag < GN_VER2005_SV)) { + if ((scopex == 0) && !gn_system_verilog()) { cerr << task->get_fileline() << ": error: task declarations " "must be contained within a module." << endl; error_count += 1; } - if ((scopex == 0) && (generation_flag >= GN_VER2005_SV)) { - cerr << task->get_fileline() << ": sorry: task declarations " - "in the compilation unit scope are not yet supported." << endl; - error_count += 1; - } if (pform_cur_generate) { // Check if the task is already in the dictionary. @@ -402,6 +402,15 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) error_count += 1; } scopex->tasks[task->pscope_name()] = task; + + } else { + if (pform_tasks.find(task_name) != pform_tasks.end()) { + cerr << task->get_fileline() << ": error: " + << "Duplicate definition for task '" << name + << "' in $root scope." << endl; + error_count += 1; + } + pform_tasks[task_name] = task; } lexical_scope = task; diff --git a/pform_dump.cc b/pform_dump.cc index f50749f31..981fbecd2 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -31,6 +31,7 @@ # include "PGenerate.h" # include "PPackage.h" # include "PSpec.h" +# include "PTask.h" # include "discipline.h" # include "ivl_target_priv.h" # include @@ -1011,20 +1012,20 @@ void PFunction::dump(ostream&out, unsigned ind) const else out << setw(ind+8) << "" << "" << endl; - dump_ports_(out, ind); + dump_ports_(out, ind+2); - dump_parameters_(out, ind); + dump_parameters_(out, ind+2); - dump_localparams_(out, ind); + dump_localparams_(out, ind+2); - dump_events_(out, ind); + dump_events_(out, ind+2); - dump_wires_(out, ind); + dump_wires_(out, ind+2); if (statement_) - statement_->dump(out, ind); + statement_->dump(out, ind+2); else - out << setw(ind) << "" << "/* NOOP */" << endl; + out << setw(ind+2) << "" << "/* NOOP */" << endl; } void PRelease::dump(ostream&out, unsigned ind) const @@ -1053,20 +1054,20 @@ void PTask::dump(ostream&out, unsigned ind) const out << pscope_name() << ";" << endl; if (method_of()) out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl; - dump_ports_(out, ind); + dump_ports_(out, ind+2); - dump_parameters_(out, ind); + dump_parameters_(out, ind+2); - dump_localparams_(out, ind); + dump_localparams_(out, ind+2); - dump_events_(out, ind); + dump_events_(out, ind+2); - dump_wires_(out, ind); + dump_wires_(out, ind+2); if (statement_) - statement_->dump(out, ind); + statement_->dump(out, ind+2); else - out << setw(ind) << "" << "/* NOOP */" << endl; + out << setw(ind+2) << "" << "/* NOOP */" << endl; } void PTaskFunc::dump_ports_(std::ostream&out, unsigned ind) const @@ -1639,6 +1640,11 @@ void pform_dump(std::ostream&out, const ivl_discipline_s*dis) out << "enddiscipline" << endl; } +void pform_dump(std::ostream&fd, const PClass*cl) +{ + cl->dump(fd, 0); +} + void pform_dump(std::ostream&out, const PPackage*pac) { pac->pform_dump(out); @@ -1654,3 +1660,8 @@ void PPackage::pform_dump(std::ostream&out) const dump_funcs_(out, 4); out << "endpackage" << endl; } + +void pform_dump(std::ostream&fd, const PTaskFunc*obj) +{ + obj->dump(fd, 0); +}