diff --git a/compiler.h b/compiler.h index d52d6d5ab..56cc4f2b8 100644 --- a/compiler.h +++ b/compiler.h @@ -101,6 +101,7 @@ extern bool verbose_flag; extern bool debug_scopes; extern bool debug_eval_tree; extern bool debug_elaborate; +extern bool debug_emit; extern bool debug_synth2; extern bool debug_optimizer; diff --git a/design_dump.cc b/design_dump.cc index 6dc20b581..538d41211 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -1192,8 +1192,8 @@ void NetScope::dump(ostream&o) const if (is_cell()) o << " (cell)"; if (nested_module()) o << " (nested)"; if (program_block()) o << " (program)"; - - o << endl; + o << " " << children_.size() << " children, " + << classes_.size() << " classes" << endl; for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) o << " (* " << attr_key(idx) << " = " diff --git a/emit.cc b/emit.cc index 60a61f96c..bc7d19eb6 100644 --- a/emit.cc +++ b/emit.cc @@ -26,7 +26,9 @@ * target. */ # include "target.h" +# include "netclass.h" # include "netlist.h" +# include "compiler.h" # include # include # include @@ -378,16 +380,29 @@ void NetRepeat::emit_recurse(struct target_t*tgt) const statement_->emit_proc(tgt); } +void netclass_t::emit_scope(struct target_t*tgt) const +{ + class_scope_->emit_scope(tgt); + class_scope_->emit_defs(tgt); +} + void NetScope::emit_scope(struct target_t*tgt) const { + if (debug_emit) { + cerr << "NetScope::emit_scope: " + << "Emit scope basename=" << basename() << endl; + } + tgt->scope(this); for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) tgt->event(cur); for (map::const_iterator cur = classes_.begin() - ; cur != classes_.end() ; ++cur) + ; cur != classes_.end() ; ++cur) { + cur->second->emit_scope(tgt); tgt->class_type(this, cur->second); + } for (list::const_iterator cur = enum_sets_.begin() ; cur != enum_sets_.end() ; ++cur) @@ -479,8 +494,8 @@ int Design::emit(struct target_t*tgt) const // emit task and function definitions bool tasks_rc = true; - for (list::const_iterator scope = root_scopes_.begin(); - scope != root_scopes_.end(); ++ scope ) + for (list::const_iterator scope = root_scopes_.begin() + ; scope != root_scopes_.end(); ++ scope ) tasks_rc &= (*scope)->emit_defs(tgt); diff --git a/ivl_target.h b/ivl_target.h index 2a7be58c3..5e7560f59 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -354,7 +354,8 @@ typedef enum ivl_scope_type_e { IVL_SCT_BEGIN = 3, IVL_SCT_FORK = 4, IVL_SCT_GENERATE= 5, - IVL_SCT_PACKAGE = 6 + IVL_SCT_PACKAGE = 6, + IVL_SCT_CLASS = 7 } ivl_scope_type_t; /* Signals (ivl_signal_t) that are ports into the scope that contains diff --git a/ivl_target_priv.h b/ivl_target_priv.h index cb9bb554d..f6949cf07 100644 --- a/ivl_target_priv.h +++ b/ivl_target_priv.h @@ -21,10 +21,13 @@ # include "ivl_target.h" # include +# include # include # include # include +class NetScope; + /* * This header has declarations related to the ivl_target.h API that * are not to be exported outside of the core via the ivl_target.h @@ -48,6 +51,7 @@ struct ivl_design_s { ivl_process_t threads_; // Keep arrays of root scopes. + std::map classes; std::vector packages; std::vector roots; diff --git a/main.cc b/main.cc index 0ac22e2bd..ae135cfcd 100644 --- a/main.cc +++ b/main.cc @@ -166,6 +166,7 @@ bool warn_anachronisms = false; bool debug_scopes = false; bool debug_eval_tree = false; bool debug_elaborate = false; +bool debug_emit = false; bool debug_synth2 = false; bool debug_optimizer = false; @@ -592,6 +593,9 @@ static void read_iconfig_file(const char*ipath) } else if (strcmp(cp,"elaborate") == 0) { debug_elaborate = true; cerr << "debug: Enable elaborate debug" << endl; + } else if (strcmp(cp,"emit") == 0) { + debug_emit = true; + cerr << "debug: Enable emit debug" << endl; } else if (strcmp(cp,"synth2") == 0) { debug_synth2 = true; cerr << "debug: Enable synth2 debug" << endl; diff --git a/netclass.h b/netclass.h index 998900a37..65310bc19 100644 --- a/netclass.h +++ b/netclass.h @@ -64,6 +64,8 @@ class netclass_t : public ivl_type_s { void elaborate_sig(Design*des, PClass*pclass); void elaborate(Design*des, PClass*pclass); + void emit_scope(struct target_t*tgt) const; + void dump_scope(ostream&fd) const; private: diff --git a/scripts/devel-stub.conf b/scripts/devel-stub.conf index 0764294d5..4f485caa5 100644 --- a/scripts/devel-stub.conf +++ b/scripts/devel-stub.conf @@ -17,6 +17,7 @@ sys_func:vpi/va_math.sft warnings:ailnpstv debug:eval_tree debug:elaborate +debug:emit debug:elab_pexpr debug:scopes debug:synth2 diff --git a/t-dll-api.cc b/t-dll-api.cc index 7f53785e7..c7ad20ab0 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -83,11 +83,16 @@ extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes, { assert (nscopes && scopes); if (des->root_scope_list.size() == 0) { - des->root_scope_list.resize(des->packages.size() + des->roots.size()); + size_t fill = 0; + des->root_scope_list.resize(des->packages.size() + des->roots.size() + des->classes.size()); + for (map::iterator idx = des->classes.begin() + ; idx != des->classes.end() ; ++ idx) + des->root_scope_list[fill++] = idx->second; + for (size_t idx = 0 ; idx < des->packages.size() ; idx += 1) - des->root_scope_list[idx] = des->packages[idx]; + des->root_scope_list[fill++] = des->packages[idx]; for (size_t idx = 0 ; idx < des->roots.size() ; idx += 1) - des->root_scope_list[idx+des->packages.size()] = des->roots[idx]; + des->root_scope_list[fill++] = des->roots[idx]; } *scopes = &des->root_scope_list[0]; diff --git a/t-dll.cc b/t-dll.cc index 69cc9a743..4cd03970b 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -213,8 +213,9 @@ static ivl_scope_t find_scope_from_root(ivl_scope_t root, const NetScope*cur) { if (const NetScope*par = cur->parent()) { ivl_scope_t parent = find_scope_from_root(root, par); - if (parent == 0) + if (parent == 0) { return 0; + } map::iterator idx = parent->children.find(cur->fullname()); if (idx == parent->children.end()) @@ -246,12 +247,26 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur) return 0; } - ivl_scope_t scope = 0; - for (unsigned i = 0; i < des.roots.size() && scope == 0; i += 1) { - assert(des.roots[i]); - scope = find_scope_from_root(des.roots[i], cur); + if (cur->type() == NetScope::CLASS) { + ivl_scope_t tmp = des.classes[cur]; + return tmp; } - return scope; + + for (unsigned idx = 0; idx < des.roots.size(); idx += 1) { + assert(des.roots[idx]); + ivl_scope_t scope = find_scope_from_root(des.roots[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); + if (scope) + return scope; + } + + return 0; } ivl_scope_t dll_target::lookup_scope_(const NetScope*cur) @@ -534,7 +549,7 @@ void dll_target::make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp) expr_ = 0; } -void dll_target::add_root(ivl_design_s &des__, const NetScope *s) +void dll_target::add_root(const NetScope *s) { ivl_scope_t root_ = new struct ivl_scope_s; perm_string name = s->basename(); @@ -549,7 +564,19 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s) root_->lpm_ = 0; root_->def = 0; make_scope_parameters(root_, s); - root_->type_ = s->type()==NetScope::PACKAGE? IVL_SCT_PACKAGE : IVL_SCT_MODULE; + switch (s->type()) { + case NetScope::PACKAGE: + root_->type_ = IVL_SCT_PACKAGE; + break; + case NetScope::MODULE: + root_->type_ = IVL_SCT_MODULE; + break; + case NetScope::CLASS: + root_->type_ = IVL_SCT_CLASS; + break; + default: + assert(0); + } root_->tname_ = root_->name_; root_->time_precision = s->time_precision(); root_->time_units = s->time_unit(); @@ -557,7 +584,9 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s) root_->attr = fill_in_attributes(s); root_->is_auto = 0; root_->is_cell = s->is_cell(); - if (s->type()==NetScope::MODULE) { + + switch (s->type()) { + case NetScope::MODULE: root_->ports = s->module_port_nets(); if (root_->ports > 0) { root_->u_.net = new NetNet*[root_->ports]; @@ -567,11 +596,22 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s) } root_->module_ports_info = s->module_port_info(); - des__.roots.push_back(root_); + des_.roots.push_back(root_); + break; - } else { + case NetScope::PACKAGE: root_->ports = 0; - des__.packages.push_back(root_); + des_.packages.push_back(root_); + break; + + case NetScope::CLASS: + root_->ports = 0; + des_.classes[s] = root_; + break; + + default: + assert(0); + break; } } @@ -613,13 +653,13 @@ bool dll_target::start_design(const Design*des) list package_scopes = des->find_package_scopes(); for (list::const_iterator scop = package_scopes.begin() ; scop != package_scopes.end(); ++ scop ) { - add_root(des_, *scop); + add_root(*scop); } list root_scopes = des->find_root_scopes(); for (list::const_iterator scop = root_scopes.begin() ; scop != root_scopes.end(); ++ scop ) { - add_root(des_, *scop); + add_root(*scop); } target_ = (target_design_f)ivl_dlsym(dll_, LU "target_design" TU); @@ -2275,20 +2315,17 @@ void dll_target::net_probe(const NetEvProbe*) void dll_target::scope(const NetScope*net) { - ivl_scope_t scop; + if (net->parent()==0 && net->type()==NetScope::CLASS) { - if (net->parent() == 0) { - unsigned i; - scop = NULL; - for (i = 0; i < des_.roots.size() && scop == NULL; i++) { - if (strcmp(des_.roots[i]->name_, net->basename()) == 0) - scop = des_.roots[i]; - } - assert(scop); + add_root(net); + + } if (net->parent() == 0) { + + // Root scopes are already created... } else { perm_string sname = make_scope_name(net->fullname()); - scop = new struct ivl_scope_s; + ivl_scope_t scop = new struct ivl_scope_s; scop->name_ = sname; FILE_NAME(scop, net); scop->parent = find_scope(des_, net->parent()); diff --git a/t-dll.h b/t-dll.h index 1c017f5ae..e7639b0b0 100644 --- a/t-dll.h +++ b/t-dll.h @@ -167,7 +167,7 @@ struct dll_target : public target_t, public expr_scan_t { static ivl_parameter_t scope_find_param(ivl_scope_t scope, const char*name); - void add_root(ivl_design_s &des_, const NetScope *s); + void add_root(const NetScope *s); void make_assign_lvals_(const NetAssignBase*net); void sub_off_from_expr_(long); diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index fdde80a8e..b6173a00f 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1564,6 +1564,9 @@ static int show_scope(ivl_scope_t net, void*x) case IVL_SCT_TASK: fprintf(out, " task %s%s", is_auto, ivl_scope_tname(net)); break; + case IVL_SCT_CLASS: + fprintf(out, " class %s", ivl_scope_tname(net)); + break; default: fprintf(out, " type(%u) %s", ivl_scope_type(net), ivl_scope_tname(net)); @@ -1701,13 +1704,23 @@ int target_design(ivl_design_t des) ivl_design_roots(des, &root_scopes, &nroot); for (idx = 0 ; idx < nroot ; idx += 1) { - if (ivl_scope_type(root_scopes[idx]) == IVL_SCT_PACKAGE) { - fprintf(out, "package = %s;\n", - ivl_scope_name(root_scopes[idx])); - } else { - fprintf(out, "root module = %s;\n", - ivl_scope_name(root_scopes[idx])); + ivl_scope_t cur = root_scopes[idx]; + switch (ivl_scope_type(cur)) { + case IVL_SCT_CLASS: + fprintf(out, "class = %s\n", ivl_scope_name(cur)); + break; + case IVL_SCT_PACKAGE: + fprintf(out, "package = %s\n", ivl_scope_name(cur)); + break; + case IVL_SCT_MODULE: + fprintf(out, "root module = %s\n", ivl_scope_name(cur)); + break; + default: + fprintf(out, "ERROR scope %s unknown type\n", ivl_scope_name(cur)); + stub_errors += 1; + break; } + show_scope(root_scopes[idx], 0); } diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 215a0c628..f4e5d7d11 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -2138,6 +2138,12 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) const char*prefix = ivl_scope_is_auto(net) ? "auto" : ""; + /* XXXX Classes may have scopes, but we are not ready yet. for + now, ignore them as they are not needed. */ + if (ivl_scope_type(net) == IVL_SCT_CLASS) { + return 0; + } + switch (ivl_scope_type(net)) { case IVL_SCT_MODULE: type = "module"; break; case IVL_SCT_FUNCTION: type = "function"; break;