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