Fix for pr2842185 and for genvar scopes.
When checking for name collisions, the compiler looks for genvar declarations in the enclosing module rather than in the current scope, which leads to false positives. The compiler also places all genvar declarations in the enclosing module scope, even when the declarations are inside a generate block which has its own scope. This patch fixes both these faults. It also fixes some typos and outdated information in comments.
This commit is contained in:
parent
b65a3691d6
commit
da010db739
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006,2009 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
|
||||
|
|
@ -55,6 +55,7 @@ void PGenerate::probe_for_direct_nesting_(void)
|
|||
if (localparams.size() > 0) return;
|
||||
if (events.size() > 0) return;
|
||||
if (wires.size() > 0) return;
|
||||
if (genvars.size() > 0) return;
|
||||
if (behaviors.size() > 0) return;
|
||||
if (analog_behaviors.size() > 0) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __PGenerate_H
|
||||
#define __PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006-2009 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
|
||||
|
|
@ -87,6 +87,9 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
map<perm_string,PTask*> tasks;
|
||||
map<perm_string,PFunction*>funcs;
|
||||
|
||||
// genvars declared within this scheme.
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
list<PGenerate*> generate_schemes;
|
||||
PGenerate*parent;
|
||||
|
|
@ -109,8 +112,8 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
bool generate_scope_case_(Design*des, NetScope*container);
|
||||
bool generate_scope_nblock_(Design*des, NetScope*container);
|
||||
|
||||
// Call probe during elaborate_scope to calulate the
|
||||
// directed_nested_ flag. It is OK to store the direct_nested_
|
||||
// Call probe during elaborate_scope to calculate the
|
||||
// direct_nested_ flag. It is OK to store the direct_nested_
|
||||
// information here because "direct nested" is a property of
|
||||
// the lexical generate code.
|
||||
void probe_for_direct_nesting_(void);
|
||||
|
|
|
|||
|
|
@ -563,7 +563,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
{
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
if (container->find_genvar(loop_index) == 0) {
|
||||
NetScope*scope = container;
|
||||
while (scope && !scope->find_genvar(loop_index))
|
||||
scope = scope->parent();
|
||||
if (!scope) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
|
|
@ -1021,6 +1024,12 @@ void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
|
|||
|
||||
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
||||
{
|
||||
// Add the genvars to this scope.
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
|
||||
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
|
||||
scope->add_genvar((*cur).first, (*cur).second);
|
||||
}
|
||||
|
||||
// Scan the generated scope for nested generate schemes,
|
||||
// and *generate* new scopes, which is slightly different
|
||||
// from simple elaboration.
|
||||
|
|
|
|||
18
net_scope.cc
18
net_scope.cc
|
|
@ -395,27 +395,17 @@ NetEvent* NetScope::find_event(perm_string name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// We only add genvars to a module scope, so we do not need to search
|
||||
// for the module scope here.
|
||||
void NetScope::add_genvar(perm_string name, LineInfo *li)
|
||||
{
|
||||
assert((type_ == MODULE) || (type_ == GENBLOCK));
|
||||
genvars_[name] = li;
|
||||
}
|
||||
|
||||
LineInfo* NetScope::find_genvar(perm_string name)
|
||||
{
|
||||
// genvars are only added to the module so we need to find it
|
||||
// if we are in a sub scope.
|
||||
NetScope *scope = this;
|
||||
while (scope->type() != NetScope::MODULE) {
|
||||
scope = scope->parent();
|
||||
assert(scope != NULL);
|
||||
}
|
||||
|
||||
if (scope->genvars_.find(name) != scope->genvars_.end()) {
|
||||
return scope->genvars_[name];
|
||||
}
|
||||
|
||||
if (genvars_.find(name) != genvars_.end())
|
||||
return genvars_[name];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
34
pform.cc
34
pform.cc
|
|
@ -829,20 +829,31 @@ void pform_endmodule(const char*name, bool in_celldefine,
|
|||
tp_local_flag = false;
|
||||
}
|
||||
|
||||
static void pform_add_genvar(const struct vlltype&li, const perm_string&name,
|
||||
map<perm_string,LineInfo*>&genvars)
|
||||
{
|
||||
LineInfo*lni = new LineInfo();
|
||||
FILE_NAME(lni, li);
|
||||
if (genvars.find(name) != genvars.end()) {
|
||||
cerr << lni->get_fileline() << ": error: genvar '"
|
||||
<< name << "' has already been declared." << endl;
|
||||
cerr << genvars[name]->get_fileline()
|
||||
<< ": the previous declaration is here." << endl;
|
||||
error_count += 1;
|
||||
delete lni;
|
||||
} else {
|
||||
genvars[name] = lni;
|
||||
}
|
||||
}
|
||||
|
||||
void pform_genvars(const struct vlltype&li, list<perm_string>*names)
|
||||
{
|
||||
list<perm_string>::const_iterator cur;
|
||||
for (cur = names->begin(); cur != names->end() ; *cur++) {
|
||||
LineInfo*lni = new LineInfo();
|
||||
FILE_NAME(lni, li);
|
||||
if (pform_cur_module->genvars.find(*cur) !=
|
||||
pform_cur_module->genvars.end()) {
|
||||
cerr << lni->get_fileline() << ": error: duplicate "
|
||||
"definition for genvar '" << *cur << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
delete lni;
|
||||
} else pform_cur_module->genvars[*cur] = lni;
|
||||
if (pform_cur_generate)
|
||||
pform_add_genvar(li, *cur, pform_cur_generate->genvars);
|
||||
else
|
||||
pform_add_genvar(li, *cur, pform_cur_module->genvars);
|
||||
}
|
||||
|
||||
delete names;
|
||||
|
|
@ -857,7 +868,6 @@ void pform_start_generate_for(const struct vlltype&li,
|
|||
|
||||
FILE_NAME(gen, li);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
gen->parent = pform_cur_generate;
|
||||
pform_cur_generate = gen;
|
||||
|
||||
|
|
@ -878,7 +888,6 @@ void pform_start_generate_if(const struct vlltype&li, PExpr*test)
|
|||
|
||||
FILE_NAME(gen, li);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
gen->parent = pform_cur_generate;
|
||||
pform_cur_generate = gen;
|
||||
|
||||
|
|
@ -901,7 +910,6 @@ void pform_start_generate_else(const struct vlltype&li)
|
|||
|
||||
FILE_NAME(gen, li);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
gen->parent = pform_cur_generate;
|
||||
pform_cur_generate = gen;
|
||||
|
||||
|
|
|
|||
2
pform.h
2
pform.h
|
|
@ -195,7 +195,7 @@ extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
|||
|
||||
/*
|
||||
* This function takes the list of names as new genvars to declare in
|
||||
* the current module scope.
|
||||
* the current module or generate scope.
|
||||
*/
|
||||
extern void pform_genvars(const struct vlltype&li, list<perm_string>*names);
|
||||
|
||||
|
|
|
|||
|
|
@ -1034,6 +1034,12 @@ void PGenerate::dump(ostream&out, unsigned indent) const
|
|||
(*idx)->dump(out, indent+2);
|
||||
}
|
||||
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_iter_t;
|
||||
for (genvar_iter_t cur = genvars.begin()
|
||||
; cur != genvars.end() ; cur++) {
|
||||
out << setw(indent+2) << "" << "genvar " << ((*cur).first) << ";" << endl;
|
||||
}
|
||||
|
||||
for (list<PGenerate*>::const_iterator idx = generate_schemes.begin()
|
||||
; idx != generate_schemes.end() ; idx++) {
|
||||
(*idx)->dump(out, indent+2);
|
||||
|
|
|
|||
Loading…
Reference in New Issue