Parser and pform use hierarchical names as hname_t

objects instead of encoded strings.
This commit is contained in:
steve 2001-12-03 04:47:14 +00:00
parent 33c7c47f73
commit ab6c8cb4b8
34 changed files with 967 additions and 565 deletions

257
HName.cc Normal file
View File

@ -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 <iostream>
# include <string.h>
# include <malloc.h>
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.
*
*/

86
HName.h Normal file
View File

@ -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 <iosfwd>
#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

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330 # 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA # 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 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 \ net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \ parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \ set_width.o \
verinum.o verireal.o target.o targets.o util.o \ verinum.o verireal.o target.o targets.o \
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \ Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o \ PExpr.o PGate.o \
PTask.o PFunction.o PWire.o Statement.o \ PTask.o PFunction.o PWire.o Statement.o \
$(FF) $(TT) $(FF) $(TT)

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -57,7 +57,7 @@ void Module::add_function(const string &name, PFunction *func)
PWire* Module::add_wire(PWire*wire) PWire* Module::add_wire(PWire*wire)
{ {
PWire*&ep = wires_[wire->name()]; PWire*&ep = wires_[wire->path()];
if (ep) return ep; if (ep) return ep;
assert(ep == 0); 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<string,PWire*>::const_iterator obj = wires_.find(name); map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end()) if (obj == wires_.end())
return 0; return 0;
else else
@ -124,7 +124,7 @@ PGate* Module::get_gate(const string&name)
return 0; return 0;
} }
const map<string,PWire*>& Module::get_wires() const const map<hname_t,PWire*>& Module::get_wires() const
{ {
return wires_; return wires_;
} }
@ -142,6 +142,10 @@ const list<PProcess*>& Module::get_behaviors() const
/* /*
* $Log: Module.cc,v $ * $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 * Revision 1.16 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string. * Scope/module names are char* instead of string.
* *

View File

@ -19,12 +19,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <list> # include <list>
# include <map> # include <map>
# include "svector.h" # include "svector.h"
# include "HName.h"
# include "named.h" # include "named.h"
# include "LineInfo.h" # include "LineInfo.h"
# include <string> # include <string>
@ -73,7 +74,7 @@ class Module : public LineInfo {
new parameters within the module, but may be used to set new parameters within the module, but may be used to set
values within this module (when instantiated) or in other values within this module (when instantiated) or in other
instantiated modules. */ instantiated modules. */
map<string,PExpr*>defparms; map<hname_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time; /* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names, 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 // Find a wire by name. This is used for connecting gates to
// existing wires, etc. // existing wires, etc.
PWire* get_wire(const string&name) const; PWire* get_wire(const hname_t&name) const;
PGate* get_gate(const string&name); PGate* get_gate(const string&name);
const map<string,PWire*>& get_wires() const; const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const; const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const; const list<PProcess*>& get_behaviors() const;
@ -130,7 +131,7 @@ class Module : public LineInfo {
named array of PEident pointers. */ named array of PEident pointers. */
svector<port_t*> ports_; svector<port_t*> ports_;
map<string,PWire*> wires_; map<hname_t,PWire*> wires_;
list<PGate*> gates_; list<PGate*> gates_;
list<PProcess*> behaviors_; list<PProcess*> behaviors_;
map<string,PTask*> tasks_; map<string,PTask*> tasks_;
@ -144,6 +145,10 @@ class Module : public LineInfo {
/* /*
* $Log: Module.h,v $ * $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 * Revision 1.23 2001/10/31 03:11:15 steve
* detect module ports not declared within the module. * detect module ports not declared within the module.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "LineInfo.h" # include "LineInfo.h"
@ -30,7 +30,8 @@ class NetScope;
/* /*
* The PEvent class represents event objects. These are things that * 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 { class PEvent : public LineInfo {
@ -52,6 +53,10 @@ class PEvent : public LineInfo {
/* /*
* $Log: PEvent.h,v $ * $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 * Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available. * Use the iosfwd header if available.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -79,13 +79,13 @@ bool PEBinary::is_constant(Module*mod) const
return left_->is_constant(mod) && right_->is_constant(mod); return left_->is_constant(mod) && right_->is_constant(mod);
} }
PECallFunction::PECallFunction(const char*n, const svector<PExpr *> &parms) PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
: name_(n), parms_(parms) : path_(n), parms_(parms)
{ {
} }
PECallFunction::PECallFunction(const char*n) PECallFunction::PECallFunction(const hname_t&n)
: name_(n) : path_(n)
{ {
} }
@ -151,8 +151,8 @@ bool PEFNumber::is_constant(Module*) const
return true; return true;
} }
PEIdent::PEIdent(const string&s) PEIdent::PEIdent(const hname_t&s)
: text_(s), msb_(0), lsb_(0), idx_(0) : 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 bool PEIdent::is_constant(Module*mod) const
{ {
map<string,PExpr*>::const_iterator cur;
if (mod == 0) return false; if (mod == 0) return false;
cur = mod->parameters.find(text_); { map<string,PExpr*>::const_iterator cur;
cur = mod->parameters.find(path_.peek_name(0));
if (cur != mod->parameters.end()) return true; if (cur != mod->parameters.end()) return true;
}
cur = mod->localparams.find(text_); { map<string,PExpr*>::const_iterator cur;
cur = mod->localparams.find(path_.peek_name(0));
if (cur != mod->localparams.end()) return true; if (cur != mod->localparams.end()) return true;
}
return false; return false;
} }
@ -264,6 +267,10 @@ bool PEUnary::is_constant(Module*m) const
/* /*
* $Log: PExpr.cc,v $ * $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 * Revision 1.27 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration. * Remove string paths from PExpr elaboration.
* *

18
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <string> # include <string>
@ -202,7 +202,7 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr { class PEIdent : public PExpr {
public: public:
explicit PEIdent(const string&s); explicit PEIdent(const hname_t&s);
~PEIdent(); ~PEIdent();
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -236,10 +236,10 @@ class PEIdent : public PExpr {
verinum* eval_const(const Design*des, const NetScope*sc) const; verinum* eval_const(const Design*des, const NetScope*sc) const;
verireal*eval_rconst(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: private:
string text_; hname_t path_;
public: public:
// Use these to support bit- and part-select operators. // Use these to support bit- and part-select operators.
@ -433,15 +433,15 @@ class PETernary : public PExpr {
*/ */
class PECallFunction : public PExpr { class PECallFunction : public PExpr {
public: public:
explicit PECallFunction(const char*n, const svector<PExpr *> &parms); explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const char*n); explicit PECallFunction(const hname_t&n);
~PECallFunction(); ~PECallFunction();
virtual void dump(ostream &) const; virtual void dump(ostream &) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
private: private:
string name_; hname_t path_;
svector<PExpr *> parms_; svector<PExpr *> parms_;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
@ -449,6 +449,10 @@ class PECallFunction : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $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 * Revision 1.52 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration. * Remove string paths from PExpr elaboration.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -25,8 +25,13 @@
# include "PWire.h" # include "PWire.h"
# include <assert.h> # include <assert.h>
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt) PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0) : 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_; 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) 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 $ * $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 * Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config * Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher) * junk, and support gcc 3.0. (Stephan Boettcher)

