Support separate compilation units in SystemVerilog.
The compilation unit scope is now treated as a specialised form of package (with an automatically generated name). All items declared outside a design element are added to the current compilation unit package. Apart from when searching for a symbol, once we get into elaboration we can treat these just like any other package.
This commit is contained in:
parent
dfddbea26b
commit
988816c0b1
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -1390,6 +1390,8 @@ void NetScope::dump(ostream&o) const
|
||||||
if (is_interface()) o << " (interface)";
|
if (is_interface()) o << " (interface)";
|
||||||
o << " " << children_.size() << " children, "
|
o << " " << children_.size() << " children, "
|
||||||
<< classes_.size() << " classes" << endl;
|
<< classes_.size() << " classes" << endl;
|
||||||
|
if (unit() && !is_unit())
|
||||||
|
o << " in compilation unit " << unit()->basename() << endl;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||||
o << " (* " << attr_key(idx) << " = "
|
o << " (* " << attr_key(idx) << " = "
|
||||||
|
|
@ -1902,18 +1904,6 @@ void Design::dump(ostream&o) const
|
||||||
cur->second->dump(o);
|
cur->second->dump(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
o << "$ROOT CLASSES:" << endl;
|
|
||||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
|
||||||
; cur != classes_.end() ; ++cur) {
|
|
||||||
cur->second->dump_scope(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
o << "$ROOT TASKS/FUNCTIONS:" << endl;
|
|
||||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
|
||||||
; cur != root_tasks_.end() ; ++ cur) {
|
|
||||||
cur->first->dump(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
o << "SCOPES:" << endl;
|
o << "SCOPES:" << endl;
|
||||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||||
scope != root_scopes_.end(); ++ scope ) {
|
scope != root_scopes_.end(); ++ scope ) {
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,7 @@ static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Elaborate the enumeration into the given scope. If scope==0, then
|
* Elaborate the enumeration into the given scope.
|
||||||
* the enumeration goes into $root instead of a scope.
|
|
||||||
*/
|
*/
|
||||||
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
enum_type_t*enum_type)
|
enum_type_t*enum_type)
|
||||||
|
|
@ -193,10 +192,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
enum_type);
|
enum_type);
|
||||||
|
|
||||||
use_enum->set_line(enum_type->li);
|
use_enum->set_line(enum_type->li);
|
||||||
if (scope)
|
scope->add_enumeration_set(enum_type, use_enum);
|
||||||
scope->add_enumeration_set(enum_type, use_enum);
|
|
||||||
else
|
|
||||||
des->add_enumeration_set(enum_type, use_enum);
|
|
||||||
|
|
||||||
size_t name_idx = 0;
|
size_t name_idx = 0;
|
||||||
// Find the enumeration width.
|
// Find the enumeration width.
|
||||||
|
|
@ -364,10 +360,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
|
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
|
||||||
if (scope)
|
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
|
||||||
else
|
|
||||||
rc_flag &= des->add_enumeration_name(use_enum, cur->name);
|
|
||||||
|
|
||||||
if (! rc_flag) {
|
if (! rc_flag) {
|
||||||
cerr << use_enum->get_fileline()
|
cerr << use_enum->get_fileline()
|
||||||
|
|
@ -397,15 +390,6 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void elaborate_rootscope_enumerations(Design*des)
|
|
||||||
{
|
|
||||||
for (set<enum_type_t*>::const_iterator cur = pform_enum_sets.begin()
|
|
||||||
; cur != pform_enum_sets.end() ; ++ cur) {
|
|
||||||
enum_type_t*curp = *cur;
|
|
||||||
elaborate_scope_enumeration(des, 0, curp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the pclass includes an implicit and explicit constructor, then
|
* If the pclass includes an implicit and explicit constructor, then
|
||||||
* merge the implicit constructor into the explicit constructor as
|
* merge the implicit constructor into the explicit constructor as
|
||||||
|
|
@ -509,10 +493,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
|
|
||||||
netclass_t*use_base_class = 0;
|
netclass_t*use_base_class = 0;
|
||||||
if (base_class) {
|
if (base_class) {
|
||||||
if (scope)
|
use_base_class = scope->find_class(base_class->name);
|
||||||
use_base_class = scope->find_class(base_class->name);
|
|
||||||
if (use_base_class == 0)
|
|
||||||
use_base_class = des->find_class(base_class->name);
|
|
||||||
if (use_base_class == 0) {
|
if (use_base_class == 0) {
|
||||||
cerr << pclass->get_fileline() << ": error: "
|
cerr << pclass->get_fileline() << ": error: "
|
||||||
<< "Base class " << base_class->name
|
<< "Base class " << base_class->name
|
||||||
|
|
@ -527,9 +508,10 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
use_type->save_elaborated_type = use_class;
|
use_type->save_elaborated_type = use_class;
|
||||||
|
|
||||||
// Class scopes have no parent scope, because references are
|
// Class scopes have no parent scope, because references are
|
||||||
// not allowed to escape a class method.
|
// not allowed to escape a class method. But they are allowed
|
||||||
|
// to reference the compilation unit scope.
|
||||||
NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()),
|
NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()),
|
||||||
NetScope::CLASS);
|
NetScope::CLASS, scope->unit());
|
||||||
class_scope->set_line(pclass);
|
class_scope->set_line(pclass);
|
||||||
class_scope->set_class_def(use_class);
|
class_scope->set_class_def(use_class);
|
||||||
use_class->set_class_scope(class_scope);
|
use_class->set_class_scope(class_scope);
|
||||||
|
|
@ -588,12 +570,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
cur->second->elaborate_scope(des, method_scope);
|
cur->second->elaborate_scope(des, method_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope) {
|
scope->add_class(use_class);
|
||||||
scope->add_class(use_class);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
des->add_class(use_class, pclass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||||
|
|
@ -605,14 +582,6 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void elaborate_rootscope_classes(Design*des)
|
|
||||||
{
|
|
||||||
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
|
|
||||||
blend_class_constructors(pform_classes[idx]);
|
|
||||||
elaborate_scope_class(des, 0, pform_classes[idx]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||||
const Module::replace_t&replacements)
|
const Module::replace_t&replacements)
|
||||||
{
|
{
|
||||||
|
|
@ -662,11 +631,6 @@ static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task)
|
||||||
task_scope->is_auto(task->is_auto());
|
task_scope->is_auto(task->is_auto());
|
||||||
task_scope->set_line(task);
|
task_scope->set_line(task);
|
||||||
|
|
||||||
if (scope==0) {
|
|
||||||
set_scope_timescale(des, task_scope, task);
|
|
||||||
des->add_root_task(task_scope, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
||||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||||
|
|
@ -729,11 +693,6 @@ static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task)
|
||||||
task_scope->is_auto(task->is_auto());
|
task_scope->is_auto(task->is_auto());
|
||||||
task_scope->set_line(task);
|
task_scope->set_line(task);
|
||||||
|
|
||||||
if (scope==0) {
|
|
||||||
set_scope_timescale(des, task_scope, task);
|
|
||||||
des->add_root_task(task_scope, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
||||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||||
|
|
@ -789,28 +748,6 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void elaborate_rootscope_tasks(Design*des)
|
|
||||||
{
|
|
||||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
|
||||||
; cur != pform_tasks.end() ; ++ cur) {
|
|
||||||
|
|
||||||
if (PTask*task = dynamic_cast<PTask*> (cur->second)) {
|
|
||||||
elaborate_scope_task(des, 0, task);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PFunction*func = dynamic_cast<PFunction*>(cur->second)) {
|
|
||||||
elaborate_scope_func(des, 0, func);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cerr << cur->second->get_fileline() << ": internal error: "
|
|
||||||
<< "elaborate_rootscope_tasks does not understand "
|
|
||||||
<< "this object," << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class generate_schemes_work_item_t : public elaborator_work_item_t {
|
class generate_schemes_work_item_t : public elaborator_work_item_t {
|
||||||
public:
|
public:
|
||||||
generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod)
|
generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod)
|
||||||
|
|
@ -1756,7 +1693,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||||
// Create the new scope as a MODULE with my name. Note
|
// Create the new scope as a MODULE with my name. Note
|
||||||
// that if this is a nested module, mark it thus so that
|
// that if this is a nested module, mark it thus so that
|
||||||
// scope searches will continue into the parent scope.
|
// scope searches will continue into the parent scope.
|
||||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
|
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE, 0,
|
||||||
bound_type_? true : false,
|
bound_type_? true : false,
|
||||||
mod->program_block,
|
mod->program_block,
|
||||||
mod->is_interface);
|
mod->is_interface);
|
||||||
|
|
|
||||||
26
elab_sig.cc
26
elab_sig.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -1333,27 +1333,3 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Design::root_elaborate_sig(void)
|
|
||||||
{
|
|
||||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
|
||||||
; cur != classes_.end() ; ++ cur) {
|
|
||||||
|
|
||||||
netclass_t*cur_class = cur->second;
|
|
||||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
|
||||||
|
|
||||||
cur_class->elaborate_sig(this, cur_pclass);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (map<NetScope*,PTaskFunc*>::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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
13
elab_type.cc
13
elab_type.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2012-2017 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -78,9 +78,8 @@ static void elaborate_array_ranges(Design*des, NetScope*scope,
|
||||||
*/
|
*/
|
||||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||||
{
|
{
|
||||||
|
ivl_assert(*this, scope);
|
||||||
Definitions*use_definitions = scope;
|
Definitions*use_definitions = scope;
|
||||||
if (use_definitions == 0)
|
|
||||||
use_definitions = des;
|
|
||||||
|
|
||||||
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||||
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
|
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
|
||||||
|
|
@ -147,13 +146,13 @@ ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||||
* available at the right time. At that time, the netenum_t* object is
|
* available at the right time. At that time, the netenum_t* object is
|
||||||
* stashed in the scope so that I can retrieve it here.
|
* stashed in the scope so that I can retrieve it here.
|
||||||
*/
|
*/
|
||||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
ivl_type_s* enum_type_t::elaborate_type_raw(Design*, NetScope*scope) const
|
||||||
{
|
{
|
||||||
ivl_assert(*this, scope);
|
ivl_assert(*this, scope);
|
||||||
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
||||||
if (tmp) return tmp;
|
if (tmp == 0 && scope->unit()) {
|
||||||
|
tmp = scope->unit()->enumeration_for_key(this);
|
||||||
tmp = des->enumeration_for_key(this);
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
72
elaborate.cc
72
elaborate.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -6170,28 +6170,6 @@ bool Design::check_proc_delay() const
|
||||||
return result_flag;
|
return result_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::root_elaborate(void)
|
|
||||||
{
|
|
||||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
|
||||||
; cur != classes_.end() ; ++ cur) {
|
|
||||||
netclass_t*cur_class = cur->second;
|
|
||||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
|
||||||
cur_class->elaborate(this, cur_pclass);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (map<NetScope*,PTaskFunc*>::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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is the root of all elaboration. The input is the list
|
* This function is the root of all elaboration. The input is the list
|
||||||
* of root module names. The function locates the Module definitions
|
* of root module names. The function locates the Module definitions
|
||||||
|
|
@ -6211,8 +6189,13 @@ struct root_elem {
|
||||||
|
|
||||||
Design* elaborate(list<perm_string>roots)
|
Design* elaborate(list<perm_string>roots)
|
||||||
{
|
{
|
||||||
|
unsigned npackages = pform_packages.size();
|
||||||
|
if (gn_system_verilog())
|
||||||
|
npackages += pform_units.size();
|
||||||
|
|
||||||
vector<struct root_elem> root_elems(roots.size());
|
vector<struct root_elem> root_elems(roots.size());
|
||||||
vector<struct pack_elem> pack_elems(pform_packages.size());
|
vector<struct pack_elem> pack_elems(npackages);
|
||||||
|
map<LexicalScope*,NetScope*> unit_scopes;
|
||||||
bool rc = true;
|
bool rc = true;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
|
|
@ -6220,23 +6203,36 @@ Design* elaborate(list<perm_string>roots)
|
||||||
// module and elaborate what I find.
|
// module and elaborate what I find.
|
||||||
Design*des = new Design;
|
Design*des = new Design;
|
||||||
|
|
||||||
// Elaborate enum sets in $root scope.
|
// Elaborate the compilation unit scopes. From here on, these are
|
||||||
elaborate_rootscope_enumerations(des);
|
// 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];
|
||||||
|
NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
|
||||||
|
scope->set_line(unit);
|
||||||
|
set_scope_timescale(des, scope, unit);
|
||||||
|
|
||||||
// Elaborate tasks and functions in $root scope.
|
elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit);
|
||||||
elaborate_rootscope_tasks(des);
|
des->elaboration_work_list.push_back(es);
|
||||||
|
|
||||||
// Elaborate classes in $root scope.
|
pack_elems[i].pack = unit;
|
||||||
elaborate_rootscope_classes(des);
|
pack_elems[i].scope = scope;
|
||||||
|
|
||||||
|
unit_scopes[unit] = scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Elaborate the packages. Package elaboration is simpler
|
// Elaborate the packages. Package elaboration is simpler
|
||||||
// because there are fewer sub-scopes involved.
|
// because there are fewer sub-scopes involved. Note that
|
||||||
i = 0;
|
// 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()
|
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||||
; pac != pform_packages.end() ; ++ pac) {
|
; pac != pform_packages.end() ; ++ pac) {
|
||||||
|
|
||||||
ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
|
ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
|
||||||
NetScope*scope = des->make_package_scope(pac->first);
|
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->set_line(pac->second);
|
||||||
set_scope_timescale(des, scope, pac->second);
|
set_scope_timescale(des, scope, pac->second);
|
||||||
|
|
||||||
|
|
@ -6267,9 +6263,13 @@ Design* elaborate(list<perm_string>roots)
|
||||||
// Get the module definition for this root instance.
|
// Get the module definition for this root instance.
|
||||||
Module *rmod = (*mod).second;
|
Module *rmod = (*mod).second;
|
||||||
|
|
||||||
|
// Get the compilation unit scope for this module.
|
||||||
|
NetScope*unit_scope = unit_scopes[rmod->parent_scope()];
|
||||||
|
|
||||||
// Make the root scope. This makes a NetScope object and
|
// Make the root scope. This makes a NetScope object and
|
||||||
// pushes it into the list of root scopes in the Design.
|
// pushes it into the list of root scopes in the Design.
|
||||||
NetScope*scope = des->make_root_scope(*root, rmod->program_block,
|
NetScope*scope = des->make_root_scope(*root, unit_scope,
|
||||||
|
rmod->program_block,
|
||||||
rmod->is_interface);
|
rmod->is_interface);
|
||||||
|
|
||||||
// Collect some basic properties of this scope from the
|
// Collect some basic properties of this scope from the
|
||||||
|
|
@ -6367,8 +6367,6 @@ Design* elaborate(list<perm_string>roots)
|
||||||
<< "Start calling $root elaborate_sig methods." << endl;
|
<< "Start calling $root elaborate_sig methods." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
des->root_elaborate_sig();
|
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << "<toplevel>: elaborate: "
|
cerr << "<toplevel>: elaborate: "
|
||||||
<< "Start calling root module elaborate_sig methods." << endl;
|
<< "Start calling root module elaborate_sig methods." << endl;
|
||||||
|
|
@ -6430,8 +6428,6 @@ Design* elaborate(list<perm_string>roots)
|
||||||
rc &= pkg->elaborate(des, scope);
|
rc &= pkg->elaborate(des, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
des->root_elaborate();
|
|
||||||
|
|
||||||
for (i = 0; i < root_elems.size(); i++) {
|
for (i = 0; i < root_elems.size(); i++) {
|
||||||
Module *rmod = root_elems[i].mod;
|
Module *rmod = root_elems[i].mod;
|
||||||
NetScope *scope = root_elems[i].scope;
|
NetScope *scope = root_elems[i].scope;
|
||||||
|
|
|
||||||
20
emit.cc
20
emit.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -510,24 +510,12 @@ int Design::emit(struct target_t*tgt) const
|
||||||
if (tgt->start_design(this) == false)
|
if (tgt->start_design(this) == false)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
|
||||||
; scope != root_tasks_.end() ; ++ scope) {
|
|
||||||
scope->first->emit_scope(tgt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// enumerate package scopes
|
// enumerate package scopes
|
||||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||||
; scope != packages_.end() ; ++ scope) {
|
; scope != packages_.end() ; ++ scope) {
|
||||||
scope->second->emit_scope(tgt);
|
scope->second->emit_scope(tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
|
||||||
; cur != classes_.end() ; ++cur) {
|
|
||||||
const NetScope*use_scope = cur->second->class_scope();
|
|
||||||
cur->second->emit_scope(tgt);
|
|
||||||
tgt->class_type(use_scope, cur->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// enumerate root scopes
|
// enumerate root scopes
|
||||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||||
; scope != root_scopes_.end(); ++ scope ) {
|
; scope != root_scopes_.end(); ++ scope ) {
|
||||||
|
|
@ -552,12 +540,6 @@ int Design::emit(struct target_t*tgt) const
|
||||||
|
|
||||||
// emit task and function definitions
|
// emit task and function definitions
|
||||||
bool tasks_rc = true;
|
bool tasks_rc = true;
|
||||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
|
||||||
; scope != root_tasks_.end() ; ++ scope)
|
|
||||||
tasks_rc &= scope->first->emit_defs(tgt);
|
|
||||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
|
||||||
; cur != classes_.end() ; ++cur)
|
|
||||||
tasks_rc &= cur->second->emit_defs(tgt);
|
|
||||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||||
; scope != packages_.end() ; ++ scope )
|
; scope != packages_.end() ; ++ scope )
|
||||||
tasks_rc &= scope->second->emit_defs(tgt);
|
tasks_rc &= scope->second->emit_defs(tgt);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_ivl_target_priv_H
|
#ifndef IVL_ivl_target_priv_H
|
||||||
#define IVL_ivl_target_priv_H
|
#define IVL_ivl_target_priv_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2008-2017 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -52,7 +52,6 @@ struct ivl_design_s {
|
||||||
|
|
||||||
// Keep arrays of root scopes.
|
// Keep arrays of root scopes.
|
||||||
std::map<const NetScope*,ivl_scope_t> classes;
|
std::map<const NetScope*,ivl_scope_t> classes;
|
||||||
std::map<const NetScope*,ivl_scope_t> root_tasks;
|
|
||||||
std::vector<ivl_scope_t> packages;
|
std::vector<ivl_scope_t> packages;
|
||||||
std::vector<ivl_scope_t> roots;
|
std::vector<ivl_scope_t> roots;
|
||||||
|
|
||||||
|
|
|
||||||
16
main.cc
16
main.cc
|
|
@ -1103,21 +1103,11 @@ int main(int argc, char*argv[])
|
||||||
; cur != disciplines.end() ; ++ cur ) {
|
; cur != disciplines.end() ; ++ cur ) {
|
||||||
pform_dump(out, (*cur).second);
|
pform_dump(out, (*cur).second);
|
||||||
}
|
}
|
||||||
out << "PFORM DUMP $ROOT TASKS/FUNCTIONS:" << endl;
|
|
||||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
|
||||||
; cur != pform_tasks.end() ; ++ cur) {
|
|
||||||
pform_dump(out, cur->second);
|
|
||||||
}
|
|
||||||
out << "PFORM DUMP $ROOT CLASSES:" << endl;
|
|
||||||
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
|
|
||||||
pform_dump(out, pform_classes[idx]);
|
|
||||||
}
|
|
||||||
out << "PFORM DUMP PACKAGES:" << endl;
|
out << "PFORM DUMP PACKAGES:" << endl;
|
||||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||||
; pac != pform_packages.end() ; ++ pac) {
|
; pac != pform_packages.end() ; ++ pac) {
|
||||||
pform_dump(out, pac->second);
|
pform_dump(out, pac->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "PFORM DUMP MODULES:" << endl;
|
out << "PFORM DUMP MODULES:" << endl;
|
||||||
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
|
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
|
||||||
; mod != pform_modules.end() ; ++ mod ) {
|
; mod != pform_modules.end() ; ++ mod ) {
|
||||||
|
|
@ -1235,12 +1225,6 @@ int main(int argc, char*argv[])
|
||||||
(*idx).second = 0;
|
(*idx).second = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(map<perm_string,data_type_t*>::iterator it = pform_typedefs.begin()
|
|
||||||
; it != pform_typedefs.end() ; ++it) {
|
|
||||||
delete (*it).second;
|
|
||||||
(*it).second = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose_flag) {
|
if (verbose_flag) {
|
||||||
if (times_flag) {
|
if (times_flag) {
|
||||||
times(cycles+2);
|
times(cycles+2);
|
||||||
|
|
|
||||||
207
net_design.cc
207
net_design.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -101,11 +101,11 @@ uint64_t Design::scale_to_precision(uint64_t val,
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope* Design::make_root_scope(perm_string root, bool program_block,
|
NetScope* Design::make_root_scope(perm_string root, NetScope*unit_scope,
|
||||||
bool is_interface)
|
bool program_block, bool is_interface)
|
||||||
{
|
{
|
||||||
NetScope *root_scope_;
|
NetScope *root_scope_;
|
||||||
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE,
|
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE, unit_scope,
|
||||||
false, program_block, is_interface);
|
false, program_block, is_interface);
|
||||||
/* This relies on the fact that the basename return value is
|
/* This relies on the fact that the basename return value is
|
||||||
permallocated. */
|
permallocated. */
|
||||||
|
|
@ -125,31 +125,18 @@ list<NetScope*> Design::find_root_scopes() const
|
||||||
return root_scopes_;
|
return root_scopes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope* Design::make_package_scope(perm_string name)
|
NetScope* Design::make_package_scope(perm_string name, NetScope*unit_scope,
|
||||||
|
bool is_unit)
|
||||||
{
|
{
|
||||||
NetScope*scope;
|
NetScope*scope;
|
||||||
|
|
||||||
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, false, false);
|
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, unit_scope,
|
||||||
|
false, false, false, is_unit);
|
||||||
scope->set_module_name(scope->basename());
|
scope->set_module_name(scope->basename());
|
||||||
packages_[name] = scope;
|
packages_[name] = scope;
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::add_class(netclass_t*cl, PClass*pclass)
|
|
||||||
{
|
|
||||||
Definitions::add_class(cl);
|
|
||||||
class_to_pclass_[cl] = pclass;
|
|
||||||
}
|
|
||||||
|
|
||||||
netclass_t* Design::find_class(perm_string name) const
|
|
||||||
{
|
|
||||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
|
||||||
if (cur != classes_.end())
|
|
||||||
return cur->second;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetScope* Design::find_package(perm_string name) const
|
NetScope* Design::find_package(perm_string name) const
|
||||||
{
|
{
|
||||||
map<perm_string,NetScope*>::const_iterator cur = packages_.find(name);
|
map<perm_string,NetScope*>::const_iterator cur = packages_.find(name);
|
||||||
|
|
@ -170,17 +157,6 @@ list<NetScope*> Design::find_package_scopes() const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
list<NetScope*> Design::find_roottask_scopes() const
|
|
||||||
{
|
|
||||||
list<NetScope*>res;
|
|
||||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
|
||||||
; cur != root_tasks_.end() ; ++ cur) {
|
|
||||||
res.push_back (cur->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method locates a scope in the design, given its rooted
|
* This method locates a scope in the design, given its rooted
|
||||||
* hierarchical name. Each component of the key is used to scan one
|
* hierarchical name. Each component of the key is used to scan one
|
||||||
|
|
@ -211,25 +187,6 @@ NetScope* Design::find_scope(const std::list<hname_t>&path) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<NetScope*,PTaskFunc*>::const_iterator root = root_tasks_.begin()
|
|
||||||
; root != root_tasks_.end() ; ++ root) {
|
|
||||||
|
|
||||||
NetScope*cur = root->first;
|
|
||||||
if (path.front() != cur->fullname())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::list<hname_t> tmp = path;
|
|
||||||
tmp.pop_front();
|
|
||||||
|
|
||||||
while (cur) {
|
|
||||||
if (tmp.empty()) return cur;
|
|
||||||
|
|
||||||
cur = cur->child( tmp.front() );
|
|
||||||
|
|
||||||
tmp.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -253,6 +210,49 @@ NetScope* Design::find_scope(const hname_t&path) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_design_unit(NetScope*scope)
|
||||||
|
{
|
||||||
|
return (scope->type() == NetScope::MODULE && !scope->nested_module())
|
||||||
|
|| (scope->type() == NetScope::PACKAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_subroutine(NetScope::TYPE type)
|
||||||
|
{
|
||||||
|
return type == NetScope::TASK || type == NetScope::FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method locates a scope within another scope, given its relative
|
||||||
|
* hierarchical name. Each component of the key is used to scan one
|
||||||
|
* more step down the tree until the name runs out or the search
|
||||||
|
* fails.
|
||||||
|
*/
|
||||||
|
NetScope* Design::find_scope_(NetScope*scope, const std::list<hname_t>&path,
|
||||||
|
NetScope::TYPE type) const
|
||||||
|
{
|
||||||
|
std::list<hname_t> tmp = path;
|
||||||
|
|
||||||
|
do {
|
||||||
|
hname_t key = tmp.front();
|
||||||
|
/* If we are looking for a module or we are not
|
||||||
|
* looking at the last path component check for
|
||||||
|
* a name match (second line). */
|
||||||
|
if (scope->type() == NetScope::MODULE
|
||||||
|
&& (type == NetScope::MODULE || tmp.size() > 1)
|
||||||
|
&& scope->module_name()==key.peek_name()) {
|
||||||
|
|
||||||
|
/* Up references may match module name */
|
||||||
|
|
||||||
|
} else {
|
||||||
|
scope = scope->child( key );
|
||||||
|
if (scope == 0) break;
|
||||||
|
}
|
||||||
|
tmp.pop_front();
|
||||||
|
} while (! tmp.empty());
|
||||||
|
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a relative lookup of a scope by name. The starting point is
|
* This is a relative lookup of a scope by name. The starting point is
|
||||||
* the scope parameter within which I start looking for the scope. If
|
* the scope parameter within which I start looking for the scope. If
|
||||||
|
|
@ -266,36 +266,62 @@ NetScope* Design::find_scope(NetScope*scope, const std::list<hname_t>&path,
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
return scope;
|
return scope;
|
||||||
|
|
||||||
for ( ; scope ; scope = scope->parent()) {
|
// Record the compilation unit scope for use later.
|
||||||
|
NetScope*unit_scope = scope->unit();
|
||||||
|
|
||||||
std::list<hname_t> tmp = path;
|
// First search upwards through the hierarchy.
|
||||||
|
while (scope) {
|
||||||
|
NetScope*found_scope = find_scope_(scope, path, type);
|
||||||
|
if (found_scope)
|
||||||
|
return found_scope;
|
||||||
|
|
||||||
NetScope*cur = scope;
|
// Avoid searching the unit scope twice.
|
||||||
do {
|
if (scope == unit_scope)
|
||||||
hname_t key = tmp.front();
|
unit_scope = 0;
|
||||||
/* If we are looking for a module or we are not
|
|
||||||
* looking at the last path component check for
|
|
||||||
* a name match (second line). */
|
|
||||||
if (cur->type() == NetScope::MODULE
|
|
||||||
&& (type == NetScope::MODULE || tmp.size() > 1)
|
|
||||||
&& cur->module_name()==key.peek_name()) {
|
|
||||||
|
|
||||||
/* Up references may match module name */
|
// Special case - see IEEE 1800-2012 section 23.8.1.
|
||||||
|
if (unit_scope && is_design_unit(scope) && is_subroutine(type)) {
|
||||||
|
found_scope = find_scope_(unit_scope, path, type);
|
||||||
|
if (found_scope)
|
||||||
|
return found_scope;
|
||||||
|
|
||||||
} else {
|
unit_scope = 0;
|
||||||
cur = cur->child( key );
|
}
|
||||||
if (cur == 0) break;
|
|
||||||
}
|
|
||||||
tmp.pop_front();
|
|
||||||
} while (! tmp.empty());
|
|
||||||
|
|
||||||
if (cur) return cur;
|
scope = scope->parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we haven't already done so, search the compilation unit scope.
|
||||||
|
if (unit_scope) {
|
||||||
|
NetScope*found_scope = find_scope_(unit_scope, path, type);
|
||||||
|
if (found_scope)
|
||||||
|
return found_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last chance. Look for the name starting at the root.
|
// Last chance. Look for the name starting at the root.
|
||||||
return find_scope(path);
|
return find_scope(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method locates a scope within another scope, given its relative
|
||||||
|
* hierarchical name. Each component of the key is used to scan one
|
||||||
|
* more step down the tree until the name runs out or the search
|
||||||
|
* fails.
|
||||||
|
*/
|
||||||
|
NetScope* Design::find_scope_(NetScope*scope, const hname_t&path,
|
||||||
|
NetScope::TYPE type) const
|
||||||
|
{
|
||||||
|
/* If we are looking for a module or we are not
|
||||||
|
* looking at the last path component check for
|
||||||
|
* a name match (second line). */
|
||||||
|
if ((scope->type() == NetScope::MODULE) && (type == NetScope::MODULE)
|
||||||
|
&& (scope->module_name() == path.peek_name())) {
|
||||||
|
/* Up references may match module name */
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
return scope->child( path );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a relative lookup of a scope by name. The starting point is
|
* This is a relative lookup of a scope by name. The starting point is
|
||||||
* the scope parameter within which I start looking for the scope. If
|
* the scope parameter within which I start looking for the scope. If
|
||||||
|
|
@ -307,24 +333,36 @@ NetScope* Design::find_scope(NetScope*scope, const hname_t&path,
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
for ( ; scope ; scope = scope->parent()) {
|
// Record the compilation unit scope for use later.
|
||||||
|
NetScope*unit_scope = scope->unit();
|
||||||
|
|
||||||
NetScope*cur = scope;
|
// First search upwards through the hierarchy.
|
||||||
|
while (scope) {
|
||||||
|
NetScope*found_scope = find_scope_(scope, path, type);
|
||||||
|
if (found_scope)
|
||||||
|
return found_scope;
|
||||||
|
|
||||||
/* If we are looking for a module or we are not
|
// Avoid searching the unit scope twice.
|
||||||
* looking at the last path component check for
|
if (scope == unit_scope)
|
||||||
* a name match (second line). */
|
unit_scope = 0;
|
||||||
if (cur->type() == NetScope::MODULE
|
|
||||||
&& (type == NetScope::MODULE)
|
|
||||||
&& cur->module_name()==path.peek_name()) {
|
|
||||||
|
|
||||||
/* Up references may match module name */
|
// Special case - see IEEE 1800-2012 section 23.8.1.
|
||||||
|
if (unit_scope && is_design_unit(scope) && is_subroutine(type)) {
|
||||||
|
found_scope = find_scope_(unit_scope, path, type);
|
||||||
|
if (found_scope)
|
||||||
|
return found_scope;
|
||||||
|
|
||||||
} else {
|
unit_scope = 0;
|
||||||
cur = cur->child( path );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur) return cur;
|
scope = scope->parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we haven't already done so, search the compilation unit scope.
|
||||||
|
if (unit_scope) {
|
||||||
|
NetScope*found_scope = find_scope_(unit_scope, path, type);
|
||||||
|
if (found_scope)
|
||||||
|
return found_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last chance. Look for the name starting at the root.
|
// Last chance. Look for the name starting at the root.
|
||||||
|
|
@ -867,11 +905,6 @@ NetScope* Design::find_task(NetScope*scope, const pform_name_t&name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::add_root_task(NetScope*tscope, PTaskFunc*tf)
|
|
||||||
{
|
|
||||||
root_tasks_[tscope] = tf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Design::add_node(NetNode*net)
|
void Design::add_node(NetNode*net)
|
||||||
{
|
{
|
||||||
assert(net->design_ == 0);
|
assert(net->design_ == 0);
|
||||||
|
|
|
||||||
45
net_scope.cc
45
net_scope.cc
|
|
@ -112,10 +112,10 @@ void Definitions::add_class(netclass_t*net_class)
|
||||||
* in question.
|
* in question.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
|
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, NetScope*unit,
|
||||||
bool program, bool interface)
|
bool nest, bool program, bool interface, bool compilation_unit)
|
||||||
: type_(t), name_(n), nested_module_(nest), program_block_(program),
|
: type_(t), name_(n), nested_module_(nest), program_block_(program),
|
||||||
is_interface_(interface), up_(up)
|
is_interface_(interface), is_unit_(compilation_unit), unit_(unit), up_(up)
|
||||||
{
|
{
|
||||||
events_ = 0;
|
events_ = 0;
|
||||||
lcounter_ = 0;
|
lcounter_ = 0;
|
||||||
|
|
@ -124,6 +124,9 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
|
||||||
calls_stask_ = false;
|
calls_stask_ = false;
|
||||||
in_final_ = false;
|
in_final_ = false;
|
||||||
|
|
||||||
|
if (compilation_unit)
|
||||||
|
unit_ = this;
|
||||||
|
|
||||||
if (up) {
|
if (up) {
|
||||||
assert(t!=CLASS);
|
assert(t!=CLASS);
|
||||||
need_const_func_ = up->need_const_func_;
|
need_const_func_ = up->need_const_func_;
|
||||||
|
|
@ -133,6 +136,8 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
|
||||||
time_from_timescale_ = up->time_from_timescale();
|
time_from_timescale_ = up->time_from_timescale();
|
||||||
// Need to check for duplicate names?
|
// Need to check for duplicate names?
|
||||||
up_->children_[name_] = this;
|
up_->children_[name_] = this;
|
||||||
|
if (unit_ == 0)
|
||||||
|
unit_ = up_->unit_;
|
||||||
} else {
|
} else {
|
||||||
need_const_func_ = false;
|
need_const_func_ = false;
|
||||||
is_const_func_ = false;
|
is_const_func_ = false;
|
||||||
|
|
@ -210,6 +215,8 @@ const netenum_t*NetScope::find_enumeration_for_name(perm_string name)
|
||||||
NetEConstEnum*tmp = cur_scope->enum_names_[name];
|
NetEConstEnum*tmp = cur_scope->enum_names_[name];
|
||||||
if (tmp) break;
|
if (tmp) break;
|
||||||
cur_scope = cur_scope->parent();
|
cur_scope = cur_scope->parent();
|
||||||
|
if (cur_scope == 0)
|
||||||
|
cur_scope = unit_;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(cur_scope);
|
assert(cur_scope);
|
||||||
|
|
@ -364,12 +371,7 @@ const NetExpr* NetScope::get_parameter(Design*des,
|
||||||
msb = 0;
|
msb = 0;
|
||||||
lsb = 0;
|
lsb = 0;
|
||||||
const NetExpr*tmp = enumeration_expr(key);
|
const NetExpr*tmp = enumeration_expr(key);
|
||||||
if (tmp) return tmp;
|
return tmp;
|
||||||
|
|
||||||
tmp = des->enumeration_expr(key);
|
|
||||||
if (tmp) return tmp;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope::param_ref_t NetScope::find_parameter(perm_string key)
|
NetScope::param_ref_t NetScope::find_parameter(perm_string key)
|
||||||
|
|
@ -386,11 +388,6 @@ NetScope::param_ref_t NetScope::find_parameter(perm_string key)
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope::TYPE NetScope::type() const
|
|
||||||
{
|
|
||||||
return type_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetScope::print_type(ostream&stream) const
|
void NetScope::print_type(ostream&stream) const
|
||||||
{
|
{
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
|
|
@ -657,15 +654,11 @@ netclass_t*NetScope::find_class(perm_string name)
|
||||||
if (type_==CLASS && name_==hname_t(name))
|
if (type_==CLASS && name_==hname_t(name))
|
||||||
return class_def_;
|
return class_def_;
|
||||||
|
|
||||||
// Look for the class that directly within this scope.
|
// Look for the class directly within this scope.
|
||||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
||||||
if (cur != classes_.end())
|
if (cur != classes_.end())
|
||||||
return cur->second;
|
return cur->second;
|
||||||
|
|
||||||
// If this is a module scope, then look no further.
|
|
||||||
if (type_==MODULE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (up_==0 && type_==CLASS) {
|
if (up_==0 && type_==CLASS) {
|
||||||
assert(class_def_);
|
assert(class_def_);
|
||||||
|
|
||||||
|
|
@ -673,12 +666,16 @@ netclass_t*NetScope::find_class(perm_string name)
|
||||||
return def_parent->find_class(name);
|
return def_parent->find_class(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no further to look, ...
|
|
||||||
if (up_ == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Try looking up for the class.
|
// Try looking up for the class.
|
||||||
return up_->find_class(name);
|
if (up_!=0 && type_!=MODULE)
|
||||||
|
return up_->find_class(name);
|
||||||
|
|
||||||
|
// Try the compilation unit.
|
||||||
|
if (unit_ != 0)
|
||||||
|
return unit_->find_class(name);
|
||||||
|
|
||||||
|
// Nowhere left to try...
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
55
netlist.h
55
netlist.h
|
|
@ -927,10 +927,13 @@ class NetScope : public Definitions, public Attrib {
|
||||||
public:
|
public:
|
||||||
enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
|
enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
|
||||||
|
|
||||||
/* Create a new scope, and attach it to the given parent. The
|
/* Create a new scope associated with a given compilation unit,
|
||||||
name is expected to have been permallocated. */
|
and attach it to the given parent. If no compilation unit is
|
||||||
NetScope(NetScope*up, const hname_t&name, TYPE t, bool nest=false,
|
specified, the parent's compilation unit is used. The name
|
||||||
bool program=false, bool interface=false);
|
is expected to have been permallocated. */
|
||||||
|
NetScope(NetScope*up, const hname_t&name, TYPE t, NetScope*unit=0,
|
||||||
|
bool nest=false, bool program=false, bool interface=false,
|
||||||
|
bool compilation_unit=false);
|
||||||
~NetScope();
|
~NetScope();
|
||||||
|
|
||||||
/* Rename the scope using the name generated by inserting as
|
/* Rename the scope using the name generated by inserting as
|
||||||
|
|
@ -1002,10 +1005,12 @@ class NetScope : public Definitions, public Attrib {
|
||||||
|
|
||||||
netclass_t* find_class(perm_string name);
|
netclass_t* find_class(perm_string name);
|
||||||
|
|
||||||
/* The parent and child() methods allow users of NetScope
|
/* The unit(), parent(), and child() methods allow users of
|
||||||
objects to locate nearby scopes. */
|
NetScope objects to locate nearby scopes. */
|
||||||
|
NetScope* unit() { return unit_; }
|
||||||
NetScope* parent() { return up_; }
|
NetScope* parent() { return up_; }
|
||||||
NetScope* child(const hname_t&name);
|
NetScope* child(const hname_t&name);
|
||||||
|
const NetScope* unit() const { return unit_; }
|
||||||
const NetScope* parent() const { return up_; }
|
const NetScope* parent() const { return up_; }
|
||||||
const NetScope* child(const hname_t&name) const;
|
const NetScope* child(const hname_t&name) const;
|
||||||
|
|
||||||
|
|
@ -1023,7 +1028,8 @@ class NetScope : public Definitions, public Attrib {
|
||||||
// Program blocks and interfaces have elaboration constraints.
|
// Program blocks and interfaces have elaboration constraints.
|
||||||
inline bool program_block() const { return program_block_; }
|
inline bool program_block() const { return program_block_; }
|
||||||
inline bool is_interface() const { return is_interface_; }
|
inline bool is_interface() const { return is_interface_; }
|
||||||
TYPE type() const;
|
inline bool is_unit() const { return is_unit_; }
|
||||||
|
inline TYPE type() const { return type_; }
|
||||||
void print_type(ostream&) const;
|
void print_type(ostream&) const;
|
||||||
|
|
||||||
// This provides a link to the variable initialisation process
|
// This provides a link to the variable initialisation process
|
||||||
|
|
@ -1249,6 +1255,8 @@ class NetScope : public Definitions, public Attrib {
|
||||||
bool program_block_;
|
bool program_block_;
|
||||||
// True if the scope is an interface
|
// True if the scope is an interface
|
||||||
bool is_interface_;
|
bool is_interface_;
|
||||||
|
// True if the scope is a compilation unit
|
||||||
|
bool is_unit_;
|
||||||
|
|
||||||
perm_string file_;
|
perm_string file_;
|
||||||
perm_string def_file_;
|
perm_string def_file_;
|
||||||
|
|
@ -1279,6 +1287,7 @@ class NetScope : public Definitions, public Attrib {
|
||||||
const PFunction*func_pform_;
|
const PFunction*func_pform_;
|
||||||
unsigned elab_stage_;
|
unsigned elab_stage_;
|
||||||
|
|
||||||
|
NetScope*unit_;
|
||||||
NetScope*up_;
|
NetScope*up_;
|
||||||
map<hname_t,NetScope*> children_;
|
map<hname_t,NetScope*> children_;
|
||||||
|
|
||||||
|
|
@ -4835,7 +4844,7 @@ struct elaborator_work_item_t {
|
||||||
* This class contains an entire design. It includes processes and a
|
* This class contains an entire design. It includes processes and a
|
||||||
* netlist, and can be passed around from function to function.
|
* netlist, and can be passed around from function to function.
|
||||||
*/
|
*/
|
||||||
class Design : public Definitions {
|
class Design {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Design();
|
Design();
|
||||||
|
|
@ -4857,12 +4866,13 @@ class Design : public Definitions {
|
||||||
|
|
||||||
const char* get_flag(const string&key) const;
|
const char* get_flag(const string&key) const;
|
||||||
|
|
||||||
NetScope* make_root_scope(perm_string name, bool program_block,
|
NetScope* make_root_scope(perm_string name, NetScope*unit_scope,
|
||||||
bool is_interface);
|
bool program_block, bool is_interface);
|
||||||
NetScope* find_root_scope();
|
NetScope* find_root_scope();
|
||||||
std::list<NetScope*> find_root_scopes() const;
|
std::list<NetScope*> find_root_scopes() const;
|
||||||
|
|
||||||
NetScope* make_package_scope(perm_string name);
|
NetScope* make_package_scope(perm_string name, NetScope*unit_scope,
|
||||||
|
bool is_unit);
|
||||||
std::list<NetScope*> find_package_scopes() const;
|
std::list<NetScope*> find_package_scopes() const;
|
||||||
|
|
||||||
/* Attempt to set the precision to the specified value. If the
|
/* Attempt to set the precision to the specified value. If the
|
||||||
|
|
@ -4912,11 +4922,6 @@ class Design : public Definitions {
|
||||||
// Look for defparams that never matched, and print warnings.
|
// Look for defparams that never matched, and print warnings.
|
||||||
void residual_defparams();
|
void residual_defparams();
|
||||||
|
|
||||||
// Do elaborate_sig for objects in $root scope.
|
|
||||||
void root_elaborate_sig(void);
|
|
||||||
|
|
||||||
void root_elaborate(void);
|
|
||||||
|
|
||||||
/* This method locates a signal, starting at a given
|
/* This method locates a signal, starting at a given
|
||||||
scope. The name parameter may be partially hierarchical, so
|
scope. The name parameter may be partially hierarchical, so
|
||||||
this method, unlike the NetScope::find_signal method,
|
this method, unlike the NetScope::find_signal method,
|
||||||
|
|
@ -4929,12 +4934,6 @@ class Design : public Definitions {
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
NetScope* find_task(NetScope*scope, const pform_name_t&name);
|
NetScope* find_task(NetScope*scope, const pform_name_t&name);
|
||||||
void add_root_task(NetScope*tscope, PTaskFunc*tf);
|
|
||||||
std::list<NetScope*> find_roottask_scopes(void) const;
|
|
||||||
|
|
||||||
// Find a class in the $root scope.
|
|
||||||
void add_class(netclass_t*cl, PClass*pclass);
|
|
||||||
netclass_t* find_class(perm_string name) const;
|
|
||||||
|
|
||||||
// NODES
|
// NODES
|
||||||
void add_node(NetNode*);
|
void add_node(NetNode*);
|
||||||
|
|
@ -4962,6 +4961,12 @@ class Design : public Definitions {
|
||||||
unsigned errors;
|
unsigned errors;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
NetScope* find_scope_(NetScope*, const hname_t&name,
|
||||||
|
NetScope::TYPE type = NetScope::MODULE) const;
|
||||||
|
|
||||||
|
NetScope* find_scope_(NetScope*, const std::list<hname_t>&path,
|
||||||
|
NetScope::TYPE type = NetScope::MODULE) const;
|
||||||
|
|
||||||
// Keep a tree of scopes. The NetScope class handles the wide
|
// Keep a tree of scopes. The NetScope class handles the wide
|
||||||
// tree and per-hop searches for me.
|
// tree and per-hop searches for me.
|
||||||
list<NetScope*>root_scopes_;
|
list<NetScope*>root_scopes_;
|
||||||
|
|
@ -4970,12 +4975,6 @@ class Design : public Definitions {
|
||||||
// packages do not nest.
|
// packages do not nest.
|
||||||
std::map<perm_string,NetScope*>packages_;
|
std::map<perm_string,NetScope*>packages_;
|
||||||
|
|
||||||
// Tasks in the $root scope
|
|
||||||
std::map<NetScope*,PTaskFunc*>root_tasks_;
|
|
||||||
|
|
||||||
// Need this for elaboration of $root scope pclass objects.
|
|
||||||
std::map<netclass_t*,PClass*> class_to_pclass_;
|
|
||||||
|
|
||||||
// List the nodes in the design.
|
// List the nodes in the design.
|
||||||
NetNode*nodes_;
|
NetNode*nodes_;
|
||||||
// These are in support of the node functor iterator.
|
// These are in support of the node functor iterator.
|
||||||
|
|
|
||||||
|
|
@ -42,20 +42,13 @@ struct enum_type_t;
|
||||||
*/
|
*/
|
||||||
extern std::map<perm_string,Module*> pform_modules;
|
extern std::map<perm_string,Module*> pform_modules;
|
||||||
extern std::map<perm_string,PUdp*> pform_primitives;
|
extern std::map<perm_string,PUdp*> pform_primitives;
|
||||||
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
extern std::vector<PPackage*> pform_units;
|
||||||
extern std::set<enum_type_t*> pform_enum_sets;
|
|
||||||
extern std::map<perm_string,PTaskFunc*> pform_tasks;
|
|
||||||
extern std::vector<PClass*> pform_classes;
|
|
||||||
extern std::map<perm_string,PPackage*> pform_packages;
|
extern std::map<perm_string,PPackage*> pform_packages;
|
||||||
|
|
||||||
extern void pform_dump(std::ostream&out, const PClass*pac);
|
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 PPackage*pac);
|
||||||
extern void pform_dump(std::ostream&out, const PTaskFunc*tf);
|
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. If the path
|
* This code actually invokes the parser to make modules. If the path
|
||||||
* parameter is "-", the parser reads from stdin, otherwise it attempts
|
* parameter is "-", the parser reads from stdin, otherwise it attempts
|
||||||
|
|
|
||||||
138
pform.cc
138
pform.cc
|
|
@ -63,20 +63,18 @@ map<perm_string,Module*> pform_modules;
|
||||||
map<perm_string,PUdp*> pform_primitives;
|
map<perm_string,PUdp*> pform_primitives;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* typedefs in the $root scope go here.
|
* The pform_units is a list of the SystemVerilog compilation unit scopes.
|
||||||
|
* The current compilation unit is the last element in the list. All items
|
||||||
|
* declared or defined at the top level (outside any design element) are
|
||||||
|
* added to the current compilation unit scope.
|
||||||
*/
|
*/
|
||||||
map<perm_string,data_type_t*>pform_typedefs;
|
vector<PPackage*> pform_units;
|
||||||
set<enum_type_t*>pform_enum_sets;
|
|
||||||
|
|
||||||
/*
|
static bool is_compilation_unit(LexicalScope*scope)
|
||||||
* Class definitions in the $root scope go here.
|
{
|
||||||
*/
|
// A compilation unit is the only scope that doesn't have a parent.
|
||||||
vector<PClass*> pform_classes;
|
return scope->parent_scope() == 0;
|
||||||
|
}
|
||||||
/*
|
|
||||||
* Task and function definitions in the $root scope go here.
|
|
||||||
*/
|
|
||||||
map<perm_string,PTaskFunc*> pform_tasks;
|
|
||||||
|
|
||||||
std::string vlltype::get_fileline() const
|
std::string vlltype::get_fileline() const
|
||||||
{
|
{
|
||||||
|
|
@ -406,6 +404,7 @@ void pform_pop_scope()
|
||||||
{
|
{
|
||||||
assert(lexical_scope);
|
assert(lexical_scope);
|
||||||
lexical_scope = lexical_scope->parent_scope();
|
lexical_scope = lexical_scope->parent_scope();
|
||||||
|
assert(lexical_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LexicalScope::lifetime_t find_lifetime(LexicalScope::lifetime_t lifetime)
|
static LexicalScope::lifetime_t find_lifetime(LexicalScope::lifetime_t lifetime)
|
||||||
|
|
@ -413,10 +412,7 @@ static LexicalScope::lifetime_t find_lifetime(LexicalScope::lifetime_t lifetime)
|
||||||
if (lifetime != LexicalScope::INHERITED)
|
if (lifetime != LexicalScope::INHERITED)
|
||||||
return lifetime;
|
return lifetime;
|
||||||
|
|
||||||
if (lexical_scope != 0)
|
return lexical_scope->default_lifetime;
|
||||||
return lexical_scope->default_lifetime;
|
|
||||||
|
|
||||||
return LexicalScope::STATIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PScopeExtra* find_nearest_scopex(LexicalScope*scope)
|
static PScopeExtra* find_nearest_scopex(LexicalScope*scope)
|
||||||
|
|
@ -440,7 +436,7 @@ static void pform_set_scope_timescale(PScope*scope, const struct vlltype&loc)
|
||||||
* a timescale directive. */
|
* a timescale directive. */
|
||||||
scope->time_from_timescale = pform_timescale_file != 0;
|
scope->time_from_timescale = pform_timescale_file != 0;
|
||||||
|
|
||||||
if (warn_timescale && (lexical_scope == 0) && pform_timescale_file
|
if (warn_timescale && is_compilation_unit(lexical_scope) && pform_timescale_file
|
||||||
&& (strcmp(pform_timescale_file, loc.text) != 0)) {
|
&& (strcmp(pform_timescale_file, loc.text) != 0)) {
|
||||||
|
|
||||||
cerr << loc.get_fileline() << ": warning: "
|
cerr << loc.get_fileline() << ": warning: "
|
||||||
|
|
@ -461,17 +457,9 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name,
|
||||||
pform_set_scope_timescale(class_scope, loc);
|
pform_set_scope_timescale(class_scope, loc);
|
||||||
|
|
||||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
||||||
|
assert(scopex);
|
||||||
assert(!pform_cur_generate);
|
assert(!pform_cur_generate);
|
||||||
|
|
||||||
/* If no scope was found then this is being defined in the
|
|
||||||
* compilation unit scope. */
|
|
||||||
if (scopex == 0) {
|
|
||||||
pform_classes.push_back(class_scope);
|
|
||||||
lexical_scope = class_scope;
|
|
||||||
return class_scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scopex->classes.find(name) != scopex->classes.end()) {
|
if (scopex->classes.find(name) != scopex->classes.end()) {
|
||||||
cerr << class_scope->get_fileline() << ": error: duplicate "
|
cerr << class_scope->get_fileline() << ": error: duplicate "
|
||||||
"definition for class '" << name << "' in '"
|
"definition for class '" << name << "' in '"
|
||||||
|
|
@ -513,7 +501,8 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
pform_set_scope_timescale(task, loc);
|
pform_set_scope_timescale(task, loc);
|
||||||
|
|
||||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
||||||
if ((scopex == 0) && !gn_system_verilog()) {
|
assert(scopex);
|
||||||
|
if (is_compilation_unit(scopex) && !gn_system_verilog()) {
|
||||||
cerr << task->get_fileline() << ": error: task declarations "
|
cerr << task->get_fileline() << ": error: task declarations "
|
||||||
"must be contained within a module." << endl;
|
"must be contained within a module." << endl;
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
|
|
@ -530,7 +519,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
}
|
}
|
||||||
pform_cur_generate->tasks[task->pscope_name()] = task;
|
pform_cur_generate->tasks[task->pscope_name()] = task;
|
||||||
} else if (scopex) {
|
} else {
|
||||||
// Check if the task is already in the dictionary.
|
// Check if the task is already in the dictionary.
|
||||||
if (scopex->tasks.find(task->pscope_name()) != scopex->tasks.end()) {
|
if (scopex->tasks.find(task->pscope_name()) != scopex->tasks.end()) {
|
||||||
cerr << task->get_fileline() << ": error: duplicate "
|
cerr << task->get_fileline() << ": error: duplicate "
|
||||||
|
|
@ -539,15 +528,6 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
}
|
}
|
||||||
scopex->tasks[task->pscope_name()] = task;
|
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;
|
lexical_scope = task;
|
||||||
|
|
@ -570,7 +550,8 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
pform_set_scope_timescale(func, loc);
|
pform_set_scope_timescale(func, loc);
|
||||||
|
|
||||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
||||||
if ((scopex == 0) && !gn_system_verilog()) {
|
assert(scopex);
|
||||||
|
if (is_compilation_unit(scopex) && !gn_system_verilog()) {
|
||||||
cerr << func->get_fileline() << ": error: function declarations "
|
cerr << func->get_fileline() << ": error: function declarations "
|
||||||
"must be contained within a module." << endl;
|
"must be contained within a module." << endl;
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
|
|
@ -588,7 +569,7 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
}
|
}
|
||||||
pform_cur_generate->funcs[func->pscope_name()] = func;
|
pform_cur_generate->funcs[func->pscope_name()] = func;
|
||||||
|
|
||||||
} else if (scopex != 0) {
|
} else {
|
||||||
// Check if the function is already in the dictionary.
|
// Check if the function is already in the dictionary.
|
||||||
if (scopex->funcs.find(func->pscope_name()) != scopex->funcs.end()) {
|
if (scopex->funcs.find(func->pscope_name()) != scopex->funcs.end()) {
|
||||||
cerr << func->get_fileline() << ": error: duplicate "
|
cerr << func->get_fileline() << ": error: duplicate "
|
||||||
|
|
@ -597,15 +578,6 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
}
|
}
|
||||||
scopex->funcs[func->pscope_name()] = func;
|
scopex->funcs[func->pscope_name()] = func;
|
||||||
|
|
||||||
} else {
|
|
||||||
if (pform_tasks.find(func_name) != pform_tasks.end()) {
|
|
||||||
cerr << func->get_fileline() << ": error: "
|
|
||||||
<< "Duplicate definition for function '" << name
|
|
||||||
<< "' in $root scope." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
pform_tasks[func_name] = func;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lexical_scope = func;
|
lexical_scope = func;
|
||||||
|
|
@ -705,11 +677,7 @@ static void pform_put_wire_in_scope(perm_string name, PWire*net)
|
||||||
|
|
||||||
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
||||||
{
|
{
|
||||||
if (lexical_scope) {
|
lexical_scope->enum_sets.insert(enum_set);
|
||||||
lexical_scope->enum_sets.insert(enum_set);
|
|
||||||
} else {
|
|
||||||
pform_enum_sets.insert(enum_set);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type)
|
PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type)
|
||||||
|
|
@ -736,12 +704,7 @@ void pform_set_typedef(perm_string name, data_type_t*data_type, std::list<pform_
|
||||||
if(unp_ranges)
|
if(unp_ranges)
|
||||||
data_type = new uarray_type_t(data_type, unp_ranges);
|
data_type = new uarray_type_t(data_type, unp_ranges);
|
||||||
|
|
||||||
// If we are in a lexical scope (i.e. a package or module)
|
data_type_t*&ref = lexical_scope->typedefs[name];
|
||||||
// then put the typedef into that scope. Otherwise, put it
|
|
||||||
// into the $root scope.
|
|
||||||
data_type_t*&ref = lexical_scope
|
|
||||||
? lexical_scope->typedefs[name]
|
|
||||||
: pform_typedefs[name];
|
|
||||||
|
|
||||||
ivl_assert(*data_type, ref == 0);
|
ivl_assert(*data_type, ref == 0);
|
||||||
ref = data_type;
|
ref = data_type;
|
||||||
|
|
@ -751,25 +714,10 @@ void pform_set_typedef(perm_string name, data_type_t*data_type, std::list<pform_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static data_type_t* test_type_identifier_in_root(perm_string name)
|
|
||||||
{
|
|
||||||
map<perm_string,data_type_t*>::iterator cur = pform_typedefs.find(name);
|
|
||||||
if (cur != pform_typedefs.end())
|
|
||||||
return cur->second;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_type_t* pform_test_type_identifier(const char*txt)
|
data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
{
|
{
|
||||||
perm_string name = lex_strings.make(txt);
|
perm_string name = lex_strings.make(txt);
|
||||||
|
|
||||||
// If there is no lexical_scope yet, then look only in the
|
|
||||||
// $root scope for typedefs.
|
|
||||||
if (lexical_scope == 0) {
|
|
||||||
return test_type_identifier_in_root(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
LexicalScope*cur_scope = lexical_scope;
|
LexicalScope*cur_scope = lexical_scope;
|
||||||
do {
|
do {
|
||||||
map<perm_string,data_type_t*>::iterator cur;
|
map<perm_string,data_type_t*>::iterator cur;
|
||||||
|
|
@ -799,10 +747,6 @@ data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
cur_scope = cur_scope->parent_scope();
|
cur_scope = cur_scope->parent_scope();
|
||||||
} while (cur_scope);
|
} while (cur_scope);
|
||||||
|
|
||||||
// See if there is a typedef in the $root scope.
|
|
||||||
if (data_type_t*tmp = test_type_identifier_in_root(name))
|
|
||||||
return tmp;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -813,13 +757,6 @@ data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
*/
|
*/
|
||||||
bool pform_test_type_identifier_local(perm_string name)
|
bool pform_test_type_identifier_local(perm_string name)
|
||||||
{
|
{
|
||||||
if (lexical_scope == 0) {
|
|
||||||
if (test_type_identifier_in_root(name))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LexicalScope*cur_scope = lexical_scope;
|
LexicalScope*cur_scope = lexical_scope;
|
||||||
|
|
||||||
map<perm_string,data_type_t*>::iterator cur;
|
map<perm_string,data_type_t*>::iterator cur;
|
||||||
|
|
@ -1418,11 +1355,9 @@ void pform_endmodule(const char*name, bool inside_celldefine,
|
||||||
use_module_map[mod_name] = cur_module;
|
use_module_map[mod_name] = cur_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The current lexical scope should be this module by now, and
|
// The current lexical scope should be this module by now.
|
||||||
// this module should not have a parent lexical scope.
|
|
||||||
ivl_assert(*cur_module, lexical_scope == cur_module);
|
ivl_assert(*cur_module, lexical_scope == cur_module);
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
ivl_assert(*cur_module, ! pform_cur_module.empty() || lexical_scope == 0);
|
|
||||||
|
|
||||||
tp_decl_flag = false;
|
tp_decl_flag = false;
|
||||||
tu_decl_flag = false;
|
tu_decl_flag = false;
|
||||||
|
|
@ -2773,11 +2708,11 @@ void pform_makewire(const struct vlltype&li,
|
||||||
NetNet::Type type,
|
NetNet::Type type,
|
||||||
data_type_t*data_type)
|
data_type_t*data_type)
|
||||||
{
|
{
|
||||||
if ((lexical_scope == 0) && !gn_system_verilog()) {
|
if (is_compilation_unit(lexical_scope) && !gn_system_verilog()) {
|
||||||
VLerror(li, "error: variable declarations must be contained within a module.");
|
VLerror(li, "error: variable declarations must be contained within a module.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (lexical_scope == 0) {
|
if (is_compilation_unit(lexical_scope)) {
|
||||||
VLerror(li, "sorry: variable declarations in the $root scope are not yet supported.");
|
VLerror(li, "sorry: variable declarations in the $root scope are not yet supported.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3080,11 +3015,11 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
LexicalScope::range_t*value_range)
|
LexicalScope::range_t*value_range)
|
||||||
{
|
{
|
||||||
LexicalScope*scope = lexical_scope;
|
LexicalScope*scope = lexical_scope;
|
||||||
if ((scope == 0) && !gn_system_verilog()) {
|
if (is_compilation_unit(scope) && !gn_system_verilog()) {
|
||||||
VLerror(loc, "error: parameter declarations must be contained within a module.");
|
VLerror(loc, "error: parameter declarations must be contained within a module.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scope == 0) {
|
if (is_compilation_unit(scope)) {
|
||||||
VLerror(loc, "sorry: parameter declarations in the $root scope are not yet supported.");
|
VLerror(loc, "sorry: parameter declarations in the $root scope are not yet supported.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3155,11 +3090,11 @@ void pform_set_localparam(const struct vlltype&loc,
|
||||||
bool signed_flag, list<pform_range_t>*range, PExpr*expr)
|
bool signed_flag, list<pform_range_t>*range, PExpr*expr)
|
||||||
{
|
{
|
||||||
LexicalScope*scope = lexical_scope;
|
LexicalScope*scope = lexical_scope;
|
||||||
if ((scope == 0) && !gn_system_verilog()) {
|
if (is_compilation_unit(scope) && !gn_system_verilog()) {
|
||||||
VLerror(loc, "error: localparam declarations must be contained within a module.");
|
VLerror(loc, "error: localparam declarations must be contained within a module.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scope == 0) {
|
if (is_compilation_unit(scope)) {
|
||||||
VLerror(loc, "sorry: localparam declarations in the $root scope are not yet supported.");
|
VLerror(loc, "sorry: localparam declarations in the $root scope are not yet supported.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3749,6 +3684,21 @@ int pform_parse(const char*path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pform_units.empty() || separate_compilation) {
|
||||||
|
char unit_name[20];
|
||||||
|
static unsigned nunits = 0;
|
||||||
|
if (separate_compilation)
|
||||||
|
sprintf(unit_name, "$unit#%u", ++nunits);
|
||||||
|
else
|
||||||
|
sprintf(unit_name, "$unit");
|
||||||
|
PPackage*unit = new PPackage(lex_strings.make(unit_name), 0);
|
||||||
|
unit->default_lifetime = LexicalScope::STATIC;
|
||||||
|
unit->time_unit = def_ts_units;
|
||||||
|
unit->time_precision = def_ts_prec;
|
||||||
|
unit->time_from_timescale = false;
|
||||||
|
pform_units.push_back(unit);
|
||||||
|
lexical_scope = unit;
|
||||||
|
}
|
||||||
reset_lexor();
|
reset_lexor();
|
||||||
error_count = 0;
|
error_count = 0;
|
||||||
warn_count = 0;
|
warn_count = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2015 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2003-2017 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -143,14 +143,21 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't scan up past a module boundary.
|
|
||||||
if (scope->type()==NetScope::MODULE && !scope->nested_module())
|
|
||||||
break;
|
|
||||||
// Don't scan up if we are searching within a prefixed scope.
|
// Don't scan up if we are searching within a prefixed scope.
|
||||||
if (prefix_scope)
|
if (prefix_scope)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
scope = scope->parent();
|
// Don't scan up past a module boundary.
|
||||||
|
if (scope->type()==NetScope::MODULE && !scope->nested_module())
|
||||||
|
scope = 0;
|
||||||
|
else
|
||||||
|
scope = scope->parent();
|
||||||
|
|
||||||
|
// Last chance - try the compilation unit.
|
||||||
|
if (scope == 0 && start_scope != 0) {
|
||||||
|
scope = start_scope->unit();
|
||||||
|
start_scope = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last chance: this is a single name, so it might be the name
|
// Last chance: this is a single name, so it might be the name
|
||||||
|
|
|
||||||
|
|
@ -93,10 +93,7 @@ extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes,
|
||||||
assert (nscopes && scopes);
|
assert (nscopes && scopes);
|
||||||
if (des->root_scope_list.size() == 0) {
|
if (des->root_scope_list.size() == 0) {
|
||||||
size_t fill = 0;
|
size_t fill = 0;
|
||||||
des->root_scope_list.resize(des->root_tasks.size() + des->packages.size() + des->roots.size() + des->classes.size());
|
des->root_scope_list.resize(des->packages.size() + des->roots.size() + des->classes.size());
|
||||||
for (map<const NetScope*,ivl_scope_t>::iterator idx = des->root_tasks.begin()
|
|
||||||
; idx != des->root_tasks.end() ; ++ idx)
|
|
||||||
des->root_scope_list[fill++] = idx->second;
|
|
||||||
|
|
||||||
for (map<const NetScope*,ivl_scope_t>::iterator idx = des->classes.begin()
|
for (map<const NetScope*,ivl_scope_t>::iterator idx = des->classes.begin()
|
||||||
; idx != des->classes.end() ; ++ idx)
|
; idx != des->classes.end() ; ++ idx)
|
||||||
|
|
|
||||||
42
t-dll.cc
42
t-dll.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -261,12 +261,6 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->type()==NetScope::TASK || cur->type()==NetScope::FUNC) {
|
|
||||||
map<const NetScope*,ivl_scope_t>::const_iterator idx = des.root_tasks.find(cur);
|
|
||||||
if (idx != des.root_tasks.end())
|
|
||||||
return idx->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned idx = 0; idx < des.roots.size(); idx += 1) {
|
for (unsigned idx = 0; idx < des.roots.size(); idx += 1) {
|
||||||
assert(des.roots[idx]);
|
assert(des.roots[idx]);
|
||||||
ivl_scope_t scope = find_scope_from_root(des.roots[idx], cur);
|
ivl_scope_t scope = find_scope_from_root(des.roots[idx], cur);
|
||||||
|
|
@ -288,13 +282,6 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<const NetScope*,ivl_scope_t>::iterator idx = des.root_tasks.begin()
|
|
||||||
; idx != des.root_tasks.end() ; ++ idx) {
|
|
||||||
ivl_scope_t scope = find_scope_from_root(idx->second, cur);
|
|
||||||
if (scope)
|
|
||||||
return scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,22 +644,6 @@ void dll_target::add_root(const NetScope *s)
|
||||||
case NetScope::CLASS:
|
case NetScope::CLASS:
|
||||||
root_->type_ = IVL_SCT_CLASS;
|
root_->type_ = IVL_SCT_CLASS;
|
||||||
break;
|
break;
|
||||||
case NetScope::TASK: {
|
|
||||||
const NetTaskDef*def = s->task_def();
|
|
||||||
if (def == 0) {
|
|
||||||
cerr << "?:?" << ": internal error: "
|
|
||||||
<< "task " << root_->name_
|
|
||||||
<< " has no definition." << endl;
|
|
||||||
}
|
|
||||||
assert(def);
|
|
||||||
root_->type_ = IVL_SCT_TASK;
|
|
||||||
root_->tname_ = def->scope()->basename();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NetScope::FUNC:
|
|
||||||
fill_in_scope_function(root_, s);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
@ -701,11 +672,6 @@ void dll_target::add_root(const NetScope *s)
|
||||||
des_.classes[s] = root_;
|
des_.classes[s] = root_;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NetScope::TASK:
|
|
||||||
case NetScope::FUNC:
|
|
||||||
des_.root_tasks[s] = root_;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
|
@ -747,11 +713,7 @@ bool dll_target::start_design(const Design*des)
|
||||||
}
|
}
|
||||||
assert(idx == des_.disciplines.size());
|
assert(idx == des_.disciplines.size());
|
||||||
|
|
||||||
list<NetScope *> scope_list = des->find_roottask_scopes();
|
list<NetScope *> scope_list;
|
||||||
for (list<NetScope*>::const_iterator cur = scope_list.begin()
|
|
||||||
; cur != scope_list.end() ; ++ cur) {
|
|
||||||
add_root(*cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope_list = des->find_package_scopes();
|
scope_list = des->find_package_scopes();
|
||||||
for (list<NetScope*>::const_iterator cur = scope_list.begin()
|
for (list<NetScope*>::const_iterator cur = scope_list.begin()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue