Keep processes in proper lexical scope

Normally processes are found in the lexical scope of a module, but
there are special cases where processes (other then task/function
definitions) are in other lexical scopes. The most likely case is
initilizations that are in the lexical scope where the assigned
variable is declared.

In the process, the behaviors list is kept in the base PScope class
instead of the Module or any other derived lexical scope class.
This commit is contained in:
Stephen Williams 2008-03-03 20:49:52 -08:00
parent 3221f70bcb
commit 8d3febff2b
8 changed files with 39 additions and 130 deletions

109
Module.cc
View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008 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
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@ -54,11 +51,6 @@ void Module::add_function(perm_string name, PFunction *func)
funcs_[name] = func;
}
void Module::add_behavior(PProcess*b)
{
behaviors_.push_back(b);
}
unsigned Module::port_count() const
{
return ports.count();
@ -119,102 +111,3 @@ const list<PGate*>& Module::get_gates() const
return gates_;
}
const list<PProcess*>& Module::get_behaviors() const
{
return behaviors_;
}
/*
* $Log: Module.cc,v $
* Revision 1.27 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.26 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.25 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.24 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
*
* Revision 1.23 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.22 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.21 2003/04/02 03:00:14 steve
* Cope with empty module ports while binding by name.
*
* Revision 1.20 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.19 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.18 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.15 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.14 2000/11/15 20:31:05 steve
* Fix warning about temporaries.
*
* Revision 1.13 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
* Revision 1.12 2000/05/16 04:05:15 steve
* Module ports are really special PEIdent
* expressions, because a name can be used
* many places in the port list.
*
* Revision 1.11 2000/03/12 17:09:40 steve
* Support localparam.
*
* Revision 1.10 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.9 2000/01/09 20:37:57 steve
* Careful with wires connected to multiple ports.
*
* Revision 1.8 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.7 1999/09/17 02:06:25 steve
* Handle unconnected module ports.
*
* Revision 1.6 1999/08/04 02:13:02 steve
* Elaborate module ports that are concatenations of
* module signals.
*
* Revision 1.5 1999/08/03 04:14:49 steve
* Parse into pform arbitrarily complex module
* port declarations.
*
* Revision 1.4 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.3 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
* Revision 1.2 1999/06/17 05:34:42 steve
* Clean up interface of the PWire class,
* Properly match wire ranges.
*
* Revision 1.1 1998/11/03 23:28:51 steve
* Introduce verilog to CVS.
*
*/

View File

@ -131,7 +131,6 @@ class Module : public PScope, public LineInfo {
perm_string mod_name() const { return pscope_name(); }
void add_gate(PGate*gate);
void add_behavior(PProcess*behave);
void add_task(perm_string name, PTask*def);
void add_function(perm_string name, PFunction*def);
@ -142,7 +141,6 @@ class Module : public PScope, public LineInfo {
PGate* get_gate(perm_string name);
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope) const;
@ -154,7 +152,6 @@ class Module : public PScope, public LineInfo {
private:
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<perm_string,PTask*> tasks_;
map<perm_string,PFunction*> funcs_;

View File

@ -24,6 +24,7 @@
# include <map>
class PEvent;
class PProcess;
class PWire;
class Design;
@ -61,11 +62,16 @@ class PScope {
// Named events in the scope.
map<perm_string,PEvent*>events;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
protected:
void dump_wires_(ostream&out, unsigned indent) const;
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
bool elaborate_behaviors_(Design*des, NetScope*scope) const;
private:
perm_string name_;
PScope*parent_;

View File

@ -283,8 +283,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors_.begin()
; cur != behaviors_.end() ; cur ++ ) {
for (proc_it_t cur = behaviors.begin()
; cur != behaviors.end() ; cur ++ ) {
(*cur) -> statement() -> elaborate_scope(des, scope);
}

View File

@ -221,8 +221,8 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors_.begin()
; cur != behaviors_.end() ; cur ++ ) {
for (proc_it_t cur = behaviors.begin()
; cur != behaviors.end() ; cur ++ ) {
(*cur) -> statement() -> elaborate_sig(des, scope);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2006 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008 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
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.374 2007/06/05 21:35:51 steve Exp $"
#endif
# include "config.h"
@ -1878,6 +1875,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
assert(nscope);
elaborate_behaviors_(des, nscope);
}
NetBlock*cur = new NetBlock(type, nscope);
@ -3148,6 +3146,11 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
void PTask::elaborate(Design*des, NetScope*task) const
{
// Elaborate any processes that are part of this scope that
// aren't the definition itself. This can happen, for example,
// with variable initialization statements in this scope.
elaborate_behaviors_(des, task);
NetTaskDef*def = task->task_def();
assert(def);
@ -3552,13 +3555,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const
// Elaborate the behaviors, making processes out of them. This
// involves scanning the PProcess* list, creating a NetProcTop
// for each process.
const list<PProcess*>&sl = get_behaviors();
for (list<PProcess*>::const_iterator st = sl.begin()
; st != sl.end() ; st ++ ) {
result_flag &= (*st)->elaborate(des, scope);
}
result_flag &= elaborate_behaviors_(des, scope);
// Elaborate the specify paths of the module.
@ -3646,6 +3643,22 @@ bool PGenerate::elaborate_(Design*des, NetScope*scope) const
return true;
}
bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const
{
bool result_flag = true;
// Elaborate the behaviors, making processes out of them. This
// involves scanning the PProcess* list, creating a NetProcTop
// for each process.
for (list<PProcess*>::const_iterator st = behaviors.begin()
; st != behaviors.end() ; st ++ ) {
result_flag &= (*st)->elaborate(des, scope);
}
return result_flag;
}
struct root_elem {
Module *mod;
NetScope *scope;

View File

@ -1255,7 +1255,7 @@ void pform_make_reginit(const struct vlltype&li,
PProcess*top = new PProcess(PProcess::PR_INITIAL, ass);
FILE_NAME(top, li);
pform_cur_module->add_behavior(top);
lexical_scope->behaviors.push_back(top);
}
/*
@ -1877,7 +1877,7 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st,
if (pform_cur_generate)
pform_cur_generate->add_behavior(pp);
else
pform_cur_module->add_behavior(pp);
pform_cur_module->behaviors.push_back(pp);
return pp;
}

View File

@ -1042,8 +1042,8 @@ void Module::dump(ostream&out) const
}
for (list<PProcess*>::const_iterator behav = behaviors_.begin()
; behav != behaviors_.end()
for (list<PProcess*>::const_iterator behav = behaviors.begin()
; behav != behaviors.end()
; behav ++ ) {
(*behav)->dump(out, 4);