From 1db70a0c46285c03fbf6406ba417026e9efd9055 Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 2 May 2000 16:27:38 +0000 Subject: [PATCH] Move signal elaboration to a seperate pass. --- Makefile.in | 4 +- Module.h | 7 +- PGate.h | 8 +- PWire.h | 7 +- elab_sig.cc | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++ elaborate.cc | 205 ++++++---------------------------------------- net_design.cc | 46 +++++++++-- 7 files changed, 306 insertions(+), 193 deletions(-) create mode 100644 elab_sig.cc diff --git a/Makefile.in b/Makefile.in index 28de0ce49..ff1295a5e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.49 2000/05/01 23:55:22 steve Exp $" +#ident "$Id: Makefile.in,v 1.50 2000/05/02 16:27:38 steve Exp $" # # SHELL = /bin/sh @@ -70,7 +70,7 @@ TT = t-null.o t-verilog.o t-vvm.o t-xnf.o FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \ -elab_net.o elab_pexpr.o elab_scope.o emit.o eval.o eval_tree.o \ +elab_net.o elab_pexpr.o elab_scope.o elab_sig.o emit.o eval.o eval_tree.o \ expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ mangle.o netlist.o \ net_design.o net_event.o net_scope.o net_udp.o nexus_from_link.o \ diff --git a/Module.h b/Module.h index 1bde23915..a4c3229b9 100644 --- a/Module.h +++ b/Module.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Module.h,v 1.17 2000/04/01 19:31:57 steve Exp $" +#ident "$Id: Module.h,v 1.18 2000/05/02 16:27:38 steve Exp $" #endif # include @@ -117,6 +117,8 @@ class Module { bool elaborate_scope(Design*, NetScope*scope) const; + bool elaborate_sig(Design*, NetScope*scope) const; + private: const string name_; @@ -135,6 +137,9 @@ class Module { /* * $Log: Module.h,v $ + * Revision 1.18 2000/05/02 16:27:38 steve + * Move signal elaboration to a seperate pass. + * * Revision 1.17 2000/04/01 19:31:57 steve * Named events as far as the pform. * diff --git a/PGate.h b/PGate.h index 46603c005..1643d4d28 100644 --- a/PGate.h +++ b/PGate.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PGate.h,v 1.16 2000/03/29 04:37:10 steve Exp $" +#ident "$Id: PGate.h,v 1.17 2000/05/02 16:27:38 steve Exp $" #endif # include "svector.h" @@ -71,6 +71,7 @@ class PGate : public LineInfo { virtual void dump(ostream&out) const; virtual void elaborate(Design*des, const string&path) const; virtual void elaborate_scope(Design*des, NetScope*sc) const; + virtual bool elaborate_sig(Design*des, NetScope*scope) const; protected: const svector* get_pins() const { return pins_; } @@ -178,6 +179,7 @@ class PGModule : public PGate { virtual void dump(ostream&out) const; virtual void elaborate(Design*, const string&path) const; virtual void elaborate_scope(Design*des, NetScope*sc) const; + virtual bool elaborate_sig(Design*des, NetScope*scope) const; private: string type_; @@ -197,10 +199,14 @@ class PGModule : public PGate { void elaborate_sudp_(Design*, PUdp *udp, const string&path) const; void elaborate_cudp_(Design*, PUdp *udp, const string&path) const; void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const; + bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const; }; /* * $Log: PGate.h,v $ + * Revision 1.17 2000/05/02 16:27:38 steve + * Move signal elaboration to a seperate pass. + * * Revision 1.16 2000/03/29 04:37:10 steve * New and improved combinational primitives. * diff --git a/PWire.h b/PWire.h index 2090fe3d1..d268e397e 100644 --- a/PWire.h +++ b/PWire.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PWire.h,v 1.7 2000/02/23 02:56:54 steve Exp $" +#ident "$Id: PWire.h,v 1.8 2000/05/02 16:27:38 steve Exp $" #endif # include "netlist.h" @@ -58,7 +58,7 @@ class PWire : public LineInfo { // Write myself to the specified stream. void dump(ostream&out) const; - void elaborate(Design*, NetScope*scope) const; + void elaborate_sig(Design*, NetScope*scope) const; private: string name_; @@ -82,6 +82,9 @@ class PWire : public LineInfo { /* * $Log: PWire.h,v $ + * Revision 1.8 2000/05/02 16:27:38 steve + * Move signal elaboration to a seperate pass. + * * Revision 1.7 2000/02/23 02:56:54 steve * Macintosh compilers do not support ident. * diff --git a/elab_sig.cc b/elab_sig.cc new file mode 100644 index 000000000..5b0517dad --- /dev/null +++ b/elab_sig.cc @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2000 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: elab_sig.cc,v 1.1 2000/05/02 16:27:38 steve Exp $" +#endif + +# include "Module.h" +# include "PExpr.h" +# include "PGate.h" +# include "PWire.h" +# include "netlist.h" +# include "util.h" + + +bool Module::elaborate_sig(Design*des, NetScope*scope) const +{ + bool flag = true; + + // Get all the explicitly declared wires of the module and + // start the signals list with them. + const map&wl = get_wires(); + + for (map::const_iterator wt = wl.begin() + ; wt != wl.end() + ; wt ++ ) { + + (*wt).second->elaborate_sig(des, scope); + } + + // Get all the gates of the module and elaborate them by + // connecting them to the signals. The gate may be simple or + // complex. What we are looking for is gates that are modules + // that can create scopes and signals. + + const list&gl = get_gates(); + + for (list::const_iterator gt = gl.begin() + ; gt != gl.end() + ; gt ++ ) { + + flag &= (*gt)->elaborate_sig(des, scope); + } + + return flag; +} + +bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope, + Module*rmod) const +{ + // Missing module instance names have already been rejected. + assert(get_name() != ""); + + if (msb_) { + cerr << get_line() << ": sorry: Module instantiation arrays " + "are not yet supported." << endl; + des->errors += 1; + return false; + } + + + // I know a priori that the elaborate_scope created the scope + // already, so just look it up as a child of the current scope. + NetScope*my_scope = scope->child(get_name()); + assert(my_scope); + + return rmod->elaborate_sig(des, my_scope); +} + + +bool PGate::elaborate_sig(Design*des, NetScope*scope) const +{ + return true; +} + +/* + * Elaborate a source wire. The "wire" is the declaration of wires, + * registers, ports and memories. The parser has already merged the + * multiple properties of a wire (i.e. "input wire") so come the + * elaboration this creates an object in the design that represent the + * defined item. + */ +void PWire::elaborate_sig(Design*des, NetScope*scope) const +{ + /* The parser may produce hierarchical names for wires. I here + follow the scopes down to the base where I actually want to + elaborate the NetNet object. */ + string basename = name_; + for (;;) { + string p = parse_first_name(basename); + if (basename == "") { + basename = p; + break; + } + + scope = scope->child(p); + assert(scope); + } + + const string path = scope->name(); + NetNet::Type wtype = type_; + if (wtype == NetNet::IMPLICIT) + wtype = NetNet::WIRE; + if (wtype == NetNet::IMPLICIT_REG) + wtype = NetNet::REG; + + unsigned wid = 1; + long lsb = 0, msb = 0; + + if (msb_.count()) { + svectormnum (msb_.count()); + svectorlnum (msb_.count()); + + /* There may be multiple declarations of ranges, because + the symbol may have its range declared in i.e. input + and reg declarations. Calculate *all* the numbers + here. I will resolve the values later. */ + + for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) { + verinum*mval = msb_[idx]->eval_const(des,path); + if (mval == 0) { + cerr << msb_[idx]->get_line() << ": error: " + "Unable to evaluate constant expression ``" << + *msb_[idx] << "''." << endl; + des->errors += 1; + return; + } + verinum*lval = lsb_[idx]->eval_const(des, path); + if (mval == 0) { + cerr << lsb_[idx]->get_line() << ": error: " + "Unable to evaluate constant expression ``" << + *lsb_[idx] << "''." << endl; + des->errors += 1; + return; + } + + mnum[idx] = mval->as_long(); + lnum[idx] = lval->as_long(); + delete mval; + delete lval; + } + + /* Make sure all the values for msb and lsb match by + value. If not, report an error. */ + for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) { + if ((mnum[idx] != mnum[0]) || (lnum[idx] != lnum[0])) { + cerr << get_line() << ": error: Inconsistent width, " + "[" << mnum[idx] << ":" << lnum[idx] << "]" + " vs. [" << mnum[0] << ":" << lnum[0] << "]" + " for signal ``" << basename << "''" << endl; + des->errors += 1; + return; + } + } + + lsb = lnum[0]; + msb = mnum[0]; + if (mnum[0] > lnum[0]) + wid = mnum[0] - lnum[0] + 1; + else + wid = lnum[0] - mnum[0] + 1; + + + } + + if (lidx_ || ridx_) { + assert(lidx_ && ridx_); + + // If the register has indices, then this is a + // memory. Create the memory object. + verinum*lval = lidx_->eval_const(des, path); + assert(lval); + verinum*rval = ridx_->eval_const(des, path); + assert(rval); + + long lnum = lval->as_long(); + long rnum = rval->as_long(); + delete lval; + delete rval; + NetMemory*sig = new NetMemory(scope, path+"."+basename, + wid, lnum, rnum); + sig->set_attributes(attributes); + + } else { + + NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb); + sig->set_line(*this); + sig->port_type(port_type_); + sig->set_attributes(attributes); + + verinum::V iv = verinum::Vz; + if (wtype == NetNet::REG) + iv = verinum::Vx; + + for (unsigned idx = 0 ; idx < wid ; idx += 1) + sig->set_ival(idx, iv); + + } +} + +/* + * $Log: elab_sig.cc,v $ + * Revision 1.1 2000/05/02 16:27:38 steve + * Move signal elaboration to a seperate pass. + * + */ + diff --git a/elaborate.cc b/elaborate.cc index 96c38ed9d..db78dcab9 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.167 2000/05/02 03:13:31 steve Exp $" +#ident "$Id: elaborate.cc,v 1.168 2000/05/02 16:27:38 steve Exp $" #endif /* @@ -42,130 +42,6 @@ static const map* modlist = 0; static const map* udplist = 0; -/* - * Elaborate a source wire. The "wire" is the declaration of wires, - * registers, ports and memories. The parser has already merged the - * multiple properties of a wire (i.e. "input wire") so come the - * elaboration this creates an object in the design that represent the - * defined item. - */ -void PWire::elaborate(Design*des, NetScope*scope) const -{ - /* The parser may produce hierarchical names for wires. I here - follow the scopes down to the base where I actually want to - elaborate the NetNet object. */ - string basename = name_; - for (;;) { - string p = parse_first_name(basename); - if (basename == "") { - basename = p; - break; - } - - scope = scope->child(p); - assert(scope); - } - - const string path = scope->name(); - NetNet::Type wtype = type_; - if (wtype == NetNet::IMPLICIT) - wtype = NetNet::WIRE; - if (wtype == NetNet::IMPLICIT_REG) - wtype = NetNet::REG; - - unsigned wid = 1; - long lsb = 0, msb = 0; - - if (msb_.count()) { - svectormnum (msb_.count()); - svectorlnum (msb_.count()); - - /* There may be multiple declarations of ranges, because - the symbol may have its range declared in i.e. input - and reg declarations. Calculate *all* the numbers - here. I will resolve the values later. */ - - for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) { - verinum*mval = msb_[idx]->eval_const(des,path); - if (mval == 0) { - cerr << msb_[idx]->get_line() << ": error: " - "Unable to evaluate constant expression ``" << - *msb_[idx] << "''." << endl; - des->errors += 1; - return; - } - verinum*lval = lsb_[idx]->eval_const(des, path); - if (mval == 0) { - cerr << lsb_[idx]->get_line() << ": error: " - "Unable to evaluate constant expression ``" << - *lsb_[idx] << "''." << endl; - des->errors += 1; - return; - } - - mnum[idx] = mval->as_long(); - lnum[idx] = lval->as_long(); - delete mval; - delete lval; - } - - /* Make sure all the values for msb and lsb match by - value. If not, report an error. */ - for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) { - if ((mnum[idx] != mnum[0]) || (lnum[idx] != lnum[0])) { - cerr << get_line() << ": error: Inconsistent width, " - "[" << mnum[idx] << ":" << lnum[idx] << "]" - " vs. [" << mnum[0] << ":" << lnum[0] << "]" - " for signal ``" << basename << "''" << endl; - des->errors += 1; - return; - } - } - - lsb = lnum[0]; - msb = mnum[0]; - if (mnum[0] > lnum[0]) - wid = mnum[0] - lnum[0] + 1; - else - wid = lnum[0] - mnum[0] + 1; - - - } - - if (lidx_ || ridx_) { - assert(lidx_ && ridx_); - - // If the register has indices, then this is a - // memory. Create the memory object. - verinum*lval = lidx_->eval_const(des, path); - assert(lval); - verinum*rval = ridx_->eval_const(des, path); - assert(rval); - - long lnum = lval->as_long(); - long rnum = rval->as_long(); - delete lval; - delete rval; - NetMemory*sig = new NetMemory(scope, path+"."+basename, - wid, lnum, rnum); - sig->set_attributes(attributes); - - } else { - - NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb); - sig->set_line(*this); - sig->port_type(port_type_); - sig->set_attributes(attributes); - - verinum::V iv = verinum::Vz; - if (wtype == NetNet::REG) - iv = verinum::Vx; - - for (unsigned idx = 0 ; idx < wid ; idx += 1) - sig->set_ival(idx, iv); - - } -} void PGate::elaborate(Design*des, const string&path) const { @@ -642,6 +518,18 @@ void PGModule::elaborate_sudp_(Design*des, PUdp*udp, const string&path) const des->add_node(net); } + +bool PGModule::elaborate_sig(Design*des, NetScope*scope) const +{ + // Look for the module type + map::const_iterator mod = modlist->find(type_); + if (mod != modlist->end()) + return elaborate_sig_mod_(des, scope, (*mod).second); + + return true; +} + + void PGModule::elaborate(Design*des, const string&path) const { // Look for the module type @@ -2273,7 +2161,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const const string path = scope->name(); bool result_flag = true; - +#if 0 // Get all the explicitly declared wires of the module and // start the signals list with them. const map&wl = get_wires(); @@ -2284,6 +2172,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const (*wt).second->elaborate(des, scope); } +#endif // Elaborate functions. typedef map::const_iterator mfunc_it_t; @@ -2411,6 +2300,15 @@ Design* elaborate(const map&modules, des->evaluate_parameters(); + // With the parameters evaluated down to constants, we have + // what we need to elaborate signals and memories. This pass + // creates all the NetNet and NetMemory objects for declared + // objects. + if (! rmod->elaborate_sig(des, scope)) { + delete des; + return 0; + } + // Now that the structure and parameters are taken care of, // run through the pform again and generate the full netlist. bool rc = rmod->elaborate(des, scope); @@ -2430,6 +2328,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.168 2000/05/02 16:27:38 steve + * Move signal elaboration to a seperate pass. + * * Revision 1.167 2000/05/02 03:13:31 steve * Move memories to the NetScope object. * @@ -2472,57 +2373,5 @@ Design* elaborate(const map&modules, * * Revision 1.157 2000/04/10 05:26:06 steve * All events now use the NetEvent class. - * - * Revision 1.156 2000/04/09 17:44:30 steve - * Catch event declarations during scope elaborate. - * - * Revision 1.155 2000/04/09 16:43:50 steve - * Catch event names in parentheses. - * - * Revision 1.154 2000/04/04 03:20:15 steve - * Simulate named event trigger and waits. - * - * Revision 1.153 2000/04/01 22:14:19 steve - * detect unsupported block on named events. - * - * Revision 1.152 2000/04/01 19:31:57 steve - * Named events as far as the pform. - * - * Revision 1.151 2000/03/29 04:37:11 steve - * New and improved combinational primitives. - * - * Revision 1.150 2000/03/20 15:28:58 steve - * Fix lval part select of non-blocking assign. - * - * Revision 1.149 2000/03/12 21:41:47 steve - * Connect output of NB assign to indexed pin. - * - * Revision 1.148 2000/03/11 03:25:52 steve - * Locate scopes in statements. - * - * Revision 1.147 2000/03/10 06:20:48 steve - * Handle defparam to partial hierarchical names. - * - * Revision 1.146 2000/03/08 04:36:53 steve - * Redesign the implementation of scopes and parameters. - * I now generate the scopes and notice the parameters - * in a separate pass over the pform. Once the scopes - * are generated, I can process overrides and evalutate - * paremeters before elaboration begins. - * - * Revision 1.145 2000/02/23 02:56:54 steve - * Macintosh compilers do not support ident. - * - * Revision 1.144 2000/02/18 05:15:02 steve - * Catch module instantiation arrays. - * - * Revision 1.143 2000/02/14 00:11:11 steve - * Mark the line numbers of NetCondit nodes. - * - * Revision 1.142 2000/02/06 23:13:14 steve - * Include the scope in named gates. - * - * Revision 1.141 2000/01/10 01:35:23 steve - * Elaborate parameters afer binding of overrides. */ diff --git a/net_design.cc b/net_design.cc index b66494f49..54c6c6b31 100644 --- a/net_design.cc +++ b/net_design.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: net_design.cc,v 1.7 2000/05/02 03:13:31 steve Exp $" +#ident "$Id: net_design.cc,v 1.8 2000/05/02 16:27:38 steve Exp $" #endif /* @@ -273,8 +273,16 @@ NetNet* Design::find_signal(NetScope*scope, const string&name) { assert(scope); + /* If the name has a path attached to it, parse it off and use + that to locate the desired scope. */ + string path = name; + string key = parse_last_name(path); + if (path != "") + scope = find_scope(scope, path); + while (scope) { - if (NetNet*net = scope->find_signal(name)) + + if (NetNet*net = scope->find_signal(key)) return net; scope = scope->parent(); } @@ -285,31 +293,48 @@ NetNet* Design::find_signal(NetScope*scope, const string&name) NetMemory* Design::find_memory(NetScope*scope, const string&name) { assert(scope); + + /* If the name has a path attached to it, parse it off and use + that to locate the desired scope. */ + string path = name; + string key = parse_last_name(path); + if (path != "") + scope = find_scope(scope, path); + while (scope) { - if (NetMemory*mem = scope->find_memory(name)) + + if (NetMemory*mem = scope->find_memory(key)) return mem; scope = scope->parent(); } return 0; } -void Design::find_symbol(NetScope*scope, const string&key, +void Design::find_symbol(NetScope*scope, const string&name, NetNet*&sig, NetMemory*&mem) { sig = 0; mem = 0; + + /* If the name has a path attached to it, parse it off and use + that to locate the desired scope. Then locate the key + within that scope. */ + string path = name; + string key = parse_last_name(path); + if (path != "") + scope = find_scope(scope, path); + + + /* If there is no path, then just search upwards for the key. */ while (scope) { - /* Form the full heirarchical name for lookups. */ - string fulname = scope->name() + "." + key; - - if (NetNet*cur = scope->find_signal(fulname)) { + if (NetNet*cur = scope->find_signal(key)) { sig = cur; return; } - if (NetMemory*cur = scope->find_memory(fulname)) { + if (NetMemory*cur = scope->find_memory(key)) { mem = cur; return; } @@ -473,6 +498,9 @@ NetNode* Design::find_node(bool (*func)(const NetNode*)) /* * $Log: net_design.cc,v $ + * Revision 1.8 2000/05/02 16:27:38 steve + * Move signal elaboration to a seperate pass. + * * Revision 1.7 2000/05/02 03:13:31 steve * Move memories to the NetScope object. *