21
PWire.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "netlist.h" # include "netlist.h"
@ -40,14 +40,21 @@ class Design;
* Wires include nets, registers and ports. A net or register becomes * Wires include nets, registers and ports. A net or register becomes
* a port by declaration, so ports are not seperate. The module * a port by declaration, so ports are not seperate. The module
* identifies a port by keeping it in its port list. * 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 { class PWire : public LineInfo {
public: 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);
// Return a hierarchical name.
const string&name() const { return name_; } //const string name() const;
const hname_t&path() const;
NetNet::Type get_wire_type() const; NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type); bool set_wire_type(NetNet::Type);
@ -70,7 +77,7 @@ class PWire : public LineInfo {
void elaborate_sig(Design*, NetScope*scope) const; void elaborate_sig(Design*, NetScope*scope) const;
private: private:
string name_; hname_t hname_;
NetNet::Type type_; NetNet::Type type_;
NetNet::PortType port_type_; NetNet::PortType port_type_;
bool signed_; bool signed_;
@ -92,6 +99,10 @@ class PWire : public LineInfo {
/* /*
* $Log: PWire.h,v $ * $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 * Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available. * Use the iosfwd header if available.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -105,8 +105,8 @@ PBlock::~PBlock()
delete list_[idx]; delete list_[idx];
} }
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p) PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
: name_(n), parms_(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<PCase::Item*>*l) PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
: type_(t), expr_(ex), items_(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) : scope_(sc)
{ {
} }
@ -260,7 +265,7 @@ PRepeat::~PRepeat()
delete statement_; delete statement_;
} }
PTrigger::PTrigger(const string&e) PTrigger::PTrigger(const hname_t&e)
: event_(e) : event_(e)
{ {
} }
@ -282,6 +287,10 @@ PWhile::~PWhile()
/* /*
* $Log: Statement.cc,v $ * $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 * Revision 1.24 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path. * Use NetScope instead of string for scope path.
* *

View File

@ -19,13 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <string> # include <string>
# include "svector.h" # include "svector.h"
# include "PDelays.h" # include "PDelays.h"
# include "PExpr.h" # include "PExpr.h"
# include "HName.h"
# include "LineInfo.h" # include "LineInfo.h"
class PExpr; class PExpr;
class Statement; class Statement;
@ -168,10 +169,10 @@ class PBlock : public Statement {
class PCallTask : public Statement { class PCallTask : public Statement {
public: public:
explicit PCallTask(const string&n, const svector<PExpr*>&parms); explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
~PCallTask(); ~PCallTask();
string name() const { return name_; } const hname_t& path() const;
unsigned nparms() const { return parms_.count(); } unsigned nparms() const { return parms_.count(); }
@ -192,7 +193,7 @@ class PCallTask : public Statement {
NetProc* elaborate_sys(Design*des, NetScope*scope) const; NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const; NetProc* elaborate_usr(Design*des, NetScope*scope) const;
const string name_; hname_t path_;
svector<PExpr*> parms_; svector<PExpr*> parms_;
}; };
@ -291,14 +292,14 @@ class PDelayStatement : public Statement {
class PDisable : public Statement { class PDisable : public Statement {
public: public:
explicit PDisable(const string&sc); explicit PDisable(const hname_t&sc);
~PDisable(); ~PDisable();
virtual void dump(ostream&out, unsigned ind) const; virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private: private:
string scope_; hname_t scope_;
}; };
/* /*
@ -422,14 +423,14 @@ class PRelease : public Statement {
class PTrigger : public Statement { class PTrigger : public Statement {
public: public:
explicit PTrigger(const string&ev); explicit PTrigger(const hname_t&ev);
~PTrigger(); ~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const; virtual void dump(ostream&out, unsigned ind) const;
private: private:
string event_; hname_t event_;
}; };
class PWhile : public Statement { class PWhile : public Statement {
@ -449,6 +450,10 @@ class PWhile : public Statement {
/* /*
* $Log: Statement.h,v $ * $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 * Revision 1.30 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path. * Use NetScope instead of string for scope path.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -700,7 +700,7 @@ void NetScope::dump(ostream&o) const
/* Dump the saved defparam assignments here. */ /* Dump the saved defparam assignments here. */
{ {
map<string,NetExpr*>::const_iterator pp; map<hname_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin() for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) { ; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " << o << " defparam " << (*pp).first << " = " <<
@ -970,6 +970,10 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $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 * Revision 1.119 2001/11/19 01:46:38 steve
* Print typename is fallback expression node dump. * Print typename is fallback expression node dump.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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* 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 (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 " cerr << get_line() << ": error: memories not allowed "
<< "on left side of procedural continuous " << "on left side of procedural continuous "
<< "asignment." << endl; << "asignment." << endl;
@ -115,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return 0; return 0;
} }
cerr << get_line() << ": error: reg ``" << text_ << "'' " cerr << get_line() << ": error: reg ``" << path_ << "'' "
<< "is undefined in this scope." << endl; << "is undefined in this scope." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -127,7 +127,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
break; break;
default: default:
cerr << get_line() << ": error: " << text_ << " is not " cerr << get_line() << ": error: " << path_ << " is not "
<< "a reg in this context." << endl; << "a reg in this context." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -149,6 +149,10 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
/* /*
* $Log: elab_anet.cc,v $ * $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 * Revision 1.3 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config * Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher) * junk, and support gcc 3.0. (Stephan Boettcher)

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -164,7 +164,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
{ {
unsigned wid = 32; unsigned wid = 32;
if (name_ == "$time") if (strcmp(path_.peek_name(0), "$time") == 0)
wid = 64; wid = 64;
@ -180,7 +180,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
if ((nparms == 1) && (parms_[0] == 0)) if ((nparms == 1) && (parms_[0] == 0))
nparms = 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 /* Now run through the expected parameters. If we find that
there are missing parameters, print an error message. 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) { 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; << " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow " cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl; << "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 NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
{ {
if (name_[0] == '$') if (path_.peek_name(0)[0] == '$')
return elaborate_sfunc_(des, scope); return elaborate_sfunc_(des, scope);
NetFuncDef*def = des->find_function(scope, name_); NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) { if (def == 0) {
cerr << get_line() << ": error: No function " << name_ << cerr << get_line() << ": error: No function " << path_ <<
" in this context (" << scope->name() << ")." << endl; " in this context (" << scope->name() << ")." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
assert(def); assert(def);
NetScope*dscope = des->find_scope(def->name()); NetScope*dscope = def->scope();
assert(dscope); assert(dscope);
/* How many parameters have I got? Normally the size of the /* 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) { 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; << " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow " cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl; << "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 dscope, in this case, is the scope of the function, so the
return value is the name within that scope. */ return value is the name within that scope. */
string rname = name_; NetNet*res = dscope->find_signal(dscope->basename());
NetNet*res = des->find_signal(dscope, parse_last_name(rname));
if (res == 0) { if (res == 0) {
cerr << get_line() << ": internal error: Unable to locate " cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << name_ << " in " << "function return value for " << path_ << " in " <<
def->name() << "." << endl; def->name() << "." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -371,19 +371,18 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
NetExpr* PEIdent::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); assert(scope);
// If the identifier name is a parameter name, then return // If the identifier name is a parameter name, then return
// a reference to the parameter expression. // 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; NetExpr*tmp;
if (dynamic_cast<const NetExpr*>(ex)) if (dynamic_cast<const NetExpr*>(ex))
tmp = ex->dup_expr(); tmp = ex->dup_expr();
else else
tmp = new NetEParam(des, scope, text_); tmp = new NetEParam(des, scope, path_);
tmp->set_line(*this); tmp->set_line(*this);
return tmp; 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) // If the identifier names a signal (a register or wire)
// then create a NetESignal node to handle it. // 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 // If this is a part select of a signal, then make a new
// temporary signal that is connected to just the // 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 // If the identifier names a memory, then this is a
// memory reference and I must generate a NetEMemory // memory reference and I must generate a NetEMemory
// object to handle it. // object to handle it.
if (NetMemory*mem = des->find_memory(scope, text_)) { if (NetMemory*mem = des->find_memory(scope, path_)) {
if (msb_ == 0) { if (msb_ == 0) {
NetEMemory*node = new NetEMemory(mem); NetEMemory*node = new NetEMemory(mem);
node->set_line(*this); node->set_line(*this);
@ -537,7 +536,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// Finally, if this is a scope name, then return that. Look // Finally, if this is a scope name, then return that. Look
// first to see if this is a name of a local scope. Failing // first to see if this is a name of a local scope. Failing
// that, search globally for a heirarchical name. // that, search globally for a heirarchical name.
if (NetScope*nsc = scope->child(text_)) { if ((path_.peek_name(1) == 0))
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
NetEScope*tmp = new NetEScope(nsc); NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this); tmp->set_line(*this);
return tmp; return tmp;
@ -546,7 +546,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// NOTE: This search pretty much assumes that text_ is a // NOTE: This search pretty much assumes that text_ is a
// complete hierarchical name, since there is no mention of // complete hierarchical name, since there is no mention of
// the current scope in the call to find_scope. // 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); NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this); tmp->set_line(*this);
return tmp; return tmp;
@ -554,7 +554,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// I cannot interpret this identifier. Error message. // I cannot interpret this identifier. Error message.
cerr << get_line() << ": error: Unable to bind wire/reg/memory " cerr << get_line() << ": error: Unable to bind wire/reg/memory "
"`" << text_ << "' in `" << scope->name() << "'" << endl; "`" << path_ << "' in `" << scope->name() << "'" << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
@ -642,6 +642,10 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/* /*
* $Log: elab_expr.cc,v $ * $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 * Revision 1.45 2001/11/19 02:54:12 steve
* Handle division and modulus by zero while * Handle division and modulus by zero while
* evaluating run-time constants. * evaluating run-time constants.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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 /* Get the signal referenced by the identifier, and make sure
it is a register. (Wires are not allows in this context. */ 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) { if (reg == 0) {
NetMemory*mem = des->find_memory(scope, name()); NetMemory*mem = des->find_memory(scope, path_);
if (mem != 0) { if (mem != 0) {
cerr << get_line() << ": sorry: I cannot handle " cerr << get_line() << ": sorry: I cannot handle "
<< "memories in this l-value context." << endl; << "memories in this l-value context." << endl;
} else { } else {
cerr << get_line() << ": error: Could not find variable ``" cerr << get_line() << ": error: Could not find variable ``"
<< name() << "'' in ``" << scope->name() << << path_ << "'' in ``" << scope->name() <<
"''" << endl; "''" << endl;
} }
des->errors += 1; des->errors += 1;
@ -153,7 +153,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
assert(reg); assert(reg);
if (reg->type() != NetNet::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() << " is not a reg/integer/time in " << scope->name() <<
"." << endl; "." << endl;
des->errors += 1; des->errors += 1;
@ -277,6 +277,10 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
/* /*
* $Log: elab_lval.cc,v $ * $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 * Revision 1.16 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration. * Remove string paths from PExpr elaboration.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -1034,24 +1034,24 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
Link::strength_t drive0, Link::strength_t drive0,
Link::strength_t drive1) const Link::strength_t drive1) const
{ {
string path = scope->name(); NetNet*sig = des->find_signal(scope, path_);
NetNet*sig = des->find_signal(scope, text_);
if (sig == 0) { if (sig == 0) {
/* If the identifier is a memory instead of a signal, /* If the identifier is a memory instead of a signal,
then handle it elsewhere. Create a RAM. */ 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, return elaborate_net_ram_(des, scope, mem, lwidth,
rise, fall, decay); 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<const NetEConst*>(pe); const NetEConst*pc = dynamic_cast<const NetEConst*>(pe);
assert(pc); assert(pc);
verinum pvalue = pc->value(); verinum pvalue = pc->value();
sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT, sig = new NetNet(scope,
pc->expr_width()); scope->name()+"."+path_.peek_name(0),
NetNet::IMPLICIT, pc->expr_width());
NetConst*cp = new NetConst(scope, scope->local_hsymbol(), NetConst*cp = new NetConst(scope, scope->local_hsymbol(),
pvalue); pvalue);
des->add_node(cp); des->add_node(cp);
@ -1060,12 +1060,13 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
} else { } 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) if (warn_implicit)
cerr << get_line() << ": warning: implicit " cerr << get_line() << ": warning: implicit "
"definition of wire " << path << "." << "definition of wire " << scope->name()
text_ << "." << endl; << "." << path_ << "." << endl;
} }
} }
@ -1143,7 +1144,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
} else if (msb_) { } else if (msb_) {
verinum*mval = msb_->eval_const(des, scope); verinum*mval = msb_->eval_const(des, scope);
if (mval == 0) { if (mval == 0) {
cerr << get_line() << ": error: index of " << text_ << cerr << get_line() << ": error: index of " << path_ <<
" needs to be constant in this context." << " needs to be constant in this context." <<
endl; endl;
des->errors += 1; des->errors += 1;
@ -1221,23 +1222,24 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
{ {
string path = scope->name(); string path = scope->name();
NetNet*sig = des->find_signal(scope, text_); NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) { if (sig == 0) {
/* Don't allow memories here. Is it a memory? */ /* Don't allow memories here. Is it a memory? */
if (des->find_memory(scope, text_)) { if (des->find_memory(scope, path_)) {
cerr << get_line() << ": error: memories (" << text_ cerr << get_line() << ": error: memories (" << path_
<< ") cannot be l-values in continuous " << ") cannot be l-values in continuous "
<< "assignments." << endl; << "assignments." << endl;
return 0; return 0;
} }
/* Fine, create an implicit wire as an l-value. */ /* 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) if (warn_implicit)
cerr << get_line() << ": warning: implicit " cerr << get_line() << ": warning: implicit "
" definition of wire " << path << "." << " definition of wire " << path << "." <<
text_ << "." << endl; path_.peek_name(0) << "." << endl;
} }
assert(sig); assert(sig);
@ -1306,7 +1308,7 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
} else if (msb_) { } else if (msb_) {
verinum*mval = msb_->eval_const(des, scope); verinum*mval = msb_->eval_const(des, scope);
if (mval == 0) { 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." << " needs to be constant in l-value of assignment." <<
endl; endl;
des->errors += 1; 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* 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) { if (sig == 0) {
cerr << get_line() << ": error: no wire/reg " << text_ cerr << get_line() << ": error: no wire/reg " << path_
<< " in module " << scope->name() << "." << endl; << " in module " << scope->name() << "." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -1354,7 +1356,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
matching input/output/inout declaration. */ matching input/output/inout declaration. */
case NetNet::NOT_A_PORT: 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; << " module " << scope->name() << " is not a port." << endl;
cerr << get_line() << ": : Are you missing an input/" cerr << get_line() << ": : Are you missing an input/"
<< "output/inout declaration?" << endl; << "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. */ function should turn it into an output.... I think. */
case NetNet::PIMPLICIT: case NetNet::PIMPLICIT:
cerr << get_line() << ": internal error: signal " << text_ cerr << get_line() << ": internal error: signal " << path_
<< " in module " << scope->name() << " is left as " << " in module " << scope->name() << " is left as "
<< "port type PIMPLICIT." << endl; << "port type PIMPLICIT." << endl;
des->errors += 1; des->errors += 1;
@ -1412,7 +1414,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
} else if (msb_) { } else if (msb_) {
verinum*mval = msb_->eval_const(des, scope); verinum*mval = msb_->eval_const(des, scope);
if (mval == 0) { if (mval == 0) {
cerr << get_line() << ": index of " << text_ << cerr << get_line() << ": index of " << path_ <<
" needs to be constant in port context." << " needs to be constant in port context." <<
endl; endl;
des->errors += 1; des->errors += 1;
@ -1878,6 +1880,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $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 * Revision 1.81 2001/11/10 02:08:49 steve
* Coerse input to inout when assigned to. * Coerse input to inout when assigned to.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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 NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{ {
string path = text_; hname_t path = path_;
string name = parse_last_name(path); char*name = path.remove_tail_name();
NetScope*pscope = scope; NetScope*pscope = scope;
if (path != "") if (path.peek_name(0))
pscope = des->find_scope(scope, path); pscope = des->find_scope(scope, path);
assert(pscope);
const NetExpr*ex = pscope->get_parameter(name); const NetExpr*ex = pscope->get_parameter(name);
if (ex == 0) { if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << text_ << cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl; "'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1; des->errors += 1;
delete name;
return 0; return 0;
} }
NetExpr*res = new NetEParam(des, pscope, name); NetExpr*res = new NetEParam(des, pscope, hname_t(name));
assert(res); assert(res);
delete name;
return res; return res;
} }
@ -218,6 +218,10 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/* /*
* $Log: elab_pexpr.cc,v $ * $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 * Revision 1.11 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path. * eval_const uses scope instead of a string path.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -55,6 +55,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// place of the elaborated expression. // place of the elaborated expression.
typedef map<string,PExpr*>::const_iterator mparm_it_t; typedef map<string,PExpr*>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
// This loop scans the parameters in the module, and creates // 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 // here becuase the parameter receiving the assignment may be
// in a scope not discovered by this pass. // 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 ++ ) { ; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second; 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. // Missing module instance names have already been rejected.
assert(get_name() != ""); assert(get_name() != "");
string path = sc->name();
// Check for duplicate scopes. Simply look up the scope I'm // Check for duplicate scopes. Simply look up the scope I'm
// about to create, and if I find it then somebody beat me to // about to create, and if I find it then somebody beat me to
// it. // it.
if (NetScope*tmp = des->find_scope(path + "." + get_name())) { if (NetScope*tmp = sc->child(get_name())) {
cerr << get_line() << ": error: Instance/Scope name " << cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." << get_name() << " already used in this context." <<
endl; 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 * 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 * 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 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 $ * $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 * Revision 1.11 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string. * Scope/module names are char* instead of string.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -39,7 +39,7 @@
* within the port_t that have a matching name. * within the port_t that have a matching name.
*/ */
static bool signal_is_in_port(const svector<Module::port_t*>&ports, static bool signal_is_in_port(const svector<Module::port_t*>&ports,
const string&name) const hname_t&name)
{ {
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) { for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
@ -53,7 +53,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
// together that form the port. // together that form the port.
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) { for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
assert(pp->expr[cc]); assert(pp->expr[cc]);
if (pp->expr[cc]->name() == name) if (pp->expr[cc]->path() == name)
return true; 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 // Get all the explicitly declared wires of the module and
// start the signals list with them. // start the signals list with them.
const map<string,PWire*>&wl = get_wires(); const map<hname_t,PWire*>&wl = get_wires();
// Scan all the ports of the module, and make sure that each // Scan all the ports of the module, and make sure that each
// is connected to wires that have port declarations. // is connected to wires that have port declarations.
@ -76,13 +76,14 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (pp == 0) if (pp == 0)
continue; continue;
map<string,PWire*>::const_iterator wt; map<hname_t,PWire*>::const_iterator wt;
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) { 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()) { if (wt == wl.end()) {
cerr << get_line() << ": error: " cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->name() << " (" << "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_ << (idx+1) << ") of module " << name_
<< " is not declared within module." << endl; << " is not declared within module." << endl;
des->errors += 1; 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) { if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
cerr << get_line() << ": error: " cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->name() << " (" << "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_ << (idx+1) << ") of module " << name_
<< " has no direction declaration." << " has no direction declaration."
<< endl; << endl;
@ -100,20 +101,26 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
} }
} }
for (map<string,PWire*>::const_iterator wt = wl.begin() for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end() ; wt != wl.end()
; wt ++ ) { ; wt ++ ) {
PWire*cur = (*wt).second; PWire*cur = (*wt).second;
cur->elaborate_sig(des, scope); 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 // If this wire is a signal of the module (as opposed to
// a port of a function) and is a port, then check that // a port of a function) and is a port, then check that
// the module knows about it. // the module knows about it. We know that the signal is
NetNet*sig = scope->find_signal(cur->name()); // 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) if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) { && (cur->get_port_type() != NetNet::NOT_A_PORT)) {
string name = (*wt).first;
hname_t name = (*wt).first;
if (! signal_is_in_port(ports_, name)) { if (! signal_is_in_port(ports_, name)) {
@ -133,7 +140,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
&& (sig->type() == NetNet::REG)) { && (sig->type() == NetNet::REG)) {
cerr << cur->get_line() << ": error: " cerr << cur->get_line() << ": error: "
<< cur->name() << " in module " << cur->path() << " in module "
<< scope->module_name() << scope->module_name()
<< " declared as input and as a reg type." << endl; << " declared as input and as a reg type." << endl;
des->errors += 1; des->errors += 1;
@ -144,7 +151,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
&& (sig->type() == NetNet::REG)) { && (sig->type() == NetNet::REG)) {
cerr << cur->get_line() << ": error: " cerr << cur->get_line() << ": error: "
<< cur->name() << " in module " << cur->path() << " in module "
<< scope->module_name() << scope->module_name()
<< " declared as inout and as a reg type." << endl; << " declared as inout and as a reg type." << endl;
des->errors += 1; 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 name. We know by design that the port name is given
as two components: <func>.<port>. */ as two components: <func>.<port>. */
string pname = (*ports_)[idx]->name(); hname_t path = (*ports_)[idx]->path();
string ppath = parse_first_name(pname); string pname = path.peek_name(1);
string ppath = path.peek_name(0);
if (ppath != scope->basename()) { if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function " cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->name() << "port " << (*ports_)[idx]->path()
<< " has wrong name for function " << " has wrong name for function "
<< scope->name() << "." << endl; << scope->name() << "." << endl;
des->errors += 1; 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 name. We know by design that the port name is given
as two components: <task>.<port>. */ as two components: <task>.<port>. */
string pname = (*ports_)[idx]->name(); hname_t path = (*ports_)[idx]->path();
string ppath = parse_first_name(pname); assert(path.peek_name(0) && path.peek_name(1));
assert(pname != "");
/* check that the current scope really does have the /* check that the current scope really does have the
name of the first component of the task port name. Do name of the first component of the task port name. Do
this by looking up the task scope in the parent of this by looking up the task scope in the parent of
the current scope. */ the current scope. */
if (scope->parent()->child(ppath) != scope) { if (scope->parent()->child(path.peek_name(0)) != scope) {
cerr << "internal error: task scope " << ppath cerr << "internal error: task scope " << path
<< " not the same as scope " << scope->name() << " not the same as scope " << scope->name()
<< "?!" << endl; << "?!" << endl;
return; return;
@ -318,11 +325,11 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
/* Find the signal for the port. We know by definition /* Find the signal for the port. We know by definition
that it is in the scope of the task, so look only in that it is in the scope of the task, so look only in
the scope. */ the scope. */
NetNet*tmp = scope->find_signal(pname); NetNet*tmp = scope->find_signal(path.peek_name(1));
if (tmp == 0) { if (tmp == 0) {
cerr << get_line() << ": internal error: " cerr << get_line() << ": internal error: "
<< "Could not find port " << pname << "Could not find port " << path.peek_name(1)
<< " in scope " << scope->name() << endl; << " in scope " << scope->name() << endl;
scope->dump(cerr); 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 /* The parser may produce hierarchical names for wires. I here
follow the scopes down to the base where I actually want to follow the scopes down to the base where I actually want to
elaborate the NetNet object. */ elaborate the NetNet object. */
string basename = name_; { hname_t tmp_path = hname_;
for (;;) { free(tmp_path.remove_tail_name());
string p = parse_first_name(basename); for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
if (basename == "") { scope = scope->child(tmp_path.peek_name(idx));
basename = p;
break;
}
scope = scope->child(p);
assert(scope); assert(scope);
} }
}
const string path = scope->name();
NetNet::Type wtype = type_; NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT) if (wtype == NetNet::IMPLICIT)
wtype = NetNet::WIRE; wtype = NetNet::WIRE;
@ -422,7 +424,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
cerr << get_line() << ": error: Inconsistent width, " cerr << get_line() << ": error: Inconsistent width, "
"[" << mnum[idx] << ":" << lnum[idx] << "]" "[" << mnum[idx] << ":" << lnum[idx] << "]"
" vs. [" << mnum[0] << ":" << lnum[0] << "]" " vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << basename << "''" << endl; " for signal ``" << hname_ << "''" << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
@ -449,7 +451,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if ((lval == 0) || (rval == 0)) { if ((lval == 0) || (rval == 0)) {
cerr << get_line() << ": internal error: There is " cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``" << "a problem evaluating indices for ``"
<< basename << "''." << endl; << hname_.peek_tail_name() << "''." << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
@ -457,16 +459,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
assert(lval); assert(lval);
assert(rval); assert(rval);
string name = scope->name();
name = name + "." + hname_.peek_tail_name();
long lnum = lval->as_long(); long lnum = lval->as_long();
long rnum = rval->as_long(); long rnum = rval->as_long();
delete lval; delete lval;
delete rval; delete rval;
NetMemory*sig = new NetMemory(scope, path+"."+basename, NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum);
wid, lnum, rnum);
} else { } 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->set_line(*this);
sig->port_type(port_type_); sig->port_type(port_type_);
sig->set_signed(get_signed()); sig->set_signed(get_signed());
@ -476,6 +484,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/* /*
* $Log: elab_sig.cc,v $ * $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 * Revision 1.17 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path. * eval_const uses scope instead of a string path.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -871,11 +871,11 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
const PEIdent*id = dynamic_cast<const PEIdent*>(lval()); const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
if (id == 0) break; 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)) if (net && (net->scope() == scope))
break; 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); return assign_to_memory_(mem, id->msb_, des, scope);
} while(0); } while(0);
@ -1053,7 +1053,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
const PEIdent*id = dynamic_cast<const PEIdent*>(lval()); const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
if (id == 0) break; 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); return assign_to_memory_(mem, id->msb_, des, scope);
} while(0); } while(0);
@ -1288,7 +1288,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
NetProc* PCallTask::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); return elaborate_sys(des, scope);
else else
return elaborate_usr(des, scope); 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; 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; return cur;
} }
@ -1351,10 +1351,10 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
NetScope*task = des->find_task(scope, name_); NetScope*task = des->find_task(scope, path_);
if (task == 0) { if (task == 0) {
cerr << get_line() << ": error: Enable of unknown task " cerr << get_line() << ": error: Enable of unknown task "
<< "``" << name_ << "''." << endl; << "``" << path_ << "''." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
@ -1363,7 +1363,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
assert(task->type() == NetScope::TASK); assert(task->type() == NetScope::TASK);
NetTaskDef*def = task->task_def(); NetTaskDef*def = task->task_def();
if (def == 0) { 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() << " doesn't have a definition in " << scope->name()
<< "." << endl; << "." << endl;
des->errors += 1; des->errors += 1;
@ -1373,7 +1373,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
if (nparms() != def->port_count()) { if (nparms() != def->port_count()) {
cerr << get_line() << ": error: Port count mismatch in call to ``" cerr << get_line() << ": error: Port count mismatch in call to ``"
<< name_ << "''." << endl; << path_ << "''." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
@ -1447,7 +1447,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
NetAssign. */ NetAssign. */
NetMemory*mem; NetMemory*mem;
const PEIdent*id = dynamic_cast<const PEIdent*>(parms_[idx]); const PEIdent*id = dynamic_cast<const PEIdent*>(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); NetExpr*ix = id->msb_->elaborate_expr(des, scope);
assert(ix); assert(ix);
@ -1733,6 +1733,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
return 0; 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()); NetEvent*ev = new NetEvent(scope->local_symbol());
scope->add_event(ev); scope->add_event(ev);
@ -1778,7 +1780,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
assert(expr_[0]->expr()); assert(expr_[0]->expr());
PEIdent*id = dynamic_cast<PEIdent*>(expr_[0]->expr()); PEIdent*id = dynamic_cast<PEIdent*>(expr_[0]->expr());
NetEvent*ev; NetEvent*ev;
if (id && (ev = scope->find_event(id->name()))) { if (id && (ev = scope->find_event(id->path()))) {
NetEvWait*pr = new NetEvWait(enet); NetEvWait*pr = new NetEvWait(enet);
pr->add_event(ev); pr->add_event(ev);
pr->set_line(*this); pr->set_line(*this);
@ -1807,7 +1809,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
skip the rest of the expression handling. */ skip the rest of the expression handling. */
if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) { if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
NetEvent*tmp = scope->find_event(id->name()); NetEvent*tmp = scope->find_event(id->path());
if (tmp) { if (tmp) {
wa->add_event(tmp); wa->add_event(tmp);
continue; continue;
@ -1958,9 +1960,9 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
/* make the expression, and later the initial assignment to /* make the expression, and later the initial assignment to
the condition variable. The statement in the for loop is the condition variable. The statement in the for loop is
very specifically an assignment. */ very specifically an assignment. */
NetNet*sig = des->find_signal(scope, id1->name()); NetNet*sig = des->find_signal(scope, id1->path());
if (sig == 0) { if (sig == 0) {
cerr << id1->get_line() << ": register ``" << id1->name() cerr << id1->get_line() << ": register ``" << id1->path()
<< "'' unknown in this context." << endl; << "'' unknown in this context." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -1991,7 +1993,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
/* Elaborate the increment assignment statement at the end of /* Elaborate the increment assignment statement at the end of
the for loop. This is also a very specific assignment the for loop. This is also a very specific assignment
statement. Put this into the "body" block. */ statement. Put this into the "body" block. */
sig = des->find_signal(scope, id2->name()); sig = des->find_signal(scope, id2->path());
assert(sig); assert(sig);
lv = new NetAssign_(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 void PFunction::elaborate(Design*des, NetScope*scope) const
{ {
NetFuncDef*def = des->find_function(scope->name()); NetFuncDef*def = scope->func_def();
assert(def); assert(def);
NetProc*st = statement_->elaborate(des, scope); NetProc*st = statement_->elaborate(des, scope);
@ -2378,6 +2380,10 @@ Design* elaborate(list<const char*>roots)
/* /*
* $Log: elaborate.cc,v $ * $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 * Revision 1.233 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path. * Use NetScope instead of string for scope path.
* *

10
eval.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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 verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
{ {
assert(scope); assert(scope);
const NetExpr*expr = des->find_parameter(scope, text_); const NetExpr*expr = des->find_parameter(scope, path_);
if (expr == 0) if (expr == 0)
return 0; return 0;
@ -125,7 +125,7 @@ verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
if (dynamic_cast<const NetEParam*>(expr)) { if (dynamic_cast<const NetEParam*>(expr)) {
cerr << get_line() << ": sorry: I cannot evaluate ``" << cerr << get_line() << ": sorry: I cannot evaluate ``" <<
text_ << "'' in this scope: " << scope->name() << endl; path_ << "'' in this scope: " << scope->name() << endl;
return 0; return 0;
} }
@ -196,6 +196,10 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
/* /*
* $Log: eval.cc,v $ * $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 * Revision 1.23 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path. * eval_const uses scope instead of a string path.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -764,7 +764,8 @@ NetExpr* NetEParam::eval_tree()
return 0; return 0;
assert(scope_); 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) { if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match " cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope " << "parameter " << name_ << " in scope "
@ -792,7 +793,7 @@ NetExpr* NetEParam::eval_tree()
// The result can be saved as the value of the parameter for // The result can be saved as the value of the parameter for
// future reference, and return a copy to the caller. // 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(); return res->dup_expr();
} }
@ -1001,6 +1002,10 @@ NetEConst* NetEUReduce::eval_tree()
/* /*
* $Log: eval_tree.cc,v $ * $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 * Revision 1.29 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb * Port close cropping behavior from mcrgb
* Move window array reset to libmc. * Move window array reset to libmc.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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]+ { \\[^ \t\b\f\r]+ {
yylval.text = strdup(yytext+1); yylval.text = strdup(yytext+1);
return IDENTIFIER; } return IDENTIFIER; }
@ -219,15 +215,6 @@ W [ \t\b\f\r]+
yylval.text = strdup(yytext); yylval.text = strdup(yytext);
return SYSTEM_IDENTIFIER; } 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_]* { [0-9][0-9_]*[ \t]*\'[sS]?[dD][ \t]*[0-9][0-9_]* {
yylval.number = make_sized_dec(yytext); yylval.number = make_sized_dec(yytext);
return NUMBER; } return NUMBER; }

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -108,27 +108,27 @@ const list<NetScope*> Design::find_root_scopes() const
* more step down the tree until the name runs out or the search * more step down the tree until the name runs out or the search
* fails. * fails.
*/ */
NetScope* Design::find_scope(const string&key) const NetScope* Design::find_scope(const hname_t&path) const
{ {
for (list<NetScope*>::const_iterator scope = root_scopes_.begin(); for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
scope != root_scopes_.end(); scope++) { ; scope != root_scopes_.end(); scope++) {
if (key == (*scope)->name())
return *scope;
string path = key;
string root = parse_first_name(path);
NetScope*cur = *scope; NetScope*cur = *scope;
if (root != cur->name()) if (strcmp(path.peek_name(0), cur->basename()) != 0)
continue; continue;
unsigned hidx = 1;
while (cur) { while (cur) {
string next = parse_first_name(path); const char*name = path.peek_name(hidx);
cur = cur->child(next); if (name == 0)
if (path == "") return cur;
}
return cur; return cur;
cur = cur->child(name);
hidx += 1;
} }
}
return 0; 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 * start looking in parent scopes until I find it, or I run out of
* parent scopes. * 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); assert(scope);
for ( ; scope ; scope = scope->parent()) { for ( ; scope ; scope = scope->parent()) {
string path = name; unsigned hidx = 0;
string key = parse_first_name(path); const char*key = path.peek_name(hidx);
NetScope*cur = scope; NetScope*cur = scope;
do { do {
cur = cur->child(key); cur = cur->child(key);
if (cur == 0) break; if (cur == 0) break;
key = parse_first_name(path); hidx += 1;
} while (key != ""); key = path.peek_name(hidx);
} while (key);
if (cur) return cur; if (cur) return cur;
} }
// Last chance. Look for the name starting at the root. // 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. * follow the scopes of the name down to to key.
*/ */
const NetExpr* Design::find_parameter(const NetScope*scope, const NetExpr* Design::find_parameter(const NetScope*scope,
const string&name) const const hname_t&path) const
{ {
for ( ; scope ; scope = scope->parent()) { for ( ; scope ; scope = scope->parent()) {
string path = name; unsigned hidx = 0;
string key = parse_first_name(path);
const NetScope*cur = scope; const NetScope*cur = scope;
while (path != "") { while (path.peek_name(hidx+1)) {
cur = cur->child(key); cur = cur->child(path.peek_name(hidx));
if (cur == 0) break; if (cur == 0)
key = parse_first_name(path); 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; return res;
} }
@ -215,16 +217,18 @@ void NetScope::run_defparams(Design*des)
cur = cur->sib_; cur = cur->sib_;
} }
map<string,NetExpr*>::const_iterator pp; map<hname_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) { for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
NetExpr*val = (*pp).second; NetExpr*val = (*pp).second;
string path = (*pp).first; hname_t path = (*pp).first;
string name = parse_last_name(path);
char*name = path.remove_tail_name();
NetScope*targ_scope = des->find_scope(this, path); NetScope*targ_scope = des->find_scope(this, path);
if (targ_scope == 0) { if (targ_scope == 0) {
cerr << val->get_line() << ": warning: scope of " << cerr << val->get_line() << ": warning: scope of " <<
path << "." << name << " not found." << endl; path << "." << name << " not found." << endl;
delete[]name;
continue; continue;
} }
@ -236,6 +240,8 @@ void NetScope::run_defparams(Design*des)
} else { } else {
delete val; 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 * It is the job of this function to properly implement Verilog scope
* rules as signals are concerned. * 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); assert(scope);
/* If the name has a path attached to it, parse it off and use char*key = path.remove_tail_name();
that to locate the desired starting scope. */ if (path.peek_name(0))
string path = name;
string key = parse_last_name(path);
if (path != "")
scope = find_scope(scope, path); 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) { while (scope) {
if (NetNet*net = scope->find_signal(key)) {
if (NetNet*net = scope->find_signal(key)) delete key;
return net; return net;
}
if (scope->type() == NetScope::MODULE) if (scope->type() == NetScope::MODULE)
break; break;
scope = scope->parent(); scope = scope->parent();
} }
delete key;
return 0; return 0;
} }
NetMemory* Design::find_memory(NetScope*scope, const string&name) NetMemory* Design::find_memory(NetScope*scope, hname_t path)
{ {
assert(scope); assert(scope);
/* If the name has a path attached to it, parse it off and use char*key = path.remove_tail_name();
that to locate the desired scope. */ if (path.peek_name(0))
string path = name;
string key = parse_last_name(path);
if (path != "")
scope = find_scope(scope, path); scope = find_scope(scope, path);
while (scope) { while (scope) {
if (NetMemory*mem = scope->find_memory(key)) {
if (NetMemory*mem = scope->find_memory(key)) delete key;
return mem; return mem;
}
scope = scope->parent(); scope = scope->parent();
} }
delete key;
return 0; return 0;
} }
void Design::find_symbol(NetScope*scope, const string&name,
NetNet*&sig, NetMemory*&mem)
{
sig = 0;
mem = 0;
NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
/* 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();
}
}
NetFuncDef* Design::find_function(NetScope*scope, const string&name)
{ {
assert(scope); assert(scope);
NetScope*func = find_scope(scope, name); NetScope*func = find_scope(scope, name);
@ -400,7 +371,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const string&name)
return 0; return 0;
} }
NetFuncDef* Design::find_function(const string&key) NetFuncDef* Design::find_function(const hname_t&key)
{ {
NetScope*func = find_scope(key); NetScope*func = find_scope(key);
if (func && (func->type() == NetScope::FUNC)) if (func && (func->type() == NetScope::FUNC))
@ -409,7 +380,7 @@ NetFuncDef* Design::find_function(const string&key)
return 0; 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); NetScope*task = find_scope(scope, name);
if (task && (task->type() == NetScope::TASK)) if (task && (task->type() == NetScope::TASK))
@ -418,7 +389,7 @@ NetScope* Design::find_task(NetScope*scope, const string&name)
return 0; return 0;
} }
NetScope* Design::find_task(const string&key) NetScope* Design::find_task(const hname_t&key)
{ {
NetScope*task = find_scope(key); NetScope*task = find_scope(key);
if (task && (task->type() == NetScope::TASK)) if (task && (task->type() == NetScope::TASK))
@ -489,6 +460,10 @@ void Design::delete_process(NetProcTop*top)
/* /*
* $Log: net_design.cc,v $ * $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 * Revision 1.22 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string. * Scope/module names are char* instead of string.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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_) for (NetEvent*cur = events_; cur ; cur = cur->snext_)
if (cur->name() == name) if (strcmp(cur->name(), name.peek_tail_name()) == 0)
return cur; return cur;
return 0; 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) NetNet* NetScope::find_signal(const string&key)
{ {
if (signals_ == 0) if (signals_ == 0)
@ -276,6 +281,27 @@ NetNet* NetScope::find_signal(const string&key)
return 0; 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) void NetScope::add_memory(NetMemory*mem)
{ {
if (memories_ == 0) { if (memories_ == 0) {
@ -376,6 +402,10 @@ string NetScope::local_hsymbol()
/* /*
* $Log: net_scope.cc,v $ * $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 * Revision 1.15 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration. * Remove string paths from PExpr elaboration.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # 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) : des_(d), scope_(s), name_(n)
{ {
} }
@ -2407,6 +2407,10 @@ const NetProc*NetTaskDef::proc() const
/* /*
* $Log: netlist.cc,v $ * $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 * Revision 1.177 2001/11/19 04:26:46 steve
* Unary reduction operators are all 1-bit results. * Unary reduction operators are all 1-bit results.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
/* /*
@ -32,6 +32,7 @@
# include <map> # include <map>
# include <list> # include <list>
# include "verinum.h" # include "verinum.h"
# include "HName.h"
# include "LineInfo.h" # include "LineInfo.h"
# include "svector.h" # include "svector.h"
# include "Attrib.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 * 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 * 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 * The NetEvWait class represents a thread wait for an event. When
* this statement is executed, it starts waiting on the * this statement is executed, it starts waiting on the
@ -2285,7 +2289,7 @@ class NetEConcat : public NetExpr {
class NetEParam : public NetExpr { class NetEParam : public NetExpr {
public: public:
NetEParam(); NetEParam();
NetEParam(class Design*des, NetScope*scope, const string&name); NetEParam(class Design*des, NetScope*scope, const hname_t&name);
~NetEParam(); ~NetEParam();
virtual bool set_width(unsigned w); virtual bool set_width(unsigned w);
@ -2299,7 +2303,7 @@ class NetEParam : public NetExpr {
private: private:
Design*des_; Design*des_;
NetScope*scope_; NetScope*scope_;
string name_; hname_t name_;
}; };
@ -2585,7 +2589,7 @@ class NetScope {
void add_event(NetEvent*); void add_event(NetEvent*);
void rem_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 /* These methods manage signals. The add_ and rem_signal
@ -2597,6 +2601,7 @@ class NetScope {
void rem_signal(NetNet*); void rem_signal(NetNet*);
NetNet* find_signal(const string&name); 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 /* ... 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 assignments from the scope pass to the parameter evaluation
step. After that, it is not used. */ step. After that, it is not used. */
map<string,NetExpr*>defparams; map<hname_t,NetExpr*>defparams;
private: private:
TYPE type_; TYPE type_;
@ -2740,18 +2745,18 @@ class Design {
unsigned long scale_to_precision(unsigned long, const NetScope*)const; unsigned long scale_to_precision(unsigned long, const NetScope*)const;
/* look up a scope. If no starting scope is passed, then the /* look up a scope. If no starting scope is passed, then the
path name string is taken as an absolute scope path is taken as an absolute scope name. Otherwise, the
name. Otherwise, the scope is located starting at the scope is located starting at the passed scope and working
passed scope and working up if needed. */ up if needed. */
NetScope* find_scope(const string&path) const; NetScope* find_scope(const hname_t&path) const;
NetScope* find_scope(NetScope*, const string&path) const; NetScope* find_scope(NetScope*, const hname_t&path) const;
// PARAMETERS // PARAMETERS
/* This method searches for a parameter, starting in the given /* This method searches for a parameter, starting in the given
scope. This method handles the upward searches that the scope. This method handles the upward searches that the
NetScope class itself does not support. */ 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 run_defparams();
void evaluate_parameters(); void evaluate_parameters();
@ -2761,10 +2766,10 @@ class Design {
this method, unlike the NetScope::find_signal method, this method, unlike the NetScope::find_signal method,
handles global name binding. */ handles global name binding. */
NetNet*find_signal(NetScope*scope, const string&name); NetNet*find_signal(NetScope*scope, hname_t path);
// Memories // 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 /* This is a more general lookup that finds the named signal
or memory, whichever is first in the search path. */ or memory, whichever is first in the search path. */
@ -2772,12 +2777,12 @@ class Design {
NetNet*&sig, NetMemory*&mem); NetNet*&sig, NetMemory*&mem);
// Functions // Functions
NetFuncDef* find_function(NetScope*scope, const string&key); NetFuncDef* find_function(NetScope*scope, const hname_t&key);
NetFuncDef* find_function(const string&path); NetFuncDef* find_function(const hname_t&path);
// Tasks // Tasks
NetScope* find_task(NetScope*scope, const string&name); NetScope* find_task(NetScope*scope, const hname_t&name);
NetScope* find_task(const string&key); NetScope* find_task(const hname_t&key);
// NODES // NODES
void add_node(NetNode*); void add_node(NetNode*);
@ -2862,6 +2867,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $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 * Revision 1.226 2001/11/29 01:58:18 steve
* Handle part selects in l-values of DFF devices. * Handle part selects in l-values of DFF devices.
* *

154
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -45,6 +45,8 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
char*text; char*text;
list<char*>*texts; list<char*>*texts;
hname_t*hier;
list<string>*strings; list<string>*strings;
struct str_pair_t drive; struct str_pair_t drive;
@ -86,7 +88,7 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
verireal* realtime; verireal* realtime;
}; };
%token <text> HIDENTIFIER IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING %token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING
%token <text> PATHPULSE_IDENTIFIER %token <text> PATHPULSE_IDENTIFIER
%token <number> NUMBER %token <number> NUMBER
%token <realtime> REALTIME %token <realtime> REALTIME
@ -123,8 +125,8 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
%type <wires> udp_port_decl udp_port_decls %type <wires> udp_port_decl udp_port_decls
%type <statement> udp_initial udp_init_opt %type <statement> udp_initial udp_init_opt
%type <text> identifier register_variable %type <hier> identifier
%type <text> spec_notifier spec_notifier_opt %type <text> register_variable
%type <texts> register_variable_list list_of_variables %type <texts> register_variable_list list_of_variables
%type <net_decl_assign> net_decl_assign net_decl_assigns %type <net_decl_assign> net_decl_assign net_decl_assigns
@ -330,7 +332,7 @@ defparam_assign
delete tmp; delete tmp;
tmp = 0; tmp = 0;
} }
pform_set_defparam($1, $3); pform_set_defparam(*$1, $3);
delete $1; delete $1;
} }
; ;
@ -423,7 +425,7 @@ delay_value_simple
} }
} }
| IDENTIFIER | IDENTIFIER
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(hname_t($1));
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
$$ = tmp; $$ = tmp;
@ -490,7 +492,7 @@ dr_strength1
event_control event_control
: '@' IDENTIFIER : '@' IDENTIFIER
{ PEIdent*tmpi = new PEIdent($2); { PEIdent*tmpi = new PEIdent(hname_t($2));
tmpi->set_file(@2.text); tmpi->set_file(@2.text);
tmpi->set_lineno(@2.first_line); tmpi->set_lineno(@2.first_line);
delete[]$2; delete[]$2;
@ -817,21 +819,21 @@ expr_primary
delete $1; delete $1;
} }
| identifier | identifier
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
$$ = tmp; $$ = tmp;
delete $1; delete $1;
} }
| SYSTEM_IDENTIFIER | SYSTEM_IDENTIFIER
{ PECallFunction*tmp = new PECallFunction($1); { PECallFunction*tmp = new PECallFunction(hname_t($1));
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
$$ = tmp; $$ = tmp;
delete $1 delete $1
} }
| identifier '[' expression ']' | identifier '[' expression ']'
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
tmp->msb_ = $3; tmp->msb_ = $3;
@ -839,7 +841,7 @@ expr_primary
$$ = tmp; $$ = tmp;
} }
| identifier '[' expression ':' expression ']' | identifier '[' expression ':' expression ']'
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
tmp->msb_ = $3; tmp->msb_ = $3;
@ -848,13 +850,14 @@ expr_primary
$$ = tmp; $$ = tmp;
} }
| identifier '(' expression_list ')' | identifier '(' expression_list ')'
{ PECallFunction*tmp = new PECallFunction($1, *$3); { PECallFunction*tmp = new PECallFunction(*$1, *$3);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp; $$ = tmp;
} }
| SYSTEM_IDENTIFIER '(' expression_list ')' | 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_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
$$ = tmp; $$ = tmp;
@ -1013,13 +1016,21 @@ gatetype
| K_rtranif1 { $$ = PGBuiltin::RTRANIF1; } | 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
: IDENTIFIER : IDENTIFIER
{ $$ = $1; } { $$ = new hname_t($1);
| HIDENTIFIER delete $1;
{ $$ = $1; }
| identifier '.' IDENTIFIER
{ hname_t * tmp = $1;
tmp->append($3);
delete $3;
$$ = tmp;
} }
;
list_of_ports list_of_ports
: port_opt : port_opt
@ -1059,14 +1070,14 @@ list_of_variables
expression meets the constraints of continuous assignments. */ expression meets the constraints of continuous assignments. */
lavalue lavalue
: identifier : identifier
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
$$ = tmp; $$ = tmp;
} }
| identifier '[' expression ']' | identifier '[' expression ']'
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
PExpr*sel = $3; PExpr*sel = $3;
if (! pform_expression_is_constant(sel)) { if (! pform_expression_is_constant(sel)) {
yyerror(@2, "error: Bit select in lvalue must " yyerror(@2, "error: Bit select in lvalue must "
@ -1081,7 +1092,7 @@ lavalue
$$ = tmp; $$ = tmp;
} }
| identifier range | identifier range
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
assert($2->count() == 2); assert($2->count() == 2);
tmp->msb_ = (*$2)[0]; tmp->msb_ = (*$2)[0];
tmp->lsb_ = (*$2)[1]; tmp->lsb_ = (*$2)[1];
@ -1104,14 +1115,14 @@ lavalue
procedural assignment. This rule handles only procedural assignments. */ procedural assignment. This rule handles only procedural assignments. */
lpvalue lpvalue
: identifier : identifier
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
$$ = tmp; $$ = tmp;
} }
| identifier '[' expression ']' | identifier '[' expression ']'
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $3; tmp->msb_ = $3;
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
@ -1120,7 +1131,7 @@ lpvalue
$$ = tmp; $$ = tmp;
} }
| identifier '[' expression ':' expression ']' | identifier '[' expression ':' expression ']'
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $3; tmp->msb_ = $3;
tmp->lsb_ = $5; tmp->lsb_ = $5;
tmp->set_file(@1.text); tmp->set_file(@1.text);
@ -1534,18 +1545,18 @@ parameter_value_opt
; ;
parameter_value_byname parameter_value_byname
: PORTNAME '(' expression ')' : '.' IDENTIFIER '(' expression ')'
{ portname_t*tmp = new portname_t; { portname_t*tmp = new portname_t;
tmp->name = $1; tmp->name = $2;
tmp->parm = $3; tmp->parm = $4;
free($1); free($2);
$$ = tmp; $$ = tmp;
} }
| PORTNAME '(' ')' | '.' IDENTIFIER '(' ')'
{ portname_t*tmp = new portname_t; { portname_t*tmp = new portname_t;
tmp->name = $1; tmp->name = $2;
tmp->parm = 0; tmp->parm = 0;
free($1); free($2);
$$ = tmp; $$ = tmp;
} }
; ;
@ -1584,12 +1595,12 @@ port
/* This syntax attaches an external name to the port reference so /* This syntax attaches an external name to the port reference so
that the caller can bind by name to non-trivial port that the caller can bind by name to non-trivial port
references. The port_t object gets its PWire from the 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 ')' | '.' IDENTIFIER '(' port_reference ')'
{ Module::port_t*tmp = $3; { Module::port_t*tmp = $4;
tmp->name = $1; tmp->name = $2;
delete $1; delete $2;
$$ = tmp; $$ = tmp;
} }
@ -1606,10 +1617,10 @@ port
/* This attaches a name to a port reference contatenation list so /* This attaches a name to a port reference contatenation list so
that parameter passing be name is possible. */ that parameter passing be name is possible. */
| PORTNAME '(' '{' port_reference_list '}' ')' | '.' IDENTIFIER '(' '{' port_reference_list '}' ')'
{ Module::port_t*tmp = $4; { Module::port_t*tmp = $5;
tmp->name = $1; tmp->name = $2;
delete $1; delete $2;
$$ = tmp; $$ = tmp;
} }
; ;
@ -1634,7 +1645,7 @@ port_reference
: IDENTIFIER : IDENTIFIER
{ Module::port_t*ptmp = new Module::port_t; { 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_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
ptmp->name = $1; ptmp->name = $1;
@ -1645,7 +1656,7 @@ port_reference
} }
| IDENTIFIER '[' expression ':' expression ']' | IDENTIFIER '[' expression ':' expression ']'
{ PEIdent*wtmp = new PEIdent($1); { PEIdent*wtmp = new PEIdent(hname_t($1));
wtmp->set_file(@1.text); wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line); wtmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) { if (!pform_expression_is_constant($3)) {
@ -1667,7 +1678,7 @@ port_reference
} }
| IDENTIFIER '[' expression ']' | IDENTIFIER '[' expression ']'
{ PEIdent*tmp = new PEIdent($1); { PEIdent*tmp = new PEIdent(hname_t($1));
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) { if (!pform_expression_is_constant($3)) {
@ -1686,7 +1697,7 @@ port_reference
| IDENTIFIER '[' error ']' | IDENTIFIER '[' error ']'
{ yyerror(@1, "error: invalid port bit select"); { yyerror(@1, "error: invalid port bit select");
Module::port_t*ptmp = new Module::port_t; 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_file(@1.text);
wtmp->set_lineno(@1.first_line); wtmp->set_lineno(@1.first_line);
ptmp->name = $1; ptmp->name = $1;
@ -1714,26 +1725,26 @@ port_reference_list
looking for the ports of a module declaration. */ looking for the ports of a module declaration. */
port_name port_name
: PORTNAME '(' expression ')' : '.' IDENTIFIER '(' expression ')'
{ portname_t*tmp = new portname_t; { portname_t*tmp = new portname_t;
tmp->name = $1; tmp->name = $2;
tmp->parm = $3; tmp->parm = $4;
delete $1; delete $2;
$$ = tmp; $$ = tmp;
} }
| PORTNAME '(' error ')' | '.' IDENTIFIER '(' error ')'
{ yyerror(@3, "error: invalid port connection expression."); { yyerror(@4, "error: invalid port connection expression.");
portname_t*tmp = new portname_t; portname_t*tmp = new portname_t;
tmp->name = $1; tmp->name = $2;
tmp->parm = 0; tmp->parm = 0;
delete $1; delete $2;
$$ = tmp; $$ = tmp;
} }
| PORTNAME '(' ')' | '.' IDENTIFIER '(' ')'
{ portname_t*tmp = new portname_t; { portname_t*tmp = new portname_t;
tmp->name = $1; tmp->name = $2;
tmp->parm = 0; tmp->parm = 0;
delete $1; delete $2;
$$ = tmp; $$ = tmp;
} }
; ;
@ -1849,34 +1860,28 @@ specify_item
| K_Shold '(' spec_reference_event ',' spec_reference_event | K_Shold '(' spec_reference_event ',' spec_reference_event
',' expression spec_notifier_opt ')' ';' ',' expression spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
if ($8) delete $8;
} }
| K_Speriod '(' spec_reference_event ',' expression | K_Speriod '(' spec_reference_event ',' expression
spec_notifier_opt ')' ';' spec_notifier_opt ')' ';'
{ delete $5; { delete $5;
if ($6) delete $6;
} }
| K_Srecovery '(' spec_reference_event ',' spec_reference_event | K_Srecovery '(' spec_reference_event ',' spec_reference_event
',' expression spec_notifier_opt ')' ';' ',' expression spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
if ($8) delete $8;
} }
| K_Ssetup '(' spec_reference_event ',' spec_reference_event | K_Ssetup '(' spec_reference_event ',' spec_reference_event
',' expression spec_notifier_opt ')' ';' ',' expression spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
if ($8) delete $8;
} }
| K_Ssetuphold '(' spec_reference_event ',' spec_reference_event | K_Ssetuphold '(' spec_reference_event ',' spec_reference_event
',' expression ',' expression spec_notifier_opt ')' ';' ',' expression ',' expression spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
delete $9; delete $9;
if ($10) delete $10;
} }
| K_Swidth '(' spec_reference_event ',' expression ',' expression | K_Swidth '(' spec_reference_event ',' expression ',' expression
spec_notifier_opt ')' ';' spec_notifier_opt ')' ';'
{ delete $5; { delete $5;
delete $7; delete $7;
if ($8) delete $8;
} }
| K_Swidth '(' spec_reference_event ',' expression ')' ';' | K_Swidth '(' spec_reference_event ',' expression ')' ';'
{ delete $5; { delete $5;
@ -1987,20 +1992,19 @@ spec_reference_event
spec_notifier_opt spec_notifier_opt
: /* empty */ : /* empty */
{ $$=0x0; } { }
| spec_notifier | spec_notifier
{ $$=$1; } { }
; ;
spec_notifier spec_notifier
: ',' : ','
{ $$ = 0x0; } { }
| ',' identifier | ',' identifier
{ $$ = $2; } { delete $2; }
| spec_notifier ',' | spec_notifier ','
{ $$ = $1; } { }
| spec_notifier ',' identifier | spec_notifier ',' identifier
{ $$ = $1; { delete $3;
delete $3;
} }
| IDENTIFIER | IDENTIFIER
{ delete $1; } { delete $1; }
@ -2117,14 +2121,14 @@ statement
} }
| K_disable identifier ';' | K_disable identifier ';'
{ PDisable*tmp = new PDisable($2); { PDisable*tmp = new PDisable(*$2);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $2; delete $2;
$$ = tmp; $$ = tmp;
} }
| K_TRIGGER IDENTIFIER ';' | K_TRIGGER IDENTIFIER ';'
{ PTrigger*tmp = new PTrigger($2); { PTrigger*tmp = new PTrigger(hname_t($2));
tmp->set_file(@2.text); tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line); tmp->set_lineno(@2.first_line);
delete $2; delete $2;
@ -2305,7 +2309,7 @@ statement
$$ = tmp; $$ = tmp;
} }
| SYSTEM_IDENTIFIER '(' expression_list ')' ';' | 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_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
@ -2314,14 +2318,14 @@ statement
} }
| SYSTEM_IDENTIFIER ';' | SYSTEM_IDENTIFIER ';'
{ svector<PExpr*>pt (0); { svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask($1, pt); PCallTask*tmp = new PCallTask(hname_t($1), pt);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
$$ = tmp; $$ = tmp;
} }
| identifier '(' expression_list ')' ';' | identifier '(' expression_list ')' ';'
{ PCallTask*tmp = new PCallTask($1, *$3); { PCallTask*tmp = new PCallTask(*$1, *$3);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
@ -2330,7 +2334,7 @@ statement
} }
| identifier ';' | identifier ';'
{ svector<PExpr*>pt (0); { svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask($1, pt); PCallTask*tmp = new PCallTask(*$1, pt);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
@ -2474,7 +2478,7 @@ udp_sequ_entry
udp_initial udp_initial
: K_initial IDENTIFIER '=' NUMBER ';' : K_initial IDENTIFIER '=' NUMBER ';'
{ PExpr*etmp = new PENumber($4); { PExpr*etmp = new PENumber($4);
PEIdent*itmp = new PEIdent($2); PEIdent*itmp = new PEIdent(hname_t($2));
PAssign*atmp = new PAssign(itmp, etmp); PAssign*atmp = new PAssign(itmp, etmp);
atmp->set_file(@2.text); atmp->set_file(@2.text);
atmp->set_lineno(@2.first_line); atmp->set_lineno(@2.first_line);
@ -2545,14 +2549,12 @@ udp_port_decl
{ PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT); { PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT);
svector<PWire*>*tmp = new svector<PWire*>(1); svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp; (*tmp)[0] = pp;
delete $2;
$$ = tmp; $$ = tmp;
} }
| K_reg IDENTIFIER ';' | K_reg IDENTIFIER ';'
{ PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT); { PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT);
svector<PWire*>*tmp = new svector<PWire*>(1); svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp; (*tmp)[0] = pp;
delete $2;
$$ = tmp; $$ = tmp;
} }
; ;

