From ab6c8cb4b883846f83b388c158a49bd014a39e6d Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 3 Dec 2001 04:47:14 +0000 Subject: [PATCH] Parser and pform use hierarchical names as hname_t objects instead of encoded strings. --- HName.cc | 257 +++++++++++++++++++++++++++++++++++++++++++++++++ HName.h | 86 +++++++++++++++++ Makefile.in | 6 +- Module.cc | 14 ++- Module.h | 15 ++- PEvent.h | 9 +- PExpr.cc | 35 ++++--- PExpr.h | 18 ++-- PWire.cc | 27 +++++- PWire.h | 21 +++- Statement.cc | 19 +++- Statement.h | 21 ++-- design_dump.cc | 8 +- elab_anet.cc | 14 ++- elab_expr.cc | 54 ++++++----- elab_lval.cc | 14 ++- elab_net.cc | 50 +++++----- elab_pexpr.cc | 20 ++-- elab_scope.cc | 17 ++-- elab_sig.cc | 92 ++++++++++-------- elaborate.cc | 40 ++++---- eval.cc | 10 +- eval_tree.cc | 11 ++- lexor.lex | 15 +-- net_design.cc | 149 ++++++++++++---------------- net_scope.cc | 36 ++++++- netlist.cc | 8 +- netlist.h | 45 +++++---- parse.y | 154 ++++++++++++++--------------- pform.cc | 109 ++++++++++----------- pform.h | 25 +++-- pform_dump.cc | 25 +++-- util.cc | 74 -------------- util.h | 26 +---- 34 files changed, 963 insertions(+), 561 deletions(-) create mode 100644 HName.cc create mode 100644 HName.h delete mode 100644 util.cc diff --git a/HName.cc b/HName.cc new file mode 100644 index 0000000000..dbadc28d12 --- /dev/null +++ b/HName.cc @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2001 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) +#ident "$Id: HName.cc,v 1.1 2001/12/03 04:47:14 steve Exp $" +#endif + +# include "HName.h" +# include +# include +# include + +hname_t::hname_t() +{ + item_ = 0; + count_ = 0; +} + +hname_t::hname_t(const char*text) +{ + item_ = strdup(text); + count_ = 1; +} + +hname_t::hname_t(const hname_t&that) +{ + count_ = that.count_; + switch (count_) { + case 0: + item_ = 0; + break; + case 1: + item_ = strdup(that.item_); + break; + default: + array_ = new char*[count_]; + for (unsigned idx = 0 ; idx < count_ ; idx += 1) + array_[idx] = strdup(that.array_[idx]); + break; + } +} + +hname_t::~hname_t() +{ + switch (count_) { + case 0: + break; + case 1: + free(item_); + break; + default: + for (unsigned idx = 0 ; idx < count_ ; idx += 1) + free(array_[idx]); + delete[]array_; + break; + } +} + +void hname_t::append(const char*text) +{ + char**tmp; + + switch (count_) { + case 0: + count_ = 1; + item_ = strdup(text); + break; + case 1: + count_ = 2; + tmp = new char*[2]; + tmp[0] = item_; + tmp[1] = strdup(text); + array_ = tmp; + break; + default: + tmp = new char*[count_+1]; + for (unsigned idx = 0 ; idx < count_ ; idx += 1) + tmp[idx] = array_[idx]; + delete[]array_; + array_ = tmp; + array_[count_] = strdup(text); + count_ += 1; + } +} + +void hname_t::prepend(const char*text) +{ + char**tmp; + + switch (count_) { + case 0: + count_ = 1; + item_ = strdup(text); + break; + case 1: + count_ = 2; + tmp = new char*[2]; + tmp[0] = strdup(text); + tmp[1] = item_; + array_ = tmp; + break; + default: + tmp = new char*[count_+1]; + tmp[0] = strdup(text); + for (unsigned idx = 0 ; idx < count_ ; idx += 1) + tmp[idx+1] = array_[idx]; + delete[]array_; + array_ = tmp; + count_ += 1; + } +} + +char* hname_t::remove_tail_name() +{ + if (count_ == 0) + return 0; + + if (count_ == 1) { + char*tmp = item_; + count_ = 0; + item_ = 0; + return tmp; + } + + if (count_ == 2) { + char*tmp1 = array_[0]; + char*tmp2 = array_[1]; + delete[]array_; + count_ = 1; + item_ = tmp1; + return tmp2; + } + + char*tmpo = array_[count_-1]; + char**tmpa = new char*[count_-1]; + for (unsigned idx = 0 ; idx < count_-1 ; idx += 1) + tmpa[idx] = array_[idx]; + + delete[]array_; + array_ = tmpa; + count_ -= 1; + return tmpo; +} + +const char* hname_t::peek_name(unsigned idx) const +{ + if (idx >= count_) + return 0; + + if (count_ == 1) + return item_; + + return array_[idx]; +} + +const char* hname_t::peek_tail_name() const +{ + switch (count_) { + case 0: + return 0; + case 1: + return item_; + default: + return array_[count_-1]; + } +} + +bool operator < (const hname_t&l, const hname_t&r) +{ + unsigned idx = 0; + const char*lc = l.peek_name(idx); + const char*rc = r.peek_name(idx); + + while (lc && rc) { + int cmp = strcmp(lc, rc); + if (cmp < 0) + return true; + if (cmp > 0) + return false; + idx += 1; + lc = l.peek_name(idx); + rc = r.peek_name(idx); + } + + if (lc && !rc) + return false; + if (rc && !lc) + return true; + + // Must be == + return false; +} + +bool operator == (const hname_t&l, const hname_t&r) +{ + unsigned idx = 0; + const char*lc = l.peek_name(idx); + const char*rc = r.peek_name(idx); + + while (lc && rc) { + int cmp = strcmp(lc, rc); + if (cmp != 0) + return false; + idx += 1; + lc = l.peek_name(idx); + rc = r.peek_name(idx); + } + + if (lc || rc) + return false; + + // Must be == + return true; +} + +ostream& operator<< (ostream&out, const hname_t&that) +{ + switch (that.count_) { + case 0: + out << ""; + return out; + case 1: + out << that.item_; + return out; + + default: + out << that.array_[0]; + for (unsigned idx = 1 ; idx < that.count_ ; idx += 1) + out << "." << that.array_[idx]; + + return out; + } +} + +/* + * $Log: HName.cc,v $ + * Revision 1.1 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * + */ + diff --git a/HName.h b/HName.h new file mode 100644 index 0000000000..e7308e690e --- /dev/null +++ b/HName.h @@ -0,0 +1,86 @@ +#ifndef __HName_H +#define __HName_H +/* + * Copyright (c) 2001 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) +#ident "$Id: HName.h,v 1.1 2001/12/03 04:47:14 steve Exp $" +#endif + +#ifdef HAVE_IOSFWD +# include +#else +class ostream; +#endif + +/* + * This class represents a Verilog hierarchical name. A hierarchical + * name is an ordered list of simple names. + */ + +class hname_t { + + public: + hname_t (); + explicit hname_t (const char*text); + hname_t (const hname_t&that); + ~hname_t(); + + // This method adds a name to the end of the hierarchical + // path. This becomes a new base name. + void append(const char*text); + + // This method adds a name to the *front* of the hierarchical + // path. The base name remains the same, unless this is the + // only component. + void prepend(const char*text); + + // This method removes the tail name from the hierarchy, and + // returns a pointer to that tail name. That tail name now + // must be removed by the caller. + char* remove_tail_name(); + + // Return the given component in the hierarchical name. If the + // idx is too large, return 0. + const char*peek_name(unsigned idx) const; + const char*peek_tail_name() const; + + friend ostream& operator<< (ostream&, const hname_t&); + + private: + union { + char**array_; + char* item_; + }; + unsigned count_; + + private: // not implemented + hname_t& operator= (const hname_t&); +}; + +extern bool operator < (const hname_t&, const hname_t&); +extern bool operator == (const hname_t&, const hname_t&); + +/* + * $Log: HName.h,v $ + * Revision 1.1 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * + */ +#endif diff --git a/Makefile.in b/Makefile.in index a0ff4a7127..82c1ea0716 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.107 2001/10/20 23:02:39 steve Exp $" +#ident "$Id: Makefile.in,v 1.108 2001/12/03 04:47:14 steve Exp $" # # SHELL = /bin/sh @@ -120,8 +120,8 @@ net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \ net_scope.o net_udp.o pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ set_width.o \ -verinum.o verireal.o target.o targets.o util.o \ -Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \ +verinum.o verireal.o target.o targets.o \ +Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \ PExpr.o PGate.o \ PTask.o PFunction.o PWire.o Statement.o \ $(FF) $(TT) diff --git a/Module.cc b/Module.cc index f7a214d7ce..a333232246 100644 --- a/Module.cc +++ b/Module.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Module.cc,v 1.16 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: Module.cc,v 1.17 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -57,7 +57,7 @@ void Module::add_function(const string &name, PFunction *func) PWire* Module::add_wire(PWire*wire) { - PWire*&ep = wires_[wire->name()]; + PWire*&ep = wires_[wire->path()]; if (ep) return ep; assert(ep == 0); @@ -102,9 +102,9 @@ unsigned Module::find_port(const string&name) const } -PWire* Module::get_wire(const string&name) const +PWire* Module::get_wire(const hname_t&name) const { - map::const_iterator obj = wires_.find(name); + map::const_iterator obj = wires_.find(name); if (obj == wires_.end()) return 0; else @@ -124,7 +124,7 @@ PGate* Module::get_gate(const string&name) return 0; } -const map& Module::get_wires() const +const map& Module::get_wires() const { return wires_; } @@ -142,6 +142,10 @@ const list& Module::get_behaviors() const /* * $Log: Module.cc,v $ + * 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. * diff --git a/Module.h b/Module.h index 888d5a83ef..97de5b0653 100644 --- a/Module.h +++ b/Module.h @@ -19,12 +19,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Module.h,v 1.23 2001/10/31 03:11:15 steve Exp $" +#ident "$Id: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $" #endif # include # include # include "svector.h" +# include "HName.h" # include "named.h" # include "LineInfo.h" # include @@ -73,7 +74,7 @@ class Module : public LineInfo { new parameters within the module, but may be used to set values within this module (when instantiated) or in other instantiated modules. */ - mapdefparms; + mapdefparms; /* Parameters may be overridden at instantiation time; the overrides do not contain explicit parameter names, @@ -109,10 +110,10 @@ class Module : public LineInfo { // Find a wire by name. This is used for connecting gates to // existing wires, etc. - PWire* get_wire(const string&name) const; + PWire* get_wire(const hname_t&name) const; PGate* get_gate(const string&name); - const map& get_wires() const; + const map& get_wires() const; const list& get_gates() const; const list& get_behaviors() const; @@ -130,7 +131,7 @@ class Module : public LineInfo { named array of PEident pointers. */ svector ports_; - map wires_; + map wires_; list gates_; list behaviors_; map tasks_; @@ -144,6 +145,10 @@ class Module : public LineInfo { /* * $Log: Module.h,v $ + * Revision 1.24 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.23 2001/10/31 03:11:15 steve * detect module ports not declared within the module. * diff --git a/PEvent.h b/PEvent.h index 9dee9e55a4..2980967459 100644 --- a/PEvent.h +++ b/PEvent.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PEvent.h,v 1.4 2001/01/16 02:44:18 steve Exp $" +#ident "$Id: PEvent.h,v 1.5 2001/12/03 04:47:14 steve Exp $" #endif # include "LineInfo.h" @@ -30,7 +30,8 @@ class NetScope; /* * The PEvent class represents event objects. These are things that - * are declared in Verilog as ``event foo;'' + * are declared in Verilog as ``event foo;'' The name passed to the + * constructure is the "foo" part of the declaration. */ class PEvent : public LineInfo { @@ -52,6 +53,10 @@ class PEvent : public LineInfo { /* * $Log: PEvent.h,v $ + * Revision 1.5 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.4 2001/01/16 02:44:18 steve * Use the iosfwd header if available. * diff --git a/PExpr.cc b/PExpr.cc index 1832f67f5c..7b94f0b0e0 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PExpr.cc,v 1.27 2001/11/08 05:15:50 steve Exp $" +#ident "$Id: PExpr.cc,v 1.28 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -79,13 +79,13 @@ bool PEBinary::is_constant(Module*mod) const return left_->is_constant(mod) && right_->is_constant(mod); } -PECallFunction::PECallFunction(const char*n, const svector &parms) -: name_(n), parms_(parms) +PECallFunction::PECallFunction(const hname_t&n, const svector &parms) +: path_(n), parms_(parms) { } -PECallFunction::PECallFunction(const char*n) -: name_(n) +PECallFunction::PECallFunction(const hname_t&n) +: path_(n) { } @@ -151,8 +151,8 @@ bool PEFNumber::is_constant(Module*) const return true; } -PEIdent::PEIdent(const string&s) -: text_(s), msb_(0), lsb_(0), idx_(0) +PEIdent::PEIdent(const hname_t&s) +: path_(s), msb_(0), lsb_(0), idx_(0) { } @@ -160,9 +160,9 @@ PEIdent::~PEIdent() { } -string PEIdent::name() const +const hname_t& PEIdent::path() const { - return text_; + return path_; } /* @@ -171,14 +171,17 @@ string PEIdent::name() const */ bool PEIdent::is_constant(Module*mod) const { - map::const_iterator cur; if (mod == 0) return false; - cur = mod->parameters.find(text_); - if (cur != mod->parameters.end()) return true; + { map::const_iterator cur; + cur = mod->parameters.find(path_.peek_name(0)); + if (cur != mod->parameters.end()) return true; + } - cur = mod->localparams.find(text_); - if (cur != mod->localparams.end()) return true; + { map::const_iterator cur; + cur = mod->localparams.find(path_.peek_name(0)); + if (cur != mod->localparams.end()) return true; + } return false; } @@ -264,6 +267,10 @@ bool PEUnary::is_constant(Module*m) const /* * $Log: PExpr.cc,v $ + * Revision 1.28 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.27 2001/11/08 05:15:50 steve * Remove string paths from PExpr elaboration. * diff --git a/PExpr.h b/PExpr.h index e8deefcd6e..7eef53ee2e 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PExpr.h,v 1.52 2001/11/08 05:15:50 steve Exp $" +#ident "$Id: PExpr.h,v 1.53 2001/12/03 04:47:14 steve Exp $" #endif # include @@ -202,7 +202,7 @@ class PEFNumber : public PExpr { class PEIdent : public PExpr { public: - explicit PEIdent(const string&s); + explicit PEIdent(const hname_t&s); ~PEIdent(); virtual void dump(ostream&) const; @@ -236,10 +236,10 @@ class PEIdent : public PExpr { verinum* eval_const(const Design*des, const NetScope*sc) const; verireal*eval_rconst(const Design*des, const NetScope*sc) const; - string name() const; + const hname_t& path() const; private: - string text_; + hname_t path_; public: // Use these to support bit- and part-select operators. @@ -433,15 +433,15 @@ class PETernary : public PExpr { */ class PECallFunction : public PExpr { public: - explicit PECallFunction(const char*n, const svector &parms); - explicit PECallFunction(const char*n); + explicit PECallFunction(const hname_t&n, const svector &parms); + explicit PECallFunction(const hname_t&n); ~PECallFunction(); virtual void dump(ostream &) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const; private: - string name_; + hname_t path_; svector parms_; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; @@ -449,6 +449,10 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.53 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.52 2001/11/08 05:15:50 steve * Remove string paths from PExpr elaboration. * diff --git a/PWire.cc b/PWire.cc index 93ea3a186a..25e4ef07ce 100644 --- a/PWire.cc +++ b/PWire.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PWire.cc,v 1.6 2001/07/25 03:10:48 steve Exp $" +#ident "$Id: PWire.cc,v 1.7 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -25,8 +25,13 @@ # include "PWire.h" # include -PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt) -: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0) +PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt) +: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0) +{ +} + +PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt) +: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0) { } @@ -34,6 +39,18 @@ NetNet::Type PWire::get_wire_type() const { return type_; } +#if 0 +string PWire::name() const +{ + string name = hname_[0]; + for (unsigned idx = 1 ; hname_[idx] ; idx += 1) + name = name + "." + hname_[idx]; +} +#endif +const hname_t& PWire::path() const +{ + return hname_; +} bool PWire::set_wire_type(NetNet::Type t) { @@ -110,6 +127,10 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx) /* * $Log: PWire.cc,v $ + * Revision 1.7 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.6 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) diff --git a/PWire.h b/PWire.h index fc995f22e9..8f9acbdcd7 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.10 2001/01/16 02:44:18 steve Exp $" +#ident "$Id: PWire.h,v 1.11 2001/12/03 04:47:14 steve Exp $" #endif # include "netlist.h" @@ -40,14 +40,21 @@ class Design; * Wires include nets, registers and ports. A net or register becomes * a port by declaration, so ports are not seperate. The module * identifies a port by keeping it in its port list. + * + * The hname parameter to the constructor is a hierarchical name. It + * is an array of strings starting with the root, running towards + * the base name, and terminated by a null pointer. The environment + * allocates the memory for me. */ class PWire : public LineInfo { public: - PWire(const string&n, NetNet::Type t, NetNet::PortType pt); - + PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt); + PWire(char*name, NetNet::Type t, NetNet::PortType pt); - const string&name() const { return name_; } + // Return a hierarchical name. + //const string name() const; + const hname_t&path() const; NetNet::Type get_wire_type() const; bool set_wire_type(NetNet::Type); @@ -70,7 +77,7 @@ class PWire : public LineInfo { void elaborate_sig(Design*, NetScope*scope) const; private: - string name_; + hname_t hname_; NetNet::Type type_; NetNet::PortType port_type_; bool signed_; @@ -92,6 +99,10 @@ class PWire : public LineInfo { /* * $Log: PWire.h,v $ + * Revision 1.11 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.10 2001/01/16 02:44:18 steve * Use the iosfwd header if available. * diff --git a/Statement.cc b/Statement.cc index 546e29ad2f..ae71a99928 100644 --- a/Statement.cc +++ b/Statement.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Statement.cc,v 1.24 2001/11/22 06:20:59 steve Exp $" +#ident "$Id: Statement.cc,v 1.25 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -105,8 +105,8 @@ PBlock::~PBlock() delete list_[idx]; } -PCallTask::PCallTask(const string&n, const svector&p) -: name_(n), parms_(p) +PCallTask::PCallTask(const hname_t&n, const svector&p) +: path_(n), parms_(p) { } @@ -114,6 +114,11 @@ PCallTask::~PCallTask() { } +const hname_t& PCallTask::path() const +{ + return path_; +} + PCase::PCase(NetCase::TYPE t, PExpr*ex, svector*l) : type_(t), expr_(ex), items_(l) { @@ -171,7 +176,7 @@ PDelayStatement::~PDelayStatement() { } -PDisable::PDisable(const string&sc) +PDisable::PDisable(const hname_t&sc) : scope_(sc) { } @@ -260,7 +265,7 @@ PRepeat::~PRepeat() delete statement_; } -PTrigger::PTrigger(const string&e) +PTrigger::PTrigger(const hname_t&e) : event_(e) { } @@ -282,6 +287,10 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.25 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.24 2001/11/22 06:20:59 steve * Use NetScope instead of string for scope path. * diff --git a/Statement.h b/Statement.h index 929b7f7b2b..e066d9047c 100644 --- a/Statement.h +++ b/Statement.h @@ -19,13 +19,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Statement.h,v 1.30 2001/11/22 06:20:59 steve Exp $" +#ident "$Id: Statement.h,v 1.31 2001/12/03 04:47:14 steve Exp $" #endif # include # include "svector.h" # include "PDelays.h" # include "PExpr.h" +# include "HName.h" # include "LineInfo.h" class PExpr; class Statement; @@ -168,10 +169,10 @@ class PBlock : public Statement { class PCallTask : public Statement { public: - explicit PCallTask(const string&n, const svector&parms); + explicit PCallTask(const hname_t&n, const svector&parms); ~PCallTask(); - string name() const { return name_; } + const hname_t& path() const; unsigned nparms() const { return parms_.count(); } @@ -192,7 +193,7 @@ class PCallTask : public Statement { NetProc* elaborate_sys(Design*des, NetScope*scope) const; NetProc* elaborate_usr(Design*des, NetScope*scope) const; - const string name_; + hname_t path_; svector parms_; }; @@ -291,14 +292,14 @@ class PDelayStatement : public Statement { class PDisable : public Statement { public: - explicit PDisable(const string&sc); + explicit PDisable(const hname_t&sc); ~PDisable(); virtual void dump(ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; private: - string scope_; + hname_t scope_; }; /* @@ -422,14 +423,14 @@ class PRelease : public Statement { class PTrigger : public Statement { public: - explicit PTrigger(const string&ev); + explicit PTrigger(const hname_t&ev); ~PTrigger(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(ostream&out, unsigned ind) const; private: - string event_; + hname_t event_; }; class PWhile : public Statement { @@ -449,6 +450,10 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.31 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.30 2001/11/22 06:20:59 steve * Use NetScope instead of string for scope path. * diff --git a/design_dump.cc b/design_dump.cc index d8a37cf3ca..8b93cc9613 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: design_dump.cc,v 1.119 2001/11/19 01:46:38 steve Exp $" +#ident "$Id: design_dump.cc,v 1.120 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -700,7 +700,7 @@ void NetScope::dump(ostream&o) const /* Dump the saved defparam assignments here. */ { - map::const_iterator pp; + map::const_iterator pp; for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) { o << " defparam " << (*pp).first << " = " << @@ -970,6 +970,10 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.120 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.119 2001/11/19 01:46:38 steve * Print typename is fallback expression node dump. * diff --git a/elab_anet.cc b/elab_anet.cc index 00196231b5..633040eb29 100644 --- a/elab_anet.cc +++ b/elab_anet.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_anet.cc,v 1.3 2001/07/25 03:10:48 steve Exp $" +#ident "$Id: elab_anet.cc,v 1.4 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -104,10 +104,10 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const { - NetNet*sig = des->find_signal(scope, text_); + NetNet*sig = des->find_signal(scope, path_); if (sig == 0) { - if (NetMemory*mem = des->find_memory(scope, text_)) { + if (NetMemory*mem = des->find_memory(scope, path_)) { cerr << get_line() << ": error: memories not allowed " << "on left side of procedural continuous " << "asignment." << endl; @@ -115,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const return 0; } - cerr << get_line() << ": error: reg ``" << text_ << "'' " + cerr << get_line() << ": error: reg ``" << path_ << "'' " << "is undefined in this scope." << endl; des->errors += 1; return 0; @@ -127,7 +127,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const break; default: - cerr << get_line() << ": error: " << text_ << " is not " + cerr << get_line() << ": error: " << path_ << " is not " << "a reg in this context." << endl; des->errors += 1; return 0; @@ -149,6 +149,10 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const /* * $Log: elab_anet.cc,v $ + * Revision 1.4 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.3 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) diff --git a/elab_expr.cc b/elab_expr.cc index 765fca14ab..4e04cedd53 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_expr.cc,v 1.45 2001/11/19 02:54:12 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.46 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -164,7 +164,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const { unsigned wid = 32; - if (name_ == "$time") + if (strcmp(path_.peek_name(0), "$time") == 0) wid = 64; @@ -180,7 +180,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const if ((nparms == 1) && (parms_[0] == 0)) nparms = 0; - NetESFunc*fun = new NetESFunc(name_, wid, nparms); + NetESFunc*fun = new NetESFunc(path_.peek_name(0), wid, nparms); /* Now run through the expected parameters. If we find that there are missing parameters, print an error message. @@ -208,7 +208,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const } if (missing_parms > 0) { - cerr << get_line() << ": error: The function " << name_ + cerr << get_line() << ": error: The function " + << path_.peek_name(0) << " has been called with empty parameters." << endl; cerr << get_line() << ": : Verilog doesn't allow " << "passing empty parameters to functions." << endl; @@ -220,19 +221,19 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const { - if (name_[0] == '$') + if (path_.peek_name(0)[0] == '$') return elaborate_sfunc_(des, scope); - NetFuncDef*def = des->find_function(scope, name_); + NetFuncDef*def = des->find_function(scope, path_); if (def == 0) { - cerr << get_line() << ": error: No function " << name_ << + cerr << get_line() << ": error: No function " << path_ << " in this context (" << scope->name() << ")." << endl; des->errors += 1; return 0; } assert(def); - NetScope*dscope = des->find_scope(def->name()); + NetScope*dscope = def->scope(); assert(dscope); /* How many parameters have I got? Normally the size of the @@ -280,7 +281,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const } if (missing_parms > 0) { - cerr << get_line() << ": error: The function " << name_ + cerr << get_line() << ": error: The function " << path_ << " has been called with empty parameters." << endl; cerr << get_line() << ": : Verilog doesn't allow " << "passing empty parameters to functions." << endl; @@ -296,11 +297,10 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const dscope, in this case, is the scope of the function, so the return value is the name within that scope. */ - string rname = name_; - NetNet*res = des->find_signal(dscope, parse_last_name(rname)); + NetNet*res = dscope->find_signal(dscope->basename()); if (res == 0) { cerr << get_line() << ": internal error: Unable to locate " - "function return value for " << name_ << " in " << + "function return value for " << path_ << " in " << def->name() << "." << endl; des->errors += 1; return 0; @@ -371,19 +371,18 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const { - assert(text_[0] != '$'); + assert(path_.peek_name(0)[0] != '$'); - //string name = path+"."+text_; assert(scope); // If the identifier name is a parameter name, then return // a reference to the parameter expression. - if (const NetExpr*ex = des->find_parameter(scope, text_)) { + if (const NetExpr*ex = des->find_parameter(scope, path_)) { NetExpr*tmp; if (dynamic_cast(ex)) tmp = ex->dup_expr(); else - tmp = new NetEParam(des, scope, text_); + tmp = new NetEParam(des, scope, path_); tmp->set_line(*this); return tmp; @@ -391,7 +390,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const // If the identifier names a signal (a register or wire) // then create a NetESignal node to handle it. - if (NetNet*net = des->find_signal(scope, text_)) { + if (NetNet*net = des->find_signal(scope, path_)) { // If this is a part select of a signal, then make a new // temporary signal that is connected to just the @@ -505,7 +504,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const // If the identifier names a memory, then this is a // memory reference and I must generate a NetEMemory // object to handle it. - if (NetMemory*mem = des->find_memory(scope, text_)) { + if (NetMemory*mem = des->find_memory(scope, path_)) { if (msb_ == 0) { NetEMemory*node = new NetEMemory(mem); node->set_line(*this); @@ -537,16 +536,17 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const // Finally, if this is a scope name, then return that. Look // first to see if this is a name of a local scope. Failing // that, search globally for a heirarchical name. - if (NetScope*nsc = scope->child(text_)) { - NetEScope*tmp = new NetEScope(nsc); - tmp->set_line(*this); - return tmp; - } + if ((path_.peek_name(1) == 0)) + if (NetScope*nsc = scope->child(path_.peek_name(0))) { + NetEScope*tmp = new NetEScope(nsc); + tmp->set_line(*this); + return tmp; + } // NOTE: This search pretty much assumes that text_ is a // complete hierarchical name, since there is no mention of // the current scope in the call to find_scope. - if (NetScope*nsc = des->find_scope(text_)) { + if (NetScope*nsc = des->find_scope(path_)) { NetEScope*tmp = new NetEScope(nsc); tmp->set_line(*this); return tmp; @@ -554,7 +554,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const // I cannot interpret this identifier. Error message. cerr << get_line() << ": error: Unable to bind wire/reg/memory " - "`" << text_ << "' in `" << scope->name() << "'" << endl; + "`" << path_ << "' in `" << scope->name() << "'" << endl; des->errors += 1; return 0; } @@ -642,6 +642,10 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const /* * $Log: elab_expr.cc,v $ + * Revision 1.46 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.45 2001/11/19 02:54:12 steve * Handle division and modulus by zero while * evaluating run-time constants. diff --git a/elab_lval.cc b/elab_lval.cc index d8f400d196..2ab20f3f98 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_lval.cc,v 1.16 2001/11/08 05:15:50 steve Exp $" +#ident "$Id: elab_lval.cc,v 1.17 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -135,16 +135,16 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const { /* Get the signal referenced by the identifier, and make sure it is a register. (Wires are not allows in this context. */ - NetNet*reg = des->find_signal(scope, name()); + NetNet*reg = des->find_signal(scope, path_); if (reg == 0) { - NetMemory*mem = des->find_memory(scope, name()); + NetMemory*mem = des->find_memory(scope, path_); if (mem != 0) { cerr << get_line() << ": sorry: I cannot handle " << "memories in this l-value context." << endl; } else { cerr << get_line() << ": error: Could not find variable ``" - << name() << "'' in ``" << scope->name() << + << path_ << "'' in ``" << scope->name() << "''" << endl; } des->errors += 1; @@ -153,7 +153,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const assert(reg); if (reg->type() != NetNet::REG) { - cerr << get_line() << ": error: " << name() << + cerr << get_line() << ": error: " << path_ << " is not a reg/integer/time in " << scope->name() << "." << endl; des->errors += 1; @@ -277,6 +277,10 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const /* * $Log: elab_lval.cc,v $ + * 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/11/08 05:15:50 steve * Remove string paths from PExpr elaboration. * diff --git a/elab_net.cc b/elab_net.cc index fc2017672e..da48f301a8 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_net.cc,v 1.81 2001/11/10 02:08:49 steve Exp $" +#ident "$Id: elab_net.cc,v 1.82 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -1034,24 +1034,24 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, Link::strength_t drive0, Link::strength_t drive1) const { - string path = scope->name(); - NetNet*sig = des->find_signal(scope, text_); + NetNet*sig = des->find_signal(scope, path_); if (sig == 0) { /* If the identifier is a memory instead of a signal, then handle it elsewhere. Create a RAM. */ - if (NetMemory*mem = des->find_memory(scope, text_)) + if (NetMemory*mem = des->find_memory(scope, path_)) return elaborate_net_ram_(des, scope, mem, lwidth, rise, fall, decay); - if (const NetExpr*pe = des->find_parameter(scope, text_)) { + if (const NetExpr*pe = des->find_parameter(scope, path_)) { const NetEConst*pc = dynamic_cast(pe); assert(pc); verinum pvalue = pc->value(); - sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT, - pc->expr_width()); + sig = new NetNet(scope, + scope->name()+"."+path_.peek_name(0), + NetNet::IMPLICIT, pc->expr_width()); NetConst*cp = new NetConst(scope, scope->local_hsymbol(), pvalue); des->add_node(cp); @@ -1060,12 +1060,13 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, } else { - sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT, 1); + sig = new NetNet(scope, scope->name()+"."+path_.peek_name(0), + NetNet::IMPLICIT, 1); if (warn_implicit) cerr << get_line() << ": warning: implicit " - "definition of wire " << path << "." << - text_ << "." << endl; + "definition of wire " << scope->name() + << "." << path_ << "." << endl; } } @@ -1143,7 +1144,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, } else if (msb_) { verinum*mval = msb_->eval_const(des, scope); if (mval == 0) { - cerr << get_line() << ": error: index of " << text_ << + cerr << get_line() << ": error: index of " << path_ << " needs to be constant in this context." << endl; des->errors += 1; @@ -1221,23 +1222,24 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const { string path = scope->name(); - NetNet*sig = des->find_signal(scope, text_); + NetNet*sig = des->find_signal(scope, path_); if (sig == 0) { /* Don't allow memories here. Is it a memory? */ - if (des->find_memory(scope, text_)) { - cerr << get_line() << ": error: memories (" << text_ + if (des->find_memory(scope, path_)) { + cerr << get_line() << ": error: memories (" << path_ << ") cannot be l-values in continuous " << "assignments." << endl; return 0; } /* Fine, create an implicit wire as an l-value. */ - sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT, 1); + sig = new NetNet(scope, path+"."+path_.peek_name(0), + NetNet::IMPLICIT, 1); if (warn_implicit) cerr << get_line() << ": warning: implicit " " definition of wire " << path << "." << - text_ << "." << endl; + path_.peek_name(0) << "." << endl; } assert(sig); @@ -1306,7 +1308,7 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const } else if (msb_) { verinum*mval = msb_->eval_const(des, scope); if (mval == 0) { - cerr << get_line() << ": error: index of " << text_ << + cerr << get_line() << ": error: index of " << path_ << " needs to be constant in l-value of assignment." << endl; des->errors += 1; @@ -1335,9 +1337,9 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const */ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const { - NetNet*sig = des->find_signal(scope, text_); + NetNet*sig = des->find_signal(scope, path_); if (sig == 0) { - cerr << get_line() << ": error: no wire/reg " << text_ + cerr << get_line() << ": error: no wire/reg " << path_ << " in module " << scope->name() << "." << endl; des->errors += 1; return 0; @@ -1354,7 +1356,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const matching input/output/inout declaration. */ case NetNet::NOT_A_PORT: - cerr << get_line() << ": error: signal " << text_ << " in" + cerr << get_line() << ": error: signal " << path_ << " in" << " module " << scope->name() << " is not a port." << endl; cerr << get_line() << ": : Are you missing an input/" << "output/inout declaration?" << endl; @@ -1366,7 +1368,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const function should turn it into an output.... I think. */ case NetNet::PIMPLICIT: - cerr << get_line() << ": internal error: signal " << text_ + cerr << get_line() << ": internal error: signal " << path_ << " in module " << scope->name() << " is left as " << "port type PIMPLICIT." << endl; des->errors += 1; @@ -1412,7 +1414,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const } else if (msb_) { verinum*mval = msb_->eval_const(des, scope); if (mval == 0) { - cerr << get_line() << ": index of " << text_ << + cerr << get_line() << ": index of " << path_ << " needs to be constant in port context." << endl; des->errors += 1; @@ -1878,6 +1880,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.82 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.81 2001/11/10 02:08:49 steve * Coerse input to inout when assigned to. * diff --git a/elab_pexpr.cc b/elab_pexpr.cc index bc4652ec81..0ba61c668d 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_pexpr.cc,v 1.11 2001/11/07 04:01:59 steve Exp $" +#ident "$Id: elab_pexpr.cc,v 1.12 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -136,25 +136,25 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const */ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const { - string path = text_; - string name = parse_last_name(path); + hname_t path = path_; + char*name = path.remove_tail_name(); NetScope*pscope = scope; - if (path != "") + if (path.peek_name(0)) pscope = des->find_scope(scope, path); - assert(pscope); - const NetExpr*ex = pscope->get_parameter(name); if (ex == 0) { - cerr << get_line() << ": error: identifier ``" << text_ << + cerr << get_line() << ": error: identifier ``" << path_ << "'' is not a parameter in " << scope->name() << "." << endl; des->errors += 1; + delete name; return 0; } - NetExpr*res = new NetEParam(des, pscope, name); + NetExpr*res = new NetEParam(des, pscope, hname_t(name)); assert(res); + delete name; return res; } @@ -218,6 +218,10 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const /* * $Log: elab_pexpr.cc,v $ + * Revision 1.12 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.11 2001/11/07 04:01:59 steve * eval_const uses scope instead of a string path. * diff --git a/elab_scope.cc b/elab_scope.cc index 61e0b68b38..edc645f4d1 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_scope.cc,v 1.11 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: elab_scope.cc,v 1.12 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -55,6 +55,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const // place of the elaborated expression. typedef map::const_iterator mparm_it_t; + typedef map::const_iterator hparm_it_t; // This loop scans the parameters in the module, and creates @@ -112,7 +113,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const // here becuase the parameter receiving the assignment may be // in a scope not discovered by this pass. - for (mparm_it_t cur = defparms.begin() + for (hparm_it_t cur = defparms.begin() ; cur != defparms.end() ; cur ++ ) { PExpr*ex = (*cur).second; @@ -205,13 +206,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const // Missing module instance names have already been rejected. assert(get_name() != ""); - string path = sc->name(); - // Check for duplicate scopes. Simply look up the scope I'm // about to create, and if I find it then somebody beat me to // it. - if (NetScope*tmp = des->find_scope(path + "." + get_name())) { + if (NetScope*tmp = sc->child(get_name())) { cerr << get_line() << ": error: Instance/Scope name " << get_name() << " already used in this context." << endl; @@ -308,7 +307,9 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const /* * The isn't really able to create new scopes, but it does create the * event name in the current scope, so can be done during the - * elaborate_scope scan. + * elaborate_scope scan. Note that the name_ of the PEvent object has + * no hierarchy, but neither does the NetEvent, until it is stored in + * the NetScope object. */ void PEvent::elaborate_scope(Design*des, NetScope*scope) const { @@ -458,6 +459,10 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const /* * $Log: elab_scope.cc,v $ + * Revision 1.12 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.11 2001/10/20 05:21:51 steve * Scope/module names are char* instead of string. * diff --git a/elab_sig.cc b/elab_sig.cc index 989a937c08..e7169fed06 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_sig.cc,v 1.17 2001/11/07 04:01:59 steve Exp $" +#ident "$Id: elab_sig.cc,v 1.18 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -39,7 +39,7 @@ * within the port_t that have a matching name. */ static bool signal_is_in_port(const svector&ports, - const string&name) + const hname_t&name) { for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) { @@ -53,7 +53,7 @@ static bool signal_is_in_port(const svector&ports, // together that form the port. for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) { assert(pp->expr[cc]); - if (pp->expr[cc]->name() == name) + if (pp->expr[cc]->path() == name) return true; } } @@ -67,7 +67,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const // Get all the explicitly declared wires of the module and // start the signals list with them. - const map&wl = get_wires(); + const map&wl = get_wires(); // Scan all the ports of the module, and make sure that each // is connected to wires that have port declarations. @@ -76,13 +76,14 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const if (pp == 0) continue; - map::const_iterator wt; + map::const_iterator wt; for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) { - wt = wl.find(pp->expr[cc]->name()); + hname_t port_path (pp->expr[cc]->path()); + wt = wl.find(port_path); if (wt == wl.end()) { cerr << get_line() << ": error: " - << "Port " << pp->expr[cc]->name() << " (" + << "Port " << pp->expr[cc]->path() << " (" << (idx+1) << ") of module " << name_ << " is not declared within module." << endl; des->errors += 1; @@ -91,7 +92,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) { cerr << get_line() << ": error: " - << "Port " << pp->expr[cc]->name() << " (" + << "Port " << pp->expr[cc]->path() << " (" << (idx+1) << ") of module " << name_ << " has no direction declaration." << endl; @@ -100,20 +101,26 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const } } - for (map::const_iterator wt = wl.begin() + for (map::const_iterator wt = wl.begin() ; wt != wl.end() ; wt ++ ) { PWire*cur = (*wt).second; cur->elaborate_sig(des, scope); + NetNet*sig = scope->find_signal_in_child(cur->path()); + // If this wire is a signal of the module (as opposed to // a port of a function) and is a port, then check that - // the module knows about it. - NetNet*sig = scope->find_signal(cur->name()); + // the module knows about it. We know that the signal is + // the name of a signal within a subscope of a module + // (a task, a function, etc.) if the name for the PWire + // has hierarchy. + if (sig && (sig->scope() == scope) && (cur->get_port_type() != NetNet::NOT_A_PORT)) { - string name = (*wt).first; + + hname_t name = (*wt).first; if (! signal_is_in_port(ports_, name)) { @@ -133,7 +140,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const && (sig->type() == NetNet::REG)) { cerr << cur->get_line() << ": error: " - << cur->name() << " in module " + << cur->path() << " in module " << scope->module_name() << " declared as input and as a reg type." << endl; des->errors += 1; @@ -144,7 +151,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const && (sig->type() == NetNet::REG)) { cerr << cur->get_line() << ": error: " - << cur->name() << " in module " + << cur->path() << " in module " << scope->module_name() << " declared as inout and as a reg type." << endl; des->errors += 1; @@ -252,12 +259,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const name. We know by design that the port name is given as two components: .. */ - string pname = (*ports_)[idx]->name(); - string ppath = parse_first_name(pname); + hname_t path = (*ports_)[idx]->path(); + string pname = path.peek_name(1); + string ppath = path.peek_name(0); if (ppath != scope->basename()) { cerr << get_line() << ": internal error: function " - << "port " << (*ports_)[idx]->name() + << "port " << (*ports_)[idx]->path() << " has wrong name for function " << scope->name() << "." << endl; des->errors += 1; @@ -300,16 +308,15 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const name. We know by design that the port name is given as two components: .. */ - string pname = (*ports_)[idx]->name(); - string ppath = parse_first_name(pname); - assert(pname != ""); + hname_t path = (*ports_)[idx]->path(); + assert(path.peek_name(0) && path.peek_name(1)); /* check that the current scope really does have the name of the first component of the task port name. Do this by looking up the task scope in the parent of the current scope. */ - if (scope->parent()->child(ppath) != scope) { - cerr << "internal error: task scope " << ppath + if (scope->parent()->child(path.peek_name(0)) != scope) { + cerr << "internal error: task scope " << path << " not the same as scope " << scope->name() << "?!" << endl; return; @@ -318,11 +325,11 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const /* Find the signal for the port. We know by definition that it is in the scope of the task, so look only in the scope. */ - NetNet*tmp = scope->find_signal(pname); + NetNet*tmp = scope->find_signal(path.peek_name(1)); if (tmp == 0) { cerr << get_line() << ": internal error: " - << "Could not find port " << pname + << "Could not find port " << path.peek_name(1) << " in scope " << scope->name() << endl; scope->dump(cerr); } @@ -351,19 +358,14 @@ 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); + { hname_t tmp_path = hname_; + free(tmp_path.remove_tail_name()); + for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) { + scope = scope->child(tmp_path.peek_name(idx)); + assert(scope); + } } - const string path = scope->name(); NetNet::Type wtype = type_; if (wtype == NetNet::IMPLICIT) wtype = NetNet::WIRE; @@ -422,7 +424,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const cerr << get_line() << ": error: Inconsistent width, " "[" << mnum[idx] << ":" << lnum[idx] << "]" " vs. [" << mnum[0] << ":" << lnum[0] << "]" - " for signal ``" << basename << "''" << endl; + " for signal ``" << hname_ << "''" << endl; des->errors += 1; return; } @@ -449,7 +451,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const if ((lval == 0) || (rval == 0)) { cerr << get_line() << ": internal error: There is " << "a problem evaluating indices for ``" - << basename << "''." << endl; + << hname_.peek_tail_name() << "''." << endl; des->errors += 1; return; } @@ -457,16 +459,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const assert(lval); assert(rval); + string name = scope->name(); + name = name + "." + hname_.peek_tail_name(); + long lnum = lval->as_long(); long rnum = rval->as_long(); delete lval; delete rval; - NetMemory*sig = new NetMemory(scope, path+"."+basename, - wid, lnum, rnum); + NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum); } else { - NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb); + /* Make a hierarchical make for the signal. */ + string name = scope->name(); + name = name + "." + hname_.peek_tail_name(); + + NetNet*sig = new NetNet(scope, name, wtype, msb, lsb); sig->set_line(*this); sig->port_type(port_type_); sig->set_signed(get_signed()); @@ -476,6 +484,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const /* * $Log: elab_sig.cc,v $ + * Revision 1.18 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.17 2001/11/07 04:01:59 steve * eval_const uses scope instead of a string path. * diff --git a/elaborate.cc b/elaborate.cc index d54b51b8c8..2c41488eac 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.233 2001/11/22 06:20:59 steve Exp $" +#ident "$Id: elaborate.cc,v 1.234 2001/12/03 04:47:14 steve Exp $" #endif # include "config.h" @@ -871,11 +871,11 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const const PEIdent*id = dynamic_cast(lval()); if (id == 0) break; - NetNet*net = des->find_signal(scope, id->name()); + NetNet*net = des->find_signal(scope, id->path()); if (net && (net->scope() == scope)) break; - if (NetMemory*mem = des->find_memory(scope, id->name())) + if (NetMemory*mem = des->find_memory(scope, id->path())) return assign_to_memory_(mem, id->msb_, des, scope); } while(0); @@ -1053,7 +1053,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const const PEIdent*id = dynamic_cast(lval()); if (id == 0) break; - if (NetMemory*mem = des->find_memory(scope, id->name())) + if (NetMemory*mem = des->find_memory(scope, id->path())) return assign_to_memory_(mem, id->msb_, des, scope); } while(0); @@ -1288,7 +1288,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const NetProc* PCallTask::elaborate(Design*des, NetScope*scope) const { - if (name_[0] == '$') + if (path_.peek_name(0)[0] == '$') return elaborate_sys(des, scope); else return elaborate_usr(des, scope); @@ -1315,7 +1315,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const eparms[idx] = ex? ex->elaborate_expr(des, scope) : 0; } - NetSTask*cur = new NetSTask(name(), eparms); + NetSTask*cur = new NetSTask(path_.peek_name(0), eparms); return cur; } @@ -1351,10 +1351,10 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const { assert(scope); - NetScope*task = des->find_task(scope, name_); + NetScope*task = des->find_task(scope, path_); if (task == 0) { cerr << get_line() << ": error: Enable of unknown task " - << "``" << name_ << "''." << endl; + << "``" << path_ << "''." << endl; des->errors += 1; return 0; } @@ -1363,7 +1363,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const assert(task->type() == NetScope::TASK); NetTaskDef*def = task->task_def(); if (def == 0) { - cerr << get_line() << ": internal error: task " << name_ + cerr << get_line() << ": internal error: task " << path_ << " doesn't have a definition in " << scope->name() << "." << endl; des->errors += 1; @@ -1373,7 +1373,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const if (nparms() != def->port_count()) { cerr << get_line() << ": error: Port count mismatch in call to ``" - << name_ << "''." << endl; + << path_ << "''." << endl; des->errors += 1; return 0; } @@ -1447,7 +1447,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const NetAssign. */ NetMemory*mem; const PEIdent*id = dynamic_cast(parms_[idx]); - if (id && (mem = des->find_memory(scope, id->name()))) { + if (id && (mem = des->find_memory(scope, id->path()))) { NetExpr*ix = id->msb_->elaborate_expr(des, scope); assert(ix); @@ -1733,6 +1733,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, return 0; } + /* Create a NetEvent object to manage this event. Note + that the NetEvent object's name has no hierarchy. */ NetEvent*ev = new NetEvent(scope->local_symbol()); scope->add_event(ev); @@ -1778,7 +1780,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, assert(expr_[0]->expr()); PEIdent*id = dynamic_cast(expr_[0]->expr()); NetEvent*ev; - if (id && (ev = scope->find_event(id->name()))) { + if (id && (ev = scope->find_event(id->path()))) { NetEvWait*pr = new NetEvWait(enet); pr->add_event(ev); pr->set_line(*this); @@ -1807,7 +1809,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, skip the rest of the expression handling. */ if (PEIdent*id = dynamic_cast(expr_[idx]->expr())) { - NetEvent*tmp = scope->find_event(id->name()); + NetEvent*tmp = scope->find_event(id->path()); if (tmp) { wa->add_event(tmp); continue; @@ -1958,9 +1960,9 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const /* make the expression, and later the initial assignment to the condition variable. The statement in the for loop is very specifically an assignment. */ - NetNet*sig = des->find_signal(scope, id1->name()); + NetNet*sig = des->find_signal(scope, id1->path()); if (sig == 0) { - cerr << id1->get_line() << ": register ``" << id1->name() + cerr << id1->get_line() << ": register ``" << id1->path() << "'' unknown in this context." << endl; des->errors += 1; return 0; @@ -1991,7 +1993,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const /* Elaborate the increment assignment statement at the end of the for loop. This is also a very specific assignment statement. Put this into the "body" block. */ - sig = des->find_signal(scope, id2->name()); + sig = des->find_signal(scope, id2->path()); assert(sig); lv = new NetAssign_(sig); @@ -2052,7 +2054,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const void PFunction::elaborate(Design*des, NetScope*scope) const { - NetFuncDef*def = des->find_function(scope->name()); + NetFuncDef*def = scope->func_def(); assert(def); NetProc*st = statement_->elaborate(des, scope); @@ -2378,6 +2380,10 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.234 2001/12/03 04:47:14 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.233 2001/11/22 06:20:59 steve * Use NetScope instead of string for scope path. * diff --git a/eval.cc b/eval.cc index cc9d1ae127..4aa20478ed 100644 --- a/eval.cc +++ b/eval.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: eval.cc,v 1.23 2001/11/07 04:01:59 steve Exp $" +#ident "$Id: eval.cc,v 1.24 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -116,7 +116,7 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const { assert(scope); - const NetExpr*expr = des->find_parameter(scope, text_); + const NetExpr*expr = des->find_parameter(scope, path_); if (expr == 0) return 0; @@ -125,7 +125,7 @@ verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const if (dynamic_cast(expr)) { cerr << get_line() << ": sorry: I cannot evaluate ``" << - text_ << "'' in this scope: " << scope->name() << endl; + path_ << "'' in this scope: " << scope->name() << endl; return 0; } @@ -196,6 +196,10 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const /* * $Log: eval.cc,v $ + * Revision 1.24 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.23 2001/11/07 04:01:59 steve * eval_const uses scope instead of a string path. * diff --git a/eval_tree.cc b/eval_tree.cc index 3144fc5119..36144c7a1c 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: eval_tree.cc,v 1.29 2001/11/19 01:54:14 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.30 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -764,7 +764,8 @@ NetExpr* NetEParam::eval_tree() return 0; assert(scope_); - const NetExpr*expr = scope_->get_parameter(name_); + assert(name_.peek_name(1) == 0); + const NetExpr*expr = scope_->get_parameter(name_.peek_name(0)); if (expr == 0) { cerr << get_line() << ": internal error: Unable to match " << "parameter " << name_ << " in scope " @@ -792,7 +793,7 @@ NetExpr* NetEParam::eval_tree() // The result can be saved as the value of the parameter for // future reference, and return a copy to the caller. - scope_->set_parameter(name_, res); + scope_->set_parameter(name_.peek_name(0), res); return res->dup_expr(); } @@ -1001,6 +1002,10 @@ NetEConst* NetEUReduce::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.30 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.29 2001/11/19 01:54:14 steve * Port close cropping behavior from mcrgb * Move window array reset to libmc. diff --git a/lexor.lex b/lexor.lex index 36ceea7d16..21932d8071 100644 --- a/lexor.lex +++ b/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: lexor.lex,v 1.66 2001/11/06 02:52:19 steve Exp $" +#ident "$Id: lexor.lex,v 1.67 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -193,10 +193,6 @@ W [ \t\b\f\r]+ } -[a-zA-Z_][a-zA-Z0-9$_]*(\.[a-zA-Z_][a-zA-Z0-9$_]*)+ { - yylval.text = strdup(yytext); - return HIDENTIFIER; } - \\[^ \t\b\f\r]+ { yylval.text = strdup(yytext+1); return IDENTIFIER; } @@ -219,15 +215,6 @@ W [ \t\b\f\r]+ yylval.text = strdup(yytext); return SYSTEM_IDENTIFIER; } -\.{W}?(([a-zA-Z_][a-zA-Z0-9$_]*)|(\\[^ \t\b\f\r]+)) { - char*cp = yytext+1; - while ( (!(isalpha(*cp) || (*cp == '_'))) && (*cp != '\\')) - cp += 1; - if (*cp == '\\') - cp++; - yylval.text = strdup(cp); - return PORTNAME; } - [0-9][0-9_]*[ \t]*\'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_sized_dec(yytext); return NUMBER; } diff --git a/net_design.cc b/net_design.cc index d52100deb5..b9b0068ebd 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.22 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: net_design.cc,v 1.23 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -108,27 +108,27 @@ const list Design::find_root_scopes() const * more step down the tree until the name runs out or the search * fails. */ -NetScope* Design::find_scope(const string&key) const +NetScope* Design::find_scope(const hname_t&path) const { - for (list::const_iterator scope = root_scopes_.begin(); - scope != root_scopes_.end(); scope++) { - if (key == (*scope)->name()) - return *scope; - - string path = key; - string root = parse_first_name(path); + for (list::const_iterator scope = root_scopes_.begin() + ; scope != root_scopes_.end(); scope++) { NetScope*cur = *scope; - if (root != cur->name()) + if (strcmp(path.peek_name(0), cur->basename()) != 0) continue; + unsigned hidx = 1; while (cur) { - string next = parse_first_name(path); - cur = cur->child(next); - if (path == "") return cur; + const char*name = path.peek_name(hidx); + if (name == 0) + return cur; + + cur = cur->child(name); + hidx += 1; } - return cur; + } + return 0; } @@ -139,26 +139,27 @@ NetScope* Design::find_scope(const string&key) const * start looking in parent scopes until I find it, or I run out of * parent scopes. */ -NetScope* Design::find_scope(NetScope*scope, const string&name) const +NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const { assert(scope); for ( ; scope ; scope = scope->parent()) { - string path = name; - string key = parse_first_name(path); + unsigned hidx = 0; + const char*key = path.peek_name(hidx); NetScope*cur = scope; do { cur = cur->child(key); if (cur == 0) break; - key = parse_first_name(path); - } while (key != ""); + hidx += 1; + key = path.peek_name(hidx); + } while (key); if (cur) return cur; } // Last chance. Look for the name starting at the root. - return find_scope(name); + return find_scope(path); } /* @@ -170,22 +171,23 @@ NetScope* Design::find_scope(NetScope*scope, const string&name) const * follow the scopes of the name down to to key. */ const NetExpr* Design::find_parameter(const NetScope*scope, - const string&name) const + const hname_t&path) const { for ( ; scope ; scope = scope->parent()) { - string path = name; - string key = parse_first_name(path); + unsigned hidx = 0; const NetScope*cur = scope; - while (path != "") { - cur = cur->child(key); - if (cur == 0) break; - key = parse_first_name(path); + while (path.peek_name(hidx+1)) { + cur = cur->child(path.peek_name(hidx)); + if (cur == 0) + break; + hidx += 1; } - if (cur == 0) continue; + if (cur == 0) + continue; - if (const NetExpr*res = cur->get_parameter(key)) + if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx))) return res; } @@ -215,16 +217,18 @@ void NetScope::run_defparams(Design*des) cur = cur->sib_; } - map::const_iterator pp; + map::const_iterator pp; for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) { NetExpr*val = (*pp).second; - string path = (*pp).first; - string name = parse_last_name(path); + hname_t path = (*pp).first; + + char*name = path.remove_tail_name(); NetScope*targ_scope = des->find_scope(this, path); if (targ_scope == 0) { cerr << val->get_line() << ": warning: scope of " << path << "." << name << " not found." << endl; + delete[]name; continue; } @@ -236,6 +240,8 @@ void NetScope::run_defparams(Design*des) } else { delete val; } + + delete[]name; } } @@ -310,87 +316,52 @@ string Design::get_flag(const string&key) const * It is the job of this function to properly implement Verilog scope * rules as signals are concerned. */ -NetNet* Design::find_signal(NetScope*scope, const string&name) +NetNet* Design::find_signal(NetScope*scope, hname_t path) { assert(scope); - /* If the name has a path attached to it, parse it off and use - that to locate the desired starting scope. */ - string path = name; - string key = parse_last_name(path); - if (path != "") + char*key = path.remove_tail_name(); + if (path.peek_name(0)) scope = find_scope(scope, path); - /* Now from the starting point, scan upwards until we find the - signal or we find a module boundary. */ while (scope) { - - if (NetNet*net = scope->find_signal(key)) + if (NetNet*net = scope->find_signal(key)) { + delete key; return net; + } if (scope->type() == NetScope::MODULE) break; - scope = scope->parent(); } + delete key; return 0; } -NetMemory* Design::find_memory(NetScope*scope, const string&name) +NetMemory* Design::find_memory(NetScope*scope, hname_t path) { 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 != "") + char*key = path.remove_tail_name(); + if (path.peek_name(0)) scope = find_scope(scope, path); while (scope) { - - if (NetMemory*mem = scope->find_memory(key)) + if (NetMemory*mem = scope->find_memory(key)) { + delete key; return mem; - scope = scope->parent(); - } - return 0; -} - -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) { - - if (NetNet*cur = scope->find_signal(key)) { - sig = cur; - return; - } - - if (NetMemory*cur = scope->find_memory(key)) { - mem = cur; - return; } scope = scope->parent(); } + + delete key; + return 0; } -NetFuncDef* Design::find_function(NetScope*scope, const string&name) + +NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name) { assert(scope); NetScope*func = find_scope(scope, name); @@ -400,7 +371,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const string&name) return 0; } -NetFuncDef* Design::find_function(const string&key) +NetFuncDef* Design::find_function(const hname_t&key) { NetScope*func = find_scope(key); if (func && (func->type() == NetScope::FUNC)) @@ -409,7 +380,7 @@ NetFuncDef* Design::find_function(const string&key) return 0; } -NetScope* Design::find_task(NetScope*scope, const string&name) +NetScope* Design::find_task(NetScope*scope, const hname_t&name) { NetScope*task = find_scope(scope, name); if (task && (task->type() == NetScope::TASK)) @@ -418,7 +389,7 @@ NetScope* Design::find_task(NetScope*scope, const string&name) return 0; } -NetScope* Design::find_task(const string&key) +NetScope* Design::find_task(const hname_t&key) { NetScope*task = find_scope(key); if (task && (task->type() == NetScope::TASK)) @@ -489,6 +460,10 @@ void Design::delete_process(NetProcTop*top) /* * $Log: net_design.cc,v $ + * Revision 1.23 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.22 2001/10/20 05:21:51 steve * Scope/module names are char* instead of string. * diff --git a/net_scope.cc b/net_scope.cc index b3e922c5d4..4345ee7cef 100644 --- a/net_scope.cc +++ b/net_scope.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_scope.cc,v 1.15 2001/11/08 05:15:50 steve Exp $" +#ident "$Id: net_scope.cc,v 1.16 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -224,10 +224,10 @@ void NetScope::rem_event(NetEvent*ev) } -NetEvent* NetScope::find_event(const string&name) +NetEvent* NetScope::find_event(const hname_t&name) { for (NetEvent*cur = events_; cur ; cur = cur->snext_) - if (cur->name() == name) + if (strcmp(cur->name(), name.peek_tail_name()) == 0) return cur; return 0; @@ -261,6 +261,11 @@ void NetScope::rem_signal(NetNet*net) } } +/* + * This method looks for a signal within the current scope. The name + * is assumed to be the base name of the signal, so no sub-scopes are + * searched. + */ NetNet* NetScope::find_signal(const string&key) { if (signals_ == 0) @@ -276,6 +281,27 @@ NetNet* NetScope::find_signal(const string&key) return 0; } +/* + * This method searches for the signal within this scope. If the path + * has hierarchy, I follow the child scopes until I get the base name, + * and look for the key in the deepest scope. + */ +NetNet* NetScope::find_signal_in_child(const hname_t&path) +{ + NetScope*cur = this; + unsigned idx = 0; + + while (path.peek_name(idx+1)) { + cur = cur->child(path.peek_name(idx)); + if (cur == 0) + return 0; + + idx += 1; + } + + return cur->find_signal(path.peek_name(idx)); +} + void NetScope::add_memory(NetMemory*mem) { if (memories_ == 0) { @@ -376,6 +402,10 @@ string NetScope::local_hsymbol() /* * $Log: net_scope.cc,v $ + * Revision 1.16 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.15 2001/11/08 05:15:50 steve * Remove string paths from PExpr elaboration. * diff --git a/netlist.cc b/netlist.cc index 51d70212d1..14667366d9 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.cc,v 1.177 2001/11/19 04:26:46 steve Exp $" +#ident "$Id: netlist.cc,v 1.178 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -2123,7 +2123,7 @@ NetEParam::NetEParam() { } -NetEParam::NetEParam(Design*d, NetScope*s, const string&n) +NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n) : des_(d), scope_(s), name_(n) { } @@ -2407,6 +2407,10 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.178 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.177 2001/11/19 04:26:46 steve * Unary reduction operators are all 1-bit results. * diff --git a/netlist.h b/netlist.h index 9721a635bb..33a87ce5b7 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.226 2001/11/29 01:58:18 steve Exp $" +#ident "$Id: netlist.h,v 1.227 2001/12/03 04:47:15 steve Exp $" #endif /* @@ -32,6 +32,7 @@ # include # include # include "verinum.h" +# include "HName.h" # include "LineInfo.h" # include "svector.h" # include "Attrib.h" @@ -1527,7 +1528,10 @@ class NetDisable : public NetProc { * * Once an object of this type exists, behavioral code can wait on the * event or trigger the event. Event waits refer to this object, as do - * the event trigger statements. + * the event trigger statements. The NetEvent class may have a name and + * a scope. The name is a simple name (no hierarchy) and the scope is + * the NetScope that contains the object. The socpe member is written + * by the NetScope object when the NetEvent is stored. * * The NetEvWait class represents a thread wait for an event. When * this statement is executed, it starts waiting on the @@ -2285,7 +2289,7 @@ class NetEConcat : public NetExpr { class NetEParam : public NetExpr { public: NetEParam(); - NetEParam(class Design*des, NetScope*scope, const string&name); + NetEParam(class Design*des, NetScope*scope, const hname_t&name); ~NetEParam(); virtual bool set_width(unsigned w); @@ -2299,7 +2303,7 @@ class NetEParam : public NetExpr { private: Design*des_; NetScope*scope_; - string name_; + hname_t name_; }; @@ -2585,7 +2589,7 @@ class NetScope { void add_event(NetEvent*); void rem_event(NetEvent*); - NetEvent*find_event(const string&name); + NetEvent*find_event(const hname_t&name); /* These methods manage signals. The add_ and rem_signal @@ -2597,6 +2601,7 @@ class NetScope { void rem_signal(NetNet*); NetNet* find_signal(const string&name); + NetNet* find_signal_in_child(const hname_t&name); /* ... and these methods manage memory the same way as signals @@ -2671,7 +2676,7 @@ class NetScope { assignments from the scope pass to the parameter evaluation step. After that, it is not used. */ - mapdefparams; + mapdefparams; private: TYPE type_; @@ -2740,18 +2745,18 @@ class Design { unsigned long scale_to_precision(unsigned long, const NetScope*)const; /* look up a scope. If no starting scope is passed, then the - path name string is taken as an absolute scope - name. Otherwise, the scope is located starting at the - passed scope and working up if needed. */ - NetScope* find_scope(const string&path) const; - NetScope* find_scope(NetScope*, const string&path) const; + path is taken as an absolute scope name. Otherwise, the + scope is located starting at the passed scope and working + up if needed. */ + NetScope* find_scope(const hname_t&path) const; + NetScope* find_scope(NetScope*, const hname_t&path) const; // PARAMETERS /* This method searches for a parameter, starting in the given scope. This method handles the upward searches that the NetScope class itself does not support. */ - const NetExpr*find_parameter(const NetScope*, const string&name) const; + const NetExpr*find_parameter(const NetScope*, const hname_t&path) const; void run_defparams(); void evaluate_parameters(); @@ -2761,10 +2766,10 @@ class Design { this method, unlike the NetScope::find_signal method, handles global name binding. */ - NetNet*find_signal(NetScope*scope, const string&name); + NetNet*find_signal(NetScope*scope, hname_t path); // Memories - NetMemory* find_memory(NetScope*scope, const string&name); + NetMemory* find_memory(NetScope*scope, hname_t path); /* This is a more general lookup that finds the named signal or memory, whichever is first in the search path. */ @@ -2772,12 +2777,12 @@ class Design { NetNet*&sig, NetMemory*&mem); // Functions - NetFuncDef* find_function(NetScope*scope, const string&key); - NetFuncDef* find_function(const string&path); + NetFuncDef* find_function(NetScope*scope, const hname_t&key); + NetFuncDef* find_function(const hname_t&path); // Tasks - NetScope* find_task(NetScope*scope, const string&name); - NetScope* find_task(const string&key); + NetScope* find_task(NetScope*scope, const hname_t&name); + NetScope* find_task(const hname_t&key); // NODES void add_node(NetNode*); @@ -2862,6 +2867,10 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.227 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.226 2001/11/29 01:58:18 steve * Handle part selects in l-values of DFF devices. * diff --git a/parse.y b/parse.y index 56efbd7f32..8bd7bb0003 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: parse.y,v 1.138 2001/12/01 02:42:39 steve Exp $" +#ident "$Id: parse.y,v 1.139 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -45,6 +45,8 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG }; char*text; list*texts; + hname_t*hier; + list*strings; struct str_pair_t drive; @@ -86,7 +88,7 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG }; verireal* realtime; }; -%token HIDENTIFIER IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING +%token IDENTIFIER SYSTEM_IDENTIFIER STRING %token PATHPULSE_IDENTIFIER %token NUMBER %token REALTIME @@ -123,8 +125,8 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG }; %type udp_port_decl udp_port_decls %type udp_initial udp_init_opt -%type identifier register_variable -%type spec_notifier spec_notifier_opt +%type identifier +%type register_variable %type register_variable_list list_of_variables %type net_decl_assign net_decl_assigns @@ -330,7 +332,7 @@ defparam_assign delete tmp; tmp = 0; } - pform_set_defparam($1, $3); + pform_set_defparam(*$1, $3); delete $1; } ; @@ -423,7 +425,7 @@ delay_value_simple } } | IDENTIFIER - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(hname_t($1)); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; @@ -490,7 +492,7 @@ dr_strength1 event_control : '@' IDENTIFIER - { PEIdent*tmpi = new PEIdent($2); + { PEIdent*tmpi = new PEIdent(hname_t($2)); tmpi->set_file(@2.text); tmpi->set_lineno(@2.first_line); delete[]$2; @@ -817,21 +819,21 @@ expr_primary delete $1; } | identifier - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; delete $1; } | SYSTEM_IDENTIFIER - { PECallFunction*tmp = new PECallFunction($1); + { PECallFunction*tmp = new PECallFunction(hname_t($1)); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; delete $1 } | identifier '[' expression ']' - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); tmp->msb_ = $3; @@ -839,7 +841,7 @@ expr_primary $$ = tmp; } | identifier '[' expression ':' expression ']' - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); tmp->msb_ = $3; @@ -848,13 +850,14 @@ expr_primary $$ = tmp; } | identifier '(' expression_list ')' - { PECallFunction*tmp = new PECallFunction($1, *$3); + { PECallFunction*tmp = new PECallFunction(*$1, *$3); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); + delete $1; $$ = tmp; } | SYSTEM_IDENTIFIER '(' expression_list ')' - { PECallFunction*tmp = new PECallFunction($1, *$3); + { PECallFunction*tmp = new PECallFunction(hname_t($1), *$3); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; @@ -1013,13 +1016,21 @@ gatetype | K_rtranif1 { $$ = PGBuiltin::RTRANIF1; } ; + + /* A general identifier is a hierarchical name, with the right most + name the base of the identifier. This rule builds up a + hierarchical name from left to right. */ identifier : IDENTIFIER - { $$ = $1; } - | HIDENTIFIER - { $$ = $1; + { $$ = new hname_t($1); + delete $1; + } + | identifier '.' IDENTIFIER + { hname_t * tmp = $1; + tmp->append($3); + delete $3; + $$ = tmp; } - ; list_of_ports : port_opt @@ -1059,14 +1070,14 @@ list_of_variables expression meets the constraints of continuous assignments. */ lavalue : identifier - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $1; $$ = tmp; } | identifier '[' expression ']' - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); PExpr*sel = $3; if (! pform_expression_is_constant(sel)) { yyerror(@2, "error: Bit select in lvalue must " @@ -1081,7 +1092,7 @@ lavalue $$ = tmp; } | identifier range - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); assert($2->count() == 2); tmp->msb_ = (*$2)[0]; tmp->lsb_ = (*$2)[1]; @@ -1104,14 +1115,14 @@ lavalue procedural assignment. This rule handles only procedural assignments. */ lpvalue : identifier - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $1; $$ = tmp; } | identifier '[' expression ']' - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->msb_ = $3; tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); @@ -1120,7 +1131,7 @@ lpvalue $$ = tmp; } | identifier '[' expression ':' expression ']' - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(*$1); tmp->msb_ = $3; tmp->lsb_ = $5; tmp->set_file(@1.text); @@ -1534,18 +1545,18 @@ parameter_value_opt ; parameter_value_byname - : PORTNAME '(' expression ')' + : '.' IDENTIFIER '(' expression ')' { portname_t*tmp = new portname_t; - tmp->name = $1; - tmp->parm = $3; - free($1); + tmp->name = $2; + tmp->parm = $4; + free($2); $$ = tmp; } - | PORTNAME '(' ')' + | '.' IDENTIFIER '(' ')' { portname_t*tmp = new portname_t; - tmp->name = $1; + tmp->name = $2; tmp->parm = 0; - free($1); + free($2); $$ = tmp; } ; @@ -1584,12 +1595,12 @@ port /* This syntax attaches an external name to the port reference so that the caller can bind by name to non-trivial port references. The port_t object gets its PWire from the - port_reference, but its name from the PORTNAME. */ + port_reference, but its name from the IDENTIFIER. */ - | PORTNAME '(' port_reference ')' - { Module::port_t*tmp = $3; - tmp->name = $1; - delete $1; + | '.' IDENTIFIER '(' port_reference ')' + { Module::port_t*tmp = $4; + tmp->name = $2; + delete $2; $$ = tmp; } @@ -1606,10 +1617,10 @@ port /* This attaches a name to a port reference contatenation list so that parameter passing be name is possible. */ - | PORTNAME '(' '{' port_reference_list '}' ')' - { Module::port_t*tmp = $4; - tmp->name = $1; - delete $1; + | '.' IDENTIFIER '(' '{' port_reference_list '}' ')' + { Module::port_t*tmp = $5; + tmp->name = $2; + delete $2; $$ = tmp; } ; @@ -1634,7 +1645,7 @@ port_reference : IDENTIFIER { Module::port_t*ptmp = new Module::port_t; - PEIdent*tmp = new PEIdent($1); + PEIdent*tmp = new PEIdent(hname_t($1)); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); ptmp->name = $1; @@ -1645,7 +1656,7 @@ port_reference } | IDENTIFIER '[' expression ':' expression ']' - { PEIdent*wtmp = new PEIdent($1); + { PEIdent*wtmp = new PEIdent(hname_t($1)); wtmp->set_file(@1.text); wtmp->set_lineno(@1.first_line); if (!pform_expression_is_constant($3)) { @@ -1667,7 +1678,7 @@ port_reference } | IDENTIFIER '[' expression ']' - { PEIdent*tmp = new PEIdent($1); + { PEIdent*tmp = new PEIdent(hname_t($1)); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); if (!pform_expression_is_constant($3)) { @@ -1686,7 +1697,7 @@ port_reference | IDENTIFIER '[' error ']' { yyerror(@1, "error: invalid port bit select"); Module::port_t*ptmp = new Module::port_t; - PEIdent*wtmp = new PEIdent($1); + PEIdent*wtmp = new PEIdent(hname_t($1)); wtmp->set_file(@1.text); wtmp->set_lineno(@1.first_line); ptmp->name = $1; @@ -1714,26 +1725,26 @@ port_reference_list looking for the ports of a module declaration. */ port_name - : PORTNAME '(' expression ')' + : '.' IDENTIFIER '(' expression ')' { portname_t*tmp = new portname_t; - tmp->name = $1; - tmp->parm = $3; - delete $1; + tmp->name = $2; + tmp->parm = $4; + delete $2; $$ = tmp; } - | PORTNAME '(' error ')' - { yyerror(@3, "error: invalid port connection expression."); + | '.' IDENTIFIER '(' error ')' + { yyerror(@4, "error: invalid port connection expression."); portname_t*tmp = new portname_t; - tmp->name = $1; + tmp->name = $2; tmp->parm = 0; - delete $1; + delete $2; $$ = tmp; } - | PORTNAME '(' ')' + | '.' IDENTIFIER '(' ')' { portname_t*tmp = new portname_t; - tmp->name = $1; + tmp->name = $2; tmp->parm = 0; - delete $1; + delete $2; $$ = tmp; } ; @@ -1849,34 +1860,28 @@ specify_item | K_Shold '(' spec_reference_event ',' spec_reference_event ',' expression spec_notifier_opt ')' ';' { delete $7; - if ($8) delete $8; } | K_Speriod '(' spec_reference_event ',' expression spec_notifier_opt ')' ';' { delete $5; - if ($6) delete $6; } | K_Srecovery '(' spec_reference_event ',' spec_reference_event ',' expression spec_notifier_opt ')' ';' { delete $7; - if ($8) delete $8; } | K_Ssetup '(' spec_reference_event ',' spec_reference_event ',' expression spec_notifier_opt ')' ';' { delete $7; - if ($8) delete $8; } | K_Ssetuphold '(' spec_reference_event ',' spec_reference_event ',' expression ',' expression spec_notifier_opt ')' ';' { delete $7; delete $9; - if ($10) delete $10; } | K_Swidth '(' spec_reference_event ',' expression ',' expression spec_notifier_opt ')' ';' { delete $5; delete $7; - if ($8) delete $8; } | K_Swidth '(' spec_reference_event ',' expression ')' ';' { delete $5; @@ -1987,20 +1992,19 @@ spec_reference_event spec_notifier_opt : /* empty */ - { $$=0x0; } + { } | spec_notifier - { $$=$1; } + { } ; spec_notifier : ',' - { $$ = 0x0; } + { } | ',' identifier - { $$ = $2; } + { delete $2; } | spec_notifier ',' - { $$ = $1; } + { } | spec_notifier ',' identifier - { $$ = $1; - delete $3; + { delete $3; } | IDENTIFIER { delete $1; } @@ -2117,14 +2121,14 @@ statement } | K_disable identifier ';' - { PDisable*tmp = new PDisable($2); + { PDisable*tmp = new PDisable(*$2); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $2; $$ = tmp; } | K_TRIGGER IDENTIFIER ';' - { PTrigger*tmp = new PTrigger($2); + { PTrigger*tmp = new PTrigger(hname_t($2)); tmp->set_file(@2.text); tmp->set_lineno(@2.first_line); delete $2; @@ -2305,7 +2309,7 @@ statement $$ = tmp; } | SYSTEM_IDENTIFIER '(' expression_list ')' ';' - { PCallTask*tmp = new PCallTask($1, *$3); + { PCallTask*tmp = new PCallTask(hname_t($1), *$3); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $1; @@ -2314,14 +2318,14 @@ statement } | SYSTEM_IDENTIFIER ';' { svectorpt (0); - PCallTask*tmp = new PCallTask($1, pt); + PCallTask*tmp = new PCallTask(hname_t($1), pt); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $1; $$ = tmp; } | identifier '(' expression_list ')' ';' - { PCallTask*tmp = new PCallTask($1, *$3); + { PCallTask*tmp = new PCallTask(*$1, *$3); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $1; @@ -2330,7 +2334,7 @@ statement } | identifier ';' { svectorpt (0); - PCallTask*tmp = new PCallTask($1, pt); + PCallTask*tmp = new PCallTask(*$1, pt); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); delete $1; @@ -2474,7 +2478,7 @@ udp_sequ_entry udp_initial : K_initial IDENTIFIER '=' NUMBER ';' { PExpr*etmp = new PENumber($4); - PEIdent*itmp = new PEIdent($2); + PEIdent*itmp = new PEIdent(hname_t($2)); PAssign*atmp = new PAssign(itmp, etmp); atmp->set_file(@2.text); atmp->set_lineno(@2.first_line); @@ -2545,14 +2549,12 @@ udp_port_decl { PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT); svector*tmp = new svector(1); (*tmp)[0] = pp; - delete $2; $$ = tmp; } | K_reg IDENTIFIER ';' { PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT); svector*tmp = new svector(1); (*tmp)[0] = pp; - delete $2; $$ = tmp; } ; diff --git a/pform.cc b/pform.cc index 41fab7afed..62888b27d4 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.cc,v 1.85 2001/11/29 17:37:51 steve Exp $" +#ident "$Id: pform.cc,v 1.86 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -51,49 +51,43 @@ static int pform_time_prec = 0; /* * The scope stack and the following functions handle the processing * of scope. As I enter a scope, the push function is called, and as I - * leave a scope the pop function is called. + * leave a scope the pop function is called. Entering tasks, functions + * and named blocks causes scope to be pushed and popped. The module + * name is not included it this scope stack. * - * The top module is not included in the scope list. + * The hier_name function, therefore, returns the name path of a + * function relative the current function. */ -struct scope_name_t { - string name; - struct scope_name_t*next; -}; -static scope_name_t*scope_stack = 0; -void pform_set_timescale(int unit, int prec) -{ - assert(unit >= prec); - pform_time_unit = unit; - pform_time_prec = prec; -} +static hname_t scope_stack; -void pform_push_scope(const string&name) +void pform_push_scope(char*name) { - scope_name_t*cur = new scope_name_t; - cur->name = name; - cur->next = scope_stack; - scope_stack = cur; + scope_stack.append(name); } void pform_pop_scope() { - assert(scope_stack); - scope_name_t*cur = scope_stack; - scope_stack = cur->next; - delete cur; + char*tmp = scope_stack.remove_tail_name(); + assert(tmp); + free(tmp); } -static string scoped_name(string name) +static hname_t hier_name(const char*tail) { - scope_name_t*cur = scope_stack; - while (cur) { - name = cur->name + "." + name; - cur = cur->next; - } + hname_t name = scope_stack; + name.append(tail); return name; } +void pform_set_timescale(int unit, int prec) +{ + assert(unit >= prec); + pform_time_unit = unit; + pform_time_prec = prec; +} + + /* * This function evaluates delay expressions. The result should be a * simple constant that I can interpret as an unsigned number. @@ -206,9 +200,9 @@ void pform_make_udp(const char*name, list*parms, map defs; for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) { - string pname = (*decl)[idx]->name(); - PWire*cur = defs[pname]; - if (PWire*cur = defs[pname]) { + hname_t pname = (*decl)[idx]->path(); + + if (PWire*cur = defs[pname.peek_name(0)]) { bool rc = true; assert((*decl)[idx]); if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) { @@ -221,7 +215,7 @@ void pform_make_udp(const char*name, list*parms, } } else { - defs[pname] = (*decl)[idx]; + defs[pname.peek_name(0)] = (*decl)[idx]; } } @@ -359,7 +353,7 @@ void pform_make_udp(const char*name, list*parms, assert(id); // XXXX - assert(id->name() == pins[0]->name()); + //assert(id->name() == pins[0]->name()); const PENumber*np = dynamic_cast(pa->rval()); assert(np); @@ -380,7 +374,7 @@ void pform_make_udp(const char*name, list*parms, // Make the port list for the UDP for (unsigned idx = 0 ; idx < pins.count() ; idx += 1) - udp->ports[idx] = pins[idx]->name(); + udp->ports[idx] = pins[idx]->path().peek_name(0); udp->tinput = input; udp->tcurrent = current; @@ -410,7 +404,7 @@ static void pform_set_net_range(const char*name, assert(range); assert(range->count() == 2); - PWire*cur = pform_cur_module->get_wire(scoped_name(name)); + PWire*cur = pform_cur_module->get_wire(hier_name(name)); if (cur == 0) { VLerror("error: name is not a valid net."); return; @@ -677,9 +671,9 @@ void pform_make_pgassign_list(svector*alist, * BTF-B14. */ void pform_make_reginit(const struct vlltype&li, - const string&name, PExpr*expr) + const char*name, PExpr*expr) { - const string sname = scoped_name(name); + const hname_t sname = hier_name(name); PWire*cur = pform_cur_module->get_wire(sname); if (cur == 0) { VLerror(li, "internal error: reginit to non-register?"); @@ -718,10 +712,10 @@ void pform_make_reginit(const struct vlltype&li, * do check to see if the name has already been declared, as this * function is called for every declaration. */ -void pform_makewire(const vlltype&li, const string&nm, +void pform_makewire(const vlltype&li, const char*nm, NetNet::Type type) { - const string name = scoped_name(nm); + hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur) { if ((cur->get_wire_type() != NetNet::IMPLICIT) @@ -792,10 +786,10 @@ void pform_makewire(const vlltype&li, if (range) pform_set_net_range(first->name, range, false); - string name = scoped_name(first->name); + hname_t name = hier_name(first->name); PWire*cur = pform_cur_module->get_wire(name); if (cur != 0) { - PEIdent*lval = new PEIdent(first->name); + PEIdent*lval = new PEIdent(hname_t(first->name)); pform_make_pgassign(lval, first->expr, delay, str); } @@ -808,7 +802,7 @@ void pform_makewire(const vlltype&li, void pform_set_port_type(const char*nm, NetNet::PortType pt, const char*file, unsigned lineno) { - const string name = scoped_name(nm); + hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur == 0) { cur = new PWire(name, NetNet::IMPLICIT, pt); @@ -872,7 +866,7 @@ svector*pform_make_task_ports(NetNet::PortType pt, ; cur != names->end() ; cur ++ ) { char*txt = *cur; - string name = scoped_name(txt); + hname_t name = hier_name(txt); /* Look for a preexisting wire. If it exists, set the port direction. If not, create it. */ @@ -913,9 +907,11 @@ void pform_set_task(const string&name, PTask*task) * with the trappings that are discovered after the basic function * name is parsed. */ -void pform_set_function(const string&name, svector*ra, PFunction *func) +void pform_set_function(const char*name, svector*ra, PFunction *func) { - PWire*out = new PWire(name+"."+name, NetNet::REG, NetNet::POUTPUT); + hname_t path_return (name); + path_return.append(name); + PWire*out = new PWire(path_return, NetNet::REG, NetNet::POUTPUT); if (ra) { assert(ra->count() == 2); out->set_range((*ra)[0], (*ra)[1]); @@ -926,10 +922,11 @@ void pform_set_function(const string&name, svector*ra, PFunction *func) pform_cur_module->add_function(name, func); } -void pform_set_attrib(const string&name, const string&key, const string&value) +void pform_set_attrib(const char*name, const string&key, const string&value) { - PWire*cur = pform_cur_module->get_wire(name); - if (PWire*cur = pform_cur_module->get_wire(name)) { + hname_t path (name); + + if (PWire*cur = pform_cur_module->get_wire(path)) { cur->attributes[key] = value; } else if (PGate*cur = pform_cur_module->get_gate(name)) { @@ -961,9 +958,9 @@ void pform_set_type_attrib(const string&name, const string&key, * This function attaches a memory index range to an existing * register. (The named wire must be a register. */ -void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r) +void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r) { - PWire*cur = pform_cur_module->get_wire(scoped_name(name)); + PWire*cur = pform_cur_module->get_wire(hier_name(name)); if (cur == 0) { VLerror("internal error: name is not a valid memory for index."); return; @@ -985,7 +982,7 @@ void pform_set_localparam(const string&name, PExpr*expr) pform_cur_module->localparams[name] = expr; } -void pform_set_defparam(const string&name, PExpr*expr) +void pform_set_defparam(const hname_t&name, PExpr*expr) { assert(expr); pform_cur_module->defparms[name] = expr; @@ -1013,7 +1010,7 @@ void pform_set_port_type(const struct vlltype&li, static void pform_set_reg_integer(const char*nm) { - string name = scoped_name(nm); + hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur == 0) { cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT); @@ -1045,7 +1042,7 @@ void pform_set_reg_integer(list*names) static void pform_set_reg_time(const char*nm) { - string name = scoped_name(nm); + hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur == 0) { cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT); @@ -1139,6 +1136,10 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.86 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.85 2001/11/29 17:37:51 steve * Properly parse net_decl assignments with delays. * diff --git a/pform.h b/pform.h index 7ff0f71762..1293462368 100644 --- a/pform.h +++ b/pform.h @@ -19,10 +19,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.h,v 1.52 2001/11/29 17:37:51 steve Exp $" +#ident "$Id: pform.h,v 1.53 2001/12/03 04:47:15 steve Exp $" #endif # include "netlist.h" +# include "HName.h" # include "named.h" # include "Module.h" # include "Statement.h" @@ -126,16 +127,18 @@ extern void pform_make_udp(const char*name, list*parms, const char*file, unsigned lineno); /* - * Enter/exit name scopes. + * Enter/exit name scopes. The push_scope function pushes the scope + * name string onto the scope hierarchy. The pop pulls it off and + * deletes it. Thus, the string pushed must be allocated. */ -extern void pform_push_scope(const string&name); +extern void pform_push_scope(char*name); extern void pform_pop_scope(); /* * The makewire functions announce to the pform code new wires. These * go into a module that is currently opened. */ -extern void pform_makewire(const struct vlltype&li, const string&name, +extern void pform_makewire(const struct vlltype&li, const char*name, NetNet::Type type = NetNet::IMPLICIT); extern void pform_makewire(const struct vlltype&li, svector*range, @@ -147,23 +150,23 @@ extern void pform_makewire(const struct vlltype&li, net_decl_assign_t*assign_list, NetNet::Type type); extern void pform_make_reginit(const struct vlltype&li, - const string&name, PExpr*expr); + const char*name, PExpr*expr); extern void pform_set_port_type(const struct vlltype&li, list*names, svector*, NetNet::PortType); extern void pform_set_net_range(list*names, svector*, bool); -extern void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r); +extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r); extern void pform_set_reg_integer(list*names); extern void pform_set_reg_time(list*names); extern void pform_set_task(const string&, PTask*); -extern void pform_set_function(const string&, svector*, PFunction*); -extern void pform_set_attrib(const string&name, const string&key, +extern void pform_set_function(const char*, svector*, PFunction*); +extern void pform_set_attrib(const char*name, const string&key, const string&value); extern void pform_set_type_attrib(const string&name, const string&key, const string&value); extern void pform_set_parameter(const string&name, PExpr*expr); extern void pform_set_localparam(const string&name, PExpr*expr); -extern void pform_set_defparam(const string&name, PExpr*expr); +extern void pform_set_defparam(const hname_t&name, PExpr*expr); extern PProcess* pform_make_behavior(PProcess::Type, Statement*); extern svector* pform_make_udp_input_ports(list*); @@ -214,6 +217,10 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.53 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.52 2001/11/29 17:37:51 steve * Properly parse net_decl assignments with delays. * diff --git a/pform_dump.cc b/pform_dump.cc index 23c10a6b95..dd97e693db 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform_dump.cc,v 1.67 2001/07/25 03:10:49 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.68 2001/12/03 04:47:15 steve Exp $" #endif # include "config.h" @@ -99,7 +99,7 @@ void PEConcat::dump(ostream&out) const void PECallFunction::dump(ostream &out) const { - out << name_ << "("; + out << path_ << "("; if (parms_.count() > 0) { if (parms_[0]) parms_[0]->dump(out); @@ -142,7 +142,7 @@ void PENumber::dump(ostream&out) const void PEIdent::dump(ostream&out) const { - out << text_; + out << path_; if (msb_) { out << "[" << *msb_; if (lsb_) { @@ -234,7 +234,7 @@ void PWire::dump(ostream&out) const out << " [" << *msb_[idx] << "]"; } - out << " " << name_; + out << " " << hname_; // If the wire has indices, dump them. if (lidx_ || ridx_) { @@ -444,7 +444,7 @@ void PBlock::dump(ostream&out, unsigned ind) const void PCallTask::dump(ostream&out, unsigned ind) const { - out << setw(ind) << "" << name_; + out << setw(ind) << "" << path_; if (parms_.count() > 0) { out << "("; @@ -587,12 +587,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const void PFunction::dump(ostream&out, unsigned ind) const { - out << setw(ind) << "" << "output " << out_->name() << ";" << endl; + out << setw(ind) << "" << "output " << out_->path() << ";" << endl; if (ports_) for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) { out << setw(ind) << ""; out << "input "; - out << (*ports_)[idx]->name() << ";" << endl; + out << (*ports_)[idx]->path() << ";" << endl; } if (statement_) @@ -629,7 +629,7 @@ void PTask::dump(ostream&out, unsigned ind) const out << "inout "; break; } - out << (*ports_)[idx]->name() << ";" << endl; + out << (*ports_)[idx]->path() << ";" << endl; } if (statement_) @@ -686,6 +686,7 @@ void Module::dump(ostream&out) const } typedef map::const_iterator parm_iter_t; + typedef map::const_iterator parm_hiter_t; for (parm_iter_t cur = parameters.begin() ; cur != parameters.end() ; cur ++) { out << " parameter " << (*cur).first << " = "; @@ -704,7 +705,7 @@ void Module::dump(ostream&out) const out << "/* ERROR */;" << endl; } - for (parm_iter_t cur = defparms.begin() + for (parm_hiter_t cur = defparms.begin() ; cur != defparms.end() ; cur ++) { out << " defparam " << (*cur).first << " = "; if ((*cur).second) @@ -721,7 +722,7 @@ void Module::dump(ostream&out) const } // Iterate through and display all the wires. - for (map::const_iterator wire = wires_.begin() + for (map::const_iterator wire = wires_.begin() ; wire != wires_.end() ; wire ++ ) { @@ -813,6 +814,10 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.68 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.67 2001/07/25 03:10:49 steve * Create a config.h.in file to hold all the config * junk, and support gcc 3.0. (Stephan Boettcher) diff --git a/util.cc b/util.cc deleted file mode 100644 index e5235b06d6..0000000000 --- a/util.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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: util.cc,v 1.4 2001/07/25 03:10:50 steve Exp $" -#endif - -# include "config.h" - -# include "util.h" - -string parse_first_name(string&path) -{ - unsigned pos = path.find('.'); - if (path[0]=='\\' || pos > path.length()) { - string res = path; - path = ""; - return res; - } - - string res = path.substr(0, pos); - path = path.substr(pos+1, path.length()); - return res; -} - -string parse_last_name(string&path) -{ - unsigned pos = path.rfind('.'); - if (path[0]=='\\' || pos > path.length()) { - string res = path; - path = ""; - return res; - } - - string res = path.substr(pos+1, path.length()); - path = path.substr(0, pos); - return res; -} - -/* - * $Log: util.cc,v $ - * Revision 1.4 2001/07/25 03:10:50 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.3 2001/07/16 18:20:27 steve - * dot in escaped identifiers are not scope. (Stephan Boettcher) - * - * Revision 1.2 2001/01/14 23:04:56 steve - * Generalize the evaluation of floating point delays, and - * get it working with delay assignment statements. - * - * Allow parameters to be referenced by hierarchical name. - * - * Revision 1.1 2000/04/28 16:50:53 steve - * Catch memory word parameters to tasks. - * - */ - diff --git a/util.h b/util.h index 621b4d7842..89bf1e5023 100644 --- a/util.h +++ b/util.h @@ -19,19 +19,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: util.h,v 1.3 2001/10/20 23:02:40 steve Exp $" +#ident "$Id: util.h,v 1.4 2001/12/03 04:47:15 steve Exp $" #endif -# include - -/* - * This function returns the first name of a hierarchical path, and - * sets the parameter to what's left. If there is no path, then the - * parameter is set to "". - */ -extern string parse_first_name(string&path); - -extern string parse_last_name(string&path); /* * This file attempts to locate a module in a file. It operates by @@ -43,17 +33,11 @@ extern bool load_module(const char*type); /* * $Log: util.h,v $ + * Revision 1.4 2001/12/03 04:47:15 steve + * Parser and pform use hierarchical names as hname_t + * objects instead of encoded strings. + * * Revision 1.3 2001/10/20 23:02:40 steve * Add automatic module libraries. - * - * Revision 1.2 2001/01/14 23:04:56 steve - * Generalize the evaluation of floating point delays, and - * get it working with delay assignment statements. - * - * Allow parameters to be referenced by hierarchical name. - * - * Revision 1.1 2000/04/29 04:53:44 steve - * missing header file. - * */ #endif