From 55219773fdb05ada7731d3ef602fad6a045ebea9 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 21 Sep 2019 23:09:48 +0100 Subject: [PATCH] Allow nested scopes to use their parent's imports. --- elab_scope.cc | 13 ++++++++++++- elab_sig.cc | 2 +- elaborate.cc | 5 ++++- net_design.cc | 23 ++++++++++++++++++++--- net_scope.cc | 30 +++++++++++++++++++++++++++--- netlist.h | 10 ++++++++-- symbol_search.cc | 7 ++++++- 7 files changed, 78 insertions(+), 12 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index cfbc2a50d..bb3592d2d 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -542,6 +542,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) // Task methods are always automatic... method_scope->is_auto(true); method_scope->set_line(cur->second); + method_scope->add_imports(&cur->second->imports); if (debug_scopes) { cerr << cur->second->get_fileline() << ": elaborate_scope_class: " @@ -560,6 +561,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) // Function methods are always automatic... method_scope->is_auto(true); method_scope->set_line(cur->second); + method_scope->add_imports(&cur->second->imports); if (debug_scopes) { cerr << cur->second->get_fileline() << ": elaborate_scope_class: " @@ -630,6 +632,7 @@ static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task) NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK); task_scope->is_auto(task->is_auto()); task_scope->set_line(task); + task_scope->add_imports(&task->imports); if (debug_scopes) { cerr << task->get_fileline() << ": elaborate_scope_task: " @@ -692,6 +695,7 @@ static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task) NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC); task_scope->is_auto(task->is_auto()); task_scope->set_line(task); + task_scope->add_imports(&task->imports); if (debug_scopes) { cerr << task->get_fileline() << ": elaborate_scope_func: " @@ -1065,6 +1069,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); + scope->add_imports(&imports); // Set in the scope a localparam for the value of the // genvar within this instance of the generate @@ -1200,6 +1205,7 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else // for myself. That is what I will pass to the subscope. NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); + scope->add_imports(&imports); elaborate_subscope_(des, scope); @@ -1340,6 +1346,8 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container) NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); + scope->add_imports(&imports); + item->elaborate_subscope_(des, scope); return true; @@ -1395,6 +1403,7 @@ bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container) NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); + scope->add_imports(&imports); elaborate_subscope_(des, scope); @@ -1700,6 +1709,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s my_scope->set_line(get_file(), mod->get_file(), get_lineno(), mod->get_lineno()); my_scope->set_module_name(mod->mod_name()); + my_scope->add_imports(&mod->imports); for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val); @@ -1924,6 +1934,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const : NetScope::BEGIN_END); my_scope->set_line(get_file(), get_lineno()); my_scope->is_auto(scope->is_auto()); + my_scope->add_imports(&imports); // Scan the parameters in the scope, and store the information // needed to evaluate the parameter expressions. diff --git a/elab_sig.cc b/elab_sig.cc index 4b64ff901..885a9253d 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1214,7 +1214,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const } else if (enum_type_t*enum_type = dynamic_cast(set_data_type_)) { list::const_iterator sample_name = enum_type->names->begin(); - const netenum_t*use_enum = scope->find_enumeration_for_name(sample_name->name); + const netenum_t*use_enum = scope->find_enumeration_for_name(des, sample_name->name); if (debug_elaborate) { cerr << get_fileline() << ": debug: Create signal " << wtype diff --git a/elaborate.cc b/elaborate.cc index 1feb9e62c..0185c3031 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2018 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -6528,6 +6528,7 @@ Design* elaborate(listroots) PPackage*unit = pform_units[i]; NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true); scope->set_line(unit); + scope->add_imports(&unit->imports); set_scope_timescale(des, scope, unit); elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit); @@ -6552,6 +6553,7 @@ Design* elaborate(listroots) NetScope*unit_scope = unit_scopes[pac->second->parent_scope()]; NetScope*scope = des->make_package_scope(pac->first, unit_scope, false); scope->set_line(pac->second); + scope->add_imports(&pac->second->imports); set_scope_timescale(des, scope, pac->second); elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second); @@ -6593,6 +6595,7 @@ Design* elaborate(listroots) // Collect some basic properties of this scope from the // Module definition. scope->set_line(rmod); + scope->add_imports(&rmod->imports); set_scope_timescale(des, scope, rmod); // Save this scope, along with its definition, in the diff --git a/net_design.cc b/net_design.cc index b071469e2..6dc0bced0 100644 --- a/net_design.cc +++ b/net_design.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2019 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 @@ -244,7 +244,13 @@ NetScope* Design::find_scope_(NetScope*scope, const std::list&path, /* Up references may match module name */ } else { - scope = scope->child( key ); + NetScope*found_scope = scope->child(key); + if (found_scope == 0) { + found_scope = scope->find_import(this, key.peek_name()); + if (found_scope) + found_scope = found_scope->child(key); + } + scope = found_scope; if (scope == 0) break; } tmp.pop_front(); @@ -319,7 +325,13 @@ NetScope* Design::find_scope_(NetScope*scope, const hname_t&path, /* Up references may match module name */ return scope; } - return scope->child( path ); + NetScope*found_scope = scope->child(path); + if (found_scope == 0) { + found_scope = scope->find_import(this, path.peek_name()); + if (found_scope) + found_scope = found_scope->child(path); + } + return found_scope; } /* @@ -864,6 +876,11 @@ NetNet* Design::find_signal(NetScope*scope, pform_name_t path) if (NetNet*net = scope->find_signal(key)) return net; + if (NetScope*import_scope = scope->find_import(this, key)) { + scope = import_scope; + continue; + } + if (scope->type() == NetScope::MODULE) break; diff --git a/net_scope.cc b/net_scope.cc index 006cbd5c2..480edf3b4 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch) * * This source code is free software; you can redistribute it @@ -25,6 +25,7 @@ # include "netclass.h" # include "netenum.h" # include "netvector.h" +# include "PPackage.h" # include # include # include @@ -117,6 +118,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, NetScope*in_u : type_(t), name_(n), nested_module_(nest), program_block_(program), is_interface_(interface), is_unit_(compilation_unit), unit_(in_unit), up_(up) { + imports_ = 0; events_ = 0; lcounter_ = 0; is_auto_ = false; @@ -205,16 +207,38 @@ void NetScope::set_line(perm_string file, perm_string def_file, def_lineno_ = def_lineno; } +void NetScope::add_imports(const map*imports) +{ + if (!imports->empty()) + imports_ = imports; +} + +NetScope*NetScope::find_import(const Design*des, perm_string name) +{ + if (imports_ == 0) + return 0; + + map::const_iterator cur = imports_->find(name); + if (cur != imports_->end()) { + return des->find_package(cur->second->pscope_name()); + } else + return 0; +} + /* * Look for the enumeration in the current scope and any parent scopes. */ -const netenum_t*NetScope::find_enumeration_for_name(perm_string name) +const netenum_t*NetScope::find_enumeration_for_name(const Design*des, perm_string name) { NetScope *cur_scope = this; while (cur_scope) { NetEConstEnum*tmp = cur_scope->enum_names_[name]; if (tmp) break; - cur_scope = cur_scope->parent(); + NetScope*import_scope = cur_scope->find_import(des, name); + if (import_scope) + cur_scope = import_scope; + else + cur_scope = cur_scope->parent(); if (cur_scope == 0) cur_scope = unit_; } diff --git a/netlist.h b/netlist.h index 31cfc889e..17602388e 100644 --- a/netlist.h +++ b/netlist.h @@ -1,7 +1,7 @@ #ifndef IVL_netlist_H #define IVL_netlist_H /* - * Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -77,6 +77,7 @@ class NetEvWait; class PClass; class PExpr; class PFunction; +class PPackage; class PTaskFunc; struct enum_type_t; class netclass_t; @@ -942,9 +943,12 @@ class NetScope : public Definitions, public Attrib { if a unique name couldn't be generated. */ bool auto_name(const char* prefix, char pad, const char* suffix); + void add_imports(const map*imports); + NetScope*find_import(const Design*des, perm_string name); + /* Routine to search for the enumeration given a name. It basically * does what enumeration_for_name() does but searched the hierarchy. */ - const netenum_t*find_enumeration_for_name(perm_string name); + const netenum_t*find_enumeration_for_name(const Design*des, perm_string name); /* Parameters exist within a scope, and these methods allow one to manipulate the set. In these cases, the name is the @@ -1269,6 +1273,8 @@ class NetScope : public Definitions, public Attrib { signed char time_unit_, time_prec_; bool time_from_timescale_; + const map*imports_; + NetEvent *events_; map genvars_; diff --git a/symbol_search.cc b/symbol_search.cc index 8b8e22239..527ebe6c5 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-2019 Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -132,6 +132,11 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, return true; } + if (NetScope*import_scope = scope->find_import(des, path_tail.name)) { + scope = import_scope; + continue; + } + if (recurse_flag) { bool flag = false; hname_t path_item = eval_path_component(des, start_scope, path_tail, flag);