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
|
||||
# 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
|
||||
|
|
@ -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_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 \
|
||||
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 \
|
||||
verinum.o verireal.o target.o targets.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
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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())
|
||||
return 0;
|
||||
else
|
||||
|
|
@ -133,11 +133,6 @@ PGate* Module::get_gate(perm_string name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const map<hname_t,PWire*>& Module::get_wires() const
|
||||
{
|
||||
return wires_;
|
||||
}
|
||||
|
||||
const list<PGate*>& Module::get_gates() const
|
||||
{
|
||||
return gates_;
|
||||
|
|
@ -151,6 +146,10 @@ const list<PProcess*>& Module::get_behaviors() const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <list>
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include "netlist.h"
|
||||
# include "pform_types.h"
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
|
|
@ -98,7 +99,7 @@ class Module : public LineInfo {
|
|||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
map<hname_t,PExpr*>defparms;
|
||||
map<pform_name_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
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
|
||||
// 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);
|
||||
|
||||
const map<hname_t,PWire*>& get_wires() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
const list<PProcess*>& get_behaviors() const;
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ class Module : public LineInfo {
|
|||
private:
|
||||
perm_string name_;
|
||||
|
||||
map<hname_t,PWire*> wires_;
|
||||
map<pform_name_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
map<perm_string,PTask*> tasks_;
|
||||
|
|
@ -182,6 +182,10 @@ class Module : public LineInfo {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
: path_(n)
|
||||
static pform_name_t pn_from_ps(perm_string 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;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const hname_t&s)
|
||||
: path_(s), msb_(0), lsb_(0), sel_(SEL_NONE), idx_(0)
|
||||
PEIdent::PEIdent(const pform_name_t&that)
|
||||
: path_(that)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s)
|
||||
{
|
||||
path_.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PEIdent::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
/*
|
||||
* An identifier can be in a constant expression if (and only if) it is
|
||||
* a parameter.
|
||||
*
|
||||
* NOTE: This test does not work if the name is hierarchical!
|
||||
*/
|
||||
bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
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.
|
||||
|
||||
The real fix is to make the path_ carry perm_strings. */
|
||||
perm_string tmp = perm_string::literal(path_.peek_name(0));
|
||||
/* */
|
||||
perm_string tmp = path_.back().name;
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(tmp);
|
||||
|
|
@ -288,6 +300,10 @@ bool PEUnary::is_constant(Module*m) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
# include "netlist.h"
|
||||
# include "verinum.h"
|
||||
# include "LineInfo.h"
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class Module;
|
||||
|
|
@ -247,9 +248,14 @@ class PEFNumber : public PExpr {
|
|||
class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(const hname_t&s);
|
||||
explicit PEIdent(perm_string);
|
||||
explicit PEIdent(const pform_name_t&);
|
||||
~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 unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
|
|
@ -286,7 +292,10 @@ class PEIdent : public PExpr {
|
|||
virtual bool is_constant(Module*) 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:
|
||||
// Common functions to calculate parts of part/bit selects.
|
||||
|
|
@ -332,9 +341,9 @@ class PEIdent : public PExpr {
|
|||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found) const;
|
||||
hname_t path_;
|
||||
|
||||
public:
|
||||
#if 0
|
||||
// Use these to support part-select operators.
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
|
@ -345,6 +354,8 @@ class PEIdent : public PExpr {
|
|||
// expression. If this is a reference to a vector, this is a
|
||||
// bit select.
|
||||
std::vector<PExpr*> idx_;
|
||||
#endif
|
||||
|
||||
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
|
||||
NetNet*sig, unsigned lwidth,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -621,8 +632,10 @@ class PETernary : public PExpr {
|
|||
*/
|
||||
class PECallFunction : public PExpr {
|
||||
public:
|
||||
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const hname_t&n);
|
||||
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
|
||||
// Call of system function (name is not heirarchical)
|
||||
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(perm_string n);
|
||||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
|
|
@ -638,7 +651,7 @@ class PECallFunction : public PExpr {
|
|||
int expr_wid, bool sys_task_arg) const;
|
||||
|
||||
private:
|
||||
hname_t path_;
|
||||
pform_name_t path_;
|
||||
svector<PExpr *> parms_;
|
||||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
|
@ -655,6 +668,10 @@ class PECallFunction : public PExpr {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "PGenerate.h"
|
||||
|
|
@ -42,9 +42,9 @@ PWire* PGenerate::add_wire(PWire*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())
|
||||
return 0;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
# include "HName.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
|
|
@ -59,9 +60,9 @@ class PGenerate : public LineInfo {
|
|||
PExpr*loop_test;
|
||||
PExpr*loop_step;
|
||||
|
||||
map<hname_t,PWire*>wires;
|
||||
map<pform_name_t,PWire*>wires;
|
||||
PWire* add_wire(PWire*);
|
||||
PWire* get_wire(const hname_t&name) const;
|
||||
PWire* get_wire(const pform_name_t&name) const;
|
||||
|
||||
list<PGate*> gates;
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const hname_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,
|
||||
PWire::PWire(const pform_name_t&n,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt)
|
||||
|
|
@ -59,7 +44,7 @@ NetNet::Type PWire::get_wire_type() const
|
|||
return type_;
|
||||
}
|
||||
|
||||
const hname_t& PWire::path() const
|
||||
const pform_name_t& PWire::path() const
|
||||
{
|
||||
return hname_;
|
||||
}
|
||||
|
|
@ -160,6 +145,10 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -43,24 +43,21 @@ class Design;
|
|||
* identifies a port by keeping it in its port list.
|
||||
*
|
||||
* The hname parameter to the constructor is a hierarchical name. It
|
||||
* is an array of strings starting with the root, running towards
|
||||
* the base name, and terminated by a null pointer. The environment
|
||||
* allocates the memory for me.
|
||||
* is the name of the wire within a module, so does not include the
|
||||
* current scope or any instances. Modules contain all the wires, so
|
||||
* from that perspective, sub-scopes within the module are a part of
|
||||
* the wire name.
|
||||
*/
|
||||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(const hname_t&hname,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt);
|
||||
PWire(perm_string name,
|
||||
PWire(const pform_name_t&hname,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt);
|
||||
|
||||
// Return a hierarchical name.
|
||||
const hname_t&path() const;
|
||||
const pform_name_t&path() const;
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
|
|
@ -84,10 +81,10 @@ class PWire : public LineInfo {
|
|||
// Write myself to the specified stream.
|
||||
void dump(ostream&out, unsigned ind=4) const;
|
||||
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
hname_t hname_;
|
||||
pform_name_t hname_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
ivl_variable_type_t data_type_;
|
||||
|
|
@ -111,6 +108,10 @@ class PWire : public LineInfo {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -107,16 +107,22 @@ PBlock::~PBlock()
|
|||
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)
|
||||
{
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
|
||||
: parms_(p)
|
||||
{
|
||||
path_.push_back(name_component_t(n));
|
||||
}
|
||||
|
||||
PCallTask::~PCallTask()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PCallTask::path() const
|
||||
const pform_name_t& PCallTask::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
|
@ -178,7 +184,7 @@ PDelayStatement::~PDelayStatement()
|
|||
{
|
||||
}
|
||||
|
||||
PDisable::PDisable(const hname_t&sc)
|
||||
PDisable::PDisable(const pform_name_t&sc)
|
||||
: scope_(sc)
|
||||
{
|
||||
}
|
||||
|
|
@ -273,7 +279,7 @@ PRepeat::~PRepeat()
|
|||
delete statement_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const hname_t&e)
|
||||
PTrigger::PTrigger(const pform_name_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
|
|
@ -295,6 +301,10 @@ PWhile::~PWhile()
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -173,10 +173,11 @@ class PBlock : public Statement {
|
|||
class PCallTask : public Statement {
|
||||
|
||||
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();
|
||||
|
||||
const hname_t& path() const;
|
||||
const pform_name_t& path() const;
|
||||
|
||||
unsigned nparms() const { return parms_.count(); }
|
||||
|
||||
|
|
@ -197,7 +198,7 @@ class PCallTask : public Statement {
|
|||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
hname_t path_;
|
||||
pform_name_t path_;
|
||||
svector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
|
|
@ -296,14 +297,14 @@ class PDelayStatement : public Statement {
|
|||
class PDisable : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDisable(const hname_t&sc);
|
||||
explicit PDisable(const pform_name_t&sc);
|
||||
~PDisable();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
hname_t scope_;
|
||||
pform_name_t scope_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -433,14 +434,14 @@ class PRelease : public Statement {
|
|||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(const hname_t&ev);
|
||||
explicit PTrigger(const pform_name_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
hname_t event_;
|
||||
pform_name_t event_;
|
||||
};
|
||||
|
||||
class PWhile : public Statement {
|
||||
|
|
@ -460,6 +461,10 @@ class PWhile : public Statement {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle processes within generate loops.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -871,7 +871,7 @@ void NetScope::dump(ostream&o) const
|
|||
|
||||
/* 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()
|
||||
; pp != defparams.end() ; pp ++ ) {
|
||||
o << " defparam " << (*pp).first << " = " <<
|
||||
|
|
@ -1205,6 +1205,10 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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
|
||||
and makes it into a signed expression. No bits are changed,
|
||||
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)) {
|
||||
cerr << get_line() << ": error: The $signed() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
|
|
@ -336,7 +336,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
|||
return sub;
|
||||
}
|
||||
/* 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)) {
|
||||
cerr << get_line() << ": error: The $unsigned() function "
|
||||
<< "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
|
||||
sub-expression is not used, so the expression itself can be
|
||||
deleted. */
|
||||
if ((strcmp(path_.peek_name(0), "$sizeof") == 0)
|
||||
|| (strcmp(path_.peek_name(0), "$bits") == 0)) {
|
||||
if ((strcmp(peek_tail_name(path_), "$sizeof") == 0)
|
||||
|| (strcmp(peek_tail_name(path_), "$bits") == 0)) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $bits() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
|
|
@ -363,7 +363,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
|||
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."
|
||||
<< " 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
|
||||
otherwise. The subexpression is elaborated but not
|
||||
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)) {
|
||||
cerr << get_line() << ": error: The $is_signed() function "
|
||||
<< "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
|
||||
in the sfunc_table. */
|
||||
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;
|
||||
unsigned wid = sfunc_info->wid;
|
||||
|
|
@ -423,7 +423,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
|||
if ((nparms == 1) && (parms_[0] == 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);
|
||||
if (sfunc_info->signed_flag)
|
||||
fun->cast_signed(true);
|
||||
|
|
@ -455,7 +455,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
|||
|
||||
if (missing_parms > 0) {
|
||||
cerr << get_line() << ": error: The function "
|
||||
<< path_.peek_name(0)
|
||||
<< peek_tail_name(path_)
|
||||
<< " has been called with empty parameters." << endl;
|
||||
cerr << get_line() << ": : Verilog doesn't allow "
|
||||
<< "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,
|
||||
int expr_wid, bool) const
|
||||
{
|
||||
if (path_.peek_name(0)[0] == '$')
|
||||
if (peek_tail_name(path_)[0] == '$')
|
||||
return elaborate_sfunc_(des, scope);
|
||||
|
||||
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,
|
||||
long&msb, long&lsb) const
|
||||
{
|
||||
assert(lsb_ != 0);
|
||||
assert(msb_ != 0);
|
||||
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.sel == index_component_t::SEL_PART);
|
||||
ivl_assert(*this, index_tail.msb && index_tail.lsb);
|
||||
|
||||
/* This handles part selects. In this case, there are
|
||||
two bit select expressions, and both must be
|
||||
constant. Evaluate them and pass the results back to
|
||||
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);
|
||||
if (lsb_c == 0) {
|
||||
cerr << lsb_->get_line() << ": error: "
|
||||
cerr << index_tail.lsb->get_line() << ": error: "
|
||||
"Part select expressions must be constant."
|
||||
<< endl;
|
||||
cerr << lsb_->get_line() << ": : This lsb expression "
|
||||
"violates the rule: " << *lsb_ << endl;
|
||||
cerr << index_tail.lsb->get_line() << ": : "
|
||||
"This lsb expression violates the rule: "
|
||||
<< *index_tail.lsb << endl;
|
||||
des->errors += 1;
|
||||
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);
|
||||
if (msb_c == 0) {
|
||||
cerr << msb_->get_line() << ": error: "
|
||||
cerr << index_tail.msb->get_line() << ": error: "
|
||||
"Part select expressions must be constant."
|
||||
<< endl;
|
||||
cerr << msb_->get_line() << ": : This msb expression "
|
||||
"violates the rule: " << *msb_ << endl;
|
||||
cerr << index_tail.msb->get_line() << ": : This msb expression "
|
||||
"violates the rule: " << *index_tail.msb << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -662,13 +667,18 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
|||
bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
|
||||
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;
|
||||
|
||||
/* Calculate the width expression (in the lsb_ position)
|
||||
first. If the expression is not constant, error but guess 1
|
||||
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);
|
||||
|
||||
if (wid_c == 0) {
|
||||
|
|
@ -695,30 +705,36 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
symbol_search(des, scope, path_,
|
||||
net, par, eve,
|
||||
ex1, ex2);
|
||||
symbol_search(des, scope, path_, net, par, eve, ex1, ex2);
|
||||
|
||||
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();
|
||||
switch (sel_) {
|
||||
case SEL_NONE:
|
||||
switch (use_sel) {
|
||||
case index_component_t::SEL_NONE:
|
||||
break;
|
||||
case SEL_PART:
|
||||
case index_component_t::SEL_PART:
|
||||
{ long msb, lsb;
|
||||
calculate_parts_(des, scope, msb, lsb);
|
||||
use_width = 1 + ((msb>lsb)? (msb-lsb) : (lsb-msb));
|
||||
break;
|
||||
}
|
||||
case SEL_IDX_UP:
|
||||
case SEL_IDX_DO:
|
||||
case index_component_t::SEL_IDX_UP:
|
||||
case index_component_t::SEL_IDX_DO:
|
||||
{ unsigned long tmp = 0;
|
||||
calculate_up_do_width_(des, scope, tmp);
|
||||
use_width = tmp;
|
||||
break;
|
||||
}
|
||||
case index_component_t::SEL_BIT:
|
||||
use_width = 1;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
ivl_assert(*this, 0);
|
||||
}
|
||||
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
|
||||
// processing generate blocks, but then the genvar_tmp will be
|
||||
// set in the scope.
|
||||
if (path_.component_count() == 1
|
||||
if (path_.size() == 1
|
||||
&& 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);
|
||||
NetEConst*tmp = new NetEConst(val);
|
||||
tmp->set_line(*this);
|
||||
|
|
@ -790,8 +806,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
if (gn_specify_blocks_flag) {
|
||||
map<perm_string,NetScope::spec_val_t>::const_iterator specp;
|
||||
perm_string key = perm_string::literal(path_.peek_name(0));
|
||||
if (path_.component_count() == 1
|
||||
perm_string key = peek_tail_name(path_);
|
||||
if (path_.size() == 1
|
||||
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
|
||||
NetScope::spec_val_t value = (*specp).second;
|
||||
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
|
||||
// first to see if this is a name of a local scope. Failing
|
||||
// that, search globally for a hierarchical name.
|
||||
if ((path_.peek_name(1) == 0))
|
||||
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
|
||||
if ((path_.size() == 1))
|
||||
if (NetScope*nsc = scope->child(peek_tail_name(path_))) {
|
||||
NetEScope*tmp = new NetEScope(nsc);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
|
|
@ -854,13 +870,18 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
|||
const NetExpr*par_msb,
|
||||
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) {
|
||||
assert(msb_ && lsb_);
|
||||
assert(idx_.empty());
|
||||
if (use_sel == index_component_t::SEL_PART) {
|
||||
ivl_assert(*this, !name_tail.index.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
|
||||
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
|
||||
width of the parameter. */
|
||||
|
||||
verinum*lsn = lsb_->eval_const(des, scope);
|
||||
verinum*msn = msb_->eval_const(des, scope);
|
||||
verinum*lsn = index_tail.lsb->eval_const(des, scope);
|
||||
verinum*msn = index_tail.msb->eval_const(des, scope);
|
||||
if ((lsn == 0) || (msn == 0)) {
|
||||
cerr << get_line() << ": error: "
|
||||
"Part select expressions must be "
|
||||
|
|
@ -926,17 +947,19 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
|||
delete tmp;
|
||||
tmp = new NetEConst(result);
|
||||
|
||||
} else if (sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO) {
|
||||
assert(msb_);
|
||||
assert(lsb_);
|
||||
assert(idx_.empty());
|
||||
} else if (use_sel == index_component_t::SEL_IDX_UP || use_sel == index_component_t::SEL_IDX_DO) {
|
||||
|
||||
ivl_assert(*this, !name_tail.index.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
|
||||
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);
|
||||
if (wid_ec == 0) {
|
||||
cerr << lsb_->get_line() << ": error: "
|
||||
cerr << index_tail.lsb->get_line() << ": error: "
|
||||
<< "Second expression of indexed part select "
|
||||
<< "most be constant." << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -945,12 +968,12 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
|||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -959,16 +982,16 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
|||
tmp = new NetESelect(tmp, idx_ex, wid);
|
||||
|
||||
|
||||
} else if (!idx_.empty()) {
|
||||
assert(!msb_);
|
||||
assert(!lsb_);
|
||||
assert(idx_.size() == 1);
|
||||
assert(sel_ == SEL_NONE);
|
||||
} else if (use_sel == index_component_t::SEL_BIT) {
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb);
|
||||
ivl_assert(*this, !index_tail.lsb);
|
||||
|
||||
/* Handle the case where a parameter has a bit
|
||||
select attached to it. Generate a NetESelect
|
||||
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)) {
|
||||
NetExpr*re = mtmp->eval_tree();
|
||||
if (re) {
|
||||
|
|
@ -1045,8 +1068,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
|||
NetEConstParam if possible. */
|
||||
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
||||
if (ctmp != 0) {
|
||||
perm_string name
|
||||
= lex_strings.make(path_.peek_tail_name());
|
||||
perm_string name = peek_tail_name(path_);
|
||||
NetEConstParam*ptmp
|
||||
= new NetEConstParam(found_in, name, ctmp->value());
|
||||
delete tmp;
|
||||
|
|
@ -1065,17 +1087,32 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
|||
NetNet*net, NetScope*found_in,
|
||||
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()
|
||||
<< " Needs an array index here." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_assert(*this, sys_task_arg || !idx_.empty());
|
||||
NetExpr*word_index = idx_.empty()
|
||||
index_component_t index_front;
|
||||
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
|
||||
: elab_and_eval(des, scope, idx_[0], -1);
|
||||
: elab_and_eval(des, scope, index_front.msb, -1);
|
||||
if (word_index == 0 && !sys_task_arg)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1106,15 +1143,22 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
|||
NetESignal*res = new NetESignal(net, word_index);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ivl_assert(*this, word_sel == index_component_t::SEL_NONE);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1125,7 +1169,6 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
|||
NetESignal*net, NetScope*found_in) const
|
||||
{
|
||||
long msv, lsv;
|
||||
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
|
||||
bool flag = calculate_parts_(des, scope, msv, lsv);
|
||||
if (!flag)
|
||||
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,
|
||||
NetESignal*net, NetScope*found_in) const
|
||||
{
|
||||
assert(lsb_ != 0);
|
||||
assert(msb_ != 0);
|
||||
const name_component_t&name_tail = path_.back();
|
||||
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;
|
||||
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,
|
||||
NetESignal*net, NetScope*found_in)const
|
||||
{
|
||||
assert(lsb_ != 0);
|
||||
assert(msb_ != 0);
|
||||
const name_component_t&name_tail = path_.back();
|
||||
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;
|
||||
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,
|
||||
NetESignal*net, NetScope*found_in) const
|
||||
{
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_.size() == 1);
|
||||
const name_component_t&name_tail = path_.back();
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
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
|
||||
// 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);
|
||||
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
|
||||
// temporary signal that is connected to just the
|
||||
// selected bits. The lsb_ and msb_ expressions are from
|
||||
// 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if (!idx_.empty())
|
||||
if (use_sel == index_component_t::SEL_BIT)
|
||||
return elaborate_expr_net_bit_(des, scope, node, found_in);
|
||||
|
||||
// It's not anything else, so this must be a simple identifier
|
||||
// expression with no part or bit select. Return the signal
|
||||
// itself as the expression.
|
||||
assert(sel_ == SEL_NONE);
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_.empty());
|
||||
assert(use_sel == index_component_t::SEL_NONE);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
|
@ -1633,6 +1684,10 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -163,11 +163,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
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
|
||||
// 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 "
|
||||
<< path_ << ". Did you forget a word index?" << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -177,19 +183,19 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
if (reg->array_dimensions() > 0)
|
||||
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);
|
||||
elaborate_lval_net_part_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
|
||||
if (sel_ == SEL_IDX_UP) {
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
|
||||
if (sel_ == SEL_IDX_DO) {
|
||||
if (use_sel == index_component_t::SEL_IDX_DO) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
||||
return lv;
|
||||
|
|
@ -208,12 +214,14 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
return 0;
|
||||
}
|
||||
|
||||
ivl_assert(*this, msb_ == 0);
|
||||
ivl_assert(*this, lsb_ == 0);
|
||||
long msb, lsb;
|
||||
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
|
||||
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 as a mux. */
|
||||
|
||||
ivl_assert(*this, idx_.size() == 1);
|
||||
|
||||
NetExpr*index_expr = elab_and_eval(des, scope, idx_[0], -1);
|
||||
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
||||
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
|
||||
msb = index_con->value().as_long();
|
||||
|
|
@ -311,9 +317,15 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
NetScope*scope,
|
||||
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
|
||||
// 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. */
|
||||
|
||||
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);
|
||||
|
||||
if (sel_ == SEL_IDX_UP)
|
||||
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||
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);
|
||||
|
||||
return lv;
|
||||
|
|
@ -417,8 +433,12 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
|||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
{
|
||||
assert(lsb_);
|
||||
assert(msb_);
|
||||
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.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb != 0);
|
||||
|
||||
NetNet*reg = lv->sig();
|
||||
assert(reg);
|
||||
|
|
@ -436,7 +456,7 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
|||
unsigned long 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. */
|
||||
if (reg->msb() < reg->lsb())
|
||||
|
|
@ -457,8 +477,13 @@ bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
|
|||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
{
|
||||
assert(lsb_);
|
||||
assert(msb_);
|
||||
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.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb != 0);
|
||||
|
||||
cerr << get_line() << ": internal error: don't know how to "
|
||||
"deal with SEL_IDX_DO in lval?" << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -475,6 +500,10 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Replace some asserts with ivl_asserts.
|
||||
*
|
||||
|
|
|
|||
171
elab_net.cc
171
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1230,7 +1230,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
|||
unsigned errors = 0;
|
||||
unsigned func_pins = 0;
|
||||
|
||||
if (path_.peek_name(0)[0] == '$')
|
||||
if (path_.front().name[0] == '$')
|
||||
return elaborate_net_sfunc_(des, scope,
|
||||
width, rise, fall, decay,
|
||||
drive0, drive1);
|
||||
|
|
@ -1320,11 +1320,13 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
|||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const
|
||||
{
|
||||
perm_string name = peek_tail_name(path_);
|
||||
|
||||
/* Handle the special case that the function call is to
|
||||
$signed. This takes a single expression argument, and
|
||||
forces it to be a signed result. Otherwise, it is as if the
|
||||
$signed did not exist. */
|
||||
if (strcmp(path_.peek_name(0), "$signed") == 0) {
|
||||
if (strcmp(name, "$signed") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $signed() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
|
|
@ -1340,7 +1342,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
/* handle $unsigned like $signed */
|
||||
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
|
||||
if (strcmp(name, "$unsigned") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $unsigned() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
|
|
@ -1355,11 +1357,11 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
|||
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) {
|
||||
cerr << get_line() << ": error: System function "
|
||||
<< path_.peek_name(0) << " not defined." << endl;
|
||||
<< peek_tail_name(path_) << " not defined." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1545,15 +1547,19 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const
|
||||
{
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_.size() == 1);
|
||||
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.sel == index_component_t::SEL_BIT);
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb == 0);
|
||||
|
||||
/* Elaborate the selector. */
|
||||
NetNet*sel;
|
||||
|
||||
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);
|
||||
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
||||
delete sel_expr;
|
||||
|
|
@ -1563,7 +1569,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|||
sel = sel_expr->synthesize(des);
|
||||
|
||||
} 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());
|
||||
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
||||
delete sel_expr;
|
||||
|
|
@ -1573,7 +1579,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|||
sel = sel_expr->synthesize(des);
|
||||
|
||||
} 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) {
|
||||
|
|
@ -1604,10 +1610,12 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
|||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const
|
||||
{
|
||||
assert(scope);
|
||||
ivl_assert(*this, scope);
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
NetNet* sig = 0;
|
||||
const NetExpr*par = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(des, scope, path_, sig, par, eve);
|
||||
|
|
@ -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
|
||||
is hierarchical. We can't just create a name in another
|
||||
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 "
|
||||
<< path_ << " is undefined in "
|
||||
<< scope->name() << "." << endl;
|
||||
|
||||
hname_t tmp_path = path_;
|
||||
delete[] tmp_path.remove_tail_name();
|
||||
pform_name_t tmp_path = path_;
|
||||
tmp_path.pop_back();
|
||||
|
||||
NetScope*tmp_scope = des->find_scope(scope, tmp_path);
|
||||
if (tmp_scope == 0) {
|
||||
|
|
@ -1667,28 +1675,28 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
|||
/* Fallback, this may be an implicitly declared net. */
|
||||
if (sig == 0) {
|
||||
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);
|
||||
sig->data_type(IVL_VT_LOGIC);
|
||||
|
||||
if (error_implicit || (nettype == NetNet::NONE)) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< scope->name() << "." << path_.peek_name(0)
|
||||
<< scope->name() << "." << name_tail.name
|
||||
<< " not defined in this scope." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else if (warn_implicit) {
|
||||
cerr << get_line() << ": warning: implicit "
|
||||
"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. */
|
||||
if (sig->array_dimensions() > 0) {
|
||||
if (idx_.size() == 0) {
|
||||
if (name_tail.index.size() == 0) {
|
||||
cerr << get_line() << ": error: Array " << sig->name()
|
||||
<< " cannot be used here without an index." << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -1700,14 +1708,16 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
|||
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
|
||||
handled elsewhere. */
|
||||
if (! idx_.empty()) {
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_.size() == 1);
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
|
||||
verinum*mval = idx_[0]->eval_const(des, scope);
|
||||
verinum*mval = index_tail.msb->eval_const(des, scope);
|
||||
if (mval == 0) {
|
||||
return elaborate_net_bitmux_(des, scope, sig, rise,
|
||||
fall, decay, drive0, drive1);
|
||||
|
|
@ -1755,9 +1765,14 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
|
|||
Link::strength_t drive0,
|
||||
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)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1821,6 +1836,10 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
|
|||
tmp->data_type(sig->data_type());
|
||||
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;
|
||||
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;
|
||||
|
||||
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);
|
||||
/* Implicit nets are always scalar logic. */
|
||||
sig->data_type(IVL_VT_LOGIC);
|
||||
|
|
@ -2014,7 +2033,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
|
|||
if (warn_implicit) {
|
||||
cerr << get_line() << ": warning: implicit "
|
||||
"definition of wire logic " << scope->name()
|
||||
<< "." << path_.peek_name(0) << "." << endl;
|
||||
<< "." << peek_tail_name(path_) << "." << endl;
|
||||
}
|
||||
|
||||
} 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,
|
||||
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:
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Unexpected sel_ value = " << sel_ << endl;
|
||||
assert(0);
|
||||
<< "Unexpected sel_ value = " << index_tail.sel << endl;
|
||||
ivl_assert(*this, 0);
|
||||
break;
|
||||
|
||||
case PEIdent::SEL_IDX_DO:
|
||||
case PEIdent::SEL_IDX_UP: {
|
||||
assert(msb_);
|
||||
assert(lsb_);
|
||||
assert(idx_.size() == sig->array_dimensions());
|
||||
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1);
|
||||
case index_component_t::SEL_IDX_DO:
|
||||
case index_component_t::SEL_IDX_UP: {
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||
assert(tmp);
|
||||
|
||||
|
|
@ -2058,14 +2087,14 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
midx = sig->sb_to_idx(midx_val);
|
||||
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);
|
||||
assert(tmp);
|
||||
|
||||
long wid = tmp->value().as_long();
|
||||
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);
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
case PEIdent::SEL_PART: {
|
||||
assert(msb_);
|
||||
assert(lsb_);
|
||||
assert(idx_.size() == sig->array_dimensions());
|
||||
case index_component_t::SEL_PART: {
|
||||
|
||||
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);
|
||||
assert(tmp);
|
||||
|
||||
|
|
@ -2092,12 +2118,12 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
midx = sig->sb_to_idx(midx_val);
|
||||
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);
|
||||
if (tmp == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "lsb expression is not constant?: "
|
||||
<< *tmp_ex << ", " << *lsb_ << endl;
|
||||
<< *tmp_ex << ", " << *index_tail.lsb << endl;
|
||||
}
|
||||
assert(tmp);
|
||||
|
||||
|
|
@ -2131,19 +2157,16 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
break;
|
||||
}
|
||||
|
||||
case PEIdent::SEL_NONE:
|
||||
if (idx_.size() > sig->array_dimensions()) {
|
||||
unsigned a_dims = sig->array_dimensions();
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_.size() == a_dims+1);
|
||||
verinum*mval = idx_[a_dims]->eval_const(des, scope);
|
||||
case index_component_t::SEL_BIT:
|
||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||
const index_component_t&index_head = name_tail.index.front();
|
||||
verinum*mval = index_head.msb->eval_const(des, scope);
|
||||
if (mval == 0) {
|
||||
cerr << get_line() << ": error: Index of " << path_ <<
|
||||
" needs to be constant in this context." <<
|
||||
endl;
|
||||
cerr << get_line() << ": : Index expression is: "
|
||||
<< *(idx_[0]) << endl;
|
||||
<< *index_head.msb << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2160,17 +2183,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
lidx = midx;
|
||||
|
||||
} else {
|
||||
if (msb_ || lsb_) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Unexpected msb_/lsb_ values?" << endl;
|
||||
if (msb_)
|
||||
cerr << get_line() << " : "
|
||||
<< *msb_ << endl;
|
||||
if (lsb_)
|
||||
cerr << get_line() << " : "
|
||||
<< *lsb_ << endl;
|
||||
}
|
||||
assert(msb_ == 0 && lsb_ == 0);
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Bit select " << path_ << endl;
|
||||
ivl_assert(*this, 0);
|
||||
midx = sig->vector_width() - 1;
|
||||
lidx = 0;
|
||||
}
|
||||
|
|
@ -2245,10 +2260,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
// The default word select is the first.
|
||||
unsigned widx = 0;
|
||||
|
||||
if (sig->array_dimensions() > 0) {
|
||||
assert(!idx_.empty());
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
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);
|
||||
assert(tmp);
|
||||
|
||||
|
|
@ -2260,7 +2281,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
cerr << get_line() << ": debug: Use [" << widx << "]"
|
||||
<< " to index l-value array." << endl;
|
||||
|
||||
} else {
|
||||
} else if (!name_tail.index.empty()) {
|
||||
if (! eval_part_select_(des, scope, sig, midx, lidx))
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2941,6 +2962,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Fix elaboration of multiply of two constants.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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
|
||||
{
|
||||
hname_t path = path_;
|
||||
perm_string name = path.remove_tail_name();
|
||||
pform_name_t path = path_;
|
||||
name_component_t name_tail = path_.back();
|
||||
path.pop_back();
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path.peek_name(0))
|
||||
if (path_.size() > 0)
|
||||
pscope = des->find_scope(scope, path);
|
||||
|
||||
const NetExpr*ex_msb;
|
||||
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) {
|
||||
cerr << get_line() << ": error: identifier ``" << path_ <<
|
||||
cerr << get_line() << ": error: identifier ``" << name_tail.name <<
|
||||
"'' is not a parameter in " << scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, name);
|
||||
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
|
||||
res->set_line(*this);
|
||||
assert(res);
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
assert(idx_.empty());
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
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 "
|
||||
"bits of parameters." << endl;
|
||||
des->errors += 1;
|
||||
break;
|
||||
|
||||
} else if (!idx_.empty()) {
|
||||
assert(msb_==0);
|
||||
assert(lsb_==0);
|
||||
assert(idx_.size() == 1);
|
||||
case index_component_t::SEL_BIT:
|
||||
|
||||
/* We have here a bit select. Insert a NetESelect node
|
||||
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) {
|
||||
res = new NetESelect(res, tmp, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
@ -233,6 +240,10 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -66,7 +66,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
// place of the elaborated expression.
|
||||
|
||||
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
|
||||
|
|
@ -200,7 +200,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
// here because the parameter receiving the assignment may be
|
||||
// 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 ++ ) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
|
|
@ -761,6 +761,10 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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) {
|
||||
|
||||
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,
|
||||
// the port has 0 or more NetEIdent objects concatenated
|
||||
// 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) {
|
||||
perm_string pname = peek_tail_name(pp->expr[cc]->path());
|
||||
assert(pp->expr[cc]);
|
||||
if (pp->expr[cc]->path() == name)
|
||||
if (pname == name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -63,6 +72,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
|
||||
{
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
const map<hname_t,PWire*>&wl = get_wires();
|
||||
|
||||
// Scan all the ports of the module, and make sure that each
|
||||
// is connected to wires that have port declarations.
|
||||
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)
|
||||
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) {
|
||||
hname_t port_path (pp->expr[cc]->path());
|
||||
wt = wl.find(port_path);
|
||||
pform_name_t port_path (pp->expr[cc]->path());
|
||||
wt = wires_.find(port_path);
|
||||
|
||||
if (wt == wl.end()) {
|
||||
if (wt == wires_.end()) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (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()
|
||||
; wt != wl.end()
|
||||
; wt ++ ) {
|
||||
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
|
||||
; wt != wires_.end() ; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
cur->elaborate_sig(des, scope);
|
||||
|
||||
NetNet*sig = find_signal_in_scope(scope, cur->path());
|
||||
NetNet*sig = cur->elaborate_sig(des, scope);
|
||||
|
||||
// If this wire is a signal of the module (as opposed to
|
||||
// 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)
|
||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
||||
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports, name)) {
|
||||
if (! signal_is_in_port(ports, sig)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: Signal "
|
||||
<< name << " has a declared direction "
|
||||
<< sig->name() << " has a declared direction "
|
||||
<< "but is not a port." << endl;
|
||||
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
|
||||
// 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()
|
||||
; 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
|
||||
as two components: <func>.<port>. */
|
||||
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
perm_string pname = lex_strings.make(path.peek_name(1));
|
||||
perm_string ppath = lex_strings.make(path.peek_name(0));
|
||||
pform_name_t path = (*ports_)[idx]->path();
|
||||
ivl_assert(*this, path.size() == 2);
|
||||
|
||||
perm_string pname = peek_tail_name(path);
|
||||
perm_string ppath = peek_head_name(path);
|
||||
|
||||
if (ppath != scope->basename()) {
|
||||
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
|
||||
as two components: <task>.<port>. */
|
||||
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
assert(path.peek_name(0) && path.peek_name(1));
|
||||
pform_name_t path = (*ports_)[idx]->path();
|
||||
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
|
||||
name of the first component of the task port name. Do
|
||||
this by looking up the task scope in the parent of
|
||||
the current scope. */
|
||||
if (scope->parent()->child(path.peek_name(0)) != scope) {
|
||||
cerr << "internal error: task scope " << path
|
||||
<< " not the same as scope " << scope->name()
|
||||
<< "?!" << endl;
|
||||
return;
|
||||
}
|
||||
ivl_assert(*this, scope->basename() == scope_name);
|
||||
|
||||
/* Find the signal for the port. We know by definition
|
||||
that it is in the scope of the task, so look only in
|
||||
the scope. */
|
||||
NetNet*tmp = scope->find_signal(path.peek_name(1));
|
||||
NetNet*tmp = scope->find_signal(port_name);
|
||||
|
||||
if (tmp == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Could not find port " << path.peek_name(1)
|
||||
<< "Could not find port " << port_name
|
||||
<< " in scope " << scope->name() << endl;
|
||||
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
|
||||
* 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
|
||||
follow the scopes down to the base where I actually want to
|
||||
elaborate the NetNet object. */
|
||||
{ hname_t tmp_path = hname_;
|
||||
tmp_path.remove_tail_name();
|
||||
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
|
||||
scope = scope->child(tmp_path.peek_name(idx));
|
||||
{ pform_name_t tmp_path = hname_;
|
||||
tmp_path.pop_back();
|
||||
while (! tmp_path.empty()) {
|
||||
name_component_t cur = tmp_path.front();
|
||||
tmp_path.pop_front();
|
||||
|
||||
scope = scope->child(cur.name);
|
||||
|
||||
if (scope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
|
|
@ -580,7 +585,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
"Unable to evaluate constant expression ``" <<
|
||||
*msb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mnum[idx] = tmp->value().as_long();
|
||||
|
|
@ -593,7 +598,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
"Unable to evaluate constant expression ``" <<
|
||||
*lsb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -622,7 +627,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||
" for signal ``" << hname_ << "''" << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -657,9 +662,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
if ((lexp == 0) || (rexp == 0)) {
|
||||
cerr << get_line() << ": internal error: There is "
|
||||
<< "a problem evaluating indices for ``"
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
<< hname_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
|
||||
|
|
@ -668,9 +673,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
if ((lcon == 0) || (rcon == 0)) {
|
||||
cerr << get_line() << ": internal error: The indices "
|
||||
<< "are not constant for array ``"
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
<< hname_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum lval = lcon->value();
|
||||
|
|
@ -679,8 +684,6 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
delete lexp;
|
||||
delete rexp;
|
||||
|
||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
||||
|
||||
array_dimensions = 1;
|
||||
array_s0 = lval.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) {
|
||||
cerr << get_line() << ": debug: Create signal "
|
||||
<< 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)
|
||||
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -770,8 +770,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
if (mport.count() == 0)
|
||||
continue;
|
||||
|
||||
NetNet*tmp = des->find_signal(instance[0],
|
||||
mport[0]->path());
|
||||
perm_string pname = peek_tail_name(mport[0]->path());
|
||||
|
||||
NetNet*tmp = instance[0]->find_signal(pname);
|
||||
assert(tmp);
|
||||
|
||||
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
|
||||
{
|
||||
if (path_.peek_name(0)[0] == '$')
|
||||
if (peek_tail_name(path_)[0] == '$')
|
||||
return elaborate_sys(des, scope);
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -3416,6 +3417,10 @@ Design* elaborate(list<perm_string>roots)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -177,16 +177,17 @@ verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
|
|||
NetEvent*eve;
|
||||
const NetExpr*expr;
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
// Handle the special case that this ident is a genvar
|
||||
// variable name. In that case, the genvar meaning preempts
|
||||
// everything and we just return that value immediately.
|
||||
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);
|
||||
}
|
||||
|
||||
symbol_search(des, scope, path_,
|
||||
net, expr, eve);
|
||||
symbol_search(des, scope, path_, net, expr, eve);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
|
@ -201,7 +202,7 @@ verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
|
|||
|
||||
assert(eval);
|
||||
|
||||
if (msb_ || lsb_)
|
||||
if (!name_tail.index.empty())
|
||||
return 0;
|
||||
|
||||
|
||||
|
|
@ -275,6 +276,10 @@ verinum* PEUnary::eval_const(const Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Lint fixes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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
|
||||
* 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;
|
||||
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); scope++) {
|
||||
|
||||
NetScope*cur = *scope;
|
||||
if (strcmp(path.peek_name(0), cur->basename()) != 0)
|
||||
if (strcmp(peek_head_name(path), cur->basename()) != 0)
|
||||
continue;
|
||||
|
||||
unsigned hidx = 1;
|
||||
while (cur) {
|
||||
const char*name = path.peek_name(hidx);
|
||||
if (name == 0)
|
||||
return cur;
|
||||
pform_name_t tmp = path;
|
||||
tmp.pop_front();
|
||||
|
||||
while (cur) {
|
||||
if (tmp.empty()) return cur;
|
||||
|
||||
perm_string name = peek_head_name(tmp);
|
||||
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
|
||||
* the scope parameter is the place within which I start looking for
|
||||
* the scope. If I do not find the scope within the passed scope,
|
||||
* start looking in parent scopes until I find it, or I run out of
|
||||
* parent scopes.
|
||||
* the scope parameter within which I start looking for the scope. If
|
||||
* I do not find the scope within the passed scope, start looking in
|
||||
* parent scopes until I find it, or I run out of 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);
|
||||
if (path.peek_name(0) == 0)
|
||||
if (path.empty())
|
||||
return scope;
|
||||
|
||||
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;
|
||||
do {
|
||||
cur = cur->child(key);
|
||||
if (cur == 0) break;
|
||||
hidx += 1;
|
||||
key = path.peek_name(hidx);
|
||||
tmp.pop_front();
|
||||
if (tmp.empty()) break;
|
||||
name_front = tmp.front();
|
||||
key = name_front.name;
|
||||
} while (key);
|
||||
|
||||
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 ++ ) {
|
||||
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
|
||||
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
|
||||
* 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);
|
||||
|
||||
perm_string key = path.remove_tail_name();
|
||||
if (path.peek_name(0))
|
||||
perm_string key = peek_tail_name(path);
|
||||
path.pop_back();
|
||||
if (! path.empty())
|
||||
scope = find_scope(scope, path);
|
||||
|
||||
while (scope) {
|
||||
|
|
@ -444,7 +451,7 @@ NetNet* Design::find_signal(NetScope*scope, hname_t path)
|
|||
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);
|
||||
NetScope*func = find_scope(scope, name);
|
||||
|
|
@ -454,7 +461,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(const hname_t&key)
|
||||
NetFuncDef* Design::find_function(const pform_name_t&key)
|
||||
{
|
||||
NetScope*func = find_scope(key);
|
||||
if (func && (func->type() == NetScope::FUNC))
|
||||
|
|
@ -463,7 +470,7 @@ NetFuncDef* Design::find_function(const hname_t&key)
|
|||
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);
|
||||
if (task && (task->type() == NetScope::TASK))
|
||||
|
|
@ -472,7 +479,7 @@ NetScope* Design::find_task(NetScope*scope, const hname_t&name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetScope* Design::find_task(const hname_t&key)
|
||||
NetScope* Design::find_task(const pform_name_t&key)
|
||||
{
|
||||
NetScope*task = find_scope(key);
|
||||
if (task && (task->type() == NetScope::TASK))
|
||||
|
|
@ -558,6 +565,10 @@ void Design::delete_process(NetProcTop*top)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
# include <list>
|
||||
# include <vector>
|
||||
# include "ivl_target.h"
|
||||
# include "pform_types.h"
|
||||
# include "config.h"
|
||||
# include "verinum.h"
|
||||
# include "verireal.h"
|
||||
|
|
@ -3291,7 +3292,7 @@ class NetScope : public Attrib {
|
|||
assignments from the scope pass to the parameter evaluation
|
||||
step. After that, it is not used. */
|
||||
|
||||
map<hname_t,NetExpr*>defparams;
|
||||
map<pform_name_t,NetExpr*>defparams;
|
||||
|
||||
public:
|
||||
/* 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
|
||||
scope is located starting at the passed scope and working
|
||||
up if needed. */
|
||||
NetScope* find_scope(const hname_t&path) const;
|
||||
NetScope* find_scope(NetScope*, const hname_t&path) const;
|
||||
NetScope* find_scope(const pform_name_t&path) const;
|
||||
NetScope* find_scope(NetScope*, const pform_name_t&path) const;
|
||||
|
||||
// PARAMETERS
|
||||
|
||||
|
|
@ -3404,15 +3405,15 @@ class Design {
|
|||
this method, unlike the NetScope::find_signal method,
|
||||
handles global name binding. */
|
||||
|
||||
NetNet*find_signal(NetScope*scope, hname_t path);
|
||||
NetNet*find_signal(NetScope*scope, pform_name_t path);
|
||||
|
||||
// Functions
|
||||
NetFuncDef* find_function(NetScope*scope, const hname_t&key);
|
||||
NetFuncDef* find_function(const hname_t&path);
|
||||
NetFuncDef* find_function(NetScope*scope, const pform_name_t&key);
|
||||
NetFuncDef* find_function(const pform_name_t&path);
|
||||
|
||||
// Tasks
|
||||
NetScope* find_task(NetScope*scope, const hname_t&name);
|
||||
NetScope* find_task(const hname_t&key);
|
||||
NetScope* find_task(NetScope*scope, const pform_name_t&name);
|
||||
NetScope* find_task(const pform_name_t&key);
|
||||
|
||||
// NODES
|
||||
void add_node(NetNode*);
|
||||
|
|
@ -3500,6 +3501,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -40,20 +40,20 @@
|
|||
* these values are set to 0.
|
||||
*/
|
||||
extern NetScope* symbol_search(const Design*des,
|
||||
NetScope*start, hname_t path,
|
||||
NetScope*start, pform_name_t path,
|
||||
NetNet*&net, /* net/reg */
|
||||
const NetExpr*&par,/* parameter */
|
||||
NetEvent*&eve, /* named event */
|
||||
const NetExpr*&ex1, const NetExpr*&ex2);
|
||||
|
||||
inline NetScope* symbol_search(const Design*des,
|
||||
NetScope*start, const hname_t&path,
|
||||
NetScope*start, const pform_name_t&path,
|
||||
NetNet*&net, /* net/reg */
|
||||
const NetExpr*&par,/* parameter */
|
||||
NetEvent*&eve /* named event */)
|
||||
{
|
||||
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 $
|
||||
* 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
|
||||
* Limit the calculated widths of constants.
|
||||
*
|
||||
|
|
|
|||
428
parse.y
428
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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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. */
|
||||
char*text;
|
||||
list<perm_string>*perm_strings;
|
||||
pform_name_t*pform_name;
|
||||
|
||||
hname_t*hier;
|
||||
|
||||
|
|
@ -123,8 +124,6 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
|
|||
|
||||
svector<PEEvent*>*event_expr;
|
||||
|
||||
PEIdent*indexed_identifier;
|
||||
|
||||
NetNet::Type nettype;
|
||||
PGBuiltin::Type gatetype;
|
||||
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 <expr> udp_initial_expr_opt
|
||||
|
||||
%type <hier> identifier
|
||||
%type <text> register_variable net_variable
|
||||
%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 <gates> gate_instance_list
|
||||
|
||||
%type <pform_name> heirarchy_identifier
|
||||
%type <expr> expression expr_primary
|
||||
%type <expr> lpvalue
|
||||
%type <expr> delay_value delay_value_simple
|
||||
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
||||
%type <exprs> expression_list_with_nuls expression_list_proper
|
||||
%type <exprs> cont_assign cont_assign_list
|
||||
%type <indexed_identifier> indexed_identifier
|
||||
|
||||
%type <exprs> range range_opt
|
||||
%type <nettype> net_type var_type net_type_opt
|
||||
|
|
@ -492,7 +490,7 @@ charge_strength_opt
|
|||
;
|
||||
|
||||
defparam_assign
|
||||
: identifier '=' expression
|
||||
: heirarchy_identifier '=' expression
|
||||
{ PExpr*tmp = $3;
|
||||
if (!pform_expression_is_constant(tmp)) {
|
||||
yyerror(@3, "error: parameter value "
|
||||
|
|
@ -605,7 +603,7 @@ delay_value_simple
|
|||
}
|
||||
}
|
||||
| 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_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
|
|
@ -671,16 +669,14 @@ dr_strength1
|
|||
;
|
||||
|
||||
event_control
|
||||
: '@' identifier
|
||||
: '@' heirarchy_identifier
|
||||
{ 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);
|
||||
PEventStatement*tmps = new PEventStatement(tmpe);
|
||||
tmps->set_file(@1.text);
|
||||
tmps->set_lineno(@1.first_line);
|
||||
$$ = tmps;
|
||||
delete $2;
|
||||
}
|
||||
| '@' '(' event_expression_list ')'
|
||||
{ PEventStatement*tmp = new PEventStatement(*$3);
|
||||
|
|
@ -1034,53 +1030,29 @@ expr_primary
|
|||
}
|
||||
| SYSTEM_IDENTIFIER
|
||||
{ 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_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
|
||||
/* The indexed_identifier rule matches simple identifiers as well as
|
||||
indexed arrays. Part selects are handled below. */
|
||||
/* The heirarchy_identifier rule matches simple identifiers as well as
|
||||
indexed arrays and part selects */
|
||||
|
||||
| indexed_identifier
|
||||
{ PEIdent*tmp = $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
| heirarchy_identifier
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
|
||||
/* An identifer followed by an expression list in parentheses is a
|
||||
function call. If a system identifier, then a system function
|
||||
call. */
|
||||
|
||||
| identifier '(' expression_list_proper ')'
|
||||
| heirarchy_identifier '(' expression_list_proper ')'
|
||||
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
|
|
@ -1089,7 +1061,7 @@ expr_primary
|
|||
}
|
||||
| SYSTEM_IDENTIFIER '(' expression_list_proper ')'
|
||||
{ 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_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
|
|
@ -1345,39 +1317,61 @@ gatetype
|
|||
|
||||
/* A general identifier is a hierarchical name, with the right most
|
||||
name the base of the identifier. This rule builds up a
|
||||
hierarchical name from left to right, forming a list of names. */
|
||||
identifier
|
||||
: IDENTIFIER
|
||||
{ $$ = new hname_t(lex_strings.make($1));
|
||||
delete $1;
|
||||
}
|
||||
| identifier '.' IDENTIFIER
|
||||
{ hname_t * tmp = $1;
|
||||
tmp->append(lex_strings.make($3));
|
||||
delete $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
hierarchical name from the left to the right, forming a list of
|
||||
names. */
|
||||
|
||||
/* An indexed_identifier is an identifier with a bit-select
|
||||
expression. This bit select may be an array index or bit index,
|
||||
to be sorted out later. */
|
||||
indexed_identifier
|
||||
: identifier
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->sel_ = PEIdent::SEL_NONE;
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| indexed_identifier '[' expression ']'
|
||||
{ PEIdent*tmp = $1;
|
||||
tmp->sel_ = PEIdent::SEL_NONE;
|
||||
tmp->idx_.push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
heirarchy_identifier
|
||||
: IDENTIFIER
|
||||
{ $$ = new pform_name_t;
|
||||
$$->push_back(name_component_t(lex_strings.make($1)));
|
||||
delete $1;
|
||||
}
|
||||
| heirarchy_identifier '.' IDENTIFIER
|
||||
{ pform_name_t * tmp = $1;
|
||||
tmp->push_back(name_component_t(lex_strings.make($3)));
|
||||
delete $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
| heirarchy_identifier '[' expression ']'
|
||||
{ pform_name_t * tmp = $1;
|
||||
name_component_t&tail = tmp->back();
|
||||
index_component_t itmp;
|
||||
itmp.sel = index_component_t::SEL_BIT;
|
||||
itmp.msb = $3;
|
||||
tail.index.push_back(itmp);
|
||||
$$ = tmp;
|
||||
}
|
||||
| heirarchy_identifier '[' expression ':' expression ']'
|
||||
{ pform_name_t * tmp = $1;
|
||||
name_component_t&tail = tmp->back();
|
||||
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;
|
||||
}
|
||||
;
|
||||
|
||||
/* This is a list of identifiers. The result is a list of strings,
|
||||
each one of the identifiers in the list. These are simple,
|
||||
|
|
@ -1552,39 +1546,21 @@ signed_opt : K_signed { $$ = true; } | {$$ = false; } ;
|
|||
assignments. It is more limited then the general expr_primary
|
||||
rule to reflect the rules for assignment l-values. */
|
||||
lpvalue
|
||||
: indexed_identifier
|
||||
{ PEIdent*tmp = $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| 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;
|
||||
}
|
||||
| '{' expression_list_proper '}'
|
||||
{ PEConcat*tmp = new PEConcat(*$2);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
: heirarchy_identifier
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
| '{' expression_list_proper '}'
|
||||
{ PEConcat*tmp = new PEConcat(*$2);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/* Continuous assignments have a list of individual assignments. */
|
||||
|
|
@ -2306,67 +2282,87 @@ port_opt
|
|||
|
||||
port_reference
|
||||
|
||||
: IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($1, @1.text,
|
||||
@1.first_line);
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
: IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
ptmp = pform_module_port_reference($1, @1.text, @1.first_line);
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
|
||||
| IDENTIFIER '[' expression ':' expression ']'
|
||||
{ PEIdent*wtmp = new PEIdent(hname_t(lex_strings.make($1)));
|
||||
wtmp->set_file(@1.text);
|
||||
wtmp->set_lineno(@1.first_line);
|
||||
if (!pform_expression_is_constant($3)) {
|
||||
yyerror(@3, "error: msb expression of "
|
||||
"port part select must be constant.");
|
||||
}
|
||||
if (!pform_expression_is_constant($5)) {
|
||||
yyerror(@5, "error: lsb expression of "
|
||||
"port part select must be constant.");
|
||||
}
|
||||
wtmp->msb_ = $3;
|
||||
wtmp->lsb_ = $5;
|
||||
wtmp->sel_ = PEIdent::SEL_PART;
|
||||
Module::port_t*ptmp = new Module::port_t;
|
||||
ptmp->name = perm_string();
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = wtmp;
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| IDENTIFIER '[' expression ':' expression ']'
|
||||
{ if (!pform_expression_is_constant($3)) {
|
||||
yyerror(@3, "error: msb expression of "
|
||||
"port part select must be constant.");
|
||||
}
|
||||
if (!pform_expression_is_constant($5)) {
|
||||
yyerror(@5, "error: lsb expression of "
|
||||
"port part select must be constant.");
|
||||
}
|
||||
index_component_t itmp;
|
||||
itmp.sel = index_component_t::SEL_PART;
|
||||
itmp.msb = $3;
|
||||
itmp.lsb = $5;
|
||||
|
||||
| IDENTIFIER '[' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent(hname_t(lex_strings.make($1)));
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
if (!pform_expression_is_constant($3)) {
|
||||
yyerror(@3, "error: port bit select "
|
||||
"must be constant.");
|
||||
}
|
||||
tmp->msb_ = $3;
|
||||
Module::port_t*ptmp = new Module::port_t;
|
||||
ptmp->name = perm_string();
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = tmp;
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
name_component_t ntmp (lex_strings.make($1));
|
||||
ntmp.index.push_back(itmp);
|
||||
|
||||
| IDENTIFIER '[' error ']'
|
||||
{ yyerror(@1, "error: invalid port bit select");
|
||||
Module::port_t*ptmp = new Module::port_t;
|
||||
PEIdent*wtmp = new PEIdent(hname_t(lex_strings.make($1)));
|
||||
wtmp->set_file(@1.text);
|
||||
wtmp->set_lineno(@1.first_line);
|
||||
ptmp->name = lex_strings.make($1);
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = wtmp;
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
;
|
||||
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;
|
||||
ptmp->name = perm_string();
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = wtmp;
|
||||
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
|
||||
| IDENTIFIER '[' expression ']'
|
||||
{ if (!pform_expression_is_constant($3)) {
|
||||
yyerror(@3, "error: port bit select "
|
||||
"must be constant.");
|
||||
}
|
||||
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;
|
||||
ptmp->name = perm_string();
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = tmp;
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
|
||||
| IDENTIFIER '[' error ']'
|
||||
{ yyerror(@1, "error: invalid port bit select");
|
||||
Module::port_t*ptmp = new Module::port_t;
|
||||
PEIdent*wtmp = new PEIdent(lex_strings.make($1));
|
||||
wtmp->set_file(@1.text);
|
||||
wtmp->set_lineno(@1.first_line);
|
||||
ptmp->name = lex_strings.make($1);
|
||||
ptmp->expr = svector<PEIdent*>(1);
|
||||
ptmp->expr[0] = wtmp;
|
||||
delete $1;
|
||||
$$ = ptmp;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
port_reference_list
|
||||
|
|
@ -2791,16 +2787,12 @@ spec_notifier_opt
|
|||
spec_notifier
|
||||
: ','
|
||||
{ }
|
||||
| ',' identifier
|
||||
| ',' heirarchy_identifier
|
||||
{ delete $2; }
|
||||
| spec_notifier ','
|
||||
{ }
|
||||
| spec_notifier ',' identifier
|
||||
| spec_notifier ',' heirarchy_identifier
|
||||
{ delete $3; }
|
||||
| spec_notifier ',' identifier '[' expr_primary ']'
|
||||
{ delete $3;
|
||||
delete $5;
|
||||
}
|
||||
| IDENTIFIER
|
||||
{ delete $1; }
|
||||
;
|
||||
|
|
@ -2917,14 +2909,14 @@ statement
|
|||
$$ = tmp;
|
||||
}
|
||||
|
||||
| K_disable identifier ';'
|
||||
| K_disable heirarchy_identifier ';'
|
||||
{ PDisable*tmp = new PDisable(*$2);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_TRIGGER identifier ';'
|
||||
| K_TRIGGER heirarchy_identifier ';'
|
||||
{ PTrigger*tmp = new PTrigger(*$2);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
|
|
@ -3132,7 +3124,7 @@ statement
|
|||
$$ = tmp;
|
||||
}
|
||||
| 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_lineno(@1.first_line);
|
||||
delete $1;
|
||||
|
|
@ -3141,13 +3133,13 @@ statement
|
|||
}
|
||||
| SYSTEM_IDENTIFIER ';'
|
||||
{ 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_lineno(@1.first_line);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '(' expression_list_proper ')' ';'
|
||||
| heirarchy_identifier '(' expression_list_proper ')' ';'
|
||||
{ PCallTask*tmp = new PCallTask(*$1, *$3);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
|
|
@ -3160,7 +3152,7 @@ statement
|
|||
between parentheses, but it seems natural, and people commonly
|
||||
want it. So accept it explicitly. */
|
||||
|
||||
| identifier '(' ')' ';'
|
||||
| heirarchy_identifier '(' ')' ';'
|
||||
{ svector<PExpr*>pt (0);
|
||||
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||
tmp->set_file(@1.text);
|
||||
|
|
@ -3168,7 +3160,7 @@ statement
|
|||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier ';'
|
||||
| heirarchy_identifier ';'
|
||||
{ svector<PExpr*>pt (0);
|
||||
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||
tmp->set_file(@1.text);
|
||||
|
|
@ -3523,7 +3515,7 @@ udp_sequ_entry
|
|||
udp_initial
|
||||
: K_initial IDENTIFIER '=' number ';'
|
||||
{ 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);
|
||||
atmp->set_file(@2.text);
|
||||
atmp->set_lineno(@2.first_line);
|
||||
|
|
@ -3588,40 +3580,40 @@ 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
|
||||
: K_input list_of_identifiers ';'
|
||||
{ $$ = pform_make_udp_input_ports($2); }
|
||||
| K_output IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire(lex_strings.make($2),
|
||||
NetNet::IMPLICIT,
|
||||
NetNet::POUTPUT,
|
||||
IVL_VT_LOGIC);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
$$ = tmp;
|
||||
delete $2;
|
||||
}
|
||||
| K_reg IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire(lex_strings.make($2),
|
||||
NetNet::REG,
|
||||
NetNet::PIMPLICIT,
|
||||
IVL_VT_LOGIC);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
$$ = tmp;
|
||||
delete $2;
|
||||
}
|
||||
| K_reg K_output IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire(lex_strings.make($3),
|
||||
NetNet::REG,
|
||||
NetNet::POUTPUT,
|
||||
IVL_VT_LOGIC);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
$$ = tmp;
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
: K_input list_of_identifiers ';'
|
||||
{ $$ = pform_make_udp_input_ports($2); }
|
||||
| K_output IDENTIFIER ';'
|
||||
{ pform_name_t pname;
|
||||
pname.push_back(lex_strings.make($2));
|
||||
PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
$$ = tmp;
|
||||
delete $2;
|
||||
}
|
||||
| K_reg IDENTIFIER ';'
|
||||
{ pform_name_t pname;
|
||||
pname.push_back(lex_strings.make($2));
|
||||
PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
$$ = tmp;
|
||||
delete $2;
|
||||
}
|
||||
| K_reg K_output IDENTIFIER ';'
|
||||
{ pform_name_t pname;
|
||||
pname.push_back(lex_strings.make($3));
|
||||
PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
$$ = tmp;
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
udp_port_decls
|
||||
: udp_port_decl
|
||||
|
|
|
|||
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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
# include <list>
|
||||
# include <map>
|
||||
# include <assert.h>
|
||||
# include <stack>
|
||||
# include <typeinfo>
|
||||
# include <sstream>
|
||||
|
||||
|
|
@ -80,34 +81,34 @@ static unsigned pform_timescale_line = 0;
|
|||
* and named blocks causes scope to be pushed and popped. The module
|
||||
* name is not included in this scope stack.
|
||||
*
|
||||
* The hier_name function, therefore, converts the name to the scope
|
||||
* of the module currently in progress.
|
||||
* The hier_name function, therefore, converts the name to the scoped
|
||||
* 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
|
||||
* scheme.
|
||||
*/
|
||||
|
||||
static hname_t scope_stack;
|
||||
static pform_name_t scope_stack;
|
||||
|
||||
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()
|
||||
{
|
||||
perm_string tmp = scope_stack.remove_tail_name();
|
||||
assert(tmp);
|
||||
scope_stack.pop_back();
|
||||
}
|
||||
|
||||
static hname_t hier_name(const char*tail)
|
||||
static pform_name_t hier_name(const char*tail)
|
||||
{
|
||||
hname_t name = scope_stack;
|
||||
name.append(lex_strings.make(tail));
|
||||
pform_name_t name = scope_stack;
|
||||
name.push_back(name_component_t(lex_strings.make(tail)));
|
||||
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
|
||||
scope depth will be empty because generate schemes
|
||||
|
|
@ -277,7 +278,7 @@ Module::port_t* pform_module_port_reference(char*name,
|
|||
unsigned lineno)
|
||||
{
|
||||
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_lineno(lineno);
|
||||
ptmp->name = lex_strings.make(name);
|
||||
|
|
@ -511,9 +512,10 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
|||
map<string,PWire*> defs;
|
||||
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;
|
||||
assert((*decl)[idx]);
|
||||
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
|
||||
|
|
@ -526,7 +528,7 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
|||
}
|
||||
|
||||
} 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
|
||||
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);
|
||||
udp->initial = init;
|
||||
|
|
@ -756,7 +758,7 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
|||
|
||||
// Make the port list for the UDP
|
||||
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(table);
|
||||
|
|
@ -1090,7 +1092,7 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
|
|||
void pform_make_reginit(const struct vlltype&li,
|
||||
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);
|
||||
if (cur == 0) {
|
||||
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<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);
|
||||
if (cur) {
|
||||
ostringstream msg;
|
||||
msg << name << " definition conflicts with "
|
||||
msg << nm << " definition conflicts with "
|
||||
<< "definition at " << cur->get_line()
|
||||
<< ".";
|
||||
VLerror(msg.str().c_str());
|
||||
|
|
@ -1196,7 +1198,7 @@ void pform_makewire(const vlltype&li, const char*nm,
|
|||
ivl_variable_type_t dt,
|
||||
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);
|
||||
|
||||
|
|
@ -1206,7 +1208,7 @@ void pform_makewire(const vlltype&li, const char*nm,
|
|||
bool rc = cur->set_wire_type(type);
|
||||
if (rc == false) {
|
||||
ostringstream msg;
|
||||
msg << name << " definition conflicts with "
|
||||
msg << nm << " definition conflicts with "
|
||||
<< "definition at " << cur->get_line()
|
||||
<< ".";
|
||||
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);
|
||||
|
||||
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);
|
||||
if (cur != 0) {
|
||||
PEIdent*lval = new PEIdent(hname_t(first_name));
|
||||
PEIdent*lval = new PEIdent(first_name);
|
||||
lval->set_file(li.text);
|
||||
lval->set_lineno(li.first_line);
|
||||
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,
|
||||
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);
|
||||
if (cur == 0) {
|
||||
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:
|
||||
cerr << file << ":" << lineno << ": error: "
|
||||
<< "port " << name << " is not in the port list."
|
||||
<< "port " << nm << " is not in the port list."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << file << ":" << lineno << ": error: "
|
||||
<< "port " << name << " already has a port declaration."
|
||||
<< "port " << nm << " already has a port declaration."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
break;
|
||||
|
|
@ -1392,7 +1394,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
|||
; cur != names->end() ; 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
|
||||
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)
|
||||
{
|
||||
hname_t path (name);
|
||||
pform_name_t path = hier_name(name);
|
||||
|
||||
if (PWire*cur = pform_cur_module->get_wire(path)) {
|
||||
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;
|
||||
}
|
||||
|
||||
void pform_set_defparam(const hname_t&name, PExpr*expr)
|
||||
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
|
||||
{
|
||||
assert(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)
|
||||
{
|
||||
hname_t name = hier_name(nm);
|
||||
pform_name_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
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)
|
||||
{
|
||||
hname_t name = hier_name(nm);
|
||||
pform_name_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||
|
|
@ -1695,7 +1697,9 @@ svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
|
|||
; cur != names->end()
|
||||
; 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::PINPUT,
|
||||
IVL_VT_LOGIC);
|
||||
|
|
@ -1769,6 +1773,10 @@ int pform_parse(const char*path, FILE*file)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -261,7 +261,7 @@ extern void pform_set_localparam(perm_string name,
|
|||
bool signed_flag,
|
||||
svector<PExpr*>*range,
|
||||
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.
|
||||
|
|
@ -340,6 +340,10 @@ extern void pform_dump(ostream&out, Module*mod);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -72,6 +72,58 @@ ostream& operator<< (ostream&o, PGate::strength_t str)
|
|||
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
|
||||
{
|
||||
out << typeid(*this).name();
|
||||
|
|
@ -145,29 +197,6 @@ void PENumber::dump(ostream&out) const
|
|||
void PEIdent::dump(ostream&out) const
|
||||
{
|
||||
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
|
||||
|
|
@ -811,7 +840,7 @@ void PGenerate::dump(ostream&out) const
|
|||
|
||||
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).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<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()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
out << " parameter ";
|
||||
|
|
@ -931,7 +960,7 @@ void Module::dump(ostream&out) const
|
|||
}
|
||||
|
||||
// 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 ++ ) {
|
||||
|
||||
|
|
@ -1032,6 +1061,10 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
/*
|
||||
* 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,
|
||||
const NetExpr*&par,
|
||||
NetEvent*&eve,
|
||||
|
|
@ -36,7 +36,8 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
|
|||
assert(scope);
|
||||
|
||||
/* 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. */
|
||||
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
|
||||
scope that we are supposed to search. */
|
||||
if (path.peek_name(0))
|
||||
if (! path.empty())
|
||||
scope = des->find_scope(scope, path);
|
||||
|
||||
while (scope) {
|
||||
|
|
@ -69,6 +70,10 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue