From 8d3febff2b412bcb78f36460d9491957b2a307b1 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 3 Mar 2008 20:49:52 -0800 Subject: [PATCH] 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. --- Module.cc | 109 +------------------------------------------------- Module.h | 3 -- PScope.h | 6 +++ elab_scope.cc | 4 +- elab_sig.cc | 4 +- elaborate.cc | 35 +++++++++++----- pform.cc | 4 +- pform_dump.cc | 4 +- 8 files changed, 39 insertions(+), 130 deletions(-) diff --git a/Module.cc b/Module.cc index ec92e9172..961940149 100644 --- a/Module.cc +++ b/Module.cc @@ -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& Module::get_gates() const return gates_; } -const list& 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. - * - */ - diff --git a/Module.h b/Module.h index 22ad3ff2f..9b80b17c7 100644 --- a/Module.h +++ b/Module.h @@ -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& get_gates() const; - const list& 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 gates_; - list behaviors_; map tasks_; map funcs_; diff --git a/PScope.h b/PScope.h index 054be2874..b82079974 100644 --- a/PScope.h +++ b/PScope.h @@ -24,6 +24,7 @@ # include class PEvent; +class PProcess; class PWire; class Design; @@ -61,11 +62,16 @@ class PScope { // Named events in the scope. mapevents; + // Behaviors (processes) in this scope + list 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_; diff --git a/elab_scope.cc b/elab_scope.cc index 280781335..640a6514c 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -283,8 +283,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope, typedef list::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); } diff --git a/elab_sig.cc b/elab_sig.cc index 9b861f6b9..7be84919f 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -221,8 +221,8 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const typedef list::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); } diff --git a/elaborate.cc b/elaborate.cc index f25b4e0f8..8992c1685 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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&sl = get_behaviors(); - - for (list::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::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; diff --git a/pform.cc b/pform.cc index a5dd5375c..1c7d72d98 100644 --- a/pform.cc +++ b/pform.cc @@ -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; } diff --git a/pform_dump.cc b/pform_dump.cc index d65ce8d72..fec687c26 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -1042,8 +1042,8 @@ void Module::dump(ostream&out) const } - for (list::const_iterator behav = behaviors_.begin() - ; behav != behaviors_.end() + for (list::const_iterator behav = behaviors.begin() + ; behav != behaviors.end() ; behav ++ ) { (*behav)->dump(out, 4);