117
pform.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -51,15 +51,34 @@ static int pform_time_prec = 0;
/* /*
* The scope stack and the following functions handle the processing * 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 * 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; static hname_t scope_stack;
struct scope_name_t*next;
}; void pform_push_scope(char*name)
static scope_name_t*scope_stack = 0; {
scope_stack.append(name);
}
void pform_pop_scope()
{
char*tmp = scope_stack.remove_tail_name();
assert(tmp);
free(tmp);
}
static hname_t hier_name(const char*tail)
{
hname_t name = scope_stack;
name.append(tail);
return name;
}
void pform_set_timescale(int unit, int prec) void pform_set_timescale(int unit, int prec)
{ {
@ -68,31 +87,6 @@ void pform_set_timescale(int unit, int prec)
pform_time_prec = prec; pform_time_prec = prec;
} }
void pform_push_scope(const string&name)
{
scope_name_t*cur = new scope_name_t;
cur->name = name;
cur->next = scope_stack;
scope_stack = cur;
}
void pform_pop_scope()
{
assert(scope_stack);
scope_name_t*cur = scope_stack;
scope_stack = cur->next;
delete cur;
}
static string scoped_name(string name)
{
scope_name_t*cur = scope_stack;
while (cur) {
name = cur->name + "." + name;
cur = cur->next;
}
return name;
}
/* /*
* This function evaluates delay expressions. The result should be a * This function evaluates delay expressions. The result should be a
@ -206,9 +200,9 @@ void pform_make_udp(const char*name, list<string>*parms,
map<string,PWire*> defs; map<string,PWire*> defs;
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) { for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
string pname = (*decl)[idx]->name(); hname_t pname = (*decl)[idx]->path();
PWire*cur = defs[pname];
if (PWire*cur = defs[pname]) { if (PWire*cur = defs[pname.peek_name(0)]) {
bool rc = true; bool rc = true;
assert((*decl)[idx]); assert((*decl)[idx]);
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) { if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
@ -221,7 +215,7 @@ void pform_make_udp(const char*name, list<string>*parms,
} }
} else { } else {
defs[pname] = (*decl)[idx]; defs[pname.peek_name(0)] = (*decl)[idx];
} }
} }
@ -359,7 +353,7 @@ void pform_make_udp(const char*name, list<string>*parms,
assert(id); assert(id);
// XXXX // XXXX
assert(id->name() == pins[0]->name()); //assert(id->name() == pins[0]->name());
const PENumber*np = dynamic_cast<const PENumber*>(pa->rval()); const PENumber*np = dynamic_cast<const PENumber*>(pa->rval());
assert(np); assert(np);
@ -380,7 +374,7 @@ void pform_make_udp(const char*name, list<string>*parms,
// Make the port list for the UDP // Make the port list for the UDP
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1) 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->tinput = input;
udp->tcurrent = current; udp->tcurrent = current;
@ -410,7 +404,7 @@ static void pform_set_net_range(const char*name,
assert(range); assert(range);
assert(range->count() == 2); 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) { if (cur == 0) {
VLerror("error: name is not a valid net."); VLerror("error: name is not a valid net.");
return; return;
@ -677,9 +671,9 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
* BTF-B14. * BTF-B14.
*/ */
void pform_make_reginit(const struct vlltype&li, 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); PWire*cur = pform_cur_module->get_wire(sname);
if (cur == 0) { if (cur == 0) {
VLerror(li, "internal error: reginit to non-register?"); 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 * do check to see if the name has already been declared, as this
* function is called for every declaration. * 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) NetNet::Type type)
{ {
const string name = scoped_name(nm); hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name); PWire*cur = pform_cur_module->get_wire(name);
if (cur) { if (cur) {
if ((cur->get_wire_type() != NetNet::IMPLICIT) if ((cur->get_wire_type() != NetNet::IMPLICIT)
@ -792,10 +786,10 @@ void pform_makewire(const vlltype&li,
if (range) if (range)
pform_set_net_range(first->name, range, false); 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); PWire*cur = pform_cur_module->get_wire(name);
if (cur != 0) { 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); 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, void pform_set_port_type(const char*nm, NetNet::PortType pt,
const char*file, unsigned lineno) 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); PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) { if (cur == 0) {
cur = new PWire(name, NetNet::IMPLICIT, pt); cur = new PWire(name, NetNet::IMPLICIT, pt);
@ -872,7 +866,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
; cur != names->end() ; cur ++ ) { ; cur != names->end() ; cur ++ ) {
char*txt = *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 /* Look for a preexisting wire. If it exists, set the
port direction. If not, create it. */ 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 * with the trappings that are discovered after the basic function
* name is parsed. * name is parsed.
*/ */
void pform_set_function(const string&name, svector<PExpr*>*ra, PFunction *func) void pform_set_function(const char*name, svector<PExpr*>*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) { if (ra) {
assert(ra->count() == 2); assert(ra->count() == 2);
out->set_range((*ra)[0], (*ra)[1]); out->set_range((*ra)[0], (*ra)[1]);
@ -926,10 +922,11 @@ void pform_set_function(const string&name, svector<PExpr*>*ra, PFunction *func)
pform_cur_module->add_function(name, 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); hname_t path (name);
if (PWire*cur = pform_cur_module->get_wire(name)) {
if (PWire*cur = pform_cur_module->get_wire(path)) {
cur->attributes[key] = value; cur->attributes[key] = value;
} else if (PGate*cur = pform_cur_module->get_gate(name)) { } 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 * This function attaches a memory index range to an existing
* register. (The named wire must be a register. * 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) { if (cur == 0) {
VLerror("internal error: name is not a valid memory for index."); VLerror("internal error: name is not a valid memory for index.");
return; return;
@ -985,7 +982,7 @@ void pform_set_localparam(const string&name, PExpr*expr)
pform_cur_module->localparams[name] = 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); assert(expr);
pform_cur_module->defparms[name] = 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) 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); PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) { if (cur == 0) {
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT); cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT);
@ -1045,7 +1042,7 @@ void pform_set_reg_integer(list<char*>*names)
static void pform_set_reg_time(const char*nm) 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); PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) { if (cur == 0) {
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT); 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 $ * $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 * Revision 1.85 2001/11/29 17:37:51 steve
* Properly parse net_decl assignments with delays. * Properly parse net_decl assignments with delays.
* *

25
pform.h
View File

@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "netlist.h" # include "netlist.h"
# include "HName.h"
# include "named.h" # include "named.h"
# include "Module.h" # include "Module.h"
# include "Statement.h" # include "Statement.h"
@ -126,16 +127,18 @@ extern void pform_make_udp(const char*name, list<string>*parms,
const char*file, unsigned lineno); 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(); extern void pform_pop_scope();
/* /*
* The makewire functions announce to the pform code new wires. These * The makewire functions announce to the pform code new wires. These
* go into a module that is currently opened. * 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); NetNet::Type type = NetNet::IMPLICIT);
extern void pform_makewire(const struct vlltype&li, extern void pform_makewire(const struct vlltype&li,
svector<PExpr*>*range, svector<PExpr*>*range,
@ -147,23 +150,23 @@ extern void pform_makewire(const struct vlltype&li,
net_decl_assign_t*assign_list, net_decl_assign_t*assign_list,
NetNet::Type type); NetNet::Type type);
extern void pform_make_reginit(const struct vlltype&li, 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, extern void pform_set_port_type(const struct vlltype&li,
list<char*>*names, svector<PExpr*>*, list<char*>*names, svector<PExpr*>*,
NetNet::PortType); NetNet::PortType);
extern void pform_set_net_range(list<char*>*names, svector<PExpr*>*, bool); extern void pform_set_net_range(list<char*>*names, svector<PExpr*>*, 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<char*>*names); extern void pform_set_reg_integer(list<char*>*names);
extern void pform_set_reg_time(list<char*>*names); extern void pform_set_reg_time(list<char*>*names);
extern void pform_set_task(const string&, PTask*); extern void pform_set_task(const string&, PTask*);
extern void pform_set_function(const string&, svector<PExpr*>*, PFunction*); extern void pform_set_function(const char*, svector<PExpr*>*, PFunction*);
extern void pform_set_attrib(const string&name, const string&key, extern void pform_set_attrib(const char*name, const string&key,
const string&value); const string&value);
extern void pform_set_type_attrib(const string&name, const string&key, extern void pform_set_type_attrib(const string&name, const string&key,
const string&value); const string&value);
extern void pform_set_parameter(const string&name, PExpr*expr); extern void pform_set_parameter(const string&name, PExpr*expr);
extern void pform_set_localparam(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 PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern svector<PWire*>* pform_make_udp_input_ports(list<char*>*); extern svector<PWire*>* pform_make_udp_input_ports(list<char*>*);
@ -214,6 +217,10 @@ extern void pform_dump(ostream&out, Module*mod);
/* /*
* $Log: pform.h,v $ * $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 * Revision 1.52 2001/11/29 17:37:51 steve
* Properly parse net_decl assignments with delays. * Properly parse net_decl assignments with delays.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "config.h" # include "config.h"
@ -99,7 +99,7 @@ void PEConcat::dump(ostream&out) const
void PECallFunction::dump(ostream &out) const void PECallFunction::dump(ostream &out) const
{ {
out << name_ << "("; out << path_ << "(";
if (parms_.count() > 0) { if (parms_.count() > 0) {
if (parms_[0]) parms_[0]->dump(out); if (parms_[0]) parms_[0]->dump(out);
@ -142,7 +142,7 @@ void PENumber::dump(ostream&out) const
void PEIdent::dump(ostream&out) const void PEIdent::dump(ostream&out) const
{ {
out << text_; out << path_;
if (msb_) { if (msb_) {
out << "[" << *msb_; out << "[" << *msb_;
if (lsb_) { if (lsb_) {
@ -234,7 +234,7 @@ void PWire::dump(ostream&out) const
out << " [" << *msb_[idx] << "]"; out << " [" << *msb_[idx] << "]";
} }
out << " " << name_; out << " " << hname_;
// If the wire has indices, dump them. // If the wire has indices, dump them.
if (lidx_ || ridx_) { if (lidx_ || ridx_) {
@ -444,7 +444,7 @@ void PBlock::dump(ostream&out, unsigned ind) const
void PCallTask::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) { if (parms_.count() > 0) {
out << "("; out << "(";
@ -587,12 +587,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const
void PFunction::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_) if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) { for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
out << setw(ind) << ""; out << setw(ind) << "";
out << "input "; out << "input ";
out << (*ports_)[idx]->name() << ";" << endl; out << (*ports_)[idx]->path() << ";" << endl;
} }
if (statement_) if (statement_)
@ -629,7 +629,7 @@ void PTask::dump(ostream&out, unsigned ind) const
out << "inout "; out << "inout ";
break; break;
} }
out << (*ports_)[idx]->name() << ";" << endl; out << (*ports_)[idx]->path() << ";" << endl;
} }
if (statement_) if (statement_)
@ -686,6 +686,7 @@ void Module::dump(ostream&out) const
} }
typedef map<string,PExpr*>::const_iterator parm_iter_t; typedef map<string,PExpr*>::const_iterator parm_iter_t;
typedef map<hname_t,PExpr*>::const_iterator parm_hiter_t;
for (parm_iter_t cur = parameters.begin() for (parm_iter_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) { ; cur != parameters.end() ; cur ++) {
out << " parameter " << (*cur).first << " = "; out << " parameter " << (*cur).first << " = ";
@ -704,7 +705,7 @@ void Module::dump(ostream&out) const
out << "/* ERROR */;" << endl; out << "/* ERROR */;" << endl;
} }
for (parm_iter_t cur = defparms.begin() for (parm_hiter_t cur = defparms.begin()
; cur != defparms.end() ; cur ++) { ; cur != defparms.end() ; cur ++) {
out << " defparam " << (*cur).first << " = "; out << " defparam " << (*cur).first << " = ";
if ((*cur).second) if ((*cur).second)
@ -721,7 +722,7 @@ void Module::dump(ostream&out) const
} }
// Iterate through and display all the wires. // Iterate through and display all the wires.
for (map<string,PWire*>::const_iterator wire = wires_.begin() for (map<hname_t,PWire*>::const_iterator wire = wires_.begin()
; wire != wires_.end() ; wire != wires_.end()
; wire ++ ) { ; wire ++ ) {
@ -813,6 +814,10 @@ void PUdp::dump(ostream&out) const
/* /*
* $Log: pform_dump.cc,v $ * $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 * Revision 1.67 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config * Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher) * junk, and support gcc 3.0. (Stephan Boettcher)

74
util.cc
View File

@ -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.
*
*/

26
util.h
View File

@ -19,19 +19,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <string>
/*
* 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 * 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 $ * $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 * Revision 1.3 2001/10/20 23:02:40 steve
* Add automatic module libraries. * 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 #endif