diff --git a/PExpr.cc b/PExpr.cc index 1992c0f28..1f08d20ca 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 1998-2012 Stephen Williams + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -305,12 +306,18 @@ const verireal& PEFNumber::value() const } PEIdent::PEIdent(const pform_name_t&that) -: path_(that), no_implicit_sig_(false) +: package_(0), path_(that), no_implicit_sig_(false) { } PEIdent::PEIdent(perm_string s, bool no_implicit_sig) -: no_implicit_sig_(no_implicit_sig) +: package_(0), no_implicit_sig_(no_implicit_sig) +{ + path_.push_back(name_component_t(s)); +} + +PEIdent::PEIdent(PPackage*pkg, perm_string s) +: package_(pkg), no_implicit_sig_(true) { path_.push_back(name_component_t(s)); } diff --git a/PExpr.h b/PExpr.h index c6bd2bc42..fb2a5ff80 100644 --- a/PExpr.h +++ b/PExpr.h @@ -2,6 +2,7 @@ #define __PExpr_H /* * Copyright (c) 1998-2011 Stephen Williams + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -33,6 +34,7 @@ class LexicalScope; class NetNet; class NetExpr; class NetScope; +class PPackage; /* * The PExpr class hierarchy supports the description of @@ -286,6 +288,7 @@ class PEIdent : public PExpr { public: explicit PEIdent(perm_string, bool no_implicit_sig=false); + explicit PEIdent(PPackage*pkg, perm_string name); explicit PEIdent(const pform_name_t&); ~PEIdent(); @@ -329,6 +332,7 @@ class PEIdent : public PExpr { const pform_name_t& path() const { return path_; } private: + PPackage*package_; pform_name_t path_; bool no_implicit_sig_; diff --git a/PPackage.cc b/PPackage.cc index e235dafc7..cde34c1d3 100644 --- a/PPackage.cc +++ b/PPackage.cc @@ -1,6 +1,6 @@ /* - * Copyright (c) 2012 Picture Elements, Inc. - * Stephen Williams (steve@icarus.com) + * Copyright (c) 2012 Stephen Williams (steve@icarus.com) + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU diff --git a/PPackage.h b/PPackage.h index ff0e0f96c..3e498d0c4 100644 --- a/PPackage.h +++ b/PPackage.h @@ -2,6 +2,7 @@ #define __PPackage_H /* * Copyright (c) 2012 Stephen Williams (steve@icarus.com) + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -36,6 +37,8 @@ class PPackage : public PScopeExtra, public LineInfo { explicit PPackage (perm_string name, LexicalScope*parent); ~PPackage(); + bool elaborate_scope(Design*des, NetScope*scope); + void pform_dump(std::ostream&out) const; }; diff --git a/design_dump.cc b/design_dump.cc index a5709fcc9..b908f3c72 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -1643,10 +1643,18 @@ void NetEUnary::dump(ostream&o) const void Design::dump(ostream&o) const { o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl; + + o << "PACKAGES:" << endl; + for (map::const_iterator cur = packages_.begin() + ; cur != packages_.end() ; ++cur) { + cur->second->dump(o); + } + o << "SCOPES:" << endl; for (list::const_iterator scope = root_scopes_.begin(); - scope != root_scopes_.end(); ++ scope ) + scope != root_scopes_.end(); ++ scope ) { (*scope)->dump(o); + } o << "ELABORATED NODES:" << endl; diff --git a/elab_expr.cc b/elab_expr.cc index fa8b3368a..9f4a99b21 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -24,6 +24,7 @@ # include # include "compiler.h" +# include "PPackage.h" # include "pform.h" # include "netlist.h" # include "netclass.h" @@ -2410,7 +2411,14 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) const NetExpr*ex1, *ex2; - NetScope*found_in = symbol_search(this, des, scope, path_, net, par, eve, + NetScope*use_scope = scope; + if (package_) { + use_scope = des->find_package(package_->pscope_name()); + ivl_assert(*this, use_scope); + } + + NetScope*found_in = symbol_search(this, des, use_scope, path_, + net, par, eve, ex1, ex2); // If there is a part/bit select expression, then process it @@ -2610,7 +2618,13 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, NetEvent* eve = 0; const NetExpr*ex1, *ex2; - /* NetScope*found_in = */ symbol_search(this, des, scope, path_, + NetScope*use_scope = scope; + if (package_) { + use_scope = des->find_package(package_->pscope_name()); + ivl_assert(*this, use_scope); + } + + /* NetScope*found_in = */ symbol_search(this, des, use_scope, path_, net, par, eve, ex1, ex2); @@ -2718,7 +2732,13 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, if (debug_elaborate) cerr << get_fileline() << ": PEIdent::elaborate_expr: path_=" << path_ << endl; - NetScope*found_in = symbol_search(this, des, scope, path_, + NetScope*use_scope = scope; + if (package_) { + use_scope = des->find_package(package_->pscope_name()); + ivl_assert(*this, use_scope); + } + + NetScope*found_in = symbol_search(this, des, use_scope, path_, net, par, eve, ex1, ex2); diff --git a/elab_scope.cc b/elab_scope.cc index 1341fb064..6131496f9 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -39,6 +39,7 @@ # include "PClass.h" # include "PGate.h" # include "PGenerate.h" +# include "PPackage.h" # include "PTask.h" # include "PWire.h" # include "Statement.h" @@ -495,6 +496,18 @@ class generate_schemes_work_item_t : public elaborator_work_item_t { Module*mod_; }; +bool PPackage::elaborate_scope(Design*des, NetScope*scope) +{ + if (debug_scopes) { + cerr << get_fileline() << ": debug: Elaborate package scope " + << scope_path(scope) << "." << endl; + } + + collect_scope_parameters_(des, scope, parameters); + + return true; +} + bool Module::elaborate_scope(Design*des, NetScope*scope, const replace_t&replacements) { diff --git a/elaborate.cc b/elaborate.cc index ca5545859..dda6bc92a 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -33,6 +33,7 @@ # include "pform.h" # include "PEvent.h" # include "PGenerate.h" +# include "PPackage.h" # include "PSpec.h" # include "netlist.h" # include "netvector.h" @@ -4860,6 +4861,25 @@ struct root_elem { NetScope *scope; }; +class elaborate_package_t : public elaborator_work_item_t { + public: + elaborate_package_t(Design*d, NetScope*scope, PPackage*p) + : elaborator_work_item_t(d), scope_(scope), package_(p) + { } + + ~elaborate_package_t() { } + + virtual void elaborate_runrun() + { + if (! package_->elaborate_scope(des, scope_)) + des->errors += 1; + } + + private: + NetScope*scope_; + PPackage*package_; +}; + class elaborate_root_scope_t : public elaborator_work_item_t { public: elaborate_root_scope_t(Design*des__, NetScope*scope, Module*rmod) @@ -5022,6 +5042,18 @@ Design* elaborate(listroots) // module and elaborate what I find. Design*des = new Design; + // Elaborate the packages. Package elaboration is simpler + // because there are fewer sub-scopes involved. + for (map::iterator pac = pform_packages.begin() + ; pac != pform_packages.end() ; ++ pac) { + + NetScope*scope = des->make_package_scope(pac->first); + scope->set_line(pac->second); + + elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second); + des->elaboration_work_list.push_back(es); + } + // Scan the root modules by name, and elaborate their scopes. for (list::const_iterator root = roots.begin() ; root != roots.end() ; ++ root ) { diff --git a/ivl_target.h b/ivl_target.h index 76c5a5412..2a7be58c3 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -353,7 +353,8 @@ typedef enum ivl_scope_type_e { IVL_SCT_TASK = 2, IVL_SCT_BEGIN = 3, IVL_SCT_FORK = 4, - IVL_SCT_GENERATE= 5 + IVL_SCT_GENERATE= 5, + IVL_SCT_PACKAGE = 6 } 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 195071f5f..cb9bb554d 100644 --- a/ivl_target_priv.h +++ b/ivl_target_priv.h @@ -47,8 +47,12 @@ struct ivl_design_s { ivl_process_t threads_; - ivl_scope_t *roots_; - unsigned nroots_; + // Keep arrays of root scopes. + std::vector packages; + std::vector roots; + + // This is used to implement the ivl_design_roots function. + std::vector root_scope_list; // Keep an array of constants objects. std::valarray consts; diff --git a/net_design.cc b/net_design.cc index a32ff236a..f945dcf7b 100644 --- a/net_design.cc +++ b/net_design.cc @@ -119,14 +119,39 @@ NetScope* Design::find_root_scope() return root_scopes_.front(); } -list Design::find_root_scopes() +list Design::find_root_scopes() const { return root_scopes_; } -const list Design::find_root_scopes() const +NetScope* Design::make_package_scope(perm_string name) { - return root_scopes_; + NetScope*scope; + + scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, false, false); + scope->set_module_name(scope->basename()); + packages_[name] = scope; + return scope; +} + +NetScope* Design::find_package(perm_string name) const +{ + map::const_iterator cur = packages_.find(name); + if (cur == packages_.end()) + return 0; + + return cur->second; +} + +list Design::find_package_scopes() const +{ + listres; + for (map::const_iterator cur = packages_.begin() + ; cur != packages_.end() ; ++cur) { + res.push_back (cur->second); + } + + return res; } /* diff --git a/net_scope.cc b/net_scope.cc index 6a5771636..6841813d8 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -60,7 +60,7 @@ 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); + assert(t==MODULE || t==PACKAGE); } switch (t) { @@ -71,6 +71,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bo func_ = 0; break; case NetScope::MODULE: + case NetScope::PACKAGE: module_name_ = perm_string(); break; default: /* BEGIN_END and FORK_JOIN, do nothing */ @@ -301,8 +302,7 @@ void NetScope::print_type(ostream&stream) const stream << "function"; break; case MODULE: - stream << "module <" << (module_name_ ? module_name_.str() : "") - << "> instance"; + stream << "module <" << module_name_ << "> instance"; break; case TASK: stream << "task"; @@ -310,6 +310,9 @@ void NetScope::print_type(ostream&stream) const case GENBLOCK: stream << "generate block"; break; + case PACKAGE: + stream << "package " << module_name_; + break; } } @@ -358,13 +361,13 @@ const NetFuncDef* NetScope::func_def() const void NetScope::set_module_name(perm_string n) { - assert(type_ == MODULE); - module_name_ = n; /* NOTE: n must have been permallocated. */ + assert(type_==MODULE || type_==PACKAGE); + module_name_ = n; } perm_string NetScope::module_name() const { - assert(type_ == MODULE); + assert(type_==MODULE || type_==PACKAGE); return module_name_; } diff --git a/netlist.h b/netlist.h index d6c928a38..655648738 100644 --- a/netlist.h +++ b/netlist.h @@ -2,6 +2,7 @@ #define __netlist_H /* * Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com) + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -763,7 +764,7 @@ class NetNet : public NetObj, public PortType { class NetScope : public Attrib { public: - enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK }; + enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE }; /* Create a new scope, and attach it to the given parent. The name is expected to have been permallocated. */ @@ -4281,9 +4282,10 @@ class Design { NetScope* make_root_scope(perm_string name, bool program_block); NetScope* find_root_scope(); - list find_root_scopes(); + std::list find_root_scopes() const; - const list find_root_scopes() const; + NetScope* make_package_scope(perm_string name); + std::list find_package_scopes() const; /* Attempt to set the precision to the specified value. If the precision is already more precise, the keep the precise @@ -4304,6 +4306,9 @@ class Design { NetScope* find_scope(const hname_t&path) const; NetScope* find_scope(NetScope*, const hname_t&name, NetScope::TYPE type = NetScope::MODULE) const; + + NetScope* find_package(perm_string name) const; + // Note: Try to remove these versions of find_scope. Avoid // using these in new code, use the above forms (or // symbol_search) instead. @@ -4372,6 +4377,10 @@ class Design { // tree and per-hop searches for me. listroot_scopes_; + // Keep a map of all the elaborated packages. Note that + // packages do not nest. + std::mappackages_; + // List the nodes in the design. NetNode*nodes_; // These are in support of the node functor iterator. diff --git a/parse.y b/parse.y index b6532c31d..0b40b1e9b 100644 --- a/parse.y +++ b/parse.y @@ -1,8 +1,8 @@ %{ /* - * Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com) - * Copyright CERN 2012 / Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com) + * Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -2962,6 +2962,9 @@ expr_primary delete $1; } + | IDENTIFIER K_SCOPE_RES IDENTIFIER + { $$ = pform_package_ident(@3, $1, $3); } + /* An identifier followed by an expression list in parentheses is a function call. If a system identifier, then a system function call. */ diff --git a/pform.h b/pform.h index 488fda62d..b7d5ac702 100644 --- a/pform.h +++ b/pform.h @@ -207,6 +207,9 @@ extern void pform_end_package_declaration(const struct vlltype&loc); extern void pform_package_import(const struct vlltype&loc, const char*pkg_name, const char*ident); +extern PExpr* pform_package_ident(const struct vlltype&loc, + const char*pkg_name, const char*ident); + /* * Enter/exit name scopes. The push_scope function pushes the scope * name string onto the scope hierarchy. The pop pulls it off and diff --git a/pform_dump.cc b/pform_dump.cc index c7b302592..b87b9c3ea 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -304,6 +304,8 @@ void PENumber::dump(ostream&out) const void PEIdent::dump(ostream&out) const { + if (package_) + out << package_->pscope_name() << "::"; out << path_; } diff --git a/pform_package.cc b/pform_package.cc index 62d48ee0b..60d93b3dd 100644 --- a/pform_package.cc +++ b/pform_package.cc @@ -111,3 +111,22 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char } } } + +PExpr* pform_package_ident(const struct vlltype&loc, + const char*pkg_name, const char*ident_name) +{ + perm_string use_name = lex_strings.make(pkg_name); + map::const_iterator pcur = pform_packages.find(use_name); + if (pcur == pform_packages.end()) { + ostringstream msg; + msg << "Package " << pkg_name << " not found." << ends; + VLerror(msg.str().c_str()); + return 0; + } + + assert(pcur->second); + perm_string use_ident = lex_strings.make(ident_name); + PEIdent*tmp = new PEIdent(pcur->second, use_ident); + FILE_NAME(tmp, loc); + return tmp; +} diff --git a/sv_vpi_user.h b/sv_vpi_user.h index ccdc21be5..81d983e26 100644 --- a/sv_vpi_user.h +++ b/sv_vpi_user.h @@ -43,6 +43,7 @@ EXTERN_C_START /********* OBJECT TYPES ***********/ +#define vpiPackage 600 #define vpiLongIntVar 610 #define vpiShortIntVar 611 #define vpiIntVar 612 diff --git a/t-dll-api.cc b/t-dll-api.cc index 7a7eebec5..7f53785e7 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com) + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -73,16 +74,24 @@ extern "C" ivl_scope_t ivl_design_root(ivl_design_t des) cerr << "ANACHRONISM: ivl_design_root called. " "Use ivl_design_roots instead." << endl; - assert (des->nroots_); - return des->roots_[0]; + assert (des->roots.size() > 0); + return des->roots[0]; } extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes, unsigned int *nscopes) { assert (nscopes && scopes); - *scopes = &des->roots_[0]; - *nscopes = des->nroots_; + if (des->root_scope_list.size() == 0) { + des->root_scope_list.resize(des->packages.size() + des->roots.size()); + for (size_t idx = 0 ; idx < des->packages.size() ; idx += 1) + des->root_scope_list[idx] = 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]; + } + + *scopes = &des->root_scope_list[0]; + *nscopes = des->root_scope_list.size(); } extern "C" int ivl_design_time_precision(ivl_design_t des) diff --git a/t-dll.cc b/t-dll.cc index aefdd3601..5d6bdeed4 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com) + * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -234,10 +235,21 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur) { assert(cur); + // If the scope is a PACKAGE, then it is a special kind of + // root scope and it in the packages array instead. + if (cur->type() == NetScope::PACKAGE) { + perm_string cur_name = cur->module_name(); + for (size_t idx = 0 ; idx < des.packages.size() ; idx += 1) { + if (des.packages[idx]->name_ = cur_name) + return des.packages[idx]; + } + return 0; + } + ivl_scope_t scope = 0; - for (unsigned i = 0; i < des.nroots_ && scope == 0; i += 1) { - assert(des.roots_[i]); - scope = find_scope_from_root(des.roots_[i], cur); + 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); } return scope; } @@ -537,7 +549,7 @@ 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_ = IVL_SCT_MODULE; + root_->type_ = s->type()==NetScope::PACKAGE? IVL_SCT_PACKAGE : IVL_SCT_MODULE; root_->tname_ = root_->name_; root_->time_precision = s->time_precision(); root_->time_units = s->time_unit(); @@ -545,29 +557,26 @@ 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(); - root_->ports = s->module_port_nets(); - if (root_->ports > 0) { - root_->u_.net = new NetNet*[root_->ports]; - for (unsigned idx = 0; idx < root_->ports; idx += 1) { - root_->u_.net[idx] = s->module_port_net(idx); + if (s->type()==NetScope::MODULE) { + root_->ports = s->module_port_nets(); + if (root_->ports > 0) { + root_->u_.net = new NetNet*[root_->ports]; + for (unsigned idx = 0; idx < root_->ports; idx += 1) { + root_->u_.net[idx] = s->module_port_net(idx); + } } - } - root_->module_ports_info = s->module_port_info(); + root_->module_ports_info = s->module_port_info(); - des__.nroots_++; - if (des__.roots_) - des__.roots_ = (ivl_scope_t *)realloc(des__.roots_, - des__.nroots_ * - sizeof(ivl_scope_t)); - else - des__.roots_ = (ivl_scope_t *)malloc(des__.nroots_ * - sizeof(ivl_scope_t)); - des__.roots_[des__.nroots_ - 1] = root_; + des__.roots.push_back(root_); + + } else { + root_->ports = 0; + des__.packages.push_back(root_); + } } bool dll_target::start_design(const Design*des) { - list root_scopes; const char*dll_path_ = des->get_flag("DLL"); dll_ = ivl_dlopen(dll_path_); @@ -591,8 +600,6 @@ bool dll_target::start_design(const Design*des) // Initialize the design object. des_.self = des; des_.time_precision = des->get_precision(); - des_.nroots_ = 0; - des_.roots_ = NULL; des_.disciplines.resize(disciplines.size()); unsigned idx = 0; @@ -603,11 +610,17 @@ bool dll_target::start_design(const Design*des) } assert(idx == des_.disciplines.size()); - root_scopes = des->find_root_scopes(); - for (list::const_iterator scop = root_scopes.begin(); - scop != root_scopes.end(); ++ scop ) + list package_scopes = des->find_package_scopes(); + for (list::const_iterator scop = package_scopes.begin(); + scop != package_scopes.end(); ++ scop ) { add_root(des_, *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); + } target_ = (target_design_f)ivl_dlsym(dll_, LU "target_design" TU); if (target_ == 0) { @@ -2267,9 +2280,9 @@ void dll_target::scope(const NetScope*net) if (net->parent() == 0) { unsigned i; scop = NULL; - for (i = 0; i < des_.nroots_ && scop == NULL; i++) { - if (strcmp(des_.roots_[i]->name_, net->basename()) == 0) - scop = des_.roots_[i]; + 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); @@ -2297,6 +2310,9 @@ void dll_target::scope(const NetScope*net) scop->is_cell = net->is_cell(); switch (net->type()) { + case NetScope::PACKAGE: + cerr << "?:?" << ": internal error: " + << "Package scopes should not have parents." << endl; case NetScope::MODULE: scop->type_ = IVL_SCT_MODULE; scop->tname_ = net->module_name(); diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index a434c5beb..fdde80a8e 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1701,8 +1701,13 @@ int target_design(ivl_design_t des) ivl_design_roots(des, &root_scopes, &nroot); for (idx = 0 ; idx < nroot ; idx += 1) { - fprintf(out, "root module = %s;\n", - ivl_scope_name(root_scopes[idx])); + 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])); + } show_scope(root_scopes[idx], 0); } diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 1bd1354d6..215a0c628 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -2145,6 +2145,7 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) case IVL_SCT_BEGIN: type = "begin"; break; case IVL_SCT_FORK: type = "fork"; break; case IVL_SCT_GENERATE: type = "generate"; break; + case IVL_SCT_PACKAGE: type = "package"; break; default: type = "?"; assert(0); } diff --git a/vvp/vpi_scope.cc b/vvp/vpi_scope.cc index 072839a03..5518aa998 100644 --- a/vvp/vpi_scope.cc +++ b/vvp/vpi_scope.cc @@ -346,6 +346,11 @@ struct vpiScopeModule : public __vpiScope { int get_type_code(void) const { return vpiModule; } }; +struct vpiScopePackage : public __vpiScope { + inline vpiScopePackage() { } + int get_type_code(void) const { return vpiPackage; } +}; + struct vpiScopeTask : public __vpiScope { inline vpiScopeTask() { } int get_type_code(void) const { return vpiTask; } @@ -424,6 +429,8 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, scope = new vpiScopeBegin; } else if (strcmp(base_type,"generate") == 0) { scope = new vpiScopeBegin; + } else if (strcmp(base_type,"package") == 0) { + scope = new vpiScopePackage; } else { scope = new vpiScopeModule; assert(0);