Elaborate package scopes in textual order (fix for issue #461)
When elaborating a subclass, the base class scope needs to be elaborated before the subclass scope. If the base class and subclass are defined in different packages, this requires the package scopes to be elaborated in the correct order. SystemVerilog reqires packages to be defined before they are used, so that is the order we should elaborate them in.
This commit is contained in:
parent
9fa9a9d95a
commit
ba25b55f53
43
elaborate.cc
43
elaborate.cc
|
|
@ -6766,18 +6766,18 @@ static void check_timescales()
|
|||
if (some_explicit && some_implicit)
|
||||
break;
|
||||
}
|
||||
map<perm_string,PPackage*>::iterator pkg;
|
||||
vector<PPackage*>::iterator pkg;
|
||||
if (gn_system_verilog() && !(some_explicit && some_implicit)) {
|
||||
for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
|
||||
const PPackage*pp = (*pkg).second;
|
||||
const PPackage*pp = *pkg;
|
||||
check_timescales(some_explicit, some_implicit, pp);
|
||||
if (some_explicit && some_implicit)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gn_system_verilog() && !(some_explicit && some_implicit)) {
|
||||
for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
|
||||
const PPackage*pp = pform_units[idx];
|
||||
for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) {
|
||||
const PPackage*pp = *pkg;
|
||||
// We don't need a timescale if the compilation unit
|
||||
// contains no items outside a design element.
|
||||
if (pp->parameters.empty() &&
|
||||
|
|
@ -6828,15 +6828,15 @@ static void check_timescales()
|
|||
return;
|
||||
|
||||
for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
|
||||
PPackage*pp = (*pkg).second;
|
||||
PPackage*pp = *pkg;
|
||||
if (pp->has_explicit_timescale())
|
||||
continue;
|
||||
cerr << " : -- package " << (*pkg).first
|
||||
cerr << " : -- package " << pp->pscope_name()
|
||||
<< " declared here: " << pp->get_fileline() << endl;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
|
||||
PPackage*pp = pform_units[idx];
|
||||
for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) {
|
||||
PPackage*pp = *pkg;
|
||||
if (pp->has_explicit_timescale())
|
||||
continue;
|
||||
|
||||
|
|
@ -6892,8 +6892,9 @@ Design* elaborate(list<perm_string>roots)
|
|||
// Elaborate the compilation unit scopes. From here on, these are
|
||||
// treated as an additional set of packages.
|
||||
if (gn_system_verilog()) {
|
||||
for (i = 0; i < pform_units.size(); i += 1) {
|
||||
PPackage*unit = pform_units[i];
|
||||
for (vector<PPackage*>::iterator pkg = pform_units.begin()
|
||||
; pkg != pform_units.end() ; ++pkg) {
|
||||
PPackage*unit = *pkg;
|
||||
NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
|
||||
scope->set_line(unit);
|
||||
scope->add_imports(&unit->explicit_imports);
|
||||
|
|
@ -6904,6 +6905,7 @@ Design* elaborate(list<perm_string>roots)
|
|||
|
||||
pack_elems[i].pack = unit;
|
||||
pack_elems[i].scope = scope;
|
||||
i += 1;
|
||||
|
||||
unit_scopes[unit] = scope;
|
||||
}
|
||||
|
|
@ -6914,20 +6916,19 @@ Design* elaborate(list<perm_string>roots)
|
|||
// in SystemVerilog, packages are not allowed to refer to
|
||||
// the compilation unit scope, but the VHDL preprocessor
|
||||
// assumes they can.
|
||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||
; pac != pform_packages.end() ; ++ pac) {
|
||||
for (vector<PPackage*>::iterator pkg = pform_packages.begin()
|
||||
; pkg != pform_packages.end() ; ++pkg) {
|
||||
PPackage*pack = *pkg;
|
||||
NetScope*unit_scope = unit_scopes[pack->parent_scope()];
|
||||
NetScope*scope = des->make_package_scope(pack->pscope_name(), unit_scope, false);
|
||||
scope->set_line(pack);
|
||||
scope->add_imports(&pack->explicit_imports);
|
||||
set_scope_timescale(des, scope, pack);
|
||||
|
||||
ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
|
||||
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->explicit_imports);
|
||||
set_scope_timescale(des, scope, pac->second);
|
||||
|
||||
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
|
||||
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pack);
|
||||
des->elaboration_work_list.push_back(es);
|
||||
|
||||
pack_elems[i].pack = pac->second;
|
||||
pack_elems[i].pack = pack;
|
||||
pack_elems[i].scope = scope;
|
||||
i += 1;
|
||||
}
|
||||
|
|
|
|||
6
main.cc
6
main.cc
|
|
@ -1,5 +1,5 @@
|
|||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)";
|
||||
"Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)";
|
||||
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -1142,9 +1142,9 @@ int main(int argc, char*argv[])
|
|||
pform_dump(out, *pac);
|
||||
}
|
||||
out << "PFORM DUMP PACKAGES:" << endl;
|
||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||
for (vector<PPackage*>::iterator pac = pform_packages.begin()
|
||||
; pac != pform_packages.end() ; ++ pac) {
|
||||
pform_dump(out, pac->second);
|
||||
pform_dump(out, *pac);
|
||||
}
|
||||
out << "PFORM DUMP MODULES:" << endl;
|
||||
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_parse_api_H
|
||||
#define IVL_parse_api_H
|
||||
/*
|
||||
* Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2021 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
|
||||
|
|
@ -43,7 +43,7 @@ struct enum_type_t;
|
|||
extern std::map<perm_string,Module*> pform_modules;
|
||||
extern std::map<perm_string,PUdp*> pform_primitives;
|
||||
extern std::vector<PPackage*> pform_units;
|
||||
extern std::map<perm_string,PPackage*> pform_packages;
|
||||
extern std::vector<PPackage*> pform_packages;
|
||||
|
||||
extern void pform_dump(std::ostream&out, const PClass*pac);
|
||||
extern void pform_dump(std::ostream&out, const PPackage*pac);
|
||||
|
|
|
|||
|
|
@ -29,9 +29,14 @@
|
|||
using namespace std;
|
||||
|
||||
/*
|
||||
* This is a map of packages that have been defined.
|
||||
* This is a list of packages in the order that they were defined.
|
||||
*/
|
||||
map<perm_string,PPackage*> pform_packages;
|
||||
vector<PPackage*> pform_packages;
|
||||
|
||||
/*
|
||||
* This allows us to easily check for name collisions.
|
||||
*/
|
||||
static map<perm_string,PPackage*> packages_by_name;
|
||||
|
||||
static PPackage*pform_cur_package = 0;
|
||||
|
||||
|
|
@ -51,8 +56,8 @@ void pform_end_package_declaration(const struct vlltype&loc)
|
|||
ivl_assert(loc, pform_cur_package);
|
||||
perm_string use_name = pform_cur_package->pscope_name();
|
||||
|
||||
map<perm_string,PPackage*>::const_iterator test = pform_packages.find(use_name);
|
||||
if (test != pform_packages.end()) {
|
||||
map<perm_string,PPackage*>::const_iterator test = packages_by_name.find(use_name);
|
||||
if (test != packages_by_name.end()) {
|
||||
ostringstream msg;
|
||||
msg << "Package " << use_name << " was already declared here: "
|
||||
<< test->second->get_fileline() << ends;
|
||||
|
|
@ -60,7 +65,8 @@ void pform_end_package_declaration(const struct vlltype&loc)
|
|||
}
|
||||
|
||||
|
||||
pform_packages[use_name] = pform_cur_package;
|
||||
packages_by_name[use_name] = pform_cur_package;
|
||||
pform_packages.push_back(pform_cur_package);
|
||||
pform_cur_package = 0;
|
||||
pform_pop_scope();
|
||||
}
|
||||
|
|
@ -152,8 +158,8 @@ data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt)
|
|||
PPackage* pform_test_package_identifier(const char*pkg_name)
|
||||
{
|
||||
perm_string use_name = lex_strings.make(pkg_name);
|
||||
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
|
||||
if (pcur == pform_packages.end())
|
||||
map<perm_string,PPackage*>::const_iterator pcur = packages_by_name.find(use_name);
|
||||
if (pcur == packages_by_name.end())
|
||||
return 0;
|
||||
|
||||
assert(pcur->second);
|
||||
|
|
|
|||
Loading…
Reference in New Issue