Rework the heirarchical identifier parse syntax and pform
to handle more general combinations of heirarch and bit selects.
This commit is contained in:
parent
67b1eee7ce
commit
ddd36ecb6c
|
|
@ -16,7 +16,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.180 2007/02/06 05:07:31 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.181 2007/05/24 04:07:11 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
@ -108,7 +108,7 @@ load_module.o netlist.o netmisc.o net_assign.o \
|
||||||
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||||
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
||||||
parse.o parse_misc.o pform.o pform_dump.o \
|
parse.o parse_misc.o pform.o pform_dump.o pform_types.o \
|
||||||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||||
verinum.o verireal.o target.o targets.o \
|
verinum.o verireal.o target.o targets.o \
|
||||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||||
|
|
|
||||||
15
Module.cc
15
Module.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: Module.cc,v 1.26 2007/04/19 02:52:53 steve Exp $"
|
#ident "$Id: Module.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -111,9 +111,9 @@ unsigned Module::find_port(const char*name) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PWire* Module::get_wire(const hname_t&name) const
|
PWire* Module::get_wire(const pform_name_t&name) const
|
||||||
{
|
{
|
||||||
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
|
map<pform_name_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||||
if (obj == wires_.end())
|
if (obj == wires_.end())
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
|
@ -133,11 +133,6 @@ PGate* Module::get_gate(perm_string name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const map<hname_t,PWire*>& Module::get_wires() const
|
|
||||||
{
|
|
||||||
return wires_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const list<PGate*>& Module::get_gates() const
|
const list<PGate*>& Module::get_gates() const
|
||||||
{
|
{
|
||||||
return gates_;
|
return gates_;
|
||||||
|
|
@ -151,6 +146,10 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: Module.cc,v $
|
* $Log: Module.cc,v $
|
||||||
|
* Revision 1.27 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.26 2007/04/19 02:52:53 steve
|
* Revision 1.26 2007/04/19 02:52:53 steve
|
||||||
* Add support for -v flag in command file.
|
* Add support for -v flag in command file.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
14
Module.h
14
Module.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: Module.h,v 1.42 2007/04/19 02:52:53 steve Exp $"
|
#ident "$Id: Module.h,v 1.43 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <list>
|
# include <list>
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
# include "named.h"
|
# include "named.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include "pform_types.h"
|
||||||
class PEvent;
|
class PEvent;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
class PEIdent;
|
class PEIdent;
|
||||||
|
|
@ -98,7 +99,7 @@ class Module : public LineInfo {
|
||||||
new parameters within the module, but may be used to set
|
new parameters within the module, but may be used to set
|
||||||
values within this module (when instantiated) or in other
|
values within this module (when instantiated) or in other
|
||||||
instantiated modules. */
|
instantiated modules. */
|
||||||
map<hname_t,PExpr*>defparms;
|
map<pform_name_t,PExpr*>defparms;
|
||||||
|
|
||||||
/* Parameters may be overridden at instantiation time;
|
/* Parameters may be overridden at instantiation time;
|
||||||
the overrides do not contain explicit parameter names,
|
the overrides do not contain explicit parameter names,
|
||||||
|
|
@ -150,10 +151,9 @@ class Module : public LineInfo {
|
||||||
|
|
||||||
// Find a wire by name. This is used for connecting gates to
|
// Find a wire by name. This is used for connecting gates to
|
||||||
// existing wires, etc.
|
// existing wires, etc.
|
||||||
PWire* get_wire(const hname_t&name) const;
|
PWire* get_wire(const pform_name_t&name) const;
|
||||||
PGate* get_gate(perm_string name);
|
PGate* get_gate(perm_string name);
|
||||||
|
|
||||||
const map<hname_t,PWire*>& get_wires() const;
|
|
||||||
const list<PGate*>& get_gates() const;
|
const list<PGate*>& get_gates() const;
|
||||||
const list<PProcess*>& get_behaviors() const;
|
const list<PProcess*>& get_behaviors() const;
|
||||||
|
|
||||||
|
|
@ -168,7 +168,7 @@ class Module : public LineInfo {
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
|
|
||||||
map<hname_t,PWire*> wires_;
|
map<pform_name_t,PWire*> wires_;
|
||||||
list<PGate*> gates_;
|
list<PGate*> gates_;
|
||||||
list<PProcess*> behaviors_;
|
list<PProcess*> behaviors_;
|
||||||
map<perm_string,PTask*> tasks_;
|
map<perm_string,PTask*> tasks_;
|
||||||
|
|
@ -182,6 +182,10 @@ class Module : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: Module.h,v $
|
* $Log: Module.h,v $
|
||||||
|
* Revision 1.43 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.42 2007/04/19 02:52:53 steve
|
* Revision 1.42 2007/04/19 02:52:53 steve
|
||||||
* Add support for -v flag in command file.
|
* Add support for -v flag in command file.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
48
PExpr.cc
48
PExpr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PExpr.cc,v 1.38 2006/10/30 05:44:49 steve Exp $"
|
#ident "$Id: PExpr.cc,v 1.39 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -93,13 +93,26 @@ PEBShift::~PEBShift()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
|
||||||
: path_(n), parms_(parms)
|
: path_(n), parms_(parms)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PECallFunction::PECallFunction(const hname_t&n)
|
static pform_name_t pn_from_ps(perm_string n)
|
||||||
: path_(n)
|
{
|
||||||
|
name_component_t tmp_name (n);
|
||||||
|
pform_name_t tmp;
|
||||||
|
tmp.push_back(tmp_name);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
|
||||||
|
: path_(pn_from_ps(n)), parms_(parms)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PECallFunction::PECallFunction(perm_string n)
|
||||||
|
: path_(pn_from_ps(n))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,33 +178,32 @@ bool PEFNumber::is_constant(Module*) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PEIdent::PEIdent(const hname_t&s)
|
PEIdent::PEIdent(const pform_name_t&that)
|
||||||
: path_(s), msb_(0), lsb_(0), sel_(SEL_NONE), idx_(0)
|
: path_(that)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEIdent::PEIdent(perm_string s)
|
||||||
|
{
|
||||||
|
path_.push_back(name_component_t(s));
|
||||||
|
}
|
||||||
|
|
||||||
PEIdent::~PEIdent()
|
PEIdent::~PEIdent()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const hname_t& PEIdent::path() const
|
|
||||||
{
|
|
||||||
return path_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An identifier can be in a constant expression if (and only if) it is
|
* An identifier can be in a constant expression if (and only if) it is
|
||||||
* a parameter.
|
* a parameter.
|
||||||
|
*
|
||||||
|
* NOTE: This test does not work if the name is hierarchical!
|
||||||
*/
|
*/
|
||||||
bool PEIdent::is_constant(Module*mod) const
|
bool PEIdent::is_constant(Module*mod) const
|
||||||
{
|
{
|
||||||
if (mod == 0) return false;
|
if (mod == 0) return false;
|
||||||
|
|
||||||
/* This is a work-around for map not matching < even when
|
/* */
|
||||||
there is a perm_string operator that can do the comprare.
|
perm_string tmp = path_.back().name;
|
||||||
|
|
||||||
The real fix is to make the path_ carry perm_strings. */
|
|
||||||
perm_string tmp = perm_string::literal(path_.peek_name(0));
|
|
||||||
|
|
||||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||||
cur = mod->parameters.find(tmp);
|
cur = mod->parameters.find(tmp);
|
||||||
|
|
@ -288,6 +300,10 @@ bool PEUnary::is_constant(Module*m) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.cc,v $
|
* $Log: PExpr.cc,v $
|
||||||
|
* Revision 1.39 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.38 2006/10/30 05:44:49 steve
|
* Revision 1.38 2006/10/30 05:44:49 steve
|
||||||
* Expression widths with unsized literals are pseudo-infinite width.
|
* Expression widths with unsized literals are pseudo-infinite width.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
31
PExpr.h
31
PExpr.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PExpr.h,v 1.87 2007/01/16 05:44:14 steve Exp $"
|
#ident "$Id: PExpr.h,v 1.88 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
# include "pform_types.h"
|
||||||
|
|
||||||
class Design;
|
class Design;
|
||||||
class Module;
|
class Module;
|
||||||
|
|
@ -247,9 +248,14 @@ class PEFNumber : public PExpr {
|
||||||
class PEIdent : public PExpr {
|
class PEIdent : public PExpr {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PEIdent(const hname_t&s);
|
explicit PEIdent(perm_string);
|
||||||
|
explicit PEIdent(const pform_name_t&);
|
||||||
~PEIdent();
|
~PEIdent();
|
||||||
|
|
||||||
|
// Add another name to the string of heirarchy that is the
|
||||||
|
// current identifier.
|
||||||
|
void append_name(perm_string);
|
||||||
|
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
unsigned min, unsigned lval,
|
unsigned min, unsigned lval,
|
||||||
|
|
@ -286,7 +292,10 @@ class PEIdent : public PExpr {
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
verinum* eval_const(const Design*des, NetScope*sc) const;
|
verinum* eval_const(const Design*des, NetScope*sc) const;
|
||||||
|
|
||||||
const hname_t& path() const;
|
const pform_name_t& path() const { return path_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
pform_name_t path_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Common functions to calculate parts of part/bit selects.
|
// Common functions to calculate parts of part/bit selects.
|
||||||
|
|
@ -332,9 +341,9 @@ class PEIdent : public PExpr {
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
NetESignal*net,
|
NetESignal*net,
|
||||||
NetScope*found) const;
|
NetScope*found) const;
|
||||||
hname_t path_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if 0
|
||||||
// Use these to support part-select operators.
|
// Use these to support part-select operators.
|
||||||
PExpr*msb_;
|
PExpr*msb_;
|
||||||
PExpr*lsb_;
|
PExpr*lsb_;
|
||||||
|
|
@ -345,6 +354,8 @@ class PEIdent : public PExpr {
|
||||||
// expression. If this is a reference to a vector, this is a
|
// expression. If this is a reference to a vector, this is a
|
||||||
// bit select.
|
// bit select.
|
||||||
std::vector<PExpr*> idx_;
|
std::vector<PExpr*> idx_;
|
||||||
|
#endif
|
||||||
|
|
||||||
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
|
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
|
||||||
NetNet*sig, unsigned lwidth,
|
NetNet*sig, unsigned lwidth,
|
||||||
const NetExpr* rise,
|
const NetExpr* rise,
|
||||||
|
|
@ -621,8 +632,10 @@ class PETernary : public PExpr {
|
||||||
*/
|
*/
|
||||||
class PECallFunction : public PExpr {
|
class PECallFunction : public PExpr {
|
||||||
public:
|
public:
|
||||||
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
|
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
|
||||||
explicit PECallFunction(const hname_t&n);
|
// Call of system function (name is not heirarchical)
|
||||||
|
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
|
||||||
|
explicit PECallFunction(perm_string n);
|
||||||
~PECallFunction();
|
~PECallFunction();
|
||||||
|
|
||||||
virtual void dump(ostream &) const;
|
virtual void dump(ostream &) const;
|
||||||
|
|
@ -638,7 +651,7 @@ class PECallFunction : public PExpr {
|
||||||
int expr_wid, bool sys_task_arg) const;
|
int expr_wid, bool sys_task_arg) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hname_t path_;
|
pform_name_t path_;
|
||||||
svector<PExpr *> parms_;
|
svector<PExpr *> parms_;
|
||||||
|
|
||||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||||
|
|
@ -655,6 +668,10 @@ class PECallFunction : public PExpr {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.h,v $
|
* $Log: PExpr.h,v $
|
||||||
|
* Revision 1.88 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.87 2007/01/16 05:44:14 steve
|
* Revision 1.87 2007/01/16 05:44:14 steve
|
||||||
* Major rework of array handling. Memories are replaced with the
|
* Major rework of array handling. Memories are replaced with the
|
||||||
* more general concept of arrays. The NetMemory and NetEMemory
|
* more general concept of arrays. The NetMemory and NetEMemory
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PGenerate.cc,v 1.2 2007/03/05 05:59:10 steve Exp $"
|
#ident "$Id: PGenerate.cc,v 1.3 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "PGenerate.h"
|
# include "PGenerate.h"
|
||||||
|
|
@ -42,9 +42,9 @@ PWire* PGenerate::add_wire(PWire*wire)
|
||||||
return wire;
|
return wire;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWire* PGenerate::get_wire(const hname_t&name) const
|
PWire* PGenerate::get_wire(const pform_name_t&name) const
|
||||||
{
|
{
|
||||||
map<hname_t,PWire*>::const_iterator obj = wires.find(name);
|
map<pform_name_t,PWire*>::const_iterator obj = wires.find(name);
|
||||||
if (obj == wires.end())
|
if (obj == wires.end())
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PGenerate.h,v 1.2 2007/03/05 05:59:10 steve Exp $"
|
#ident "$Id: PGenerate.h,v 1.3 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
# include "HName.h"
|
# include "HName.h"
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
|
# include "pform_types.h"
|
||||||
|
|
||||||
class Design;
|
class Design;
|
||||||
class NetScope;
|
class NetScope;
|
||||||
|
|
@ -59,9 +60,9 @@ class PGenerate : public LineInfo {
|
||||||
PExpr*loop_test;
|
PExpr*loop_test;
|
||||||
PExpr*loop_step;
|
PExpr*loop_step;
|
||||||
|
|
||||||
map<hname_t,PWire*>wires;
|
map<pform_name_t,PWire*>wires;
|
||||||
PWire* add_wire(PWire*);
|
PWire* add_wire(PWire*);
|
||||||
PWire* get_wire(const hname_t&name) const;
|
PWire* get_wire(const pform_name_t&name) const;
|
||||||
|
|
||||||
list<PGate*> gates;
|
list<PGate*> gates;
|
||||||
void add_gate(PGate*);
|
void add_gate(PGate*);
|
||||||
|
|
|
||||||
27
PWire.cc
27
PWire.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -17,29 +17,14 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PWire.cc,v 1.13 2007/04/26 03:06:21 steve Exp $"
|
#ident "$Id: PWire.cc,v 1.14 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include "PWire.h"
|
# include "PWire.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
PWire::PWire(const hname_t&n,
|
PWire::PWire(const pform_name_t&n,
|
||||||
NetNet::Type t,
|
|
||||||
NetNet::PortType pt,
|
|
||||||
ivl_variable_type_t dt)
|
|
||||||
: hname_(n), type_(t), port_type_(pt), data_type_(dt),
|
|
||||||
signed_(false), isint_(false),
|
|
||||||
lidx_(0), ridx_(0)
|
|
||||||
{
|
|
||||||
if (t == NetNet::INTEGER) {
|
|
||||||
type_ = NetNet::REG;
|
|
||||||
signed_ = true;
|
|
||||||
isint_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PWire::PWire(perm_string n,
|
|
||||||
NetNet::Type t,
|
NetNet::Type t,
|
||||||
NetNet::PortType pt,
|
NetNet::PortType pt,
|
||||||
ivl_variable_type_t dt)
|
ivl_variable_type_t dt)
|
||||||
|
|
@ -59,7 +44,7 @@ NetNet::Type PWire::get_wire_type() const
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hname_t& PWire::path() const
|
const pform_name_t& PWire::path() const
|
||||||
{
|
{
|
||||||
return hname_;
|
return hname_;
|
||||||
}
|
}
|
||||||
|
|
@ -160,6 +145,10 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PWire.cc,v $
|
* $Log: PWire.cc,v $
|
||||||
|
* Revision 1.14 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.13 2007/04/26 03:06:21 steve
|
* Revision 1.13 2007/04/26 03:06:21 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
25
PWire.h
25
PWire.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PWire.h,v 1.20 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -43,24 +43,21 @@ class Design;
|
||||||
* identifies a port by keeping it in its port list.
|
* identifies a port by keeping it in its port list.
|
||||||
*
|
*
|
||||||
* The hname parameter to the constructor is a hierarchical name. It
|
* The hname parameter to the constructor is a hierarchical name. It
|
||||||
* is an array of strings starting with the root, running towards
|
* is the name of the wire within a module, so does not include the
|
||||||
* the base name, and terminated by a null pointer. The environment
|
* current scope or any instances. Modules contain all the wires, so
|
||||||
* allocates the memory for me.
|
* from that perspective, sub-scopes within the module are a part of
|
||||||
|
* the wire name.
|
||||||
*/
|
*/
|
||||||
class PWire : public LineInfo {
|
class PWire : public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PWire(const hname_t&hname,
|
PWire(const pform_name_t&hname,
|
||||||
NetNet::Type t,
|
|
||||||
NetNet::PortType pt,
|
|
||||||
ivl_variable_type_t dt);
|
|
||||||
PWire(perm_string name,
|
|
||||||
NetNet::Type t,
|
NetNet::Type t,
|
||||||
NetNet::PortType pt,
|
NetNet::PortType pt,
|
||||||
ivl_variable_type_t dt);
|
ivl_variable_type_t dt);
|
||||||
|
|
||||||
// Return a hierarchical name.
|
// Return a hierarchical name.
|
||||||
const hname_t&path() const;
|
const pform_name_t&path() const;
|
||||||
|
|
||||||
NetNet::Type get_wire_type() const;
|
NetNet::Type get_wire_type() const;
|
||||||
bool set_wire_type(NetNet::Type);
|
bool set_wire_type(NetNet::Type);
|
||||||
|
|
@ -84,10 +81,10 @@ class PWire : public LineInfo {
|
||||||
// Write myself to the specified stream.
|
// Write myself to the specified stream.
|
||||||
void dump(ostream&out, unsigned ind=4) const;
|
void dump(ostream&out, unsigned ind=4) const;
|
||||||
|
|
||||||
void elaborate_sig(Design*, NetScope*scope) const;
|
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hname_t hname_;
|
pform_name_t hname_;
|
||||||
NetNet::Type type_;
|
NetNet::Type type_;
|
||||||
NetNet::PortType port_type_;
|
NetNet::PortType port_type_;
|
||||||
ivl_variable_type_t data_type_;
|
ivl_variable_type_t data_type_;
|
||||||
|
|
@ -111,6 +108,10 @@ class PWire : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PWire.h,v $
|
* $Log: PWire.h,v $
|
||||||
|
* Revision 1.21 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.20 2007/04/26 03:06:22 steve
|
* Revision 1.20 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
20
Statement.cc
20
Statement.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: Statement.cc,v 1.29 2004/02/18 17:11:54 steve Exp $"
|
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -107,16 +107,22 @@ PBlock::~PBlock()
|
||||||
delete list_[idx];
|
delete list_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
|
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
|
||||||
: path_(n), parms_(p)
|
: path_(n), parms_(p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
|
||||||
|
: parms_(p)
|
||||||
|
{
|
||||||
|
path_.push_back(name_component_t(n));
|
||||||
|
}
|
||||||
|
|
||||||
PCallTask::~PCallTask()
|
PCallTask::~PCallTask()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const hname_t& PCallTask::path() const
|
const pform_name_t& PCallTask::path() const
|
||||||
{
|
{
|
||||||
return path_;
|
return path_;
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +184,7 @@ PDelayStatement::~PDelayStatement()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PDisable::PDisable(const hname_t&sc)
|
PDisable::PDisable(const pform_name_t&sc)
|
||||||
: scope_(sc)
|
: scope_(sc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -273,7 +279,7 @@ PRepeat::~PRepeat()
|
||||||
delete statement_;
|
delete statement_;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTrigger::PTrigger(const hname_t&e)
|
PTrigger::PTrigger(const pform_name_t&e)
|
||||||
: event_(e)
|
: event_(e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -295,6 +301,10 @@ PWhile::~PWhile()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: Statement.cc,v $
|
* $Log: Statement.cc,v $
|
||||||
|
* Revision 1.30 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.29 2004/02/18 17:11:54 steve
|
* Revision 1.29 2004/02/18 17:11:54 steve
|
||||||
* Use perm_strings for named langiage items.
|
* Use perm_strings for named langiage items.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
21
Statement.h
21
Statement.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: Statement.h,v 1.43 2007/03/05 05:59:10 steve Exp $"
|
#ident "$Id: Statement.h,v 1.44 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -173,10 +173,11 @@ class PBlock : public Statement {
|
||||||
class PCallTask : public Statement {
|
class PCallTask : public Statement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
|
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
|
||||||
|
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
|
||||||
~PCallTask();
|
~PCallTask();
|
||||||
|
|
||||||
const hname_t& path() const;
|
const pform_name_t& path() const;
|
||||||
|
|
||||||
unsigned nparms() const { return parms_.count(); }
|
unsigned nparms() const { return parms_.count(); }
|
||||||
|
|
||||||
|
|
@ -197,7 +198,7 @@ class PCallTask : public Statement {
|
||||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
hname_t path_;
|
pform_name_t path_;
|
||||||
svector<PExpr*> parms_;
|
svector<PExpr*> parms_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -296,14 +297,14 @@ class PDelayStatement : public Statement {
|
||||||
class PDisable : public Statement {
|
class PDisable : public Statement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PDisable(const hname_t&sc);
|
explicit PDisable(const pform_name_t&sc);
|
||||||
~PDisable();
|
~PDisable();
|
||||||
|
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hname_t scope_;
|
pform_name_t scope_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -433,14 +434,14 @@ class PRelease : public Statement {
|
||||||
class PTrigger : public Statement {
|
class PTrigger : public Statement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PTrigger(const hname_t&ev);
|
explicit PTrigger(const pform_name_t&ev);
|
||||||
~PTrigger();
|
~PTrigger();
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hname_t event_;
|
pform_name_t event_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PWhile : public Statement {
|
class PWhile : public Statement {
|
||||||
|
|
@ -460,6 +461,10 @@ class PWhile : public Statement {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: Statement.h,v $
|
* $Log: Statement.h,v $
|
||||||
|
* Revision 1.44 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.43 2007/03/05 05:59:10 steve
|
* Revision 1.43 2007/03/05 05:59:10 steve
|
||||||
* Handle processes within generate loops.
|
* Handle processes within generate loops.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: design_dump.cc,v 1.174 2007/03/02 06:13:22 steve Exp $"
|
#ident "$Id: design_dump.cc,v 1.175 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -871,7 +871,7 @@ void NetScope::dump(ostream&o) const
|
||||||
|
|
||||||
/* Dump the saved defparam assignments here. */
|
/* Dump the saved defparam assignments here. */
|
||||||
{
|
{
|
||||||
map<hname_t,NetExpr*>::const_iterator pp;
|
map<pform_name_t,NetExpr*>::const_iterator pp;
|
||||||
for (pp = defparams.begin()
|
for (pp = defparams.begin()
|
||||||
; pp != defparams.end() ; pp ++ ) {
|
; pp != defparams.end() ; pp ++ ) {
|
||||||
o << " defparam " << (*pp).first << " = " <<
|
o << " defparam " << (*pp).first << " = " <<
|
||||||
|
|
@ -1205,6 +1205,10 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $Log: design_dump.cc,v $
|
||||||
|
* Revision 1.175 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.174 2007/03/02 06:13:22 steve
|
* Revision 1.174 2007/03/02 06:13:22 steve
|
||||||
* Add support for edge sensitive spec paths.
|
* Add support for edge sensitive spec paths.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
233
elab_expr.cc
233
elab_expr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_expr.cc,v 1.124 2007/04/01 05:28:26 steve Exp $"
|
#ident "$Id: elab_expr.cc,v 1.125 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -322,7 +322,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
not lead to executable code but takes the single parameter
|
not lead to executable code but takes the single parameter
|
||||||
and makes it into a signed expression. No bits are changed,
|
and makes it into a signed expression. No bits are changed,
|
||||||
it just changes the interpretation. */
|
it just changes the interpretation. */
|
||||||
if (strcmp(path_.peek_name(0), "$signed") == 0) {
|
if (strcmp(peek_tail_name(path_), "$signed") == 0) {
|
||||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||||
cerr << get_line() << ": error: The $signed() function "
|
cerr << get_line() << ": error: The $signed() function "
|
||||||
<< "takes exactly one(1) argument." << endl;
|
<< "takes exactly one(1) argument." << endl;
|
||||||
|
|
@ -336,7 +336,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
/* add $unsigned to match $signed */
|
/* add $unsigned to match $signed */
|
||||||
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
|
if (strcmp(peek_tail_name(path_), "$unsigned") == 0) {
|
||||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||||
cerr << get_line() << ": error: The $unsigned() function "
|
cerr << get_line() << ": error: The $unsigned() function "
|
||||||
<< "takes exactly one(1) argument." << endl;
|
<< "takes exactly one(1) argument." << endl;
|
||||||
|
|
@ -354,8 +354,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
the bit width of the sub-expression. The value of the
|
the bit width of the sub-expression. The value of the
|
||||||
sub-expression is not used, so the expression itself can be
|
sub-expression is not used, so the expression itself can be
|
||||||
deleted. */
|
deleted. */
|
||||||
if ((strcmp(path_.peek_name(0), "$sizeof") == 0)
|
if ((strcmp(peek_tail_name(path_), "$sizeof") == 0)
|
||||||
|| (strcmp(path_.peek_name(0), "$bits") == 0)) {
|
|| (strcmp(peek_tail_name(path_), "$bits") == 0)) {
|
||||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||||
cerr << get_line() << ": error: The $bits() function "
|
cerr << get_line() << ": error: The $bits() function "
|
||||||
<< "takes exactly one(1) argument." << endl;
|
<< "takes exactly one(1) argument." << endl;
|
||||||
|
|
@ -363,7 +363,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(path_.peek_name(0), "$sizeof") == 0)
|
if (strcmp(peek_tail_name(path_), "$sizeof") == 0)
|
||||||
cerr << get_line() << ": warning: $sizeof is deprecated."
|
cerr << get_line() << ": warning: $sizeof is deprecated."
|
||||||
<< " Use $bits() instead." << endl;
|
<< " Use $bits() instead." << endl;
|
||||||
|
|
||||||
|
|
@ -382,7 +382,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
a single bit flag -- 1 if the expression is signed, 0
|
a single bit flag -- 1 if the expression is signed, 0
|
||||||
otherwise. The subexpression is elaborated but not
|
otherwise. The subexpression is elaborated but not
|
||||||
evaluated. */
|
evaluated. */
|
||||||
if (strcmp(path_.peek_name(0), "$is_signed") == 0) {
|
if (strcmp(peek_tail_name(path_), "$is_signed") == 0) {
|
||||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||||
cerr << get_line() << ": error: The $is_signed() function "
|
cerr << get_line() << ": error: The $is_signed() function "
|
||||||
<< "takes exactly one(1) argument." << endl;
|
<< "takes exactly one(1) argument." << endl;
|
||||||
|
|
@ -405,7 +405,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
/* Get the return type of the system function by looking it up
|
/* Get the return type of the system function by looking it up
|
||||||
in the sfunc_table. */
|
in the sfunc_table. */
|
||||||
const struct sfunc_return_type*sfunc_info
|
const struct sfunc_return_type*sfunc_info
|
||||||
= lookup_sys_func(path_.peek_name(0));
|
= lookup_sys_func(peek_tail_name(path_));
|
||||||
|
|
||||||
ivl_variable_type_t sfunc_type = sfunc_info->type;
|
ivl_variable_type_t sfunc_type = sfunc_info->type;
|
||||||
unsigned wid = sfunc_info->wid;
|
unsigned wid = sfunc_info->wid;
|
||||||
|
|
@ -423,7 +423,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
if ((nparms == 1) && (parms_[0] == 0))
|
if ((nparms == 1) && (parms_[0] == 0))
|
||||||
nparms = 0;
|
nparms = 0;
|
||||||
|
|
||||||
NetESFunc*fun = new NetESFunc(path_.peek_name(0), sfunc_type,
|
NetESFunc*fun = new NetESFunc(peek_tail_name(path_), sfunc_type,
|
||||||
wid, nparms);
|
wid, nparms);
|
||||||
if (sfunc_info->signed_flag)
|
if (sfunc_info->signed_flag)
|
||||||
fun->cast_signed(true);
|
fun->cast_signed(true);
|
||||||
|
|
@ -455,7 +455,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (missing_parms > 0) {
|
if (missing_parms > 0) {
|
||||||
cerr << get_line() << ": error: The function "
|
cerr << get_line() << ": error: The function "
|
||||||
<< path_.peek_name(0)
|
<< peek_tail_name(path_)
|
||||||
<< " has been called with empty parameters." << endl;
|
<< " has been called with empty parameters." << endl;
|
||||||
cerr << get_line() << ": : Verilog doesn't allow "
|
cerr << get_line() << ": : Verilog doesn't allow "
|
||||||
<< "passing empty parameters to functions." << endl;
|
<< "passing empty parameters to functions." << endl;
|
||||||
|
|
@ -468,7 +468,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
||||||
int expr_wid, bool) const
|
int expr_wid, bool) const
|
||||||
{
|
{
|
||||||
if (path_.peek_name(0)[0] == '$')
|
if (peek_tail_name(path_)[0] == '$')
|
||||||
return elaborate_sfunc_(des, scope);
|
return elaborate_sfunc_(des, scope);
|
||||||
|
|
||||||
NetFuncDef*def = des->find_function(scope, path_);
|
NetFuncDef*def = des->find_function(scope, path_);
|
||||||
|
|
@ -620,33 +620,38 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, int, bool) const
|
||||||
bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
||||||
long&msb, long&lsb) const
|
long&msb, long&lsb) const
|
||||||
{
|
{
|
||||||
assert(lsb_ != 0);
|
const name_component_t&name_tail = path_.back();
|
||||||
assert(msb_ != 0);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.sel == index_component_t::SEL_PART);
|
||||||
|
ivl_assert(*this, index_tail.msb && index_tail.lsb);
|
||||||
|
|
||||||
/* This handles part selects. In this case, there are
|
/* This handles part selects. In this case, there are
|
||||||
two bit select expressions, and both must be
|
two bit select expressions, and both must be
|
||||||
constant. Evaluate them and pass the results back to
|
constant. Evaluate them and pass the results back to
|
||||||
the caller. */
|
the caller. */
|
||||||
NetExpr*lsb_ex = elab_and_eval(des, scope, lsb_, -1);
|
NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||||
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
|
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
|
||||||
if (lsb_c == 0) {
|
if (lsb_c == 0) {
|
||||||
cerr << lsb_->get_line() << ": error: "
|
cerr << index_tail.lsb->get_line() << ": error: "
|
||||||
"Part select expressions must be constant."
|
"Part select expressions must be constant."
|
||||||
<< endl;
|
<< endl;
|
||||||
cerr << lsb_->get_line() << ": : This lsb expression "
|
cerr << index_tail.lsb->get_line() << ": : "
|
||||||
"violates the rule: " << *lsb_ << endl;
|
"This lsb expression violates the rule: "
|
||||||
|
<< *index_tail.lsb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr*msb_ex = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
|
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
|
||||||
if (msb_c == 0) {
|
if (msb_c == 0) {
|
||||||
cerr << msb_->get_line() << ": error: "
|
cerr << index_tail.msb->get_line() << ": error: "
|
||||||
"Part select expressions must be constant."
|
"Part select expressions must be constant."
|
||||||
<< endl;
|
<< endl;
|
||||||
cerr << msb_->get_line() << ": : This msb expression "
|
cerr << index_tail.msb->get_line() << ": : This msb expression "
|
||||||
"violates the rule: " << *msb_ << endl;
|
"violates the rule: " << *index_tail.msb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -662,13 +667,18 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
||||||
bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
|
bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
|
||||||
unsigned long&wid) const
|
unsigned long&wid) const
|
||||||
{
|
{
|
||||||
assert(lsb_);
|
const name_component_t&name_tail = path_.back();
|
||||||
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.lsb && index_tail.msb);
|
||||||
|
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
|
|
||||||
/* Calculate the width expression (in the lsb_ position)
|
/* Calculate the width expression (in the lsb_ position)
|
||||||
first. If the expression is not constant, error but guess 1
|
first. If the expression is not constant, error but guess 1
|
||||||
so we can keep going and find more errors. */
|
so we can keep going and find more errors. */
|
||||||
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1);
|
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||||
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
||||||
|
|
||||||
if (wid_c == 0) {
|
if (wid_c == 0) {
|
||||||
|
|
@ -695,30 +705,36 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
||||||
|
|
||||||
const NetExpr*ex1, *ex2;
|
const NetExpr*ex1, *ex2;
|
||||||
|
|
||||||
symbol_search(des, scope, path_,
|
symbol_search(des, scope, path_, net, par, eve, ex1, ex2);
|
||||||
net, par, eve,
|
|
||||||
ex1, ex2);
|
|
||||||
|
|
||||||
if (net != 0) {
|
if (net != 0) {
|
||||||
|
const name_component_t&name_tail = path_.back();
|
||||||
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
|
if (!name_tail.index.empty())
|
||||||
|
use_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
unsigned use_width = net->vector_width();
|
unsigned use_width = net->vector_width();
|
||||||
switch (sel_) {
|
switch (use_sel) {
|
||||||
case SEL_NONE:
|
case index_component_t::SEL_NONE:
|
||||||
break;
|
break;
|
||||||
case SEL_PART:
|
case index_component_t::SEL_PART:
|
||||||
{ long msb, lsb;
|
{ long msb, lsb;
|
||||||
calculate_parts_(des, scope, msb, lsb);
|
calculate_parts_(des, scope, msb, lsb);
|
||||||
use_width = 1 + ((msb>lsb)? (msb-lsb) : (lsb-msb));
|
use_width = 1 + ((msb>lsb)? (msb-lsb) : (lsb-msb));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEL_IDX_UP:
|
case index_component_t::SEL_IDX_UP:
|
||||||
case SEL_IDX_DO:
|
case index_component_t::SEL_IDX_DO:
|
||||||
{ unsigned long tmp = 0;
|
{ unsigned long tmp = 0;
|
||||||
calculate_up_do_width_(des, scope, tmp);
|
calculate_up_do_width_(des, scope, tmp);
|
||||||
use_width = tmp;
|
use_width = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case index_component_t::SEL_BIT:
|
||||||
|
use_width = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
ivl_assert(*this, 0);
|
||||||
}
|
}
|
||||||
return use_width;
|
return use_width;
|
||||||
}
|
}
|
||||||
|
|
@ -774,9 +790,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
// Hmm... maybe this is a genvar? This is only possible while
|
// Hmm... maybe this is a genvar? This is only possible while
|
||||||
// processing generate blocks, but then the genvar_tmp will be
|
// processing generate blocks, but then the genvar_tmp will be
|
||||||
// set in the scope.
|
// set in the scope.
|
||||||
if (path_.component_count() == 1
|
if (path_.size() == 1
|
||||||
&& scope->genvar_tmp.str()
|
&& scope->genvar_tmp.str()
|
||||||
&& strcmp(path_.peek_name(0), scope->genvar_tmp) == 0) {
|
&& strcmp(peek_tail_name(path_), scope->genvar_tmp) == 0) {
|
||||||
verinum val (scope->genvar_tmp_val);
|
verinum val (scope->genvar_tmp_val);
|
||||||
NetEConst*tmp = new NetEConst(val);
|
NetEConst*tmp = new NetEConst(val);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
|
|
@ -790,8 +806,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
if (gn_specify_blocks_flag) {
|
if (gn_specify_blocks_flag) {
|
||||||
map<perm_string,NetScope::spec_val_t>::const_iterator specp;
|
map<perm_string,NetScope::spec_val_t>::const_iterator specp;
|
||||||
perm_string key = perm_string::literal(path_.peek_name(0));
|
perm_string key = peek_tail_name(path_);
|
||||||
if (path_.component_count() == 1
|
if (path_.size() == 1
|
||||||
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
|
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
|
||||||
NetScope::spec_val_t value = (*specp).second;
|
NetScope::spec_val_t value = (*specp).second;
|
||||||
NetExpr*tmp = 0;
|
NetExpr*tmp = 0;
|
||||||
|
|
@ -814,8 +830,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
// Finally, if this is a scope name, then return that. Look
|
// Finally, if this is a scope name, then return that. Look
|
||||||
// first to see if this is a name of a local scope. Failing
|
// first to see if this is a name of a local scope. Failing
|
||||||
// that, search globally for a hierarchical name.
|
// that, search globally for a hierarchical name.
|
||||||
if ((path_.peek_name(1) == 0))
|
if ((path_.size() == 1))
|
||||||
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
|
if (NetScope*nsc = scope->child(peek_tail_name(path_))) {
|
||||||
NetEScope*tmp = new NetEScope(nsc);
|
NetEScope*tmp = new NetEScope(nsc);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
@ -854,13 +870,18 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
const NetExpr*par_msb,
|
const NetExpr*par_msb,
|
||||||
const NetExpr*par_lsb) const
|
const NetExpr*par_lsb) const
|
||||||
{
|
{
|
||||||
NetExpr*tmp;
|
NetExpr*tmp = par->dup_expr();
|
||||||
|
|
||||||
tmp = par->dup_expr();
|
const name_component_t&name_tail = path_.back();
|
||||||
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
|
if (!name_tail.index.empty())
|
||||||
|
use_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
if (sel_ == SEL_PART) {
|
if (use_sel == index_component_t::SEL_PART) {
|
||||||
assert(msb_ && lsb_);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
assert(idx_.empty());
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.msb);
|
||||||
|
ivl_assert(*this, index_tail.lsb);
|
||||||
|
|
||||||
/* If the identifier has a part select, we support
|
/* If the identifier has a part select, we support
|
||||||
it by pulling the right bits out and making a
|
it by pulling the right bits out and making a
|
||||||
|
|
@ -868,8 +889,8 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
lsb of a parameter is 0 and the msb is the
|
lsb of a parameter is 0 and the msb is the
|
||||||
width of the parameter. */
|
width of the parameter. */
|
||||||
|
|
||||||
verinum*lsn = lsb_->eval_const(des, scope);
|
verinum*lsn = index_tail.lsb->eval_const(des, scope);
|
||||||
verinum*msn = msb_->eval_const(des, scope);
|
verinum*msn = index_tail.msb->eval_const(des, scope);
|
||||||
if ((lsn == 0) || (msn == 0)) {
|
if ((lsn == 0) || (msn == 0)) {
|
||||||
cerr << get_line() << ": error: "
|
cerr << get_line() << ": error: "
|
||||||
"Part select expressions must be "
|
"Part select expressions must be "
|
||||||
|
|
@ -926,17 +947,19 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
delete tmp;
|
delete tmp;
|
||||||
tmp = new NetEConst(result);
|
tmp = new NetEConst(result);
|
||||||
|
|
||||||
} else if (sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO) {
|
} else if (use_sel == index_component_t::SEL_IDX_UP || use_sel == index_component_t::SEL_IDX_DO) {
|
||||||
assert(msb_);
|
|
||||||
assert(lsb_);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
assert(idx_.empty());
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.msb);
|
||||||
|
ivl_assert(*this, index_tail.lsb);
|
||||||
|
|
||||||
/* Get and evaluate the width of the index
|
/* Get and evaluate the width of the index
|
||||||
select. This must be constant. */
|
select. This must be constant. */
|
||||||
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1);
|
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||||
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
|
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
|
||||||
if (wid_ec == 0) {
|
if (wid_ec == 0) {
|
||||||
cerr << lsb_->get_line() << ": error: "
|
cerr << index_tail.lsb->get_line() << ": error: "
|
||||||
<< "Second expression of indexed part select "
|
<< "Second expression of indexed part select "
|
||||||
<< "most be constant." << endl;
|
<< "most be constant." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -945,12 +968,12 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
|
|
||||||
unsigned wid = wid_ec->value().as_ulong();
|
unsigned wid = wid_ec->value().as_ulong();
|
||||||
|
|
||||||
NetExpr*idx_ex = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*idx_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
if (idx_ex == 0) {
|
if (idx_ex == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_DO && wid > 1) {
|
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1) {
|
||||||
idx_ex = make_add_expr(idx_ex, 1-(long)wid);
|
idx_ex = make_add_expr(idx_ex, 1-(long)wid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -959,16 +982,16 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
tmp = new NetESelect(tmp, idx_ex, wid);
|
tmp = new NetESelect(tmp, idx_ex, wid);
|
||||||
|
|
||||||
|
|
||||||
} else if (!idx_.empty()) {
|
} else if (use_sel == index_component_t::SEL_BIT) {
|
||||||
assert(!msb_);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
assert(!lsb_);
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
assert(idx_.size() == 1);
|
ivl_assert(*this, index_tail.msb);
|
||||||
assert(sel_ == SEL_NONE);
|
ivl_assert(*this, !index_tail.lsb);
|
||||||
|
|
||||||
/* Handle the case where a parameter has a bit
|
/* Handle the case where a parameter has a bit
|
||||||
select attached to it. Generate a NetESelect
|
select attached to it. Generate a NetESelect
|
||||||
object to select the bit as desired. */
|
object to select the bit as desired. */
|
||||||
NetExpr*mtmp = idx_[0]->elaborate_expr(des, scope, -1,false);
|
NetExpr*mtmp = index_tail.msb->elaborate_expr(des, scope, -1,false);
|
||||||
if (! dynamic_cast<NetEConst*>(mtmp)) {
|
if (! dynamic_cast<NetEConst*>(mtmp)) {
|
||||||
NetExpr*re = mtmp->eval_tree();
|
NetExpr*re = mtmp->eval_tree();
|
||||||
if (re) {
|
if (re) {
|
||||||
|
|
@ -1045,8 +1068,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
NetEConstParam if possible. */
|
NetEConstParam if possible. */
|
||||||
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
||||||
if (ctmp != 0) {
|
if (ctmp != 0) {
|
||||||
perm_string name
|
perm_string name = peek_tail_name(path_);
|
||||||
= lex_strings.make(path_.peek_tail_name());
|
|
||||||
NetEConstParam*ptmp
|
NetEConstParam*ptmp
|
||||||
= new NetEConstParam(found_in, name, ctmp->value());
|
= new NetEConstParam(found_in, name, ctmp->value());
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
@ -1065,17 +1087,32 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
||||||
NetNet*net, NetScope*found_in,
|
NetNet*net, NetScope*found_in,
|
||||||
bool sys_task_arg) const
|
bool sys_task_arg) const
|
||||||
{
|
{
|
||||||
if (idx_.empty() && !sys_task_arg) {
|
const name_component_t&name_tail = path_.back();
|
||||||
|
|
||||||
|
if (name_tail.index.empty() && !sys_task_arg) {
|
||||||
cerr << get_line() << ": error: Array " << path()
|
cerr << get_line() << ": error: Array " << path()
|
||||||
<< " Needs an array index here." << endl;
|
<< " Needs an array index here." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, sys_task_arg || !idx_.empty());
|
index_component_t index_front;
|
||||||
NetExpr*word_index = idx_.empty()
|
if (! name_tail.index.empty()) {
|
||||||
|
index_front = name_tail.index.front();
|
||||||
|
ivl_assert(*this, index_front.sel != index_component_t::SEL_NONE);
|
||||||
|
if (index_front.sel != index_component_t::SEL_BIT) {
|
||||||
|
cerr << get_line() << ": error: Array " << path_
|
||||||
|
<< " cannot be indexed by a range." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ivl_assert(*this, index_front.msb);
|
||||||
|
ivl_assert(*this, !index_front.lsb);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr*word_index = index_front.sel == index_component_t::SEL_NONE
|
||||||
? 0
|
? 0
|
||||||
: elab_and_eval(des, scope, idx_[0], -1);
|
: elab_and_eval(des, scope, index_front.msb, -1);
|
||||||
if (word_index == 0 && !sys_task_arg)
|
if (word_index == 0 && !sys_task_arg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1106,15 +1143,22 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
||||||
NetESignal*res = new NetESignal(net, word_index);
|
NetESignal*res = new NetESignal(net, word_index);
|
||||||
res->set_line(*this);
|
res->set_line(*this);
|
||||||
|
|
||||||
if (sel_ == SEL_PART)
|
// Detect that the word has a part select as well.
|
||||||
|
|
||||||
|
index_component_t::ctype_t word_sel = index_component_t::SEL_NONE;
|
||||||
|
if (name_tail.index.size() > 1)
|
||||||
|
word_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
|
if (word_sel == index_component_t::SEL_PART)
|
||||||
return elaborate_expr_net_part_(des, scope, res, found_in);
|
return elaborate_expr_net_part_(des, scope, res, found_in);
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_UP)
|
if (word_sel == index_component_t::SEL_IDX_UP)
|
||||||
return elaborate_expr_net_idx_up_(des, scope, res, found_in);
|
return elaborate_expr_net_idx_up_(des, scope, res, found_in);
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_DO)
|
if (word_sel == index_component_t::SEL_IDX_DO)
|
||||||
return elaborate_expr_net_idx_do_(des, scope, res, found_in);
|
return elaborate_expr_net_idx_do_(des, scope, res, found_in);
|
||||||
|
|
||||||
|
ivl_assert(*this, word_sel == index_component_t::SEL_NONE);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1125,7 +1169,6 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
||||||
NetESignal*net, NetScope*found_in) const
|
NetESignal*net, NetScope*found_in) const
|
||||||
{
|
{
|
||||||
long msv, lsv;
|
long msv, lsv;
|
||||||
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
|
|
||||||
bool flag = calculate_parts_(des, scope, msv, lsv);
|
bool flag = calculate_parts_(des, scope, msv, lsv);
|
||||||
if (!flag)
|
if (!flag)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1183,12 +1226,14 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
||||||
NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
||||||
NetESignal*net, NetScope*found_in) const
|
NetESignal*net, NetScope*found_in) const
|
||||||
{
|
{
|
||||||
assert(lsb_ != 0);
|
const name_component_t&name_tail = path_.back();
|
||||||
assert(msb_ != 0);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.lsb != 0);
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
|
||||||
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
|
|
||||||
unsigned long wid = 0;
|
unsigned long wid = 0;
|
||||||
calculate_up_do_width_(des, scope, wid);
|
calculate_up_do_width_(des, scope, wid);
|
||||||
|
|
@ -1235,12 +1280,14 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
||||||
NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
||||||
NetESignal*net, NetScope*found_in)const
|
NetESignal*net, NetScope*found_in)const
|
||||||
{
|
{
|
||||||
assert(lsb_ != 0);
|
const name_component_t&name_tail = path_.back();
|
||||||
assert(msb_ != 0);
|
ivl_assert(*this, ! name_tail.index.empty());
|
||||||
|
|
||||||
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.lsb != 0);
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
|
||||||
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
|
|
||||||
unsigned long wid = 0;
|
unsigned long wid = 0;
|
||||||
calculate_up_do_width_(des, scope, wid);
|
calculate_up_do_width_(des, scope, wid);
|
||||||
|
|
@ -1284,11 +1331,14 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
||||||
NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
||||||
NetESignal*net, NetScope*found_in) const
|
NetESignal*net, NetScope*found_in) const
|
||||||
{
|
{
|
||||||
assert(msb_ == 0);
|
const name_component_t&name_tail = path_.back();
|
||||||
assert(lsb_ == 0);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
assert(idx_.size() == 1);
|
|
||||||
|
|
||||||
NetExpr*ex = elab_and_eval(des, scope, idx_[0], -1);
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
ivl_assert(*this, index_tail.lsb == 0);
|
||||||
|
|
||||||
|
NetExpr*ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
|
|
||||||
// If the bit select is constant, then treat it similar
|
// If the bit select is constant, then treat it similar
|
||||||
// to the part select, so that I save the effort of
|
// to the part select, so that I save the effort of
|
||||||
|
|
@ -1358,29 +1408,30 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
||||||
NetESignal*node = new NetESignal(net);
|
NetESignal*node = new NetESignal(net);
|
||||||
node->set_line(*this);
|
node->set_line(*this);
|
||||||
|
|
||||||
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
|
if (! path_.back().index.empty())
|
||||||
|
use_sel = path_.back().index.back().sel;
|
||||||
|
|
||||||
// If this is a part select of a signal, then make a new
|
// If this is a part select of a signal, then make a new
|
||||||
// temporary signal that is connected to just the
|
// temporary signal that is connected to just the
|
||||||
// selected bits. The lsb_ and msb_ expressions are from
|
// selected bits. The lsb_ and msb_ expressions are from
|
||||||
// the foo[msb:lsb] expression in the original.
|
// the foo[msb:lsb] expression in the original.
|
||||||
if (sel_ == SEL_PART)
|
if (use_sel == index_component_t::SEL_PART)
|
||||||
return elaborate_expr_net_part_(des, scope, node, found_in);
|
return elaborate_expr_net_part_(des, scope, node, found_in);
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_UP)
|
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||||
return elaborate_expr_net_idx_up_(des, scope, node, found_in);
|
return elaborate_expr_net_idx_up_(des, scope, node, found_in);
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_DO)
|
if (use_sel == index_component_t::SEL_IDX_DO)
|
||||||
return elaborate_expr_net_idx_do_(des, scope, node, found_in);
|
return elaborate_expr_net_idx_do_(des, scope, node, found_in);
|
||||||
|
|
||||||
if (!idx_.empty())
|
if (use_sel == index_component_t::SEL_BIT)
|
||||||
return elaborate_expr_net_bit_(des, scope, node, found_in);
|
return elaborate_expr_net_bit_(des, scope, node, found_in);
|
||||||
|
|
||||||
// It's not anything else, so this must be a simple identifier
|
// It's not anything else, so this must be a simple identifier
|
||||||
// expression with no part or bit select. Return the signal
|
// expression with no part or bit select. Return the signal
|
||||||
// itself as the expression.
|
// itself as the expression.
|
||||||
assert(sel_ == SEL_NONE);
|
assert(use_sel == index_component_t::SEL_NONE);
|
||||||
assert(msb_ == 0);
|
|
||||||
assert(lsb_ == 0);
|
|
||||||
assert(idx_.empty());
|
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
@ -1633,6 +1684,10 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_expr.cc,v $
|
* $Log: elab_expr.cc,v $
|
||||||
|
* Revision 1.125 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.124 2007/04/01 05:28:26 steve
|
* Revision 1.124 2007/04/01 05:28:26 steve
|
||||||
* Get offsets into indexed part selects correct.
|
* Get offsets into indexed part selects correct.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
73
elab_lval.cc
73
elab_lval.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_lval.cc,v 1.42 2007/03/14 05:06:49 steve Exp $"
|
#ident "$Id: elab_lval.cc,v 1.43 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -163,11 +163,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(reg);
|
ivl_assert(*this, reg);
|
||||||
|
|
||||||
|
const name_component_t&name_tail = path_.back();
|
||||||
|
|
||||||
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
|
if (!name_tail.index.empty())
|
||||||
|
use_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
// This is the special case that the l-value is an entire
|
// This is the special case that the l-value is an entire
|
||||||
// memory. This is, in fact, an error.
|
// memory. This is, in fact, an error.
|
||||||
if (reg->array_dimensions() > 0 && idx_.size() == 0) {
|
if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
|
||||||
cerr << get_line() << ": error: Cannot assign to array "
|
cerr << get_line() << ": error: Cannot assign to array "
|
||||||
<< path_ << ". Did you forget a word index?" << endl;
|
<< path_ << ". Did you forget a word index?" << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -177,19 +183,19 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
if (reg->array_dimensions() > 0)
|
if (reg->array_dimensions() > 0)
|
||||||
return elaborate_lval_net_word_(des, scope, reg);
|
return elaborate_lval_net_word_(des, scope, reg);
|
||||||
|
|
||||||
if (sel_ == SEL_PART) {
|
if (use_sel == index_component_t::SEL_PART) {
|
||||||
NetAssign_*lv = new NetAssign_(reg);
|
NetAssign_*lv = new NetAssign_(reg);
|
||||||
elaborate_lval_net_part_(des, scope, lv);
|
elaborate_lval_net_part_(des, scope, lv);
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_UP) {
|
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||||
NetAssign_*lv = new NetAssign_(reg);
|
NetAssign_*lv = new NetAssign_(reg);
|
||||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
elaborate_lval_net_idx_up_(des, scope, lv);
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_DO) {
|
if (use_sel == index_component_t::SEL_IDX_DO) {
|
||||||
NetAssign_*lv = new NetAssign_(reg);
|
NetAssign_*lv = new NetAssign_(reg);
|
||||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
elaborate_lval_net_idx_do_(des, scope, lv);
|
||||||
return lv;
|
return lv;
|
||||||
|
|
@ -208,12 +214,14 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, msb_ == 0);
|
|
||||||
ivl_assert(*this, lsb_ == 0);
|
|
||||||
long msb, lsb;
|
long msb, lsb;
|
||||||
NetExpr*mux;
|
NetExpr*mux;
|
||||||
|
|
||||||
if (! idx_.empty()) {
|
if (use_sel == index_component_t::SEL_BIT) {
|
||||||
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
ivl_assert(*this, index_tail.lsb == 0);
|
||||||
|
|
||||||
/* If there is only a single select expression, it is a
|
/* If there is only a single select expression, it is a
|
||||||
bit select. Evaluate the constant value and treat it
|
bit select. Evaluate the constant value and treat it
|
||||||
|
|
@ -221,9 +229,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
expression it not constant, then return the
|
expression it not constant, then return the
|
||||||
expression as a mux. */
|
expression as a mux. */
|
||||||
|
|
||||||
ivl_assert(*this, idx_.size() == 1);
|
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
|
|
||||||
NetExpr*index_expr = elab_and_eval(des, scope, idx_[0], -1);
|
|
||||||
|
|
||||||
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
|
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
|
||||||
msb = index_con->value().as_long();
|
msb = index_con->value().as_long();
|
||||||
|
|
@ -311,9 +317,15 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
NetNet*reg) const
|
NetNet*reg) const
|
||||||
{
|
{
|
||||||
assert(idx_.size() == 1);
|
const name_component_t&name_tail = path_.back();
|
||||||
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
NetExpr*word = elab_and_eval(des, scope, idx_[0], -1);
|
const index_component_t&index_head = name_tail.index.front();
|
||||||
|
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||||
|
ivl_assert(*this, index_head.msb != 0);
|
||||||
|
ivl_assert(*this, index_head.lsb == 0);
|
||||||
|
|
||||||
|
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
|
||||||
|
|
||||||
// If there is a non-zero base to the memory, then build an
|
// If there is a non-zero base to the memory, then build an
|
||||||
// expression to calculate the canonical address.
|
// expression to calculate the canonical address.
|
||||||
|
|
@ -348,13 +360,17 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||||
|
|
||||||
/* An array word may also have part selects applied to them. */
|
/* An array word may also have part selects applied to them. */
|
||||||
|
|
||||||
if (sel_ == SEL_PART)
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
|
if (name_tail.index.size() > 1)
|
||||||
|
use_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
|
if (use_sel == index_component_t::SEL_PART)
|
||||||
elaborate_lval_net_part_(des, scope, lv);
|
elaborate_lval_net_part_(des, scope, lv);
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_UP)
|
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
elaborate_lval_net_idx_up_(des, scope, lv);
|
||||||
|
|
||||||
if (sel_ == SEL_IDX_DO)
|
if (use_sel == index_component_t::SEL_IDX_DO)
|
||||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
elaborate_lval_net_idx_do_(des, scope, lv);
|
||||||
|
|
||||||
return lv;
|
return lv;
|
||||||
|
|
@ -417,8 +433,12 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
NetAssign_*lv) const
|
NetAssign_*lv) const
|
||||||
{
|
{
|
||||||
assert(lsb_);
|
const name_component_t&name_tail = path_.back();;
|
||||||
assert(msb_);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
ivl_assert(*this, index_tail.lsb != 0);
|
||||||
|
|
||||||
NetNet*reg = lv->sig();
|
NetNet*reg = lv->sig();
|
||||||
assert(reg);
|
assert(reg);
|
||||||
|
|
@ -436,7 +456,7 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
||||||
unsigned long wid;
|
unsigned long wid;
|
||||||
calculate_up_do_width_(des, scope, wid);
|
calculate_up_do_width_(des, scope, wid);
|
||||||
|
|
||||||
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
|
|
||||||
/* Correct the mux for the range of the vector. */
|
/* Correct the mux for the range of the vector. */
|
||||||
if (reg->msb() < reg->lsb())
|
if (reg->msb() < reg->lsb())
|
||||||
|
|
@ -457,8 +477,13 @@ bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
NetAssign_*lv) const
|
NetAssign_*lv) const
|
||||||
{
|
{
|
||||||
assert(lsb_);
|
const name_component_t&name_tail = path_.back();;
|
||||||
assert(msb_);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
ivl_assert(*this, index_tail.lsb != 0);
|
||||||
|
|
||||||
cerr << get_line() << ": internal error: don't know how to "
|
cerr << get_line() << ": internal error: don't know how to "
|
||||||
"deal with SEL_IDX_DO in lval?" << endl;
|
"deal with SEL_IDX_DO in lval?" << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -475,6 +500,10 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_lval.cc,v $
|
* $Log: elab_lval.cc,v $
|
||||||
|
* Revision 1.43 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.42 2007/03/14 05:06:49 steve
|
* Revision 1.42 2007/03/14 05:06:49 steve
|
||||||
* Replace some asserts with ivl_asserts.
|
* Replace some asserts with ivl_asserts.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
167
elab_net.cc
167
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_net.cc,v 1.203 2007/04/18 01:40:49 steve Exp $"
|
#ident "$Id: elab_net.cc,v 1.204 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1230,7 +1230,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned errors = 0;
|
unsigned errors = 0;
|
||||||
unsigned func_pins = 0;
|
unsigned func_pins = 0;
|
||||||
|
|
||||||
if (path_.peek_name(0)[0] == '$')
|
if (path_.front().name[0] == '$')
|
||||||
return elaborate_net_sfunc_(des, scope,
|
return elaborate_net_sfunc_(des, scope,
|
||||||
width, rise, fall, decay,
|
width, rise, fall, decay,
|
||||||
drive0, drive1);
|
drive0, drive1);
|
||||||
|
|
@ -1320,11 +1320,13 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
||||||
Link::strength_t drive0,
|
Link::strength_t drive0,
|
||||||
Link::strength_t drive1) const
|
Link::strength_t drive1) const
|
||||||
{
|
{
|
||||||
|
perm_string name = peek_tail_name(path_);
|
||||||
|
|
||||||
/* Handle the special case that the function call is to
|
/* Handle the special case that the function call is to
|
||||||
$signed. This takes a single expression argument, and
|
$signed. This takes a single expression argument, and
|
||||||
forces it to be a signed result. Otherwise, it is as if the
|
forces it to be a signed result. Otherwise, it is as if the
|
||||||
$signed did not exist. */
|
$signed did not exist. */
|
||||||
if (strcmp(path_.peek_name(0), "$signed") == 0) {
|
if (strcmp(name, "$signed") == 0) {
|
||||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||||
cerr << get_line() << ": error: The $signed() function "
|
cerr << get_line() << ": error: The $signed() function "
|
||||||
<< "takes exactly one(1) argument." << endl;
|
<< "takes exactly one(1) argument." << endl;
|
||||||
|
|
@ -1340,7 +1342,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle $unsigned like $signed */
|
/* handle $unsigned like $signed */
|
||||||
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
|
if (strcmp(name, "$unsigned") == 0) {
|
||||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||||
cerr << get_line() << ": error: The $unsigned() function "
|
cerr << get_line() << ": error: The $unsigned() function "
|
||||||
<< "takes exactly one(1) argument." << endl;
|
<< "takes exactly one(1) argument." << endl;
|
||||||
|
|
@ -1355,11 +1357,11 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct sfunc_return_type*def = lookup_sys_func(path_.peek_name(0));
|
const struct sfunc_return_type*def = lookup_sys_func(name);
|
||||||
|
|
||||||
if (def == 0) {
|
if (def == 0) {
|
||||||
cerr << get_line() << ": error: System function "
|
cerr << get_line() << ": error: System function "
|
||||||
<< path_.peek_name(0) << " not defined." << endl;
|
<< peek_tail_name(path_) << " not defined." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1545,15 +1547,19 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||||
Link::strength_t drive0,
|
Link::strength_t drive0,
|
||||||
Link::strength_t drive1) const
|
Link::strength_t drive1) const
|
||||||
{
|
{
|
||||||
assert(msb_ == 0);
|
const name_component_t&name_tail = path_.back();
|
||||||
assert(lsb_ == 0);
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
assert(idx_.size() == 1);
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
ivl_assert(*this, index_tail.sel == index_component_t::SEL_BIT);
|
||||||
|
ivl_assert(*this, index_tail.msb != 0);
|
||||||
|
ivl_assert(*this, index_tail.lsb == 0);
|
||||||
|
|
||||||
/* Elaborate the selector. */
|
/* Elaborate the selector. */
|
||||||
NetNet*sel;
|
NetNet*sel;
|
||||||
|
|
||||||
if (sig->msb() < sig->lsb()) {
|
if (sig->msb() < sig->lsb()) {
|
||||||
NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope, -1, false);
|
NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1, false);
|
||||||
sel_expr = make_sub_expr(sig->lsb(), sel_expr);
|
sel_expr = make_sub_expr(sig->lsb(), sel_expr);
|
||||||
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
||||||
delete sel_expr;
|
delete sel_expr;
|
||||||
|
|
@ -1563,7 +1569,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||||
sel = sel_expr->synthesize(des);
|
sel = sel_expr->synthesize(des);
|
||||||
|
|
||||||
} else if (sig->lsb() != 0) {
|
} else if (sig->lsb() != 0) {
|
||||||
NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope, -1,false);
|
NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1,false);
|
||||||
sel_expr = make_add_expr(sel_expr, - sig->lsb());
|
sel_expr = make_add_expr(sel_expr, - sig->lsb());
|
||||||
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
||||||
delete sel_expr;
|
delete sel_expr;
|
||||||
|
|
@ -1573,7 +1579,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||||
sel = sel_expr->synthesize(des);
|
sel = sel_expr->synthesize(des);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sel = idx_[0]->elaborate_net(des, scope, 0, 0, 0, 0);
|
sel = index_tail.msb->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
|
|
@ -1604,7 +1610,9 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||||
Link::strength_t drive0,
|
Link::strength_t drive0,
|
||||||
Link::strength_t drive1) const
|
Link::strength_t drive1) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
ivl_assert(*this, scope);
|
||||||
|
|
||||||
|
const name_component_t&name_tail = path_.back();
|
||||||
|
|
||||||
NetNet* sig = 0;
|
NetNet* sig = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
|
|
@ -1646,13 +1654,13 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||||
/* Check for the error case that the name is not found, and it
|
/* Check for the error case that the name is not found, and it
|
||||||
is hierarchical. We can't just create a name in another
|
is hierarchical. We can't just create a name in another
|
||||||
scope, it's just not allowed. */
|
scope, it's just not allowed. */
|
||||||
if (sig == 0 && path_.component_count() != 1) {
|
if (sig == 0 && path_.size() != 1) {
|
||||||
cerr << get_line() << ": error: The hierarchical name "
|
cerr << get_line() << ": error: The hierarchical name "
|
||||||
<< path_ << " is undefined in "
|
<< path_ << " is undefined in "
|
||||||
<< scope->name() << "." << endl;
|
<< scope->name() << "." << endl;
|
||||||
|
|
||||||
hname_t tmp_path = path_;
|
pform_name_t tmp_path = path_;
|
||||||
delete[] tmp_path.remove_tail_name();
|
tmp_path.pop_back();
|
||||||
|
|
||||||
NetScope*tmp_scope = des->find_scope(scope, tmp_path);
|
NetScope*tmp_scope = des->find_scope(scope, tmp_path);
|
||||||
if (tmp_scope == 0) {
|
if (tmp_scope == 0) {
|
||||||
|
|
@ -1667,28 +1675,28 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||||
/* Fallback, this may be an implicitly declared net. */
|
/* Fallback, this may be an implicitly declared net. */
|
||||||
if (sig == 0) {
|
if (sig == 0) {
|
||||||
NetNet::Type nettype = scope->default_nettype();
|
NetNet::Type nettype = scope->default_nettype();
|
||||||
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
|
sig = new NetNet(scope, name_tail.name,
|
||||||
nettype, 1);
|
nettype, 1);
|
||||||
sig->data_type(IVL_VT_LOGIC);
|
sig->data_type(IVL_VT_LOGIC);
|
||||||
|
|
||||||
if (error_implicit || (nettype == NetNet::NONE)) {
|
if (error_implicit || (nettype == NetNet::NONE)) {
|
||||||
cerr << get_line() << ": error: "
|
cerr << get_line() << ": error: "
|
||||||
<< scope->name() << "." << path_.peek_name(0)
|
<< scope->name() << "." << name_tail.name
|
||||||
<< " not defined in this scope." << endl;
|
<< " not defined in this scope." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
||||||
} else if (warn_implicit) {
|
} else if (warn_implicit) {
|
||||||
cerr << get_line() << ": warning: implicit "
|
cerr << get_line() << ": warning: implicit "
|
||||||
"definition of wire " << scope->name()
|
"definition of wire " << scope->name()
|
||||||
<< "." << path_.peek_name(0) << "." << endl;
|
<< "." << name_tail.name << "." << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sig);
|
ivl_assert(*this, sig);
|
||||||
|
|
||||||
/* Handle the case that this is an array elsewhere. */
|
/* Handle the case that this is an array elsewhere. */
|
||||||
if (sig->array_dimensions() > 0) {
|
if (sig->array_dimensions() > 0) {
|
||||||
if (idx_.size() == 0) {
|
if (name_tail.index.size() == 0) {
|
||||||
cerr << get_line() << ": error: Array " << sig->name()
|
cerr << get_line() << ": error: Array " << sig->name()
|
||||||
<< " cannot be used here without an index." << endl;
|
<< " cannot be used here without an index." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -1700,14 +1708,16 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||||
drive0, drive1);
|
drive0, drive1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
|
if (!name_tail.index.empty())
|
||||||
|
use_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
/* Catch the case of a non-constant bit select. That should be
|
/* Catch the case of a non-constant bit select. That should be
|
||||||
handled elsewhere. */
|
handled elsewhere. */
|
||||||
if (! idx_.empty()) {
|
if (use_sel == index_component_t::SEL_BIT) {
|
||||||
assert(msb_ == 0);
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
assert(lsb_ == 0);
|
|
||||||
assert(idx_.size() == 1);
|
|
||||||
|
|
||||||
verinum*mval = idx_[0]->eval_const(des, scope);
|
verinum*mval = index_tail.msb->eval_const(des, scope);
|
||||||
if (mval == 0) {
|
if (mval == 0) {
|
||||||
return elaborate_net_bitmux_(des, scope, sig, rise,
|
return elaborate_net_bitmux_(des, scope, sig, rise,
|
||||||
fall, decay, drive0, drive1);
|
fall, decay, drive0, drive1);
|
||||||
|
|
@ -1755,9 +1765,14 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
|
||||||
Link::strength_t drive0,
|
Link::strength_t drive0,
|
||||||
Link::strength_t drive1) const
|
Link::strength_t drive1) const
|
||||||
{
|
{
|
||||||
ivl_assert(*this, idx_.size() >= 1);
|
const name_component_t&name_tail = path_.back();
|
||||||
|
ivl_assert(*this, name_tail.index.size() >= 1);
|
||||||
|
const index_component_t&index_head = name_tail.index.front();
|
||||||
|
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||||
|
ivl_assert(*this, index_head.msb != 0);
|
||||||
|
ivl_assert(*this, index_head.lsb == 0);
|
||||||
|
|
||||||
NetExpr*index_ex = elab_and_eval(des, scope, idx_[0], -1);
|
NetExpr*index_ex = elab_and_eval(des, scope, index_head.msb, -1);
|
||||||
if (index_ex == 0)
|
if (index_ex == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1821,6 +1836,10 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
|
||||||
tmp->data_type(sig->data_type());
|
tmp->data_type(sig->data_type());
|
||||||
connect(tmp->pin(0), mux->pin_Result());
|
connect(tmp->pin(0), mux->pin_Result());
|
||||||
|
|
||||||
|
// If there are more index items then there are array
|
||||||
|
// dimensions, then treat them as word part selects. For
|
||||||
|
// example, if this is a memory array, then array dimensions
|
||||||
|
// is 1 and
|
||||||
unsigned midx, lidx;
|
unsigned midx, lidx;
|
||||||
if (eval_part_select_(des, scope, sig, midx, lidx)) do {
|
if (eval_part_select_(des, scope, sig, midx, lidx)) do {
|
||||||
|
|
||||||
|
|
@ -2006,7 +2025,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
|
||||||
NetNet*sig = 0;
|
NetNet*sig = 0;
|
||||||
|
|
||||||
if (!error_implicit && nettype!=NetNet::NONE) {
|
if (!error_implicit && nettype!=NetNet::NONE) {
|
||||||
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
|
sig = new NetNet(scope, peek_tail_name(path_),
|
||||||
NetNet::IMPLICIT, 1);
|
NetNet::IMPLICIT, 1);
|
||||||
/* Implicit nets are always scalar logic. */
|
/* Implicit nets are always scalar logic. */
|
||||||
sig->data_type(IVL_VT_LOGIC);
|
sig->data_type(IVL_VT_LOGIC);
|
||||||
|
|
@ -2014,7 +2033,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
|
||||||
if (warn_implicit) {
|
if (warn_implicit) {
|
||||||
cerr << get_line() << ": warning: implicit "
|
cerr << get_line() << ": warning: implicit "
|
||||||
"definition of wire logic " << scope->name()
|
"definition of wire logic " << scope->name()
|
||||||
<< "." << path_.peek_name(0) << "." << endl;
|
<< "." << peek_tail_name(path_) << "." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2037,20 +2056,30 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
|
||||||
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
unsigned&midx, unsigned&lidx) const
|
unsigned&midx, unsigned&lidx) const
|
||||||
{
|
{
|
||||||
switch (sel_) {
|
const name_component_t&name_tail = path_.back();
|
||||||
|
// Only treat as part/bit selects any index that is beyond the
|
||||||
|
// word selects for an array. This is not an array, then
|
||||||
|
// dimensions==0 and any index is treated as a select.
|
||||||
|
if (name_tail.index.size() <= sig->array_dimensions()) {
|
||||||
|
midx = sig->vector_width()-1;
|
||||||
|
lidx = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
|
|
||||||
|
switch (index_tail.sel) {
|
||||||
default:
|
default:
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
<< "Unexpected sel_ value = " << sel_ << endl;
|
<< "Unexpected sel_ value = " << index_tail.sel << endl;
|
||||||
assert(0);
|
ivl_assert(*this, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PEIdent::SEL_IDX_DO:
|
case index_component_t::SEL_IDX_DO:
|
||||||
case PEIdent::SEL_IDX_UP: {
|
case index_component_t::SEL_IDX_UP: {
|
||||||
assert(msb_);
|
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
assert(lsb_);
|
|
||||||
assert(idx_.size() == sig->array_dimensions());
|
|
||||||
|
|
||||||
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1);
|
|
||||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
|
|
@ -2058,14 +2087,14 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
midx = sig->sb_to_idx(midx_val);
|
midx = sig->sb_to_idx(midx_val);
|
||||||
delete tmp_ex;
|
delete tmp_ex;
|
||||||
|
|
||||||
tmp_ex = elab_and_eval(des, scope, lsb_, -1);
|
tmp_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||||
tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
long wid = tmp->value().as_long();
|
long wid = tmp->value().as_long();
|
||||||
delete tmp_ex;
|
delete tmp_ex;
|
||||||
|
|
||||||
if (sel_ == PEIdent::SEL_IDX_UP)
|
if (index_tail.sel == index_component_t::SEL_IDX_UP)
|
||||||
lidx = sig->sb_to_idx(midx_val+wid-1);
|
lidx = sig->sb_to_idx(midx_val+wid-1);
|
||||||
else
|
else
|
||||||
lidx = sig->sb_to_idx(midx_val-wid+1);
|
lidx = sig->sb_to_idx(midx_val-wid+1);
|
||||||
|
|
@ -2079,12 +2108,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PEIdent::SEL_PART: {
|
case index_component_t::SEL_PART: {
|
||||||
assert(msb_);
|
|
||||||
assert(lsb_);
|
|
||||||
assert(idx_.size() == sig->array_dimensions());
|
|
||||||
|
|
||||||
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
|
|
@ -2092,12 +2118,12 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
midx = sig->sb_to_idx(midx_val);
|
midx = sig->sb_to_idx(midx_val);
|
||||||
delete tmp_ex;
|
delete tmp_ex;
|
||||||
|
|
||||||
tmp_ex = elab_and_eval(des, scope, lsb_, -1);
|
tmp_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||||
tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
<< "lsb expression is not constant?: "
|
<< "lsb expression is not constant?: "
|
||||||
<< *tmp_ex << ", " << *lsb_ << endl;
|
<< *tmp_ex << ", " << *index_tail.lsb << endl;
|
||||||
}
|
}
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
|
|
@ -2131,19 +2157,16 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PEIdent::SEL_NONE:
|
case index_component_t::SEL_BIT:
|
||||||
if (idx_.size() > sig->array_dimensions()) {
|
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||||
unsigned a_dims = sig->array_dimensions();
|
const index_component_t&index_head = name_tail.index.front();
|
||||||
assert(msb_ == 0);
|
verinum*mval = index_head.msb->eval_const(des, scope);
|
||||||
assert(lsb_ == 0);
|
|
||||||
assert(idx_.size() == a_dims+1);
|
|
||||||
verinum*mval = idx_[a_dims]->eval_const(des, scope);
|
|
||||||
if (mval == 0) {
|
if (mval == 0) {
|
||||||
cerr << get_line() << ": error: Index of " << path_ <<
|
cerr << get_line() << ": error: Index of " << path_ <<
|
||||||
" needs to be constant in this context." <<
|
" needs to be constant in this context." <<
|
||||||
endl;
|
endl;
|
||||||
cerr << get_line() << ": : Index expression is: "
|
cerr << get_line() << ": : Index expression is: "
|
||||||
<< *(idx_[0]) << endl;
|
<< *index_head.msb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2160,17 +2183,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
lidx = midx;
|
lidx = midx;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (msb_ || lsb_) {
|
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
<< "Unexpected msb_/lsb_ values?" << endl;
|
<< "Bit select " << path_ << endl;
|
||||||
if (msb_)
|
ivl_assert(*this, 0);
|
||||||
cerr << get_line() << " : "
|
|
||||||
<< *msb_ << endl;
|
|
||||||
if (lsb_)
|
|
||||||
cerr << get_line() << " : "
|
|
||||||
<< *lsb_ << endl;
|
|
||||||
}
|
|
||||||
assert(msb_ == 0 && lsb_ == 0);
|
|
||||||
midx = sig->vector_width() - 1;
|
midx = sig->vector_width() - 1;
|
||||||
lidx = 0;
|
lidx = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2245,10 +2260,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
// The default word select is the first.
|
// The default word select is the first.
|
||||||
unsigned widx = 0;
|
unsigned widx = 0;
|
||||||
|
|
||||||
if (sig->array_dimensions() > 0) {
|
const name_component_t&name_tail = path_.back();
|
||||||
assert(!idx_.empty());
|
|
||||||
|
|
||||||
NetExpr*tmp_ex = elab_and_eval(des, scope, idx_[0], -1);
|
if (sig->array_dimensions() > 0) {
|
||||||
|
|
||||||
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
|
const index_component_t&index_head = name_tail.index.front();
|
||||||
|
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||||
|
|
||||||
|
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
|
||||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
|
|
@ -2260,7 +2281,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
cerr << get_line() << ": debug: Use [" << widx << "]"
|
cerr << get_line() << ": debug: Use [" << widx << "]"
|
||||||
<< " to index l-value array." << endl;
|
<< " to index l-value array." << endl;
|
||||||
|
|
||||||
} else {
|
} else if (!name_tail.index.empty()) {
|
||||||
if (! eval_part_select_(des, scope, sig, midx, lidx))
|
if (! eval_part_select_(des, scope, sig, midx, lidx))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2941,6 +2962,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_net.cc,v $
|
* $Log: elab_net.cc,v $
|
||||||
|
* Revision 1.204 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.203 2007/04/18 01:40:49 steve
|
* Revision 1.203 2007/04/18 01:40:49 steve
|
||||||
* Fix elaboration of multiply of two constants.
|
* Fix elaboration of multiply of two constants.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_pexpr.cc,v 1.26 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: elab_pexpr.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -130,44 +130,51 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||||
*/
|
*/
|
||||||
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
hname_t path = path_;
|
pform_name_t path = path_;
|
||||||
perm_string name = path.remove_tail_name();
|
name_component_t name_tail = path_.back();
|
||||||
|
path.pop_back();
|
||||||
|
|
||||||
NetScope*pscope = scope;
|
NetScope*pscope = scope;
|
||||||
if (path.peek_name(0))
|
if (path_.size() > 0)
|
||||||
pscope = des->find_scope(scope, path);
|
pscope = des->find_scope(scope, path);
|
||||||
|
|
||||||
const NetExpr*ex_msb;
|
const NetExpr*ex_msb;
|
||||||
const NetExpr*ex_lsb;
|
const NetExpr*ex_lsb;
|
||||||
const NetExpr*ex = pscope->get_parameter(name, ex_msb, ex_lsb);
|
const NetExpr*ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
|
||||||
if (ex == 0) {
|
if (ex == 0) {
|
||||||
cerr << get_line() << ": error: identifier ``" << path_ <<
|
cerr << get_line() << ": error: identifier ``" << name_tail.name <<
|
||||||
"'' is not a parameter in " << scope->name() << "." << endl;
|
"'' is not a parameter in " << scope->name() << "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr*res = new NetEParam(des, pscope, name);
|
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
|
||||||
res->set_line(*this);
|
res->set_line(*this);
|
||||||
assert(res);
|
assert(res);
|
||||||
|
|
||||||
if (msb_ && lsb_) {
|
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||||
assert(idx_.empty());
|
if (!name_tail.index.empty())
|
||||||
|
use_sel = name_tail.index.back().sel;
|
||||||
|
|
||||||
|
switch (use_sel) {
|
||||||
|
case index_component_t::SEL_NONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case index_component_t::SEL_PART:
|
||||||
cerr << get_line() << ": sorry: Cannot part select "
|
cerr << get_line() << ": sorry: Cannot part select "
|
||||||
"bits of parameters." << endl;
|
"bits of parameters." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (!idx_.empty()) {
|
case index_component_t::SEL_BIT:
|
||||||
assert(msb_==0);
|
|
||||||
assert(lsb_==0);
|
|
||||||
assert(idx_.size() == 1);
|
|
||||||
|
|
||||||
/* We have here a bit select. Insert a NetESelect node
|
/* We have here a bit select. Insert a NetESelect node
|
||||||
to handle it. */
|
to handle it. */
|
||||||
NetExpr*tmp = idx_[0]->elaborate_pexpr(des, scope);
|
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
|
||||||
if (tmp != 0) {
|
if (tmp != 0) {
|
||||||
res = new NetESelect(res, tmp, 1);
|
res = new NetESelect(res, tmp, 1);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -233,6 +240,10 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_pexpr.cc,v $
|
* $Log: elab_pexpr.cc,v $
|
||||||
|
* Revision 1.27 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.26 2007/04/26 03:06:22 steve
|
* Revision 1.26 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_scope.cc,v 1.44 2007/03/22 16:08:15 steve Exp $"
|
#ident "$Id: elab_scope.cc,v 1.45 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -66,7 +66,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||||
// place of the elaborated expression.
|
// place of the elaborated expression.
|
||||||
|
|
||||||
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
|
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
|
||||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
|
||||||
|
|
||||||
|
|
||||||
// This loop scans the parameters in the module, and creates
|
// This loop scans the parameters in the module, and creates
|
||||||
|
|
@ -200,7 +200,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||||
// here because the parameter receiving the assignment may be
|
// here because the parameter receiving the assignment may be
|
||||||
// in a scope not discovered by this pass.
|
// in a scope not discovered by this pass.
|
||||||
|
|
||||||
for (hparm_it_t cur = defparms.begin()
|
for (pform_parm_it_t cur = defparms.begin()
|
||||||
; cur != defparms.end() ; cur ++ ) {
|
; cur != defparms.end() ; cur ++ ) {
|
||||||
|
|
||||||
PExpr*ex = (*cur).second;
|
PExpr*ex = (*cur).second;
|
||||||
|
|
@ -761,6 +761,10 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_scope.cc,v $
|
* $Log: elab_scope.cc,v $
|
||||||
|
* Revision 1.45 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.44 2007/03/22 16:08:15 steve
|
* Revision 1.44 2007/03/22 16:08:15 steve
|
||||||
* Spelling fixes from Larry
|
* Spelling fixes from Larry
|
||||||
*
|
*
|
||||||
|
|
|
||||||
111
elab_sig.cc
111
elab_sig.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_sig.cc,v 1.50 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: elab_sig.cc,v 1.51 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This local function checks if a named signal is connected to a
|
* This local function checks if a named signal is connected to a
|
||||||
|
|
@ -41,8 +42,10 @@
|
||||||
* within the port_t that have a matching name.
|
* within the port_t that have a matching name.
|
||||||
*/
|
*/
|
||||||
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||||
const hname_t&name)
|
NetNet*sig)
|
||||||
{
|
{
|
||||||
|
perm_string name = sig->name();
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||||
|
|
||||||
Module::port_t*pp = ports[idx];
|
Module::port_t*pp = ports[idx];
|
||||||
|
|
@ -53,9 +56,15 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||||
// This port has an internal connection. In this case,
|
// This port has an internal connection. In this case,
|
||||||
// the port has 0 or more NetEIdent objects concatenated
|
// the port has 0 or more NetEIdent objects concatenated
|
||||||
// together that form the port.
|
// together that form the port.
|
||||||
|
|
||||||
|
// Note that module ports should not have any heirarchy
|
||||||
|
// in their names: they are in the root of the module
|
||||||
|
// scope by definition.
|
||||||
|
|
||||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||||
|
perm_string pname = peek_tail_name(pp->expr[cc]->path());
|
||||||
assert(pp->expr[cc]);
|
assert(pp->expr[cc]);
|
||||||
if (pp->expr[cc]->path() == name)
|
if (pname == name)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,6 +72,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
|
static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
|
||||||
{
|
{
|
||||||
NetScope*cur = scope;
|
NetScope*cur = scope;
|
||||||
|
|
@ -78,15 +88,12 @@ static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
|
||||||
|
|
||||||
return cur->find_signal(path.peek_name(idx));
|
return cur->find_signal(path.peek_name(idx));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
|
|
||||||
// Get all the explicitly declared wires of the module and
|
|
||||||
// start the signals list with them.
|
|
||||||
const map<hname_t,PWire*>&wl = get_wires();
|
|
||||||
|
|
||||||
// Scan all the ports of the module, and make sure that each
|
// Scan all the ports of the module, and make sure that each
|
||||||
// is connected to wires that have port declarations.
|
// is connected to wires that have port declarations.
|
||||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||||
|
|
@ -94,12 +101,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (pp == 0)
|
if (pp == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
map<hname_t,PWire*>::const_iterator wt;
|
map<pform_name_t,PWire*>::const_iterator wt;
|
||||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||||
hname_t port_path (pp->expr[cc]->path());
|
pform_name_t port_path (pp->expr[cc]->path());
|
||||||
wt = wl.find(port_path);
|
wt = wires_.find(port_path);
|
||||||
|
|
||||||
if (wt == wl.end()) {
|
if (wt == wires_.end()) {
|
||||||
cerr << get_line() << ": error: "
|
cerr << get_line() << ": error: "
|
||||||
<< "Port " << pp->expr[cc]->path() << " ("
|
<< "Port " << pp->expr[cc]->path() << " ("
|
||||||
<< (idx+1) << ") of module " << name_
|
<< (idx+1) << ") of module " << name_
|
||||||
|
|
@ -119,14 +126,11 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
|
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
|
||||||
; wt != wl.end()
|
; wt != wires_.end() ; wt ++ ) {
|
||||||
; wt ++ ) {
|
|
||||||
|
|
||||||
PWire*cur = (*wt).second;
|
PWire*cur = (*wt).second;
|
||||||
cur->elaborate_sig(des, scope);
|
NetNet*sig = cur->elaborate_sig(des, scope);
|
||||||
|
|
||||||
NetNet*sig = find_signal_in_scope(scope, cur->path());
|
|
||||||
|
|
||||||
// If this wire is a signal of the module (as opposed to
|
// If this wire is a signal of the module (as opposed to
|
||||||
// a port of a function) and is a port, then check that
|
// a port of a function) and is a port, then check that
|
||||||
|
|
@ -138,12 +142,10 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (sig && (sig->scope() == scope)
|
if (sig && (sig->scope() == scope)
|
||||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
||||||
|
|
||||||
hname_t name = (*wt).first;
|
if (! signal_is_in_port(ports, sig)) {
|
||||||
|
|
||||||
if (! signal_is_in_port(ports, name)) {
|
|
||||||
|
|
||||||
cerr << cur->get_line() << ": error: Signal "
|
cerr << cur->get_line() << ": error: Signal "
|
||||||
<< name << " has a declared direction "
|
<< sig->name() << " has a declared direction "
|
||||||
<< "but is not a port." << endl;
|
<< "but is not a port." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -286,7 +288,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
// Scan the declared PWires to elaborate the obvious signals
|
// Scan the declared PWires to elaborate the obvious signals
|
||||||
// in the current scope.
|
// in the current scope.
|
||||||
typedef map<hname_t,PWire*>::const_iterator wires_it_t;
|
typedef map<pform_name_t,PWire*>::const_iterator wires_it_t;
|
||||||
for (wires_it_t wt = wires.begin()
|
for (wires_it_t wt = wires.begin()
|
||||||
; wt != wires.end() ; wt ++ ) {
|
; wt != wires.end() ; wt ++ ) {
|
||||||
|
|
||||||
|
|
@ -420,9 +422,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
name. We know by design that the port name is given
|
name. We know by design that the port name is given
|
||||||
as two components: <func>.<port>. */
|
as two components: <func>.<port>. */
|
||||||
|
|
||||||
hname_t path = (*ports_)[idx]->path();
|
pform_name_t path = (*ports_)[idx]->path();
|
||||||
perm_string pname = lex_strings.make(path.peek_name(1));
|
ivl_assert(*this, path.size() == 2);
|
||||||
perm_string ppath = lex_strings.make(path.peek_name(0));
|
|
||||||
|
perm_string pname = peek_tail_name(path);
|
||||||
|
perm_string ppath = peek_head_name(path);
|
||||||
|
|
||||||
if (ppath != scope->basename()) {
|
if (ppath != scope->basename()) {
|
||||||
cerr << get_line() << ": internal error: function "
|
cerr << get_line() << ": internal error: function "
|
||||||
|
|
@ -473,28 +477,26 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
name. We know by design that the port name is given
|
name. We know by design that the port name is given
|
||||||
as two components: <task>.<port>. */
|
as two components: <task>.<port>. */
|
||||||
|
|
||||||
hname_t path = (*ports_)[idx]->path();
|
pform_name_t path = (*ports_)[idx]->path();
|
||||||
assert(path.peek_name(0) && path.peek_name(1));
|
ivl_assert(*this, path.size() == 2);
|
||||||
|
|
||||||
|
perm_string scope_name = peek_head_name(path);
|
||||||
|
perm_string port_name = peek_tail_name(path);
|
||||||
|
|
||||||
/* check that the current scope really does have the
|
/* check that the current scope really does have the
|
||||||
name of the first component of the task port name. Do
|
name of the first component of the task port name. Do
|
||||||
this by looking up the task scope in the parent of
|
this by looking up the task scope in the parent of
|
||||||
the current scope. */
|
the current scope. */
|
||||||
if (scope->parent()->child(path.peek_name(0)) != scope) {
|
ivl_assert(*this, scope->basename() == scope_name);
|
||||||
cerr << "internal error: task scope " << path
|
|
||||||
<< " not the same as scope " << scope->name()
|
|
||||||
<< "?!" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the signal for the port. We know by definition
|
/* Find the signal for the port. We know by definition
|
||||||
that it is in the scope of the task, so look only in
|
that it is in the scope of the task, so look only in
|
||||||
the scope. */
|
the scope. */
|
||||||
NetNet*tmp = scope->find_signal(path.peek_name(1));
|
NetNet*tmp = scope->find_signal(port_name);
|
||||||
|
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
<< "Could not find port " << path.peek_name(1)
|
<< "Could not find port " << port_name
|
||||||
<< " in scope " << scope->name() << endl;
|
<< " in scope " << scope->name() << endl;
|
||||||
scope->dump(cerr);
|
scope->dump(cerr);
|
||||||
}
|
}
|
||||||
|
|
@ -518,16 +520,19 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
* elaboration this creates an object in the design that represent the
|
* elaboration this creates an object in the design that represent the
|
||||||
* defined item.
|
* defined item.
|
||||||
*/
|
*/
|
||||||
void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
|
|
||||||
/* The parser may produce hierarchical names for wires. I here
|
/* The parser may produce hierarchical names for wires. I here
|
||||||
follow the scopes down to the base where I actually want to
|
follow the scopes down to the base where I actually want to
|
||||||
elaborate the NetNet object. */
|
elaborate the NetNet object. */
|
||||||
{ hname_t tmp_path = hname_;
|
{ pform_name_t tmp_path = hname_;
|
||||||
tmp_path.remove_tail_name();
|
tmp_path.pop_back();
|
||||||
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
|
while (! tmp_path.empty()) {
|
||||||
scope = scope->child(tmp_path.peek_name(idx));
|
name_component_t cur = tmp_path.front();
|
||||||
|
tmp_path.pop_front();
|
||||||
|
|
||||||
|
scope = scope->child(cur.name);
|
||||||
|
|
||||||
if (scope == 0) {
|
if (scope == 0) {
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
|
|
@ -580,7 +585,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
"Unable to evaluate constant expression ``" <<
|
"Unable to evaluate constant expression ``" <<
|
||||||
*msb_[idx] << "''." << endl;
|
*msb_[idx] << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mnum[idx] = tmp->value().as_long();
|
mnum[idx] = tmp->value().as_long();
|
||||||
|
|
@ -593,7 +598,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
"Unable to evaluate constant expression ``" <<
|
"Unable to evaluate constant expression ``" <<
|
||||||
*lsb_[idx] << "''." << endl;
|
*lsb_[idx] << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lnum[idx] = tmp->value().as_long();
|
lnum[idx] = tmp->value().as_long();
|
||||||
|
|
@ -609,7 +614,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
<< "'' declared both as a vector and a scalar."
|
<< "'' declared both as a vector and a scalar."
|
||||||
<< endl;
|
<< endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -622,7 +627,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||||
" for signal ``" << hname_ << "''" << endl;
|
" for signal ``" << hname_ << "''" << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,9 +662,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if ((lexp == 0) || (rexp == 0)) {
|
if ((lexp == 0) || (rexp == 0)) {
|
||||||
cerr << get_line() << ": internal error: There is "
|
cerr << get_line() << ": internal error: There is "
|
||||||
<< "a problem evaluating indices for ``"
|
<< "a problem evaluating indices for ``"
|
||||||
<< hname_.peek_tail_name() << "''." << endl;
|
<< hname_ << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
|
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
|
||||||
|
|
@ -668,9 +673,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if ((lcon == 0) || (rcon == 0)) {
|
if ((lcon == 0) || (rcon == 0)) {
|
||||||
cerr << get_line() << ": internal error: The indices "
|
cerr << get_line() << ": internal error: The indices "
|
||||||
<< "are not constant for array ``"
|
<< "are not constant for array ``"
|
||||||
<< hname_.peek_tail_name() << "''." << endl;
|
<< hname_ << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum lval = lcon->value();
|
verinum lval = lcon->value();
|
||||||
|
|
@ -679,8 +684,6 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
delete lexp;
|
delete lexp;
|
||||||
delete rexp;
|
delete rexp;
|
||||||
|
|
||||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
|
||||||
|
|
||||||
array_dimensions = 1;
|
array_dimensions = 1;
|
||||||
array_s0 = lval.as_long();
|
array_s0 = lval.as_long();
|
||||||
array_e0 = rval.as_long();
|
array_e0 = rval.as_long();
|
||||||
|
|
@ -720,7 +723,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
perm_string name = peek_tail_name(hname_);
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_line() << ": debug: Create signal "
|
cerr << get_line() << ": debug: Create signal "
|
||||||
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
|
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
|
||||||
|
|
@ -754,10 +757,16 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
|
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
|
||||||
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
||||||
|
|
||||||
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_sig.cc,v $
|
* $Log: elab_sig.cc,v $
|
||||||
|
* Revision 1.51 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.50 2007/04/26 03:06:22 steve
|
* Revision 1.50 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
15
elaborate.cc
15
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elaborate.cc,v 1.370 2007/04/16 01:10:07 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.371 2007/05/24 04:07:11 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -770,8 +770,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
if (mport.count() == 0)
|
if (mport.count() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
NetNet*tmp = des->find_signal(instance[0],
|
perm_string pname = peek_tail_name(mport[0]->path());
|
||||||
mport[0]->path());
|
|
||||||
|
NetNet*tmp = instance[0]->find_signal(pname);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
if (tmp->port_type() == NetNet::PINPUT) {
|
if (tmp->port_type() == NetNet::PINPUT) {
|
||||||
|
|
@ -1833,7 +1834,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
NetProc* PCallTask::elaborate(Design*des, NetScope*scope) const
|
NetProc* PCallTask::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
if (path_.peek_name(0)[0] == '$')
|
if (peek_tail_name(path_)[0] == '$')
|
||||||
return elaborate_sys(des, scope);
|
return elaborate_sys(des, scope);
|
||||||
else
|
else
|
||||||
return elaborate_usr(des, scope);
|
return elaborate_usr(des, scope);
|
||||||
|
|
@ -1877,7 +1878,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetSTask*cur = new NetSTask(path_.peek_name(0), eparms);
|
NetSTask*cur = new NetSTask(peek_tail_name(path_), eparms);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3416,6 +3417,10 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.371 2007/05/24 04:07:11 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.370 2007/04/16 01:10:07 steve
|
* Revision 1.370 2007/04/16 01:10:07 steve
|
||||||
* Properly ignore unsupported ifnone.
|
* Properly ignore unsupported ifnone.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
15
eval.cc
15
eval.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: eval.cc,v 1.45 2007/03/07 00:38:15 steve Exp $"
|
#ident "$Id: eval.cc,v 1.46 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -177,16 +177,17 @@ verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
|
||||||
NetEvent*eve;
|
NetEvent*eve;
|
||||||
const NetExpr*expr;
|
const NetExpr*expr;
|
||||||
|
|
||||||
|
const name_component_t&name_tail = path_.back();
|
||||||
|
|
||||||
// Handle the special case that this ident is a genvar
|
// Handle the special case that this ident is a genvar
|
||||||
// variable name. In that case, the genvar meaning preempts
|
// variable name. In that case, the genvar meaning preempts
|
||||||
// everything and we just return that value immediately.
|
// everything and we just return that value immediately.
|
||||||
if (scope->genvar_tmp
|
if (scope->genvar_tmp
|
||||||
&& strcmp(path_.peek_tail_name(),scope->genvar_tmp) == 0) {
|
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
|
||||||
return new verinum(scope->genvar_tmp_val);
|
return new verinum(scope->genvar_tmp_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol_search(des, scope, path_,
|
symbol_search(des, scope, path_, net, expr, eve);
|
||||||
net, expr, eve);
|
|
||||||
|
|
||||||
if (expr == 0)
|
if (expr == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -201,7 +202,7 @@ verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
|
||||||
|
|
||||||
assert(eval);
|
assert(eval);
|
||||||
|
|
||||||
if (msb_ || lsb_)
|
if (!name_tail.index.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -275,6 +276,10 @@ verinum* PEUnary::eval_const(const Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: eval.cc,v $
|
* $Log: eval.cc,v $
|
||||||
|
* Revision 1.46 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.45 2007/03/07 00:38:15 steve
|
* Revision 1.45 2007/03/07 00:38:15 steve
|
||||||
* Lint fixes.
|
* Lint fixes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_design.cc,v 1.51 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: net_design.cc,v 1.52 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -114,26 +114,28 @@ const list<NetScope*> Design::find_root_scopes() const
|
||||||
* more step down the tree until the name runs out or the search
|
* more step down the tree until the name runs out or the search
|
||||||
* fails.
|
* fails.
|
||||||
*/
|
*/
|
||||||
NetScope* Design::find_scope(const hname_t&path) const
|
NetScope* Design::find_scope(const pform_name_t&path) const
|
||||||
{
|
{
|
||||||
if (path.peek_name(0) == 0)
|
if (path.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||||
; scope != root_scopes_.end(); scope++) {
|
; scope != root_scopes_.end(); scope++) {
|
||||||
|
|
||||||
NetScope*cur = *scope;
|
NetScope*cur = *scope;
|
||||||
if (strcmp(path.peek_name(0), cur->basename()) != 0)
|
if (strcmp(peek_head_name(path), cur->basename()) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned hidx = 1;
|
pform_name_t tmp = path;
|
||||||
while (cur) {
|
tmp.pop_front();
|
||||||
const char*name = path.peek_name(hidx);
|
|
||||||
if (name == 0)
|
|
||||||
return cur;
|
|
||||||
|
|
||||||
|
while (cur) {
|
||||||
|
if (tmp.empty()) return cur;
|
||||||
|
|
||||||
|
perm_string name = peek_head_name(tmp);
|
||||||
cur = cur->child(name);
|
cur = cur->child(name);
|
||||||
hidx += 1;
|
|
||||||
|
tmp.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -143,27 +145,30 @@ NetScope* Design::find_scope(const hname_t&path) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a relative lookup of a scope by name. The starting point is
|
* This is a relative lookup of a scope by name. The starting point is
|
||||||
* the scope parameter is the place within which I start looking for
|
* the scope parameter within which I start looking for the scope. If
|
||||||
* the scope. If I do not find the scope within the passed scope,
|
* I do not find the scope within the passed scope, start looking in
|
||||||
* start looking in parent scopes until I find it, or I run out of
|
* parent scopes until I find it, or I run out of parent scopes.
|
||||||
* parent scopes.
|
|
||||||
*/
|
*/
|
||||||
NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const
|
NetScope* Design::find_scope(NetScope*scope, const pform_name_t&path) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
if (path.peek_name(0) == 0)
|
if (path.empty())
|
||||||
return scope;
|
return scope;
|
||||||
|
|
||||||
for ( ; scope ; scope = scope->parent()) {
|
for ( ; scope ; scope = scope->parent()) {
|
||||||
unsigned hidx = 0;
|
|
||||||
const char*key = path.peek_name(hidx);
|
pform_name_t tmp = path;
|
||||||
|
name_component_t name_front = tmp.front();
|
||||||
|
perm_string key = name_front.name;
|
||||||
|
|
||||||
NetScope*cur = scope;
|
NetScope*cur = scope;
|
||||||
do {
|
do {
|
||||||
cur = cur->child(key);
|
cur = cur->child(key);
|
||||||
if (cur == 0) break;
|
if (cur == 0) break;
|
||||||
hidx += 1;
|
tmp.pop_front();
|
||||||
key = path.peek_name(hidx);
|
if (tmp.empty()) break;
|
||||||
|
name_front = tmp.front();
|
||||||
|
key = name_front.name;
|
||||||
} while (key);
|
} while (key);
|
||||||
|
|
||||||
if (cur) return cur;
|
if (cur) return cur;
|
||||||
|
|
@ -196,12 +201,13 @@ void NetScope::run_defparams(Design*des)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map<hname_t,NetExpr*>::const_iterator pp;
|
map<pform_name_t,NetExpr*>::const_iterator pp;
|
||||||
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
|
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
|
||||||
NetExpr*val = (*pp).second;
|
NetExpr*val = (*pp).second;
|
||||||
hname_t path = (*pp).first;
|
pform_name_t path = (*pp).first;
|
||||||
|
|
||||||
perm_string perm_name = path.remove_tail_name();
|
perm_string perm_name = peek_tail_name(path);
|
||||||
|
path.pop_back();
|
||||||
|
|
||||||
/* If there is no path on the name, then the targ_scope
|
/* If there is no path on the name, then the targ_scope
|
||||||
is the current scope. */
|
is the current scope. */
|
||||||
|
|
@ -423,12 +429,13 @@ const char* Design::get_flag(const string&key) const
|
||||||
* It is the job of this function to properly implement Verilog scope
|
* It is the job of this function to properly implement Verilog scope
|
||||||
* rules as signals are concerned.
|
* rules as signals are concerned.
|
||||||
*/
|
*/
|
||||||
NetNet* Design::find_signal(NetScope*scope, hname_t path)
|
NetNet* Design::find_signal(NetScope*scope, pform_name_t path)
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
perm_string key = path.remove_tail_name();
|
perm_string key = peek_tail_name(path);
|
||||||
if (path.peek_name(0))
|
path.pop_back();
|
||||||
|
if (! path.empty())
|
||||||
scope = find_scope(scope, path);
|
scope = find_scope(scope, path);
|
||||||
|
|
||||||
while (scope) {
|
while (scope) {
|
||||||
|
|
@ -444,7 +451,7 @@ NetNet* Design::find_signal(NetScope*scope, hname_t path)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
|
NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name)
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
NetScope*func = find_scope(scope, name);
|
NetScope*func = find_scope(scope, name);
|
||||||
|
|
@ -454,7 +461,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetFuncDef* Design::find_function(const hname_t&key)
|
NetFuncDef* Design::find_function(const pform_name_t&key)
|
||||||
{
|
{
|
||||||
NetScope*func = find_scope(key);
|
NetScope*func = find_scope(key);
|
||||||
if (func && (func->type() == NetScope::FUNC))
|
if (func && (func->type() == NetScope::FUNC))
|
||||||
|
|
@ -463,7 +470,7 @@ NetFuncDef* Design::find_function(const hname_t&key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope* Design::find_task(NetScope*scope, const hname_t&name)
|
NetScope* Design::find_task(NetScope*scope, const pform_name_t&name)
|
||||||
{
|
{
|
||||||
NetScope*task = find_scope(scope, name);
|
NetScope*task = find_scope(scope, name);
|
||||||
if (task && (task->type() == NetScope::TASK))
|
if (task && (task->type() == NetScope::TASK))
|
||||||
|
|
@ -472,7 +479,7 @@ NetScope* Design::find_task(NetScope*scope, const hname_t&name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope* Design::find_task(const hname_t&key)
|
NetScope* Design::find_task(const pform_name_t&key)
|
||||||
{
|
{
|
||||||
NetScope*task = find_scope(key);
|
NetScope*task = find_scope(key);
|
||||||
if (task && (task->type() == NetScope::TASK))
|
if (task && (task->type() == NetScope::TASK))
|
||||||
|
|
@ -558,6 +565,10 @@ void Design::delete_process(NetProcTop*top)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_design.cc,v $
|
* $Log: net_design.cc,v $
|
||||||
|
* Revision 1.52 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.51 2007/04/26 03:06:22 steve
|
* Revision 1.51 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
23
netlist.h
23
netlist.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netlist.h,v 1.378 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: netlist.h,v 1.379 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <vector>
|
# include <vector>
|
||||||
# include "ivl_target.h"
|
# include "ivl_target.h"
|
||||||
|
# include "pform_types.h"
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
# include "verireal.h"
|
# include "verireal.h"
|
||||||
|
|
@ -3291,7 +3292,7 @@ class NetScope : public Attrib {
|
||||||
assignments from the scope pass to the parameter evaluation
|
assignments from the scope pass to the parameter evaluation
|
||||||
step. After that, it is not used. */
|
step. After that, it is not used. */
|
||||||
|
|
||||||
map<hname_t,NetExpr*>defparams;
|
map<pform_name_t,NetExpr*>defparams;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* After everything is all set up, the code generators like
|
/* After everything is all set up, the code generators like
|
||||||
|
|
@ -3391,8 +3392,8 @@ class Design {
|
||||||
path is taken as an absolute scope name. Otherwise, the
|
path is taken as an absolute scope name. Otherwise, the
|
||||||
scope is located starting at the passed scope and working
|
scope is located starting at the passed scope and working
|
||||||
up if needed. */
|
up if needed. */
|
||||||
NetScope* find_scope(const hname_t&path) const;
|
NetScope* find_scope(const pform_name_t&path) const;
|
||||||
NetScope* find_scope(NetScope*, const hname_t&path) const;
|
NetScope* find_scope(NetScope*, const pform_name_t&path) const;
|
||||||
|
|
||||||
// PARAMETERS
|
// PARAMETERS
|
||||||
|
|
||||||
|
|
@ -3404,15 +3405,15 @@ class Design {
|
||||||
this method, unlike the NetScope::find_signal method,
|
this method, unlike the NetScope::find_signal method,
|
||||||
handles global name binding. */
|
handles global name binding. */
|
||||||
|
|
||||||
NetNet*find_signal(NetScope*scope, hname_t path);
|
NetNet*find_signal(NetScope*scope, pform_name_t path);
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
NetFuncDef* find_function(NetScope*scope, const hname_t&key);
|
NetFuncDef* find_function(NetScope*scope, const pform_name_t&key);
|
||||||
NetFuncDef* find_function(const hname_t&path);
|
NetFuncDef* find_function(const pform_name_t&path);
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
NetScope* find_task(NetScope*scope, const hname_t&name);
|
NetScope* find_task(NetScope*scope, const pform_name_t&name);
|
||||||
NetScope* find_task(const hname_t&key);
|
NetScope* find_task(const pform_name_t&key);
|
||||||
|
|
||||||
// NODES
|
// NODES
|
||||||
void add_node(NetNode*);
|
void add_node(NetNode*);
|
||||||
|
|
@ -3500,6 +3501,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.379 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.378 2007/04/26 03:06:22 steve
|
* Revision 1.378 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
netmisc.h
12
netmisc.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netmisc.h,v 1.29 2007/03/08 05:30:03 steve Exp $"
|
#ident "$Id: netmisc.h,v 1.30 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -40,20 +40,20 @@
|
||||||
* these values are set to 0.
|
* these values are set to 0.
|
||||||
*/
|
*/
|
||||||
extern NetScope* symbol_search(const Design*des,
|
extern NetScope* symbol_search(const Design*des,
|
||||||
NetScope*start, hname_t path,
|
NetScope*start, pform_name_t path,
|
||||||
NetNet*&net, /* net/reg */
|
NetNet*&net, /* net/reg */
|
||||||
const NetExpr*&par,/* parameter */
|
const NetExpr*&par,/* parameter */
|
||||||
NetEvent*&eve, /* named event */
|
NetEvent*&eve, /* named event */
|
||||||
const NetExpr*&ex1, const NetExpr*&ex2);
|
const NetExpr*&ex1, const NetExpr*&ex2);
|
||||||
|
|
||||||
inline NetScope* symbol_search(const Design*des,
|
inline NetScope* symbol_search(const Design*des,
|
||||||
NetScope*start, const hname_t&path,
|
NetScope*start, const pform_name_t&path,
|
||||||
NetNet*&net, /* net/reg */
|
NetNet*&net, /* net/reg */
|
||||||
const NetExpr*&par,/* parameter */
|
const NetExpr*&par,/* parameter */
|
||||||
NetEvent*&eve /* named event */)
|
NetEvent*&eve /* named event */)
|
||||||
{
|
{
|
||||||
const NetExpr*ex1, *ex2;
|
const NetExpr*ex1, *ex2;
|
||||||
return symbol_search(des, start, path, net, /*mem,*/ par, eve, ex1, ex2);
|
return symbol_search(des, start, path, net, par, eve, ex1, ex2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -125,6 +125,10 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netmisc.h,v $
|
* $Log: netmisc.h,v $
|
||||||
|
* Revision 1.30 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.29 2007/03/08 05:30:03 steve
|
* Revision 1.29 2007/03/08 05:30:03 steve
|
||||||
* Limit the calculated widths of constants.
|
* Limit the calculated widths of constants.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
256
parse.y
256
parse.y
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2006 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: parse.y,v 1.236 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: parse.y,v 1.237 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -98,6 +98,7 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
|
||||||
strdup. They can be put into lists with the texts type. */
|
strdup. They can be put into lists with the texts type. */
|
||||||
char*text;
|
char*text;
|
||||||
list<perm_string>*perm_strings;
|
list<perm_string>*perm_strings;
|
||||||
|
pform_name_t*pform_name;
|
||||||
|
|
||||||
hname_t*hier;
|
hname_t*hier;
|
||||||
|
|
||||||
|
|
@ -123,8 +124,6 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
|
||||||
|
|
||||||
svector<PEEvent*>*event_expr;
|
svector<PEEvent*>*event_expr;
|
||||||
|
|
||||||
PEIdent*indexed_identifier;
|
|
||||||
|
|
||||||
NetNet::Type nettype;
|
NetNet::Type nettype;
|
||||||
PGBuiltin::Type gatetype;
|
PGBuiltin::Type gatetype;
|
||||||
NetNet::PortType porttype;
|
NetNet::PortType porttype;
|
||||||
|
|
@ -191,7 +190,6 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
|
||||||
%type <statement> udp_initial udp_init_opt
|
%type <statement> udp_initial udp_init_opt
|
||||||
%type <expr> udp_initial_expr_opt
|
%type <expr> udp_initial_expr_opt
|
||||||
|
|
||||||
%type <hier> identifier
|
|
||||||
%type <text> register_variable net_variable
|
%type <text> register_variable net_variable
|
||||||
%type <perm_strings> register_variable_list net_variable_list list_of_identifiers
|
%type <perm_strings> register_variable_list net_variable_list list_of_identifiers
|
||||||
|
|
||||||
|
|
@ -217,13 +215,13 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
|
||||||
%type <gate> gate_instance
|
%type <gate> gate_instance
|
||||||
%type <gates> gate_instance_list
|
%type <gates> gate_instance_list
|
||||||
|
|
||||||
|
%type <pform_name> heirarchy_identifier
|
||||||
%type <expr> expression expr_primary
|
%type <expr> expression expr_primary
|
||||||
%type <expr> lpvalue
|
%type <expr> lpvalue
|
||||||
%type <expr> delay_value delay_value_simple
|
%type <expr> delay_value delay_value_simple
|
||||||
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
||||||
%type <exprs> expression_list_with_nuls expression_list_proper
|
%type <exprs> expression_list_with_nuls expression_list_proper
|
||||||
%type <exprs> cont_assign cont_assign_list
|
%type <exprs> cont_assign cont_assign_list
|
||||||
%type <indexed_identifier> indexed_identifier
|
|
||||||
|
|
||||||
%type <exprs> range range_opt
|
%type <exprs> range range_opt
|
||||||
%type <nettype> net_type var_type net_type_opt
|
%type <nettype> net_type var_type net_type_opt
|
||||||
|
|
@ -492,7 +490,7 @@ charge_strength_opt
|
||||||
;
|
;
|
||||||
|
|
||||||
defparam_assign
|
defparam_assign
|
||||||
: identifier '=' expression
|
: heirarchy_identifier '=' expression
|
||||||
{ PExpr*tmp = $3;
|
{ PExpr*tmp = $3;
|
||||||
if (!pform_expression_is_constant(tmp)) {
|
if (!pform_expression_is_constant(tmp)) {
|
||||||
yyerror(@3, "error: parameter value "
|
yyerror(@3, "error: parameter value "
|
||||||
|
|
@ -605,7 +603,7 @@ delay_value_simple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{ PEIdent*tmp = new PEIdent(hname_t(lex_strings.make($1)));
|
{ PEIdent*tmp = new PEIdent(lex_strings.make($1));
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -671,16 +669,14 @@ dr_strength1
|
||||||
;
|
;
|
||||||
|
|
||||||
event_control
|
event_control
|
||||||
: '@' identifier
|
: '@' heirarchy_identifier
|
||||||
{ PEIdent*tmpi = new PEIdent(*$2);
|
{ PEIdent*tmpi = new PEIdent(*$2);
|
||||||
tmpi->set_file(@2.text);
|
|
||||||
tmpi->set_lineno(@2.first_line);
|
|
||||||
delete $2;
|
|
||||||
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
|
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
|
||||||
PEventStatement*tmps = new PEventStatement(tmpe);
|
PEventStatement*tmps = new PEventStatement(tmpe);
|
||||||
tmps->set_file(@1.text);
|
tmps->set_file(@1.text);
|
||||||
tmps->set_lineno(@1.first_line);
|
tmps->set_lineno(@1.first_line);
|
||||||
$$ = tmps;
|
$$ = tmps;
|
||||||
|
delete $2;
|
||||||
}
|
}
|
||||||
| '@' '(' event_expression_list ')'
|
| '@' '(' event_expression_list ')'
|
||||||
{ PEventStatement*tmp = new PEventStatement(*$3);
|
{ PEventStatement*tmp = new PEventStatement(*$3);
|
||||||
|
|
@ -1034,53 +1030,29 @@ expr_primary
|
||||||
}
|
}
|
||||||
| SYSTEM_IDENTIFIER
|
| SYSTEM_IDENTIFIER
|
||||||
{ perm_string tn = lex_strings.make($1);
|
{ perm_string tn = lex_strings.make($1);
|
||||||
PECallFunction*tmp = new PECallFunction(hname_t(tn));
|
PECallFunction*tmp = new PECallFunction(tn);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The indexed_identifier rule matches simple identifiers as well as
|
/* The heirarchy_identifier rule matches simple identifiers as well as
|
||||||
indexed arrays. Part selects are handled below. */
|
indexed arrays and part selects */
|
||||||
|
|
||||||
| indexed_identifier
|
| heirarchy_identifier
|
||||||
{ PEIdent*tmp = $1;
|
{ PEIdent*tmp = new PEIdent(*$1);
|
||||||
$$ = tmp;
|
tmp->set_file(@1.text);
|
||||||
}
|
tmp->set_lineno(@1.first_line);
|
||||||
|
|
||||||
/* There are 3 kinds of part selects. The basic part select has the
|
|
||||||
usual [M:L] syntax. The indexed part selects use +: or -: in
|
|
||||||
place of the : in the basic part select, and the first expression
|
|
||||||
is not limited to constant values. */
|
|
||||||
|
|
||||||
| indexed_identifier '[' expression ':' expression ']'
|
|
||||||
{ PEIdent*tmp = $1;
|
|
||||||
tmp->msb_ = $3;
|
|
||||||
tmp->lsb_ = $5;
|
|
||||||
tmp->sel_ = PEIdent::SEL_PART;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| indexed_identifier '[' expression K_PO_POS expression ']'
|
|
||||||
{ PEIdent*tmp = $1;
|
|
||||||
tmp->msb_ = $3;
|
|
||||||
tmp->lsb_ = $5;
|
|
||||||
tmp->sel_ = PEIdent::SEL_IDX_UP;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| indexed_identifier '[' expression K_PO_NEG expression ']'
|
|
||||||
{ PEIdent*tmp = $1;
|
|
||||||
tmp->msb_ = $3;
|
|
||||||
tmp->lsb_ = $5;
|
|
||||||
tmp->sel_ = PEIdent::SEL_IDX_DO;
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
delete $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* An identifer followed by an expression list in parentheses is a
|
/* An identifer followed by an expression list in parentheses is a
|
||||||
function call. If a system identifier, then a system function
|
function call. If a system identifier, then a system function
|
||||||
call. */
|
call. */
|
||||||
|
|
||||||
| identifier '(' expression_list_proper ')'
|
| heirarchy_identifier '(' expression_list_proper ')'
|
||||||
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
|
|
@ -1089,7 +1061,7 @@ expr_primary
|
||||||
}
|
}
|
||||||
| SYSTEM_IDENTIFIER '(' expression_list_proper ')'
|
| SYSTEM_IDENTIFIER '(' expression_list_proper ')'
|
||||||
{ perm_string tn = lex_strings.make($1);
|
{ perm_string tn = lex_strings.make($1);
|
||||||
PECallFunction*tmp = new PECallFunction(hname_t(tn), *$3);
|
PECallFunction*tmp = new PECallFunction(tn, *$3);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -1345,36 +1317,58 @@ gatetype
|
||||||
|
|
||||||
/* A general identifier is a hierarchical name, with the right most
|
/* A general identifier is a hierarchical name, with the right most
|
||||||
name the base of the identifier. This rule builds up a
|
name the base of the identifier. This rule builds up a
|
||||||
hierarchical name from left to right, forming a list of names. */
|
hierarchical name from the left to the right, forming a list of
|
||||||
identifier
|
names. */
|
||||||
|
|
||||||
|
heirarchy_identifier
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
{ $$ = new hname_t(lex_strings.make($1));
|
{ $$ = new pform_name_t;
|
||||||
|
$$->push_back(name_component_t(lex_strings.make($1)));
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
| identifier '.' IDENTIFIER
|
| heirarchy_identifier '.' IDENTIFIER
|
||||||
{ hname_t * tmp = $1;
|
{ pform_name_t * tmp = $1;
|
||||||
tmp->append(lex_strings.make($3));
|
tmp->push_back(name_component_t(lex_strings.make($3)));
|
||||||
delete $3;
|
delete $3;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
| heirarchy_identifier '[' expression ']'
|
||||||
|
{ pform_name_t * tmp = $1;
|
||||||
/* An indexed_identifier is an identifier with a bit-select
|
name_component_t&tail = tmp->back();
|
||||||
expression. This bit select may be an array index or bit index,
|
index_component_t itmp;
|
||||||
to be sorted out later. */
|
itmp.sel = index_component_t::SEL_BIT;
|
||||||
indexed_identifier
|
itmp.msb = $3;
|
||||||
: identifier
|
tail.index.push_back(itmp);
|
||||||
{ PEIdent*tmp = new PEIdent(*$1);
|
|
||||||
tmp->sel_ = PEIdent::SEL_NONE;
|
|
||||||
tmp->set_file(@1.text);
|
|
||||||
tmp->set_lineno(@1.first_line);
|
|
||||||
delete $1;
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| indexed_identifier '[' expression ']'
|
| heirarchy_identifier '[' expression ':' expression ']'
|
||||||
{ PEIdent*tmp = $1;
|
{ pform_name_t * tmp = $1;
|
||||||
tmp->sel_ = PEIdent::SEL_NONE;
|
name_component_t&tail = tmp->back();
|
||||||
tmp->idx_.push_back($3);
|
index_component_t itmp;
|
||||||
|
itmp.sel = index_component_t::SEL_PART;
|
||||||
|
itmp.msb = $3;
|
||||||
|
itmp.lsb = $5;
|
||||||
|
tail.index.push_back(itmp);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| heirarchy_identifier '[' expression K_PO_POS expression ']'
|
||||||
|
{ pform_name_t * tmp = $1;
|
||||||
|
name_component_t&tail = tmp->back();
|
||||||
|
index_component_t itmp;
|
||||||
|
itmp.sel = index_component_t::SEL_IDX_UP;
|
||||||
|
itmp.msb = $3;
|
||||||
|
itmp.lsb = $5;
|
||||||
|
tail.index.push_back(itmp);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| heirarchy_identifier '[' expression K_PO_NEG expression ']'
|
||||||
|
{ pform_name_t * tmp = $1;
|
||||||
|
name_component_t&tail = tmp->back();
|
||||||
|
index_component_t itmp;
|
||||||
|
itmp.sel = index_component_t::SEL_IDX_DO;
|
||||||
|
itmp.msb = $3;
|
||||||
|
itmp.lsb = $5;
|
||||||
|
tail.index.push_back(itmp);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -1552,30 +1546,12 @@ signed_opt : K_signed { $$ = true; } | {$$ = false; } ;
|
||||||
assignments. It is more limited then the general expr_primary
|
assignments. It is more limited then the general expr_primary
|
||||||
rule to reflect the rules for assignment l-values. */
|
rule to reflect the rules for assignment l-values. */
|
||||||
lpvalue
|
lpvalue
|
||||||
: indexed_identifier
|
: heirarchy_identifier
|
||||||
{ PEIdent*tmp = $1;
|
{ PEIdent*tmp = new PEIdent(*$1);
|
||||||
$$ = tmp;
|
tmp->set_file(@1.text);
|
||||||
}
|
tmp->set_lineno(@1.first_line);
|
||||||
| indexed_identifier '[' expression ':' expression ']'
|
|
||||||
{ PEIdent*tmp = $1;
|
|
||||||
tmp->msb_ = $3;
|
|
||||||
tmp->lsb_ = $5;
|
|
||||||
tmp->sel_ = PEIdent::SEL_PART;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| indexed_identifier '[' expression K_PO_POS expression ']'
|
|
||||||
{ PEIdent*tmp = $1;
|
|
||||||
tmp->msb_ = $3;
|
|
||||||
tmp->lsb_ = $5;
|
|
||||||
tmp->sel_ = PEIdent::SEL_IDX_UP;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| indexed_identifier '[' expression K_PO_NEG expression ']'
|
|
||||||
{ PEIdent*tmp = $1;
|
|
||||||
tmp->msb_ = $3;
|
|
||||||
tmp->lsb_ = $5;
|
|
||||||
tmp->sel_ = PEIdent::SEL_IDX_DO;
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
delete $1;
|
||||||
}
|
}
|
||||||
| '{' expression_list_proper '}'
|
| '{' expression_list_proper '}'
|
||||||
{ PEConcat*tmp = new PEConcat(*$2);
|
{ PEConcat*tmp = new PEConcat(*$2);
|
||||||
|
|
@ -2308,17 +2284,13 @@ port_reference
|
||||||
|
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
{ Module::port_t*ptmp;
|
{ Module::port_t*ptmp;
|
||||||
ptmp = pform_module_port_reference($1, @1.text,
|
ptmp = pform_module_port_reference($1, @1.text, @1.first_line);
|
||||||
@1.first_line);
|
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| IDENTIFIER '[' expression ':' expression ']'
|
| IDENTIFIER '[' expression ':' expression ']'
|
||||||
{ PEIdent*wtmp = new PEIdent(hname_t(lex_strings.make($1)));
|
{ if (!pform_expression_is_constant($3)) {
|
||||||
wtmp->set_file(@1.text);
|
|
||||||
wtmp->set_lineno(@1.first_line);
|
|
||||||
if (!pform_expression_is_constant($3)) {
|
|
||||||
yyerror(@3, "error: msb expression of "
|
yyerror(@3, "error: msb expression of "
|
||||||
"port part select must be constant.");
|
"port part select must be constant.");
|
||||||
}
|
}
|
||||||
|
|
@ -2326,26 +2298,50 @@ port_reference
|
||||||
yyerror(@5, "error: lsb expression of "
|
yyerror(@5, "error: lsb expression of "
|
||||||
"port part select must be constant.");
|
"port part select must be constant.");
|
||||||
}
|
}
|
||||||
wtmp->msb_ = $3;
|
index_component_t itmp;
|
||||||
wtmp->lsb_ = $5;
|
itmp.sel = index_component_t::SEL_PART;
|
||||||
wtmp->sel_ = PEIdent::SEL_PART;
|
itmp.msb = $3;
|
||||||
|
itmp.lsb = $5;
|
||||||
|
|
||||||
|
name_component_t ntmp (lex_strings.make($1));
|
||||||
|
ntmp.index.push_back(itmp);
|
||||||
|
|
||||||
|
pform_name_t pname;
|
||||||
|
pname.push_back(ntmp);
|
||||||
|
|
||||||
|
PEIdent*wtmp = new PEIdent(pname);
|
||||||
|
wtmp->set_file(@1.text);
|
||||||
|
wtmp->set_lineno(@1.first_line);
|
||||||
|
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
ptmp->name = perm_string();
|
ptmp->name = perm_string();
|
||||||
ptmp->expr = svector<PEIdent*>(1);
|
ptmp->expr = svector<PEIdent*>(1);
|
||||||
ptmp->expr[0] = wtmp;
|
ptmp->expr[0] = wtmp;
|
||||||
|
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| IDENTIFIER '[' expression ']'
|
| IDENTIFIER '[' expression ']'
|
||||||
{ PEIdent*tmp = new PEIdent(hname_t(lex_strings.make($1)));
|
{ if (!pform_expression_is_constant($3)) {
|
||||||
tmp->set_file(@1.text);
|
|
||||||
tmp->set_lineno(@1.first_line);
|
|
||||||
if (!pform_expression_is_constant($3)) {
|
|
||||||
yyerror(@3, "error: port bit select "
|
yyerror(@3, "error: port bit select "
|
||||||
"must be constant.");
|
"must be constant.");
|
||||||
}
|
}
|
||||||
tmp->msb_ = $3;
|
index_component_t itmp;
|
||||||
|
itmp.sel = index_component_t::SEL_BIT;
|
||||||
|
itmp.msb = $3;
|
||||||
|
itmp.lsb = 0;
|
||||||
|
|
||||||
|
name_component_t ntmp (lex_strings.make($1));
|
||||||
|
ntmp.index.push_back(itmp);
|
||||||
|
|
||||||
|
pform_name_t pname;
|
||||||
|
pname.push_back(ntmp);
|
||||||
|
|
||||||
|
PEIdent*tmp = new PEIdent(pname);
|
||||||
|
tmp->set_file(@1.text);
|
||||||
|
tmp->set_lineno(@1.first_line);
|
||||||
|
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
ptmp->name = perm_string();
|
ptmp->name = perm_string();
|
||||||
ptmp->expr = svector<PEIdent*>(1);
|
ptmp->expr = svector<PEIdent*>(1);
|
||||||
|
|
@ -2357,7 +2353,7 @@ port_reference
|
||||||
| IDENTIFIER '[' error ']'
|
| IDENTIFIER '[' error ']'
|
||||||
{ yyerror(@1, "error: invalid port bit select");
|
{ yyerror(@1, "error: invalid port bit select");
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
PEIdent*wtmp = new PEIdent(hname_t(lex_strings.make($1)));
|
PEIdent*wtmp = new PEIdent(lex_strings.make($1));
|
||||||
wtmp->set_file(@1.text);
|
wtmp->set_file(@1.text);
|
||||||
wtmp->set_lineno(@1.first_line);
|
wtmp->set_lineno(@1.first_line);
|
||||||
ptmp->name = lex_strings.make($1);
|
ptmp->name = lex_strings.make($1);
|
||||||
|
|
@ -2791,16 +2787,12 @@ spec_notifier_opt
|
||||||
spec_notifier
|
spec_notifier
|
||||||
: ','
|
: ','
|
||||||
{ }
|
{ }
|
||||||
| ',' identifier
|
| ',' heirarchy_identifier
|
||||||
{ delete $2; }
|
{ delete $2; }
|
||||||
| spec_notifier ','
|
| spec_notifier ','
|
||||||
{ }
|
{ }
|
||||||
| spec_notifier ',' identifier
|
| spec_notifier ',' heirarchy_identifier
|
||||||
{ delete $3; }
|
{ delete $3; }
|
||||||
| spec_notifier ',' identifier '[' expr_primary ']'
|
|
||||||
{ delete $3;
|
|
||||||
delete $5;
|
|
||||||
}
|
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{ delete $1; }
|
{ delete $1; }
|
||||||
;
|
;
|
||||||
|
|
@ -2917,14 +2909,14 @@ statement
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_disable identifier ';'
|
| K_disable heirarchy_identifier ';'
|
||||||
{ PDisable*tmp = new PDisable(*$2);
|
{ PDisable*tmp = new PDisable(*$2);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_TRIGGER identifier ';'
|
| K_TRIGGER heirarchy_identifier ';'
|
||||||
{ PTrigger*tmp = new PTrigger(*$2);
|
{ PTrigger*tmp = new PTrigger(*$2);
|
||||||
tmp->set_file(@2.text);
|
tmp->set_file(@2.text);
|
||||||
tmp->set_lineno(@2.first_line);
|
tmp->set_lineno(@2.first_line);
|
||||||
|
|
@ -3132,7 +3124,7 @@ statement
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| SYSTEM_IDENTIFIER '(' expression_list_with_nuls ')' ';'
|
| SYSTEM_IDENTIFIER '(' expression_list_with_nuls ')' ';'
|
||||||
{ PCallTask*tmp = new PCallTask(hname_t(lex_strings.make($1)), *$3);
|
{ PCallTask*tmp = new PCallTask(lex_strings.make($1), *$3);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
delete $1;
|
delete $1;
|
||||||
|
|
@ -3141,13 +3133,13 @@ statement
|
||||||
}
|
}
|
||||||
| SYSTEM_IDENTIFIER ';'
|
| SYSTEM_IDENTIFIER ';'
|
||||||
{ svector<PExpr*>pt (0);
|
{ svector<PExpr*>pt (0);
|
||||||
PCallTask*tmp = new PCallTask(hname_t(lex_strings.make($1)), pt);
|
PCallTask*tmp = new PCallTask(lex_strings.make($1), pt);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| identifier '(' expression_list_proper ')' ';'
|
| heirarchy_identifier '(' expression_list_proper ')' ';'
|
||||||
{ PCallTask*tmp = new PCallTask(*$1, *$3);
|
{ PCallTask*tmp = new PCallTask(*$1, *$3);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
|
|
@ -3160,7 +3152,7 @@ statement
|
||||||
between parentheses, but it seems natural, and people commonly
|
between parentheses, but it seems natural, and people commonly
|
||||||
want it. So accept it explicitly. */
|
want it. So accept it explicitly. */
|
||||||
|
|
||||||
| identifier '(' ')' ';'
|
| heirarchy_identifier '(' ')' ';'
|
||||||
{ svector<PExpr*>pt (0);
|
{ svector<PExpr*>pt (0);
|
||||||
PCallTask*tmp = new PCallTask(*$1, pt);
|
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
|
|
@ -3168,7 +3160,7 @@ statement
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| identifier ';'
|
| heirarchy_identifier ';'
|
||||||
{ svector<PExpr*>pt (0);
|
{ svector<PExpr*>pt (0);
|
||||||
PCallTask*tmp = new PCallTask(*$1, pt);
|
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
|
|
@ -3523,7 +3515,7 @@ udp_sequ_entry
|
||||||
udp_initial
|
udp_initial
|
||||||
: K_initial IDENTIFIER '=' number ';'
|
: K_initial IDENTIFIER '=' number ';'
|
||||||
{ PExpr*etmp = new PENumber($4);
|
{ PExpr*etmp = new PENumber($4);
|
||||||
PEIdent*itmp = new PEIdent(hname_t(lex_strings.make($2)));
|
PEIdent*itmp = new PEIdent(lex_strings.make($2));
|
||||||
PAssign*atmp = new PAssign(itmp, etmp);
|
PAssign*atmp = new PAssign(itmp, etmp);
|
||||||
atmp->set_file(@2.text);
|
atmp->set_file(@2.text);
|
||||||
atmp->set_lineno(@2.first_line);
|
atmp->set_lineno(@2.first_line);
|
||||||
|
|
@ -3588,34 +3580,34 @@ udp_output_sym
|
||||||
| '-' { $$ = '-'; }
|
| '-' { $$ = '-'; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* Port declarations create wires for the inputs and the output. The
|
||||||
|
makes for these ports are scoped within the UDP, so there is no
|
||||||
|
heirarchy involved. */
|
||||||
udp_port_decl
|
udp_port_decl
|
||||||
: K_input list_of_identifiers ';'
|
: K_input list_of_identifiers ';'
|
||||||
{ $$ = pform_make_udp_input_ports($2); }
|
{ $$ = pform_make_udp_input_ports($2); }
|
||||||
| K_output IDENTIFIER ';'
|
| K_output IDENTIFIER ';'
|
||||||
{ PWire*pp = new PWire(lex_strings.make($2),
|
{ pform_name_t pname;
|
||||||
NetNet::IMPLICIT,
|
pname.push_back(lex_strings.make($2));
|
||||||
NetNet::POUTPUT,
|
PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||||
IVL_VT_LOGIC);
|
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
(*tmp)[0] = pp;
|
(*tmp)[0] = pp;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
| K_reg IDENTIFIER ';'
|
| K_reg IDENTIFIER ';'
|
||||||
{ PWire*pp = new PWire(lex_strings.make($2),
|
{ pform_name_t pname;
|
||||||
NetNet::REG,
|
pname.push_back(lex_strings.make($2));
|
||||||
NetNet::PIMPLICIT,
|
PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
||||||
IVL_VT_LOGIC);
|
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
(*tmp)[0] = pp;
|
(*tmp)[0] = pp;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
| K_reg K_output IDENTIFIER ';'
|
| K_reg K_output IDENTIFIER ';'
|
||||||
{ PWire*pp = new PWire(lex_strings.make($3),
|
{ pform_name_t pname;
|
||||||
NetNet::REG,
|
pname.push_back(lex_strings.make($3));
|
||||||
NetNet::POUTPUT,
|
PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||||
IVL_VT_LOGIC);
|
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
(*tmp)[0] = pp;
|
(*tmp)[0] = pp;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
|
||||||
76
pform.cc
76
pform.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2004 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform.cc,v 1.145 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: pform.cc,v 1.146 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
# include <stack>
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
|
|
||||||
|
|
@ -80,34 +81,34 @@ static unsigned pform_timescale_line = 0;
|
||||||
* and named blocks causes scope to be pushed and popped. The module
|
* and named blocks causes scope to be pushed and popped. The module
|
||||||
* name is not included in this scope stack.
|
* name is not included in this scope stack.
|
||||||
*
|
*
|
||||||
* The hier_name function, therefore, converts the name to the scope
|
* The hier_name function, therefore, converts the name to the scoped
|
||||||
* of the module currently in progress.
|
* name within the module currently in progress. It never includes an
|
||||||
|
* instance name.
|
||||||
*
|
*
|
||||||
* The scope stack does not include any scope created by a generate
|
* The scope stack does not include any scope created by a generate
|
||||||
* scheme.
|
* scheme.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static hname_t scope_stack;
|
static pform_name_t scope_stack;
|
||||||
|
|
||||||
void pform_push_scope(char*name)
|
void pform_push_scope(char*name)
|
||||||
{
|
{
|
||||||
scope_stack.append(lex_strings.make(name));
|
scope_stack.push_back(name_component_t(lex_strings.make(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_pop_scope()
|
void pform_pop_scope()
|
||||||
{
|
{
|
||||||
perm_string tmp = scope_stack.remove_tail_name();
|
scope_stack.pop_back();
|
||||||
assert(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static hname_t hier_name(const char*tail)
|
static pform_name_t hier_name(const char*tail)
|
||||||
{
|
{
|
||||||
hname_t name = scope_stack;
|
pform_name_t name = scope_stack;
|
||||||
name.append(lex_strings.make(tail));
|
name.push_back(name_component_t(lex_strings.make(tail)));
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PWire*get_wire_in_module(const hname_t&name)
|
static PWire*get_wire_in_module(const pform_name_t&name)
|
||||||
{
|
{
|
||||||
/* Note that if we are processing a generate, then the
|
/* Note that if we are processing a generate, then the
|
||||||
scope depth will be empty because generate schemes
|
scope depth will be empty because generate schemes
|
||||||
|
|
@ -277,7 +278,7 @@ Module::port_t* pform_module_port_reference(char*name,
|
||||||
unsigned lineno)
|
unsigned lineno)
|
||||||
{
|
{
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
PEIdent*tmp = new PEIdent(hname_t(lex_strings.make(name)));
|
PEIdent*tmp = new PEIdent(lex_strings.make(name));
|
||||||
tmp->set_file(file);
|
tmp->set_file(file);
|
||||||
tmp->set_lineno(lineno);
|
tmp->set_lineno(lineno);
|
||||||
ptmp->name = lex_strings.make(name);
|
ptmp->name = lex_strings.make(name);
|
||||||
|
|
@ -511,9 +512,10 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
||||||
map<string,PWire*> defs;
|
map<string,PWire*> defs;
|
||||||
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
|
||||||
|
|
||||||
hname_t pname = (*decl)[idx]->path();
|
pform_name_t pname = (*decl)[idx]->path();
|
||||||
|
string port_name = peek_tail_name(pname).str();
|
||||||
|
|
||||||
if (PWire*cur = defs[pname.peek_name(0).str()]) {
|
if (PWire*cur = defs[port_name]) {
|
||||||
bool rc = true;
|
bool rc = true;
|
||||||
assert((*decl)[idx]);
|
assert((*decl)[idx]);
|
||||||
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
|
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
|
||||||
|
|
@ -526,7 +528,7 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
defs[pname.peek_name(0).str()] = (*decl)[idx];
|
defs[port_name] = (*decl)[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -672,7 +674,7 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
||||||
|
|
||||||
// Make the port list for the UDP
|
// Make the port list for the UDP
|
||||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
||||||
udp->ports[idx] = pins[idx]->path().peek_name(0);
|
udp->ports[idx] = peek_tail_name(pins[idx]->path());
|
||||||
|
|
||||||
process_udp_table(udp, table, file, lineno);
|
process_udp_table(udp, table, file, lineno);
|
||||||
udp->initial = init;
|
udp->initial = init;
|
||||||
|
|
@ -756,7 +758,7 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
||||||
|
|
||||||
// Make the port list for the UDP
|
// Make the port list for the UDP
|
||||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
||||||
udp->ports[idx] = pins[idx]->path().peek_name(0);
|
udp->ports[idx] = peek_tail_name(pins[idx]->path());
|
||||||
|
|
||||||
assert(udp);
|
assert(udp);
|
||||||
assert(table);
|
assert(table);
|
||||||
|
|
@ -1090,7 +1092,7 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
|
||||||
void pform_make_reginit(const struct vlltype&li,
|
void pform_make_reginit(const struct vlltype&li,
|
||||||
const char*name, PExpr*expr)
|
const char*name, PExpr*expr)
|
||||||
{
|
{
|
||||||
const hname_t sname = hier_name(name);
|
const pform_name_t sname = hier_name(name);
|
||||||
PWire*cur = pform_cur_module->get_wire(sname);
|
PWire*cur = pform_cur_module->get_wire(sname);
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
VLerror(li, "internal error: reginit to non-register?");
|
VLerror(li, "internal error: reginit to non-register?");
|
||||||
|
|
@ -1129,11 +1131,11 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
svector<named_pexpr_t*>*attr)
|
svector<named_pexpr_t*>*attr)
|
||||||
{
|
{
|
||||||
hname_t name = hier_name(nm);
|
pform_name_t name = hier_name(nm);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
PWire*cur = pform_cur_module->get_wire(name);
|
||||||
if (cur) {
|
if (cur) {
|
||||||
ostringstream msg;
|
ostringstream msg;
|
||||||
msg << name << " definition conflicts with "
|
msg << nm << " definition conflicts with "
|
||||||
<< "definition at " << cur->get_line()
|
<< "definition at " << cur->get_line()
|
||||||
<< ".";
|
<< ".";
|
||||||
VLerror(msg.str().c_str());
|
VLerror(msg.str().c_str());
|
||||||
|
|
@ -1196,7 +1198,7 @@ void pform_makewire(const vlltype&li, const char*nm,
|
||||||
ivl_variable_type_t dt,
|
ivl_variable_type_t dt,
|
||||||
svector<named_pexpr_t*>*attr)
|
svector<named_pexpr_t*>*attr)
|
||||||
{
|
{
|
||||||
hname_t name = hier_name(nm);
|
pform_name_t name = hier_name(nm);
|
||||||
|
|
||||||
PWire*cur = get_wire_in_module(name);
|
PWire*cur = get_wire_in_module(name);
|
||||||
|
|
||||||
|
|
@ -1206,7 +1208,7 @@ void pform_makewire(const vlltype&li, const char*nm,
|
||||||
bool rc = cur->set_wire_type(type);
|
bool rc = cur->set_wire_type(type);
|
||||||
if (rc == false) {
|
if (rc == false) {
|
||||||
ostringstream msg;
|
ostringstream msg;
|
||||||
msg << name << " definition conflicts with "
|
msg << nm << " definition conflicts with "
|
||||||
<< "definition at " << cur->get_line()
|
<< "definition at " << cur->get_line()
|
||||||
<< ".";
|
<< ".";
|
||||||
VLerror(msg.str().c_str());
|
VLerror(msg.str().c_str());
|
||||||
|
|
@ -1286,10 +1288,10 @@ void pform_makewire(const vlltype&li,
|
||||||
pform_set_net_range(first->name, range, signed_flag, dt);
|
pform_set_net_range(first->name, range, signed_flag, dt);
|
||||||
|
|
||||||
perm_string first_name = lex_strings.make(first->name);
|
perm_string first_name = lex_strings.make(first->name);
|
||||||
hname_t name = hier_name(first_name);
|
pform_name_t name = hier_name(first_name);
|
||||||
PWire*cur = get_wire_in_module(name);
|
PWire*cur = get_wire_in_module(name);
|
||||||
if (cur != 0) {
|
if (cur != 0) {
|
||||||
PEIdent*lval = new PEIdent(hname_t(first_name));
|
PEIdent*lval = new PEIdent(first_name);
|
||||||
lval->set_file(li.text);
|
lval->set_file(li.text);
|
||||||
lval->set_lineno(li.first_line);
|
lval->set_lineno(li.first_line);
|
||||||
PGAssign*ass = pform_make_pgassign(lval, first->expr,
|
PGAssign*ass = pform_make_pgassign(lval, first->expr,
|
||||||
|
|
@ -1307,7 +1309,7 @@ void pform_makewire(const vlltype&li,
|
||||||
void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
||||||
const char*file, unsigned lineno)
|
const char*file, unsigned lineno)
|
||||||
{
|
{
|
||||||
hname_t name = hier_name(nm);
|
pform_name_t name = hier_name(nm);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
PWire*cur = pform_cur_module->get_wire(name);
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
||||||
|
|
@ -1324,14 +1326,14 @@ void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
||||||
|
|
||||||
case NetNet::NOT_A_PORT:
|
case NetNet::NOT_A_PORT:
|
||||||
cerr << file << ":" << lineno << ": error: "
|
cerr << file << ":" << lineno << ": error: "
|
||||||
<< "port " << name << " is not in the port list."
|
<< "port " << nm << " is not in the port list."
|
||||||
<< endl;
|
<< endl;
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cerr << file << ":" << lineno << ": error: "
|
cerr << file << ":" << lineno << ": error: "
|
||||||
<< "port " << name << " already has a port declaration."
|
<< "port " << nm << " already has a port declaration."
|
||||||
<< endl;
|
<< endl;
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1392,7 +1394,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
; cur != names->end() ; cur ++ ) {
|
; cur != names->end() ; cur ++ ) {
|
||||||
|
|
||||||
perm_string txt = *cur;
|
perm_string txt = *cur;
|
||||||
hname_t name = hier_name(txt);
|
pform_name_t name = hier_name(txt);
|
||||||
|
|
||||||
/* Look for a preexisting wire. If it exists, set the
|
/* Look for a preexisting wire. If it exists, set the
|
||||||
port direction. If not, create it. */
|
port direction. If not, create it. */
|
||||||
|
|
@ -1437,7 +1439,7 @@ void pform_set_function(perm_string name, PFunction*func)
|
||||||
|
|
||||||
void pform_set_attrib(perm_string name, perm_string key, char*value)
|
void pform_set_attrib(perm_string name, perm_string key, char*value)
|
||||||
{
|
{
|
||||||
hname_t path (name);
|
pform_name_t path = hier_name(name);
|
||||||
|
|
||||||
if (PWire*cur = pform_cur_module->get_wire(path)) {
|
if (PWire*cur = pform_cur_module->get_wire(path)) {
|
||||||
cur->attributes[key] = new PEString(value);
|
cur->attributes[key] = new PEString(value);
|
||||||
|
|
@ -1530,7 +1532,7 @@ void pform_set_specparam(perm_string name, PExpr*expr)
|
||||||
pform_cur_module->specparams[name] = expr;
|
pform_cur_module->specparams[name] = expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_defparam(const hname_t&name, PExpr*expr)
|
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
|
||||||
{
|
{
|
||||||
assert(expr);
|
assert(expr);
|
||||||
pform_cur_module->defparms[name] = expr;
|
pform_cur_module->defparms[name] = expr;
|
||||||
|
|
@ -1624,7 +1626,7 @@ void pform_set_port_type(const struct vlltype&li,
|
||||||
|
|
||||||
static void pform_set_reg_integer(const char*nm)
|
static void pform_set_reg_integer(const char*nm)
|
||||||
{
|
{
|
||||||
hname_t name = hier_name(nm);
|
pform_name_t name = hier_name(nm);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
PWire*cur = pform_cur_module->get_wire(name);
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, NetNet::INTEGER,
|
cur = new PWire(name, NetNet::INTEGER,
|
||||||
|
|
@ -1658,7 +1660,7 @@ void pform_set_reg_integer(list<perm_string>*names)
|
||||||
|
|
||||||
static void pform_set_reg_time(const char*nm)
|
static void pform_set_reg_time(const char*nm)
|
||||||
{
|
{
|
||||||
hname_t name = hier_name(nm);
|
pform_name_t name = hier_name(nm);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
PWire*cur = pform_cur_module->get_wire(name);
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||||
|
|
@ -1695,7 +1697,9 @@ svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
|
||||||
; cur != names->end()
|
; cur != names->end()
|
||||||
; cur ++ ) {
|
; cur ++ ) {
|
||||||
perm_string txt = *cur;
|
perm_string txt = *cur;
|
||||||
PWire*pp = new PWire(hname_t(txt),
|
pform_name_t tmp;
|
||||||
|
tmp.push_back(name_component_t(txt));
|
||||||
|
PWire*pp = new PWire(tmp,
|
||||||
NetNet::IMPLICIT,
|
NetNet::IMPLICIT,
|
||||||
NetNet::PINPUT,
|
NetNet::PINPUT,
|
||||||
IVL_VT_LOGIC);
|
IVL_VT_LOGIC);
|
||||||
|
|
@ -1769,6 +1773,10 @@ int pform_parse(const char*path, FILE*file)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.cc,v $
|
* $Log: pform.cc,v $
|
||||||
|
* Revision 1.146 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.145 2007/04/26 03:06:22 steve
|
* Revision 1.145 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
8
pform.h
8
pform.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform.h,v 1.90 2007/04/19 02:52:53 steve Exp $"
|
#ident "$Id: pform.h,v 1.91 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -261,7 +261,7 @@ extern void pform_set_localparam(perm_string name,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
PExpr*expr);
|
PExpr*expr);
|
||||||
extern void pform_set_defparam(const hname_t&name, PExpr*expr);
|
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions related to specify blocks.
|
* Functions related to specify blocks.
|
||||||
|
|
@ -340,6 +340,10 @@ extern void pform_dump(ostream&out, Module*mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.h,v $
|
* $Log: pform.h,v $
|
||||||
|
* Revision 1.91 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.90 2007/04/19 02:52:53 steve
|
* Revision 1.90 2007/04/19 02:52:53 steve
|
||||||
* Add support for -v flag in command file.
|
* Add support for -v flag in command file.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform_dump.cc,v 1.97 2007/03/07 00:38:15 steve Exp $"
|
#ident "$Id: pform_dump.cc,v 1.98 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -72,6 +72,58 @@ ostream& operator<< (ostream&o, PGate::strength_t str)
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ostream& operator<< (ostream&out, perm_string that)
|
||||||
|
{
|
||||||
|
out << that.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& operator<< (ostream&out, const name_component_t&that)
|
||||||
|
{
|
||||||
|
out << that.name.str();
|
||||||
|
|
||||||
|
typedef std::list<index_component_t>::const_iterator index_it_t;
|
||||||
|
for (index_it_t idx = that.index.begin()
|
||||||
|
; idx != that.index.end() ; idx++) {
|
||||||
|
|
||||||
|
out << "[";
|
||||||
|
switch ((*idx).sel) {
|
||||||
|
case index_component_t::SEL_BIT:
|
||||||
|
out << *(*idx).msb;
|
||||||
|
break;
|
||||||
|
case index_component_t::SEL_PART:
|
||||||
|
out << *(*idx).msb << ":" << *(*idx).lsb;
|
||||||
|
break;
|
||||||
|
case index_component_t::SEL_IDX_UP:
|
||||||
|
out << *(*idx).msb << "+:" << *(*idx).lsb;
|
||||||
|
break;
|
||||||
|
case index_component_t::SEL_IDX_DO:
|
||||||
|
out << *(*idx).msb << "-:" << *(*idx).lsb;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out << "???";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out << "]";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& operator<< (ostream&o, const pform_name_t&that)
|
||||||
|
{
|
||||||
|
pform_name_t::const_iterator cur;
|
||||||
|
|
||||||
|
cur = that.begin();
|
||||||
|
o << *cur;
|
||||||
|
|
||||||
|
cur++;
|
||||||
|
while (cur != that.end()) {
|
||||||
|
o << "." << *cur;
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
void PExpr::dump(ostream&out) const
|
void PExpr::dump(ostream&out) const
|
||||||
{
|
{
|
||||||
out << typeid(*this).name();
|
out << typeid(*this).name();
|
||||||
|
|
@ -145,29 +197,6 @@ void PENumber::dump(ostream&out) const
|
||||||
void PEIdent::dump(ostream&out) const
|
void PEIdent::dump(ostream&out) const
|
||||||
{
|
{
|
||||||
out << path_;
|
out << path_;
|
||||||
if (msb_) {
|
|
||||||
out << "[" << *msb_;
|
|
||||||
if (lsb_) switch (sel_) {
|
|
||||||
case SEL_IDX_UP:
|
|
||||||
out << "+:" << *lsb_;
|
|
||||||
break;
|
|
||||||
case SEL_IDX_DO:
|
|
||||||
out << "-:" << *lsb_;
|
|
||||||
break;
|
|
||||||
case SEL_PART:
|
|
||||||
out << ":" << *lsb_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
out << ":?:" << *lsb_;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef std::vector<PExpr*>::const_iterator vector_it_t;
|
|
||||||
for (vector_it_t cur = idx_.begin() ; cur != idx_.end() ; cur++) {
|
|
||||||
out << "[" << *(*cur) << "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PEString::dump(ostream&out) const
|
void PEString::dump(ostream&out) const
|
||||||
|
|
@ -811,7 +840,7 @@ void PGenerate::dump(ostream&out) const
|
||||||
|
|
||||||
out << endl;
|
out << endl;
|
||||||
|
|
||||||
for (map<hname_t,PWire*>::const_iterator idx = wires.begin()
|
for (map<pform_name_t,PWire*>::const_iterator idx = wires.begin()
|
||||||
; idx != wires.end() ; idx++) {
|
; idx != wires.end() ; idx++) {
|
||||||
|
|
||||||
(*idx).second->dump(out, 6);
|
(*idx).second->dump(out, 6);
|
||||||
|
|
@ -866,7 +895,7 @@ void Module::dump(ostream&out) const
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
|
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
|
||||||
typedef map<hname_t,PExpr*>::const_iterator parm_hiter_t;
|
typedef map<pform_name_t,PExpr*>::const_iterator parm_hiter_t;
|
||||||
for (parm_iter_t cur = parameters.begin()
|
for (parm_iter_t cur = parameters.begin()
|
||||||
; cur != parameters.end() ; cur ++) {
|
; cur != parameters.end() ; cur ++) {
|
||||||
out << " parameter ";
|
out << " parameter ";
|
||||||
|
|
@ -931,7 +960,7 @@ void Module::dump(ostream&out) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through and display all the wires.
|
// Iterate through and display all the wires.
|
||||||
for (map<hname_t,PWire*>::const_iterator wire = wires_.begin()
|
for (map<pform_name_t,PWire*>::const_iterator wire = wires_.begin()
|
||||||
; wire != wires_.end()
|
; wire != wires_.end()
|
||||||
; wire ++ ) {
|
; wire ++ ) {
|
||||||
|
|
||||||
|
|
@ -1032,6 +1061,10 @@ void PUdp::dump(ostream&out) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform_dump.cc,v $
|
* $Log: pform_dump.cc,v $
|
||||||
|
* Revision 1.98 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.97 2007/03/07 00:38:15 steve
|
* Revision 1.97 2007/03/07 00:38:15 steve
|
||||||
* Lint fixes.
|
* Lint fixes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 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
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CVS_IDENT
|
||||||
|
#ident "$Id: pform_types.cc,v 1.1 2007/05/24 04:07:12 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
# include "pform_types.h"
|
||||||
|
|
||||||
|
bool operator < (const name_component_t&lef, const name_component_t&rig)
|
||||||
|
{
|
||||||
|
if (lef.name < rig.name)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
#ifndef __pform_types_H
|
||||||
|
#define __pform_types_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 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
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CVS_IDENT
|
||||||
|
#ident "$Id: pform_types.h,v 1.1 2007/05/24 04:07:12 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This for the perm_string type.
|
||||||
|
# include "StringHeap.h"
|
||||||
|
# include <iostream>
|
||||||
|
# include <list>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse-form types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct index_component_t {
|
||||||
|
enum ctype_t { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO };
|
||||||
|
|
||||||
|
index_component_t() : sel(SEL_NONE), msb(0), lsb(0) { };
|
||||||
|
~index_component_t() { }
|
||||||
|
|
||||||
|
ctype_t sel;
|
||||||
|
class PExpr*msb;
|
||||||
|
class PExpr*lsb;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct name_component_t {
|
||||||
|
name_component_t(perm_string n) : name(n) { }
|
||||||
|
~name_component_t() { }
|
||||||
|
|
||||||
|
perm_string name;
|
||||||
|
std::list<index_component_t>index;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern bool operator < (const name_component_t&lef, const name_component_t&rig);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The pform_name_t is the general form for a heirarchical identifier.
|
||||||
|
*/
|
||||||
|
typedef std::list<name_component_t> pform_name_t;
|
||||||
|
|
||||||
|
inline perm_string peek_head_name(const pform_name_t&that)
|
||||||
|
{
|
||||||
|
return that.front().name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline perm_string peek_tail_name(const pform_name_t&that)
|
||||||
|
{
|
||||||
|
return that.back().name;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern std::ostream& operator<< (std::ostream&o, const pform_name_t&);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: symbol_search.cc,v 1.5 2007/04/26 03:06:22 steve Exp $"
|
#ident "$Id: symbol_search.cc,v 1.6 2007/05/24 04:07:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
/*
|
/*
|
||||||
* Search for the hierarchical name.
|
* Search for the hierarchical name.
|
||||||
*/
|
*/
|
||||||
NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
|
NetScope*symbol_search(const Design*des, NetScope*scope, pform_name_t path,
|
||||||
NetNet*&net,
|
NetNet*&net,
|
||||||
const NetExpr*&par,
|
const NetExpr*&par,
|
||||||
NetEvent*&eve,
|
NetEvent*&eve,
|
||||||
|
|
@ -36,7 +36,8 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
/* Get the tail name of the object we are looking for. */
|
/* Get the tail name of the object we are looking for. */
|
||||||
perm_string key = path.remove_tail_name();
|
perm_string key = peek_tail_name(path);
|
||||||
|
path.pop_back();
|
||||||
|
|
||||||
/* Initialize output argument to cleared. */
|
/* Initialize output argument to cleared. */
|
||||||
net = 0;
|
net = 0;
|
||||||
|
|
@ -45,7 +46,7 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
|
||||||
|
|
||||||
/* If the path has a scope part, then search for the specified
|
/* If the path has a scope part, then search for the specified
|
||||||
scope that we are supposed to search. */
|
scope that we are supposed to search. */
|
||||||
if (path.peek_name(0))
|
if (! path.empty())
|
||||||
scope = des->find_scope(scope, path);
|
scope = des->find_scope(scope, path);
|
||||||
|
|
||||||
while (scope) {
|
while (scope) {
|
||||||
|
|
@ -69,6 +70,10 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: symbol_search.cc,v $
|
* $Log: symbol_search.cc,v $
|
||||||
|
* Revision 1.6 2007/05/24 04:07:12 steve
|
||||||
|
* Rework the heirarchical identifier parse syntax and pform
|
||||||
|
* to handle more general combinations of heirarch and bit selects.
|
||||||
|
*
|
||||||
* Revision 1.5 2007/04/26 03:06:22 steve
|
* Revision 1.5 2007/04/26 03:06:22 steve
|
||||||
* Rework hname_t to use perm_strings.
|
* Rework hname_t to use perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue