Redesign the implementation of scopes and parameters.
I now generate the scopes and notice the parameters in a separate pass over the pform. Once the scopes are generated, I can process overrides and evalutate paremeters before elaboration begins.
This commit is contained in:
parent
0fbca815b4
commit
e7efc2709a
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.36 2000/02/05 06:40:35 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.37 2000/03/08 04:36:53 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -70,8 +70,9 @@ TT = t-null.o t-verilog.o t-vvm.o t-xnf.o
|
|||
FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o xnfsyn.o
|
||||
|
||||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_net.o emit.o eval.o eval_tree.o expr_synth.o functor.o \
|
||||
lexor.o lexor_keyword.o mangle.o netlist.o pad_to_width.o \
|
||||
elab_net.o elab_pexpr.o elab_scope.o emit.o eval.o eval_tree.o \
|
||||
expr_synth.o functor.o lexor.o lexor_keyword.o mangle.o netlist.o \
|
||||
net_design.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \
|
||||
|
|
|
|||
21
Module.h
21
Module.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.h,v 1.14 2000/02/23 02:56:53 steve Exp $"
|
||||
#ident "$Id: Module.h,v 1.15 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
|
|
@ -66,6 +66,12 @@ class Module {
|
|||
into this map. */
|
||||
map<string,PExpr*>parameters;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
map<string,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
but rather refer to parameters in the order they
|
||||
|
|
@ -101,9 +107,9 @@ class Module {
|
|||
const list<PProcess*>& get_behaviors() const { return behaviors_; }
|
||||
|
||||
void dump(ostream&out) const;
|
||||
bool elaborate(Design*, NetScope*scope,
|
||||
named<PExpr*>*parms, unsigned nparms,
|
||||
svector<PExpr*>*overrides_) const;
|
||||
bool elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
bool elaborate_scope(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
|
|
@ -123,6 +129,13 @@ class Module {
|
|||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.15 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.14 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
37
PExpr.h
37
PExpr.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.29 2000/02/23 02:56:53 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.30 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
|
@ -32,6 +32,7 @@ class Design;
|
|||
class Module;
|
||||
class NetNet;
|
||||
class NetExpr;
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
* The PExpr class hierarchy supports the description of
|
||||
|
|
@ -49,7 +50,13 @@ class PExpr : public LineInfo {
|
|||
virtual void dump(ostream&) const;
|
||||
|
||||
// Procedural elaboration of the expression.
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
|
||||
|
||||
// Elaborate expressions that are the r-value of parameter
|
||||
// assignments. This elaboration follows the restrictions of
|
||||
// constant expressions and supports later overriding and
|
||||
// evaluation of parameters.
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
// This method elaborate the expression as gates, for use in a
|
||||
// continuous assign or other wholly structural context.
|
||||
|
|
@ -97,7 +104,7 @@ class PEConcat : public PExpr {
|
|||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private:
|
||||
|
|
@ -140,7 +147,7 @@ class PEIdent : public PExpr {
|
|||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
|
@ -182,7 +189,8 @@ class PENumber : public PExpr {
|
|||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
virtual bool is_the_same(const PExpr*that) const;
|
||||
|
|
@ -200,7 +208,7 @@ class PEString : public PExpr {
|
|||
|
||||
string value() const { return text_; }
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
|
|
@ -220,7 +228,7 @@ class PEUnary : public PExpr {
|
|||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
|
||||
|
||||
private:
|
||||
char op_;
|
||||
|
|
@ -241,7 +249,7 @@ class PEBinary : public PExpr {
|
|||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
private:
|
||||
|
|
@ -299,7 +307,7 @@ class PETernary : public PExpr {
|
|||
unsigned long rise =0,
|
||||
unsigned long fall =0,
|
||||
unsigned long decay =0) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
private:
|
||||
|
|
@ -317,17 +325,24 @@ class PECallFunction : public PExpr {
|
|||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
svector<PExpr *> parms_;
|
||||
|
||||
NetESFunc* elaborate_sfunc_(Design*des, const string&path) const;
|
||||
NetESFunc* elaborate_sfunc_(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.30 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.29 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
13
PGate.cc
13
PGate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.cc,v 1.7 2000/02/23 02:56:53 steve Exp $"
|
||||
#ident "$Id: PGate.cc,v 1.8 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PGate.h"
|
||||
|
|
@ -50,6 +50,10 @@ PGate::~PGate()
|
|||
{
|
||||
}
|
||||
|
||||
void PGate::elaborate_scope(Design*, NetScope*) const
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is used during elaboration to calculate the
|
||||
* rise/fall/decay times for the gate. These values were set in pform
|
||||
|
|
@ -148,6 +152,13 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
|||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* Revision 1.8 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
13
PGate.h
13
PGate.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.h,v 1.14 2000/02/23 02:56:53 steve Exp $"
|
||||
#ident "$Id: PGate.h,v 1.15 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
class PExpr;
|
||||
class PUdp;
|
||||
class Design;
|
||||
class NetScope;
|
||||
class Module;
|
||||
|
||||
/*
|
||||
|
|
@ -69,6 +70,7 @@ class PGate : public LineInfo {
|
|||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, const string&path) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
|
||||
protected:
|
||||
const svector<PExpr*>* get_pins() const { return pins_; }
|
||||
|
|
@ -175,6 +177,7 @@ class PGModule : public PGate {
|
|||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, const string&path) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
|
||||
private:
|
||||
string type_;
|
||||
|
|
@ -192,10 +195,18 @@ class PGModule : public PGate {
|
|||
|
||||
void elaborate_mod_(Design*, Module*mod, const string&path) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.15 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.14 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
22
PTask.h
22
PTask.h
|
|
@ -19,13 +19,14 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.h,v 1.7 2000/02/23 02:56:53 steve Exp $"
|
||||
#ident "$Id: PTask.h,v 1.8 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PWire;
|
||||
class Statement;
|
||||
|
||||
|
|
@ -38,6 +39,12 @@ class PTask : public LineInfo {
|
|||
explicit PTask(svector<PWire*>*p, Statement*s);
|
||||
~PTask();
|
||||
|
||||
// Tasks introduce scope, to need to be handled during the
|
||||
// scope elaboration pass. The scope passed is my scope,
|
||||
// created by the containing scope. I fill it in with stuff if
|
||||
// I need to.
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
void elaborate_1(Design*des, const string&path) const;
|
||||
void elaborate_2(Design*des, const string&path) const;
|
||||
|
||||
|
|
@ -65,9 +72,11 @@ class PFunction : public LineInfo {
|
|||
|
||||
void set_output(PWire*);
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
/* Functions are elaborated in 2 passes. */
|
||||
void elaborate_1(Design *des, const string &path) const;
|
||||
void elaborate_2(Design *des, const string &path) const;
|
||||
void elaborate_1(Design *des, NetScope*) const;
|
||||
void elaborate_2(Design *des, NetScope*) const;
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
|
|
@ -79,6 +88,13 @@ class PFunction : public LineInfo {
|
|||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* Revision 1.8 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
27
README.txt
27
README.txt
|
|
@ -104,6 +104,33 @@ optimized netlist by using the ``-N <path>'' flag to the compiler. If
|
|||
elaboration succeeds, the final netlist (i.e. after optimizations but
|
||||
before code generation) will be dumped into the file named <path>.
|
||||
|
||||
Elaboration is actually performed it two steps: scopes and parameters
|
||||
first, followed by the structural and behavioral elaboration.
|
||||
|
||||
3.3.1 Scope Elaboration
|
||||
|
||||
This pass scans through the pform looking for scopes and
|
||||
parameters. A tree of NetScope objects is built up and placed in the
|
||||
Design object, with the root module represented by the root NetScope
|
||||
object.
|
||||
|
||||
The elab_scope.cc and elab_pexpr.cc files contain most of the code for
|
||||
handling this phase.
|
||||
|
||||
The tail of the elaborate_scope behavior (after the pform is
|
||||
traversed) includes a scan of the NetScope tree to locate defparam
|
||||
assignments that were collected during scope elaboration. This is when
|
||||
the defparam overrides are applied to the parameters.
|
||||
|
||||
3.3.2 Netlist Elaboration
|
||||
|
||||
After the scopes and parameters are generated and the NetScope tree
|
||||
fully formed, the elaboration runs through teh pform again, this time
|
||||
generating the structural and behavioral netlist. Parameters are
|
||||
elaborated and evaluated by now so all the constants of code
|
||||
generation are now known locally, so the netlist can be generated by
|
||||
simply passing through the pform.
|
||||
|
||||
3.4 Optimization
|
||||
|
||||
This is actually a collection of processing steps that perform
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: design_dump.cc,v 1.67 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.68 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -523,7 +523,7 @@ void NetForever::dump(ostream&o, unsigned ind) const
|
|||
|
||||
void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "function " << name_ << endl;
|
||||
o << setw(ind) << "" << "function " << scope_->name() << endl;
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
else
|
||||
|
|
@ -596,11 +596,41 @@ void NetScope::dump(ostream&o) const
|
|||
case FORK_JOIN:
|
||||
o << " parallel block";
|
||||
break;
|
||||
case FUNC:
|
||||
o << " function";
|
||||
break;
|
||||
case MODULE:
|
||||
o << " module";
|
||||
break;
|
||||
case TASK:
|
||||
o << " task";
|
||||
break;
|
||||
}
|
||||
o << endl;
|
||||
|
||||
/* Dump the parameters for this scope. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
for (pp = parameters_.begin()
|
||||
; pp != parameters_.end() ; pp ++) {
|
||||
o << " parameter " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the saved defparam assignments here. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin()
|
||||
; pp != defparams.end() ; pp ++ ) {
|
||||
o << " defparam " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump any sub-scopes. */
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->dump(o);
|
||||
}
|
||||
|
||||
void NetSTask::dump(ostream&o, unsigned ind) const
|
||||
|
|
@ -756,7 +786,7 @@ void NetEMemory::dump(ostream&o) const
|
|||
|
||||
void NetEParam::dump(ostream&o) const
|
||||
{
|
||||
o << "<" << path_ << "." << name_ << ">";
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
}
|
||||
|
||||
void NetETernary::dump(ostream&o) const
|
||||
|
|
@ -795,22 +825,7 @@ void NetEUnary::dump(ostream&o) const
|
|||
void Design::dump(ostream&o) const
|
||||
{
|
||||
o << "SCOPES:" << endl;
|
||||
{
|
||||
map<string,NetScope*>::const_iterator pp;
|
||||
for (pp = scopes_.begin()
|
||||
; pp != scopes_.end() ; pp ++)
|
||||
(*pp).second -> dump(o);
|
||||
}
|
||||
|
||||
o << "ELABORATED PARAMETERS:" << endl;
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
for (pp = parameters_.begin()
|
||||
; pp != parameters_.end() ; pp ++) {
|
||||
o << " " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
}
|
||||
}
|
||||
root_scope_->dump(o);
|
||||
|
||||
o << "ELABORATED SIGNALS:" << endl;
|
||||
|
||||
|
|
@ -871,6 +886,13 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.68 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.67 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
137
elab_expr.cc
137
elab_expr.cc
|
|
@ -17,23 +17,30 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_expr.cc,v 1.16 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: elab_expr.cc,v 1.17 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "pform.h"
|
||||
# include "netlist.h"
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": I do not know how to elaborate expression: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate binary expressions. This involves elaborating the left
|
||||
* and right sides, and creating one of a variety of different NetExpr
|
||||
* types.
|
||||
*/
|
||||
NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag;
|
||||
NetExpr*lp = left_->elaborate_expr(des, path);
|
||||
NetExpr*rp = right_->elaborate_expr(des, path);
|
||||
NetExpr*lp = left_->elaborate_expr(des, scope);
|
||||
NetExpr*rp = right_->elaborate_expr(des, scope);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
delete lp;
|
||||
delete rp;
|
||||
|
|
@ -116,7 +123,7 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
|
|||
return tmp;
|
||||
}
|
||||
|
||||
NetESFunc* PECallFunction::elaborate_sfunc_(Design*des, const string&path) const
|
||||
NetESFunc* PECallFunction::elaborate_sfunc_(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": sorry: system functions not supported."
|
||||
<< endl;
|
||||
|
|
@ -124,29 +131,39 @@ NetESFunc* PECallFunction::elaborate_sfunc_(Design*des, const string&path) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, const string&path) const
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (name_[0] == '$')
|
||||
return elaborate_sfunc_(des, path);
|
||||
return elaborate_sfunc_(des, scope);
|
||||
|
||||
string myname = path+"."+name_;
|
||||
NetFuncDef*def = des->find_function(path, name_);
|
||||
NetFuncDef*def = des->find_function(scope->name(), name_);
|
||||
if (def == 0) {
|
||||
cerr << get_line() << ": error: No function " << name_ <<
|
||||
" in this context (" << path << ")." << endl;
|
||||
" in this context (" << scope->name() << ")." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
assert(def);
|
||||
|
||||
|
||||
svector<NetExpr*> parms (parms_.count());
|
||||
|
||||
/* Elaborate the input expressions for the function. This is
|
||||
done in the scope of the function call, and not the scope
|
||||
of the function being called. The scope of the called
|
||||
function is elaborated when the definition is elaborated. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
|
||||
NetExpr*tmp = parms_[idx]->elaborate_expr(des, myname);
|
||||
NetExpr*tmp = parms_[idx]->elaborate_expr(des, scope);
|
||||
parms[idx] = tmp;
|
||||
}
|
||||
|
||||
/* Look for the return value signal for the called function in
|
||||
the context of the function definition, not my context. */
|
||||
|
||||
/* Look for the return value signal for the called
|
||||
function. This return value is a magic signal in the scope
|
||||
of the function, that has the name of the function. The
|
||||
function code assigns to this signal to return a value. */
|
||||
|
||||
NetNet*res = des->find_signal(def->name(), name_);
|
||||
if (res == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to locate "
|
||||
|
|
@ -164,14 +181,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, const string&path) const
|
|||
}
|
||||
|
||||
|
||||
NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const
|
||||
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned repeat = 1;
|
||||
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count. */
|
||||
if (repeat_) {
|
||||
verinum*vrep = repeat_->eval_const(des, path);
|
||||
verinum*vrep = repeat_->eval_const(des, scope->name());
|
||||
if (vrep == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
|
|
@ -191,7 +208,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const
|
|||
/* Elaborate all the parameters and attach them to the concat node. */
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_expr(des, path);
|
||||
NetExpr*ex = parms_[idx]->elaborate_expr(des, scope);
|
||||
if (ex == 0) continue;
|
||||
ex->set_line(*parms_[idx]);
|
||||
tmp->set(idx, ex);
|
||||
|
|
@ -200,22 +217,23 @@ NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const
|
|||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
// System identifiers show up in the netlist as identifiers.
|
||||
if (text_[0] == '$')
|
||||
return new NetEIdent(text_, 64);
|
||||
|
||||
string name = path+"."+text_;
|
||||
//string name = path+"."+text_;
|
||||
assert(scope);
|
||||
|
||||
// If the identifier name is a parameter name, then return
|
||||
// a reference to the parameter expression.
|
||||
if (const NetExpr*ex = des->find_parameter(path, text_)) {
|
||||
if (const NetExpr*ex = des->find_parameter(scope, text_)) {
|
||||
NetExpr*tmp;
|
||||
if (dynamic_cast<const NetExpr*>(ex))
|
||||
tmp = ex->dup_expr();
|
||||
else
|
||||
tmp = new NetEParam(des, path, text_);
|
||||
tmp = new NetEParam(des, scope, text_);
|
||||
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
|
|
@ -223,15 +241,15 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
|
||||
// If the identifier names a signal (a register or wire)
|
||||
// then create a NetESignal node to handle it.
|
||||
if (NetNet*net = des->find_signal(path, text_)) {
|
||||
if (NetNet*net = des->find_signal(scope->name(), text_)) {
|
||||
|
||||
// If this is a part select of a signal, then make a new
|
||||
// temporary signal that is connected to just the
|
||||
// selected bits.
|
||||
if (lsb_) {
|
||||
assert(msb_);
|
||||
verinum*lsn = lsb_->eval_const(des, path);
|
||||
verinum*msn = msb_->eval_const(des, path);
|
||||
verinum*lsn = lsb_->eval_const(des, scope->name());
|
||||
verinum*msn = msb_->eval_const(des, scope->name());
|
||||
if ((lsn == 0) || (msn == 0)) {
|
||||
cerr << get_line() << ": error: "
|
||||
"Part select expresions must be "
|
||||
|
|
@ -248,7 +266,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
assert(wid <= net->pin_count());
|
||||
assert(net->sb_to_idx(msv) >= net->sb_to_idx(lsv));
|
||||
|
||||
string tname = des->local_symbol(path);
|
||||
string tname = des->local_symbol(scope->name());
|
||||
NetTmp*tsig = new NetTmp(tname, wid);
|
||||
|
||||
// Connect the pins from the lsb up to the msb.
|
||||
|
|
@ -267,11 +285,11 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
// to the part select, so that I save the effort of
|
||||
// making a mux part in the netlist.
|
||||
verinum*msn;
|
||||
if (msb_ && (msn = msb_->eval_const(des, path))) {
|
||||
if (msb_ && (msn = msb_->eval_const(des, scope->name()))) {
|
||||
assert(idx_ == 0);
|
||||
unsigned long msv = msn->as_ulong();
|
||||
|
||||
string tname = des->local_symbol(path);
|
||||
string tname = des->local_symbol(scope->name());
|
||||
NetTmp*tsig = new NetTmp(tname);
|
||||
connect(tsig->pin(0), net->pin(msv));
|
||||
NetESignal*tmp = new NetESignal(tsig);
|
||||
|
|
@ -287,7 +305,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
// Non-constant bit select? punt and make a subsignal
|
||||
// device to mux the bit in the net.
|
||||
if (msb_) {
|
||||
NetExpr*ex = msb_->elaborate_expr(des, path);
|
||||
NetExpr*ex = msb_->elaborate_expr(des, scope);
|
||||
NetESubSignal*ss = new NetESubSignal(node, ex);
|
||||
ss->set_line(*this);
|
||||
return ss;
|
||||
|
|
@ -302,22 +320,16 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
// If the identifier names a memory, then this is a
|
||||
// memory reference and I must generate a NetEMemory
|
||||
// object to handle it.
|
||||
if (NetMemory*mem = des->find_memory(path, text_)) {
|
||||
if (NetMemory*mem = des->find_memory(scope->name(), text_)) {
|
||||
if (msb_ == 0) {
|
||||
NetEMemory*node = new NetEMemory(mem);
|
||||
node->set_line(*this);
|
||||
return node;
|
||||
#if 0
|
||||
cerr << get_line() << ": error: Memory ``" << name <<
|
||||
"'' referenced without an index expression." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
assert(msb_ != 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_ == 0);
|
||||
NetExpr*i = msb_->elaborate_expr(des, path);
|
||||
NetExpr*i = msb_->elaborate_expr(des, scope);
|
||||
if (msb_ && i == 0) {
|
||||
cerr << get_line() << ": error: Unable to exaborate "
|
||||
"index expression `" << *msb_ << "'" << endl;
|
||||
|
|
@ -339,33 +351,48 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
|
||||
// I cannot interpret this identifier. Error message.
|
||||
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
|
||||
"`" << path << "." << text_ << "'" << endl;
|
||||
"`" << text_ << "' in `" << scope->name() << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
|
||||
{
|
||||
assert(value_);
|
||||
NetEConst*tmp = new NetEConst(*value_);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the Ternary operator. I know that the expressions were
|
||||
* parsed so I can presume that they exist, and call elaboration
|
||||
* methods. If any elaboration fails, then give up and return 0.
|
||||
*/
|
||||
NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const
|
||||
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(expr_);
|
||||
assert(tru_);
|
||||
assert(fal_);
|
||||
|
||||
NetExpr*con = expr_->elaborate_expr(des, path);
|
||||
NetExpr*con = expr_->elaborate_expr(des, scope);
|
||||
if (con == 0)
|
||||
return 0;
|
||||
|
||||
NetExpr*tru = tru_->elaborate_expr(des, path);
|
||||
NetExpr*tru = tru_->elaborate_expr(des, scope);
|
||||
if (tru == 0) {
|
||||
delete con;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*fal = fal_->elaborate_expr(des, path);
|
||||
NetExpr*fal = fal_->elaborate_expr(des, scope);
|
||||
if (fal == 0) {
|
||||
delete con;
|
||||
delete tru;
|
||||
|
|
@ -376,8 +403,38 @@ NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const
|
|||
return res;
|
||||
}
|
||||
|
||||
NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*ip = expr_->elaborate_expr(des, scope);
|
||||
if (ip == 0) return 0;
|
||||
|
||||
/* Should we evaluate expressions ahead of time,
|
||||
* just like in PEBinary::elaborate_expr() ?
|
||||
*/
|
||||
|
||||
NetEUnary*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
case '~':
|
||||
tmp = new NetEUBits(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.17 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.16 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
11
elab_net.cc
11
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_net.cc,v 1.23 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: elab_net.cc,v 1.24 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PExpr.h"
|
||||
|
|
@ -823,7 +823,7 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path,
|
|||
rise, fall, decay);
|
||||
|
||||
|
||||
if (const NetExpr*pe = des->find_parameter(path, text_)) {
|
||||
if (const NetExpr*pe = des->find_parameter(scope, text_)) {
|
||||
|
||||
const NetEConst*pc = dynamic_cast<const NetEConst*>(pe);
|
||||
assert(pc);
|
||||
|
|
@ -1336,6 +1336,13 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path,
|
|||
|
||||
/*
|
||||
* $Log: elab_net.cc,v $
|
||||
* Revision 1.24 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.23 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_pexpr.cc,v 1.1 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PExpr.h"
|
||||
|
||||
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
cerr << get_line() << ": error: invalid parameter expression: "
|
||||
<< *this << endl;
|
||||
des->errors += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple numbers can be elaborated by the elaborate_expr method.
|
||||
*/
|
||||
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
return elaborate_expr(des, sc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.1 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_scope.cc,v 1.1 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Elaboration happens in two passes, generally. The first scans the
|
||||
* pform to generate the NetScope tree and attach it to the Design
|
||||
* object. The methods in this source file implement the elaboration
|
||||
* of the scopes.
|
||||
*/
|
||||
|
||||
# include "Module.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PTask.h"
|
||||
# include "netlist.h"
|
||||
|
||||
bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Generate all the parameters that this instance of this
|
||||
// module introduces to the design. This loop elaborates the
|
||||
// parameters, but doesn't evaluate references to
|
||||
// parameters. This scan practically locates all the
|
||||
// parameters and puts them in the parameter table in the
|
||||
// design.
|
||||
|
||||
// No expressions are evaluated, yet. For now, leave them in
|
||||
// the pform and just place a NetEParam placeholder in the
|
||||
// place of the elaborated expression.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
|
||||
|
||||
// This loop scans the parameters in the module, and creates
|
||||
// stub parameter entries in the scope for the parameter name.
|
||||
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
scope->set_parameter((*cur).first, new NetEParam);
|
||||
}
|
||||
|
||||
// Now scan the parameters again, this time elaborating them
|
||||
// for use as parameter values. This is after the previous
|
||||
// scan so that local parameter names can be used in the
|
||||
// r-value expressions.
|
||||
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
|
||||
// Run through the defparams for this module, elaborate the
|
||||
// expressions in this context and save the result is a table
|
||||
// for later final override.
|
||||
|
||||
// It is OK to elaborate the expressions of the defparam here
|
||||
// because Verilog requires that the expressions only use
|
||||
// local parameter names. It is *not* OK to do the override
|
||||
// here becuase the parameter receiving the assignment may be
|
||||
// in a scope not discovered by this pass.
|
||||
|
||||
for (mparm_it_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; cur ++ ) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
if (val == 0) continue;
|
||||
scope->defparams[(*cur).first] = val;
|
||||
}
|
||||
|
||||
|
||||
// Tasks introduce new scopes, so scan the tasks in this
|
||||
// module. Create a scope for the task and pass that to the
|
||||
// elaborate_scope method of the PTask for detailed
|
||||
// processing.
|
||||
|
||||
typedef map<string,PTask*>::const_iterator tasks_it_t;
|
||||
|
||||
for (tasks_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, (*cur).first,
|
||||
NetScope::TASK);
|
||||
(*cur).second->elaborate_scope(des, task_scope);
|
||||
}
|
||||
|
||||
|
||||
// Functions are very similar to tasks, at least from the
|
||||
// perspective of scopes. So handle them exactly the same
|
||||
// way.
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator funcs_it_t;
|
||||
|
||||
for (funcs_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*func_scope = new NetScope(scope, (*cur).first,
|
||||
NetScope::FUNC);
|
||||
(*cur).second->elaborate_scope(des, func_scope);
|
||||
}
|
||||
|
||||
|
||||
// Gates include modules, which might introduce new scopes, so
|
||||
// scan all of them to create those scopes.
|
||||
|
||||
typedef list<PGate*>::const_iterator gates_it_t;
|
||||
|
||||
for (gates_it_t cur = gates_.begin()
|
||||
; cur != gates_.end() ; cur ++ ) {
|
||||
|
||||
(*cur)->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
|
||||
return des->errors == 0;
|
||||
}
|
||||
|
||||
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
{
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
|
||||
string path = sc->name();
|
||||
|
||||
// Check for duplicate scopes. Simply look up the scope I'm
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (NetScope*tmp = des->find_scope(path + "." + get_name())) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = des->make_scope(path, NetScope::MODULE, get_name());
|
||||
|
||||
// This call actually arranges for the description of the
|
||||
// module type to process this instance and handle parameters
|
||||
// and sub-scopes that might occur. Parameters are also
|
||||
// created in that scope, as they exist. (I'll override them
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
|
||||
// Look for module parameter replacements. This map receives
|
||||
// those replacements.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
|
||||
|
||||
// Positional parameter overrides are matched to parameter
|
||||
// names by using the param_names list of parameter
|
||||
// names. This is an ordered list of names so the first name
|
||||
// is parameter 0, the second parameter 1, and so on.
|
||||
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<string>::const_iterator cur = mod->param_names.begin();
|
||||
for (unsigned idx = 0
|
||||
; idx < overrides_->count()
|
||||
; idx += 1, cur++) {
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
||||
replace[parms_[idx].name] = parms_[idx].parm;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// And here we scan the replacements we collected. Elaborate
|
||||
// the expression in my context, then replace the sub-scope
|
||||
// parameter value with the new expression.
|
||||
|
||||
for (mparm_it_t cur = replace.begin()
|
||||
; cur != replace.end() ; cur ++ ) {
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
val = my_scope->set_parameter((*cur).first, val);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
}
|
||||
|
||||
void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
}
|
||||
|
||||
void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* Revision 1.1 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
*/
|
||||
|
||||
486
elaborate.cc
486
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elaborate.cc,v 1.145 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.146 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -385,14 +385,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
|||
{
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
// Check for duplicate scopes.
|
||||
if (NetScope*tmp = des->find_scope(path + "." + get_name())) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (msb_) {
|
||||
cerr << get_line() << ": sorry: Module instantiation arrays "
|
||||
|
|
@ -401,7 +393,13 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
|||
return;
|
||||
}
|
||||
|
||||
NetScope*my_scope = des->make_scope(path, NetScope::MODULE, get_name());
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
// I know a priori that the elaborate_scope created the scope
|
||||
// already, so just look it up as a child of the current scope.
|
||||
NetScope*my_scope = scope->child(get_name());
|
||||
assert(my_scope);
|
||||
const string my_name = my_scope -> name();
|
||||
|
||||
const svector<PExpr*>*pins;
|
||||
|
|
@ -471,7 +469,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
|||
// elaboration causes the module to generate a netlist with
|
||||
// the ports represented by NetNet objects. I will find them
|
||||
// later.
|
||||
rmod->elaborate(des, my_scope, parms_, nparms_, overrides_);
|
||||
rmod->elaborate(des, my_scope);
|
||||
|
||||
// Now connect the ports of the newly elaborated designs to
|
||||
// the expressions that are the instantiation parameters. Scan
|
||||
|
|
@ -614,7 +612,27 @@ void PGModule::elaborate(Design*des, const string&path) const
|
|||
return;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": error: Unknown module: " << type_ << endl;
|
||||
cerr << get_line() << ": internal error: Unknown module type: " <<
|
||||
type_ << endl;
|
||||
}
|
||||
|
||||
void PGModule::elaborate_scope(Design*des, NetScope*sc) const
|
||||
{
|
||||
// Look for the module type
|
||||
map<string,Module*>::const_iterator mod = modlist->find(type_);
|
||||
if (mod != modlist->end()) {
|
||||
elaborate_scope_mod_(des, (*mod).second, sc);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try a primitive type
|
||||
map<string,PUdp*>::const_iterator udp = udplist->find(type_);
|
||||
if (udp != udplist->end())
|
||||
return;
|
||||
|
||||
|
||||
cerr << get_line() << ": error: Unknown module type: " << type_ << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -672,51 +690,6 @@ NetNet* PEConcat::elaborate_lnet(Design*des, const string&path) const
|
|||
return osig;
|
||||
}
|
||||
|
||||
NetExpr* PENumber::elaborate_expr(Design*des, const string&path) const
|
||||
{
|
||||
assert(value_);
|
||||
NetEConst*tmp = new NetEConst(*value_);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEString::elaborate_expr(Design*des, const string&path) const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, const string&path) const
|
||||
{
|
||||
cerr << get_line() << ": I do not know how to elaborate expression: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr* PEUnary::elaborate_expr(Design*des, const string&path) const
|
||||
{
|
||||
NetExpr*ip = expr_->elaborate_expr(des, path);
|
||||
if (ip == 0) return 0;
|
||||
|
||||
/* Should we evaluate expressions ahead of time,
|
||||
* just like in PEBinary::elaborate_expr() ?
|
||||
*/
|
||||
|
||||
NetEUnary*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
case '~':
|
||||
tmp = new NetEUBits(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetProc* Statement::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
cerr << "internal error: elaborate: What kind of statement? " <<
|
||||
|
|
@ -728,7 +701,9 @@ NetProc* Statement::elaborate(Design*des, const string&path) const
|
|||
NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix,
|
||||
Design*des, const string&path) const
|
||||
{
|
||||
NetExpr*rv = rval()->elaborate_expr(des, path);
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
NetExpr*rv = rval()->elaborate_expr(des, scope);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -751,6 +726,9 @@ NetNet* PAssign_::elaborate_lval(Design*des, const string&path,
|
|||
unsigned&msb, unsigned&lsb,
|
||||
NetExpr*&mux) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
/* Get the l-value, and assume that it is an identifier. */
|
||||
const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
|
||||
|
||||
|
|
@ -828,7 +806,7 @@ NetNet* PAssign_::elaborate_lval(Design*des, const string&path,
|
|||
assert(id->lsb_ == 0);
|
||||
verinum*v = id->msb_->eval_const(des, path);
|
||||
if (v == 0) {
|
||||
NetExpr*m = id->msb_->elaborate_expr(des, path);
|
||||
NetExpr*m = id->msb_->elaborate_expr(des, scope);
|
||||
assert(m);
|
||||
msb = 0;
|
||||
lsb = 0;
|
||||
|
|
@ -858,6 +836,9 @@ NetNet* PAssign_::elaborate_lval(Design*des, const string&path,
|
|||
|
||||
NetProc* PAssign::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
/* Catch the case where the lvalue is a reference to a memory
|
||||
item. These are handled differently. */
|
||||
do {
|
||||
|
|
@ -891,7 +872,7 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
|
|||
rv = new NetEConst(*val);
|
||||
delete val;
|
||||
|
||||
} else if (rv = rval()->elaborate_expr(des, path)) {
|
||||
} else if (rv = rval()->elaborate_expr(des, scope)) {
|
||||
|
||||
/* OK, go on. */
|
||||
|
||||
|
|
@ -1036,8 +1017,11 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
|
|||
NetProc* PAssignNB::assign_to_memory_(NetMemory*mem, PExpr*ix,
|
||||
Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
/* Elaborate the r-value expression, ... */
|
||||
NetExpr*rv = rval()->elaborate_expr(des, path);
|
||||
NetExpr*rv = rval()->elaborate_expr(des, scope);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1065,6 +1049,9 @@ NetProc* PAssignNB::assign_to_memory_(NetMemory*mem, PExpr*ix,
|
|||
*/
|
||||
NetProc* PAssignNB::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
/* Catch the case where the lvalue is a reference to a memory
|
||||
item. These are handled differently. */
|
||||
do {
|
||||
|
|
@ -1086,7 +1073,7 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const
|
|||
|
||||
/* Elaborate the r-value expression. This generates a
|
||||
procedural expression that I attach to the assignment. */
|
||||
NetExpr*rv = rval()->elaborate_expr(des, path);
|
||||
NetExpr*rv = rval()->elaborate_expr(des, scope);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1132,6 +1119,9 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const
|
|||
*/
|
||||
NetProc* PBlock::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetBlock::Type type = (bl_type_==PBlock::BL_PAR)
|
||||
? NetBlock::PARA
|
||||
: NetBlock::SEQU;
|
||||
|
|
@ -1139,19 +1129,14 @@ NetProc* PBlock::elaborate(Design*des, const string&path) const
|
|||
bool fail_flag = false;
|
||||
|
||||
string npath;
|
||||
NetScope*nscope;
|
||||
if (name_.length()) {
|
||||
// Check for duplicate scopes.
|
||||
if (NetScope*tmp = des->find_scope(path + "." + name_)) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
name_ << " already used in this context." <<
|
||||
endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
// Make this new scope.
|
||||
npath = des->make_scope(path, NetScope::BEGIN_END, name_)->name();
|
||||
nscope = scope->child(name_);
|
||||
assert(nscope);
|
||||
npath = nscope->name();
|
||||
|
||||
} else {
|
||||
nscope = scope;
|
||||
npath = path;
|
||||
}
|
||||
|
||||
|
|
@ -1184,7 +1169,10 @@ NetProc* PBlock::elaborate(Design*des, const string&path) const
|
|||
*/
|
||||
NetProc* PCase::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetExpr*expr = expr_->elaborate_expr(des, path);
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetExpr*expr = expr_->elaborate_expr(des, scope);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": error: Unable to elaborate this case"
|
||||
" expression." << endl;
|
||||
|
|
@ -1229,7 +1217,7 @@ NetProc* PCase::elaborate(Design*des, const string&path) const
|
|||
NetExpr*gu = 0;
|
||||
NetProc*st = 0;
|
||||
assert(cur->expr[e]);
|
||||
gu = cur->expr[e]->elaborate_expr(des, path);
|
||||
gu = cur->expr[e]->elaborate_expr(des, scope);
|
||||
|
||||
if (cur->stat)
|
||||
st = cur->stat->elaborate(des, path);
|
||||
|
|
@ -1244,8 +1232,11 @@ NetProc* PCase::elaborate(Design*des, const string&path) const
|
|||
|
||||
NetProc* PCondit::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
// Elaborate and try to evaluate the conditional expression.
|
||||
NetExpr*expr = expr_->elaborate_expr(des, path);
|
||||
NetExpr*expr = expr_->elaborate_expr(des, scope);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": error: Unable to elaborate"
|
||||
" condition expression." << endl;
|
||||
|
|
@ -1321,12 +1312,15 @@ NetProc* PCallTask::elaborate(Design*des, const string&path) const
|
|||
*/
|
||||
NetProc* PCallTask::elaborate_sys(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
svector<NetExpr*>eparms (nparms());
|
||||
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
PExpr*ex = parm(idx);
|
||||
|
||||
eparms[idx] = ex? ex->elaborate_expr(des, path) : 0;
|
||||
eparms[idx] = ex? ex->elaborate_expr(des, scope) : 0;
|
||||
}
|
||||
|
||||
NetSTask*cur = new NetSTask(name(), eparms);
|
||||
|
|
@ -1363,6 +1357,9 @@ NetProc* PCallTask::elaborate_sys(Design*des, const string&path) const
|
|||
*/
|
||||
NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetTaskDef*def = des->find_task(path, name_);
|
||||
if (def == 0) {
|
||||
cerr << get_line() << ": error: Enable of unknown task ``" <<
|
||||
|
|
@ -1400,7 +1397,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
|||
if (port->port_type() == NetNet::POUTPUT)
|
||||
continue;
|
||||
|
||||
NetExpr*rv = parms_[idx]->elaborate_expr(des, path);
|
||||
NetExpr*rv = parms_[idx]->elaborate_expr(des, scope);
|
||||
NetAssign*pr = new NetAssign("@", des, port->pin_count(), rv);
|
||||
for (unsigned pi = 0 ; pi < port->pin_count() ; pi += 1)
|
||||
connect(port->pin(pi), pr->pin(pi));
|
||||
|
|
@ -1566,6 +1563,9 @@ NetProc* PForever::elaborate(Design*des, const string&path) const
|
|||
*/
|
||||
NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
const PEIdent*id1 = dynamic_cast<const PEIdent*>(name1_);
|
||||
assert(id1);
|
||||
const PEIdent*id2 = dynamic_cast<const PEIdent*>(name2_);
|
||||
|
|
@ -1585,7 +1585,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
|||
}
|
||||
assert(sig);
|
||||
NetAssign*init = new NetAssign("@for-assign", des, sig->pin_count(),
|
||||
expr1_->elaborate_expr(des, path));
|
||||
expr1_->elaborate_expr(des, scope));
|
||||
for (unsigned idx = 0 ; idx < init->pin_count() ; idx += 1)
|
||||
connect(init->pin(idx), sig->pin(idx));
|
||||
|
||||
|
|
@ -1608,7 +1608,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
|||
sig = des->find_signal(path, id2->name());
|
||||
assert(sig);
|
||||
NetAssign*step = new NetAssign("@for-assign", des, sig->pin_count(),
|
||||
expr2_->elaborate_expr(des, path));
|
||||
expr2_->elaborate_expr(des, scope));
|
||||
for (unsigned idx = 0 ; idx < step->pin_count() ; idx += 1)
|
||||
connect(step->pin(idx), sig->pin(idx));
|
||||
|
||||
|
|
@ -1618,7 +1618,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
|||
/* Elaborate the condition expression. Try to evaluate it too,
|
||||
in case it is a constant. This is an interesting case
|
||||
worthy of a warning. */
|
||||
NetExpr*ce = cond_->elaborate_expr(des, path);
|
||||
NetExpr*ce = cond_->elaborate_expr(des, scope);
|
||||
if (ce == 0) {
|
||||
delete top;
|
||||
return 0;
|
||||
|
|
@ -1647,8 +1647,12 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
|||
* within. These passes are needed because the statement may invoke
|
||||
* the function itself (or other functions) so can't be elaborated
|
||||
* until all the functions are partially elaborated.
|
||||
*
|
||||
* In both cases, the scope parameter is the scope of the function. In
|
||||
* other words, it is the scope that has the name of the function with
|
||||
* the path of the containing module.
|
||||
*/
|
||||
void PFunction::elaborate_1(Design*des, const string&path) const
|
||||
void PFunction::elaborate_1(Design*des, NetScope*scope) const
|
||||
{
|
||||
/* Translate the wires that are ports to NetNet pointers by
|
||||
presuming that the name is already elaborated, and look it
|
||||
|
|
@ -1656,26 +1660,27 @@ void PFunction::elaborate_1(Design*des, const string&path) const
|
|||
calls to the task. (Remember, the task itself does not need
|
||||
these ports.) */
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
ports[0] = des->find_signal(path, path);
|
||||
ports[0] = des->find_signal(scope->name(), scope->name());
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
NetNet*tmp = des->find_signal(path, (*ports_)[idx]->name());
|
||||
NetNet*tmp = des->find_signal(scope->name(),
|
||||
(*ports_)[idx]->name());
|
||||
|
||||
ports[idx+1] = tmp;
|
||||
}
|
||||
|
||||
NetFuncDef*def = new NetFuncDef(path, ports);
|
||||
des->add_function(path, def);
|
||||
NetFuncDef*def = new NetFuncDef(scope, ports);
|
||||
des->add_function(scope->name(), def);
|
||||
}
|
||||
|
||||
void PFunction::elaborate_2(Design*des, const string&path) const
|
||||
void PFunction::elaborate_2(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetFuncDef*def = des->find_function(path);
|
||||
NetFuncDef*def = des->find_function(scope->name());
|
||||
assert(def);
|
||||
|
||||
NetProc*st = statement_->elaborate(des, path);
|
||||
NetProc*st = statement_->elaborate(des, scope->name());
|
||||
if (st == 0) {
|
||||
cerr << statement_->get_line() << ": error: Unable to elaborate "
|
||||
"statement in function " << path << "." << endl;
|
||||
"statement in function " << def->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1685,7 +1690,10 @@ void PFunction::elaborate_2(Design*des, const string&path) const
|
|||
|
||||
NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetExpr*expr = expr_->elaborate_expr(des, path);
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetExpr*expr = expr_->elaborate_expr(des, scope);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": Unable to elaborate"
|
||||
" repeat expression." << endl;
|
||||
|
|
@ -1775,120 +1783,19 @@ void PTask::elaborate_2(Design*des, const string&path) const
|
|||
*/
|
||||
NetProc* PWhile::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, path),
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, scope),
|
||||
statement_->elaborate(des, path));
|
||||
return loop;
|
||||
}
|
||||
|
||||
bool Module::elaborate(Design*des, NetScope*scope,
|
||||
named<PExpr*>*parms, unsigned nparms,
|
||||
svector<PExpr*>*overrides_) const
|
||||
bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
const string path = scope->name();
|
||||
bool result_flag = true;
|
||||
|
||||
// Generate all the parameters that this instance of this
|
||||
// module introduce to the design. This needs to be done in
|
||||
// two passes. The first pass marks the parameter names as
|
||||
// available so that they can be discovered when the second
|
||||
// pass references them during elaboration.
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
|
||||
// So this loop elaborates the parameters, but doesn't
|
||||
// evaluate references to parameters. This scan practically
|
||||
// locates all the parameters and puts them in the parameter
|
||||
// table in the design. No expressions are evaluated.
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
string pname = path + "." + (*cur).first;
|
||||
des->set_parameter(pname, new NetEParam);
|
||||
}
|
||||
|
||||
// The replace map contains replacement expressions for the
|
||||
// parameters. If there is a replacement expression, use that
|
||||
// instead of the default expression. Otherwise, use the
|
||||
// default expression.
|
||||
|
||||
// Replacement expressions can come from the ordered list of
|
||||
// overrides, or from the parameter replace by name list.
|
||||
|
||||
map<string,PExpr*> replace;
|
||||
|
||||
if (overrides_) {
|
||||
assert(parms == 0);
|
||||
list<string>::const_iterator cur = param_names.begin();
|
||||
for (unsigned idx = 0
|
||||
; idx < overrides_->count()
|
||||
; idx += 1, cur++) {
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
}
|
||||
|
||||
} else if (parms) {
|
||||
|
||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1)
|
||||
replace[parms[idx].name] = parms[idx].parm;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ... and this loop elaborates the expressions. The parameter
|
||||
// expressions are reduced to ordinary expressions that do not
|
||||
// include references to other parameters. Take careful note
|
||||
// of the fact that override expressions are elaborated in the
|
||||
// *parent* scope.
|
||||
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
string pname = path + "." + (*cur).first;
|
||||
NetExpr*expr;
|
||||
|
||||
if (PExpr*tmp = replace[(*cur).first])
|
||||
expr = tmp->elaborate_expr(des, scope->parent()->name());
|
||||
else
|
||||
expr = (*cur).second->elaborate_expr(des, path);
|
||||
|
||||
des->set_parameter(pname, expr);
|
||||
}
|
||||
|
||||
|
||||
// Finally, evaluate the parameter value. This step collapses
|
||||
// the parameters to NetEConst values.
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
// Get the NetExpr for the parameter.
|
||||
string pname = path + "." + (*cur).first;
|
||||
const NetExpr*expr = des->find_parameter(path, (*cur).first);
|
||||
assert(expr);
|
||||
|
||||
// If it's already a NetEConst, then this parameter is done.
|
||||
if (dynamic_cast<const NetEConst*>(expr))
|
||||
continue;
|
||||
|
||||
// Get a non-constant copy of the expression to evaluate...
|
||||
NetExpr*nexpr = expr->dup_expr();
|
||||
if (nexpr == 0) {
|
||||
cerr << (*cur).second->get_line() << ": internal error: "
|
||||
"unable to dup expression: " << *expr << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to evaluate the expression.
|
||||
nexpr = nexpr->eval_tree();
|
||||
if (nexpr == 0) {
|
||||
cerr << (*cur).second->get_line() << ": internal error: "
|
||||
"unable to evaluate parm expression: " <<
|
||||
*expr << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The evaluate worked, replace the old expression with
|
||||
// this constant value.
|
||||
assert(nexpr);
|
||||
des->set_parameter(pname, nexpr);
|
||||
}
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
|
|
@ -1906,14 +1813,24 @@ bool Module::elaborate(Design*des, NetScope*scope,
|
|||
|
||||
for (mfunc_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++) {
|
||||
string pname = path + "." + (*cur).first;
|
||||
(*cur).second->elaborate_1(des, pname);
|
||||
NetScope*fscope = scope->child((*cur).first);
|
||||
if (scope == 0) {
|
||||
cerr << (*cur).second->get_line() << ": internal error: "
|
||||
<< "Child scope for function " << (*cur).first
|
||||
<< " missing in " << scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
(*cur).second->elaborate_1(des, fscope);
|
||||
}
|
||||
|
||||
for (mfunc_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++) {
|
||||
string pname = path + "." + (*cur).first;
|
||||
(*cur).second->elaborate_2(des, pname);
|
||||
|
||||
NetScope*fscope = scope->child((*cur).first);
|
||||
assert(fscope);
|
||||
(*cur).second->elaborate_2(des, fscope);
|
||||
}
|
||||
|
||||
// Elaborate the task definitions. This is done before the
|
||||
|
|
@ -1992,11 +1909,26 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
// module and elaborate what I find.
|
||||
Design*des = new Design;
|
||||
|
||||
NetScope*scope = des->make_root_scope(root);
|
||||
|
||||
modlist = &modules;
|
||||
udplist = &primitives;
|
||||
bool rc = rmod->elaborate(des, scope, 0, 0, (svector<PExpr*>*)0);
|
||||
|
||||
// Make the root scope, then scan the pform looking for scopes
|
||||
// and parameters.
|
||||
NetScope*scope = des->make_root_scope(root);
|
||||
if (! rmod->elaborate_scope(des, scope)) {
|
||||
delete des;
|
||||
return 0;
|
||||
}
|
||||
|
||||
des->run_defparams();
|
||||
des->evaluate_parameters();
|
||||
|
||||
// Now that the structure and parameters are taken care of,
|
||||
// run through the pform again and generate the full netlist.
|
||||
|
||||
bool rc = rmod->elaborate(des, scope);
|
||||
|
||||
|
||||
modlist = 0;
|
||||
udplist = 0;
|
||||
|
||||
|
|
@ -2004,12 +1936,20 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
delete des;
|
||||
des = 0;
|
||||
}
|
||||
|
||||
return des;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.146 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.145 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
@ -2024,145 +1964,5 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
*
|
||||
* Revision 1.141 2000/01/10 01:35:23 steve
|
||||
* Elaborate parameters afer binding of overrides.
|
||||
*
|
||||
* Revision 1.140 2000/01/09 20:37:57 steve
|
||||
* Careful with wires connected to multiple ports.
|
||||
*
|
||||
* Revision 1.139 2000/01/09 05:50:48 steve
|
||||
* Support named parameter override lists.
|
||||
*
|
||||
* Revision 1.138 2000/01/02 19:39:03 steve
|
||||
* Structural reduction XNOR.
|
||||
*
|
||||
* Revision 1.137 2000/01/02 18:25:37 steve
|
||||
* Do not overrun the pin index when the LSB != 0.
|
||||
*
|
||||
* Revision 1.136 2000/01/01 06:18:00 steve
|
||||
* Handle synthesis of concatenation.
|
||||
*
|
||||
* Revision 1.135 1999/12/14 23:42:16 steve
|
||||
* Detect duplicate scopes.
|
||||
*
|
||||
* Revision 1.134 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
*
|
||||
* Revision 1.133 1999/12/05 02:24:08 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.132 1999/12/02 04:08:10 steve
|
||||
* Elaborate net repeat concatenations.
|
||||
*
|
||||
* Revision 1.131 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.130 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.129 1999/11/24 04:01:58 steve
|
||||
* Detect and list scope names.
|
||||
*
|
||||
* Revision 1.128 1999/11/21 20:03:24 steve
|
||||
* Handle multiply in constant expressions.
|
||||
*
|
||||
* Revision 1.127 1999/11/21 17:35:37 steve
|
||||
* Memory name lookup handles scopes.
|
||||
*
|
||||
* Revision 1.126 1999/11/21 01:16:51 steve
|
||||
* Fix coding errors handling names of logic devices,
|
||||
* and add support for buf device in vvm.
|
||||
*
|
||||
* Revision 1.125 1999/11/21 00:13:08 steve
|
||||
* Support memories in continuous assignments.
|
||||
*
|
||||
* Revision 1.124 1999/11/18 03:52:19 steve
|
||||
* Turn NetTmp objects into normal local NetNet objects,
|
||||
* and add the nodangle functor to clean up the local
|
||||
* symbols generated by elaboration and other steps.
|
||||
*
|
||||
* Revision 1.123 1999/11/10 02:52:24 steve
|
||||
* Create the vpiMemory handle type.
|
||||
*
|
||||
* Revision 1.122 1999/11/05 21:45:19 steve
|
||||
* Fix NetConst being set to zero width, and clean
|
||||
* up elaborate_set_cmp_ for NetEBinary.
|
||||
*
|
||||
* Revision 1.121 1999/11/04 03:53:26 steve
|
||||
* Patch to synthesize unary ~ and the ternary operator.
|
||||
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.
|
||||
*
|
||||
* Add the LPM_MUX device, and integrate it with the
|
||||
* ternary synthesis from Larry. Replace the lpm_mux
|
||||
* generator in t-xnf.cc to use XNF EQU devices to
|
||||
* put muxs into function units.
|
||||
*
|
||||
* Rewrite elaborate_net for the PETernary class to
|
||||
* also use the LPM_MUX device.
|
||||
*
|
||||
* Revision 1.120 1999/10/31 20:08:24 steve
|
||||
* Include subtraction in LPM_ADD_SUB device.
|
||||
*
|
||||
* Revision 1.119 1999/10/31 04:11:27 steve
|
||||
* Add to netlist links pin name and instance number,
|
||||
* and arrange in vvm for pin connections by name
|
||||
* and instance number.
|
||||
*
|
||||
* Revision 1.118 1999/10/18 00:02:21 steve
|
||||
* Catch unindexed memory reference.
|
||||
*
|
||||
* Revision 1.117 1999/10/13 03:16:36 steve
|
||||
* Remove commented out do_assign.
|
||||
*
|
||||
* Revision 1.116 1999/10/10 01:59:54 steve
|
||||
* Structural case equals device.
|
||||
*
|
||||
* Revision 1.115 1999/10/09 21:30:16 steve
|
||||
* Support parameters in continuous assignments.
|
||||
*
|
||||
* Revision 1.114 1999/10/09 19:24:04 steve
|
||||
* Better message for combinational operators.
|
||||
*
|
||||
* Revision 1.113 1999/10/08 17:48:08 steve
|
||||
* Support + in constant expressions.
|
||||
*
|
||||
* Revision 1.112 1999/10/08 17:27:23 steve
|
||||
* Accept adder parameters with different widths,
|
||||
* and simplify continuous assign construction.
|
||||
*
|
||||
* Revision 1.111 1999/10/07 05:25:33 steve
|
||||
* Add non-const bit select in l-value of assignment.
|
||||
*
|
||||
* Revision 1.110 1999/10/06 00:39:00 steve
|
||||
* == and != connected to the wrong pins of the compare.
|
||||
*
|
||||
* Revision 1.109 1999/10/05 06:19:46 steve
|
||||
* Add support for reduction NOR.
|
||||
*
|
||||
* Revision 1.108 1999/10/05 02:00:06 steve
|
||||
* sorry message for non-constant l-value bit select.
|
||||
*
|
||||
* Revision 1.107 1999/09/30 21:28:34 steve
|
||||
* Handle mutual reference of tasks by elaborating
|
||||
* task definitions in two passes, like functions.
|
||||
*
|
||||
* Revision 1.106 1999/09/30 17:22:33 steve
|
||||
* catch non-constant delays as unsupported.
|
||||
*
|
||||
* Revision 1.105 1999/09/30 02:43:02 steve
|
||||
* Elaborate ~^ and ~| operators.
|
||||
*
|
||||
* Revision 1.104 1999/09/30 00:48:50 steve
|
||||
* Cope with errors during ternary operator elaboration.
|
||||
*
|
||||
* Revision 1.103 1999/09/29 22:57:10 steve
|
||||
* Move code to elab_expr.cc
|
||||
*
|
||||
* Revision 1.102 1999/09/29 18:36:03 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.101 1999/09/29 00:42:50 steve
|
||||
* Allow expanding of additive operators.
|
||||
*
|
||||
* Revision 1.100 1999/09/25 02:57:30 steve
|
||||
*/
|
||||
|
||||
|
|
|
|||
22
emit.cc
22
emit.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.33 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.34 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -250,6 +250,13 @@ void NetRepeat::emit_recurse(ostream&o, struct target_t*tgt) const
|
|||
statement_->emit_proc(o, tgt);
|
||||
}
|
||||
|
||||
void NetScope::emit_scope(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->scope(o, this);
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_scope(o, tgt);
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
proc_->emit_proc(o, tgt);
|
||||
|
|
@ -261,11 +268,7 @@ bool Design::emit(ostream&o, struct target_t*tgt) const
|
|||
tgt->start_design(o, this);
|
||||
|
||||
// enumerate the scopes
|
||||
{ map<string,NetScope*>::const_iterator sc;
|
||||
for (sc = scopes_.begin() ; sc != scopes_.end() ; sc++) {
|
||||
tgt->scope(o, (*sc).second);
|
||||
}
|
||||
}
|
||||
root_scope_->emit_scope(o, tgt);
|
||||
|
||||
// emit signals
|
||||
if (signals_) {
|
||||
|
|
@ -394,6 +397,13 @@ bool emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.34 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.33 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
13
eval.cc
13
eval.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval.cc,v 1.13 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: eval.cc,v 1.14 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PExpr.h"
|
||||
|
|
@ -96,7 +96,9 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
|||
*/
|
||||
verinum* PEIdent::eval_const(const Design*des, const string&path) const
|
||||
{
|
||||
const NetExpr*expr = des->find_parameter(path, text_);
|
||||
const NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
const NetExpr*expr = des->find_parameter(scope, text_);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
|
@ -142,6 +144,13 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
|
|||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.14 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.13 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
14
eval_tree.cc
14
eval_tree.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval_tree.cc,v 1.8 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.9 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -241,7 +241,8 @@ NetExpr* NetEParam::eval_tree()
|
|||
if (des_ == 0)
|
||||
return 0;
|
||||
|
||||
const NetExpr*expr = des_->find_parameter(path_, name_);
|
||||
assert(scope_);
|
||||
const NetExpr*expr = scope_->get_parameter(name_);
|
||||
assert(expr);
|
||||
|
||||
NetExpr*nexpr = expr->dup_expr();
|
||||
|
|
@ -262,12 +263,19 @@ NetExpr* NetEParam::eval_tree()
|
|||
|
||||
// The result can be saved as the value of the parameter for
|
||||
// future reference, and return a copy to the caller.
|
||||
des_->set_parameter(path_+"."+name_, res);
|
||||
scope_->set_parameter(name_, res);
|
||||
return res->dup_expr();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.9 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.8 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,533 @@
|
|||
/*
|
||||
* Copyright (c) 2000Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_design.cc,v 1.1 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This source file contains all the implementations of the Design
|
||||
* class declared in netlist.h.
|
||||
*/
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
static string parse_first_name(string&path)
|
||||
{
|
||||
unsigned pos = path.find('.');
|
||||
if (pos > path.length()) {
|
||||
string res = path;
|
||||
path = "";
|
||||
return res;
|
||||
}
|
||||
|
||||
string res = path.substr(0, pos);
|
||||
path = path.substr(pos+1, path.length());
|
||||
return res;
|
||||
}
|
||||
|
||||
static string parse_last_name(string&path)
|
||||
{
|
||||
unsigned pos = path.rfind('.');
|
||||
if (pos > path.length()) {
|
||||
string res = path;
|
||||
path = "";
|
||||
return res;
|
||||
}
|
||||
|
||||
string res = path.substr(pos+1, path.length());
|
||||
path = path.substr(0, pos);
|
||||
return res;
|
||||
}
|
||||
|
||||
Design:: Design()
|
||||
: errors(0), root_scope_(0), signals_(0), nodes_(0), procs_(0), lcounter_(0)
|
||||
{
|
||||
}
|
||||
|
||||
Design::~Design()
|
||||
{
|
||||
}
|
||||
|
||||
NetScope* Design::make_root_scope(const string&root)
|
||||
{
|
||||
assert(root_scope_ == 0);
|
||||
root_scope_ = new NetScope(root);
|
||||
return root_scope_;
|
||||
}
|
||||
|
||||
NetScope* Design::make_scope(const string&path,
|
||||
NetScope::TYPE t,
|
||||
const string&name)
|
||||
{
|
||||
NetScope*up = find_scope(path);
|
||||
assert(up);
|
||||
|
||||
NetScope*scope = new NetScope(up, name, t);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This method locates a scope in the design, given its rooted
|
||||
* heirarchical name. Each component of the key is used to scan one
|
||||
* more step down the tree until the name runs out or the search
|
||||
* fails.
|
||||
*/
|
||||
NetScope* Design::find_scope(const string&key)
|
||||
{
|
||||
if (key == root_scope_->name())
|
||||
return root_scope_;
|
||||
|
||||
string path = key;
|
||||
string root = parse_first_name(path);
|
||||
|
||||
NetScope*cur = root_scope_;
|
||||
if (root != cur->name())
|
||||
return 0;
|
||||
|
||||
while (cur) {
|
||||
string next = parse_first_name(path);
|
||||
cur = cur->child(next);
|
||||
if (path == "") return cur;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a parameter from within a specified context. If the name is
|
||||
* not here, keep looking up until I run out of up to look at. The
|
||||
* method works by scanning scopes, starting with the passed scope and
|
||||
* working up towards the root, looking for the named parameter. The
|
||||
* name in this case can be hierarchical, so there is an inner loop to
|
||||
* follow the scopes of the name down to to key.
|
||||
*/
|
||||
const NetExpr* Design::find_parameter(const NetScope*scope,
|
||||
const string&name) const
|
||||
{
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
string path = name;
|
||||
string key = parse_first_name(path);
|
||||
|
||||
const NetScope*cur = scope;
|
||||
while (path != "") {
|
||||
cur = cur->child(key);
|
||||
if (cur == 0) break;
|
||||
key = parse_first_name(path);
|
||||
}
|
||||
|
||||
if (cur == 0) continue;
|
||||
|
||||
if (const NetExpr*res = cur->get_parameter(key))
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This method runs through the scope, noticing the defparam
|
||||
* statements that were collected during the elaborate_scope pass and
|
||||
* applying them to the target parameters. The implementation actually
|
||||
* works by using a specialized method from the NetScope class that
|
||||
* does all the work for me.
|
||||
*/
|
||||
void Design::run_defparams()
|
||||
{
|
||||
root_scope_->run_defparams(this);
|
||||
}
|
||||
|
||||
void NetScope::run_defparams(Design*des)
|
||||
{
|
||||
NetScope*cur = sub_;
|
||||
while (cur) {
|
||||
cur->run_defparams(des);
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
|
||||
NetExpr*val = (*pp).second;
|
||||
string path = (*pp).first;
|
||||
string name = parse_last_name(path);
|
||||
|
||||
NetScope*targ_scope = des->find_scope(path);
|
||||
if (targ_scope == 0) {
|
||||
cerr << val->get_line() << ": warning: scope of " <<
|
||||
path << "." << name << " not found." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
val = targ_scope->set_parameter(name, val);
|
||||
if (val == 0) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< name << " not found in " << targ_scope->name()
|
||||
<< "." << endl;
|
||||
} else {
|
||||
delete val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Design::evaluate_parameters()
|
||||
{
|
||||
root_scope_->evaluate_parameters(this);
|
||||
}
|
||||
|
||||
void NetScope::evaluate_parameters(Design*des)
|
||||
{
|
||||
NetScope*cur = sub_;
|
||||
while (cur) {
|
||||
cur->evaluate_parameters(des);
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
|
||||
// Evaluate the parameter values. The parameter expressions
|
||||
// have already been elaborated and replaced by the scope
|
||||
// scanning code. Now the parameter expression can be fully
|
||||
// evaluated, or it cannot be evaluated at all.
|
||||
|
||||
typedef map<string,NetExpr*>::iterator mparm_it_t;
|
||||
|
||||
for (mparm_it_t cur = parameters_.begin()
|
||||
; cur != parameters_.end() ; cur ++) {
|
||||
|
||||
// Get the NetExpr for the parameter.
|
||||
NetExpr*expr = (*cur).second;
|
||||
assert(expr);
|
||||
|
||||
// If it's already a NetEConst, then this parameter is done.
|
||||
if (dynamic_cast<const NetEConst*>(expr))
|
||||
continue;
|
||||
|
||||
// Try to evaluate the expression.
|
||||
NetExpr*nexpr = expr->eval_tree();
|
||||
if (nexpr == 0) {
|
||||
cerr << (*cur).second->get_line() << ": internal error: "
|
||||
"unable to evaluate parm expression: " <<
|
||||
*expr << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The evaluate worked, replace the old expression with
|
||||
// this constant value.
|
||||
assert(nexpr);
|
||||
delete expr;
|
||||
(*cur).second = nexpr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
string Design::get_flag(const string&key) const
|
||||
{
|
||||
map<string,string>::const_iterator tmp = flags_.find(key);
|
||||
if (tmp == flags_.end())
|
||||
return "";
|
||||
else
|
||||
return (*tmp).second;
|
||||
}
|
||||
|
||||
void Design::add_signal(NetNet*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
if (signals_ == 0) {
|
||||
net->sig_next_ = net;
|
||||
net->sig_prev_ = net;
|
||||
} else {
|
||||
net->sig_next_ = signals_->sig_next_;
|
||||
net->sig_prev_ = signals_;
|
||||
net->sig_next_->sig_prev_ = net;
|
||||
net->sig_prev_->sig_next_ = net;
|
||||
}
|
||||
signals_ = net;
|
||||
net->design_ = this;
|
||||
}
|
||||
|
||||
void Design::del_signal(NetNet*net)
|
||||
{
|
||||
assert(net->design_ == this);
|
||||
if (signals_ == net)
|
||||
signals_ = net->sig_prev_;
|
||||
|
||||
if (signals_ == net) {
|
||||
signals_ = 0;
|
||||
} else {
|
||||
net->sig_prev_->sig_next_ = net->sig_next_;
|
||||
net->sig_next_->sig_prev_ = net->sig_prev_;
|
||||
}
|
||||
net->design_ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method looks for a string given a current context as a
|
||||
* starting point.
|
||||
*/
|
||||
NetNet* Design::find_signal(const string&path, const string&name)
|
||||
{
|
||||
if (signals_ == 0)
|
||||
return 0;
|
||||
|
||||
const NetScope*scope = find_scope(path);
|
||||
if (scope == 0) {
|
||||
cerr << "internal error: invalid scope: " << path << endl;
|
||||
return 0;
|
||||
}
|
||||
assert(scope);
|
||||
|
||||
for (;;) {
|
||||
string fulname = scope? (scope->name() + "." + name) : name;
|
||||
|
||||
NetNet*cur = signals_;
|
||||
do {
|
||||
if (cur->name() == fulname)
|
||||
return cur;
|
||||
|
||||
cur = cur->sig_prev_;
|
||||
} while (cur != signals_);
|
||||
|
||||
if (scope == 0)
|
||||
return 0;
|
||||
|
||||
scope = scope->parent();
|
||||
}
|
||||
}
|
||||
|
||||
void Design::add_memory(NetMemory*mem)
|
||||
{
|
||||
memories_[mem->name()] = mem;
|
||||
}
|
||||
|
||||
NetMemory* Design::find_memory(const string&path, const string&name)
|
||||
{
|
||||
string root = path;
|
||||
|
||||
for (;;) {
|
||||
string fulname = root + "." + name;
|
||||
map<string,NetMemory*>::const_iterator cur
|
||||
= memories_.find(fulname);
|
||||
|
||||
if (cur != memories_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_function(const string&key, NetFuncDef*def)
|
||||
{
|
||||
funcs_[key] = def;
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(const string&path, const string&name)
|
||||
{
|
||||
string root = path;
|
||||
for (;;) {
|
||||
string key = root + "." + name;
|
||||
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
||||
if (cur != funcs_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(const string&key)
|
||||
{
|
||||
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
||||
if (cur != funcs_.end())
|
||||
return (*cur).second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_task(const string&key, NetTaskDef*def)
|
||||
{
|
||||
tasks_[key] = def;
|
||||
}
|
||||
|
||||
NetTaskDef* Design::find_task(const string&path, const string&name)
|
||||
{
|
||||
string root = path;
|
||||
for (;;) {
|
||||
string key = root + "." + name;
|
||||
map<string,NetTaskDef*>::const_iterator cur = tasks_.find(key);
|
||||
if (cur != tasks_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetTaskDef* Design::find_task(const string&key)
|
||||
{
|
||||
map<string,NetTaskDef*>::const_iterator cur = tasks_.find(key);
|
||||
if (cur == tasks_.end())
|
||||
return 0;
|
||||
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
void Design::add_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
if (nodes_ == 0) {
|
||||
net->node_next_ = net;
|
||||
net->node_prev_ = net;
|
||||
} else {
|
||||
net->node_next_ = nodes_->node_next_;
|
||||
net->node_prev_ = nodes_;
|
||||
net->node_next_->node_prev_ = net;
|
||||
net->node_prev_->node_next_ = net;
|
||||
}
|
||||
nodes_ = net;
|
||||
net->design_ = this;
|
||||
}
|
||||
|
||||
void Design::del_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == this);
|
||||
if (nodes_ == net)
|
||||
nodes_ = net->node_prev_;
|
||||
|
||||
if (nodes_ == net) {
|
||||
nodes_ = 0;
|
||||
} else {
|
||||
net->node_next_->node_prev_ = net->node_prev_;
|
||||
net->node_prev_->node_next_ = net->node_next_;
|
||||
}
|
||||
|
||||
net->design_ = 0;
|
||||
}
|
||||
|
||||
void Design::add_process(NetProcTop*pro)
|
||||
{
|
||||
pro->next_ = procs_;
|
||||
procs_ = pro;
|
||||
}
|
||||
|
||||
void Design::delete_process(NetProcTop*top)
|
||||
{
|
||||
assert(top);
|
||||
if (procs_ == top) {
|
||||
procs_ = top->next_;
|
||||
|
||||
} else {
|
||||
NetProcTop*cur = procs_;
|
||||
while (cur->next_ != top) {
|
||||
assert(cur->next_);
|
||||
cur = cur->next_;
|
||||
}
|
||||
|
||||
cur->next_ = top->next_;
|
||||
}
|
||||
|
||||
if (procs_idx_ == top)
|
||||
procs_idx_ = top->next_;
|
||||
|
||||
delete top;
|
||||
}
|
||||
|
||||
void Design::clear_node_marks()
|
||||
{
|
||||
if (nodes_ == 0)
|
||||
return;
|
||||
|
||||
NetNode*cur = nodes_;
|
||||
do {
|
||||
cur->set_mark(false);
|
||||
cur = cur->node_next_;
|
||||
} while (cur != nodes_);
|
||||
}
|
||||
|
||||
void Design::clear_signal_marks()
|
||||
{
|
||||
if (signals_ == 0)
|
||||
return;
|
||||
|
||||
NetNet*cur = signals_;
|
||||
do {
|
||||
cur->set_mark(false);
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_);
|
||||
}
|
||||
|
||||
NetNode* Design::find_node(bool (*func)(const NetNode*))
|
||||
{
|
||||
if (nodes_ == 0)
|
||||
return 0;
|
||||
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
do {
|
||||
if ((cur->test_mark() == false) && func(cur))
|
||||
return cur;
|
||||
|
||||
cur = cur->node_next_;
|
||||
} while (cur != nodes_->node_next_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||
{
|
||||
if (signals_ == 0)
|
||||
return 0;
|
||||
|
||||
NetNet*cur = signals_->sig_next_;
|
||||
do {
|
||||
if ((cur->test_mark() == false) && func(cur))
|
||||
return cur;
|
||||
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_->sig_next_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_design.cc,v $
|
||||
* Revision 1.1 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
*/
|
||||
|
||||
730
netlist.cc
730
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.cc,v 1.105 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.106 2000/03/08 04:36:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -1639,8 +1639,8 @@ verinum::V NetConst::value(unsigned idx) const
|
|||
return value_[idx];
|
||||
}
|
||||
|
||||
NetFuncDef::NetFuncDef(const string&n, const svector<NetNet*>&po)
|
||||
: name_(n), statement_(0), ports_(po)
|
||||
NetFuncDef::NetFuncDef(NetScope*s, const svector<NetNet*>&po)
|
||||
: scope_(s), statement_(0), ports_(po)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1648,9 +1648,9 @@ NetFuncDef::~NetFuncDef()
|
|||
{
|
||||
}
|
||||
|
||||
const string& NetFuncDef::name() const
|
||||
const string NetFuncDef::name() const
|
||||
{
|
||||
return name_;
|
||||
return scope_->name();
|
||||
}
|
||||
|
||||
void NetFuncDef::set_proc(NetProc*st)
|
||||
|
|
@ -1665,6 +1665,11 @@ const NetProc* NetFuncDef::proc() const
|
|||
return statement_;
|
||||
}
|
||||
|
||||
NetScope*NetFuncDef::scope()
|
||||
{
|
||||
return scope_;
|
||||
}
|
||||
|
||||
unsigned NetFuncDef::port_count() const
|
||||
{
|
||||
return ports_.count();
|
||||
|
|
@ -1747,7 +1752,7 @@ NetEUFunc::~NetEUFunc()
|
|||
delete parms_[idx];
|
||||
}
|
||||
|
||||
const string& NetEUFunc::name() const
|
||||
const string NetEUFunc::name() const
|
||||
{
|
||||
return func_->name();
|
||||
}
|
||||
|
|
@ -2054,8 +2059,8 @@ NetEParam::NetEParam()
|
|||
{
|
||||
}
|
||||
|
||||
NetEParam::NetEParam(Design*d, const string&p, const string&n)
|
||||
: des_(d), path_(p), name_(n)
|
||||
NetEParam::NetEParam(Design*d, NetScope*s, const string&n)
|
||||
: des_(d), scope_(s), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -2237,18 +2242,47 @@ const NetExpr* NetRepeat::expr() const
|
|||
return expr_;
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetScope class keeps a scope tree organized. Each node of the
|
||||
* scope tree points to its parent, its right sibling and its leftmost
|
||||
* child. The root node has no parent or siblings. The node stores the
|
||||
* name of the scope. The complete hierarchical name of the scope is
|
||||
* formed by appending the path of scopes from the root to the scope
|
||||
* in question.
|
||||
*/
|
||||
NetScope::NetScope(const string&n)
|
||||
: type_(NetScope::MODULE), name_(n), up_(0)
|
||||
: type_(NetScope::MODULE), name_(n), up_(0), sib_(0), sub_(0)
|
||||
{
|
||||
}
|
||||
|
||||
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
|
||||
: type_(t), name_(n), up_(up)
|
||||
: type_(t), name_(n), up_(up), sib_(0), sub_(0)
|
||||
{
|
||||
sib_ = up_->sub_;
|
||||
up_->sub_ = this;
|
||||
}
|
||||
|
||||
NetScope::~NetScope()
|
||||
{
|
||||
assert(sib_ == 0);
|
||||
assert(sub_ == 0);
|
||||
}
|
||||
|
||||
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr)
|
||||
{
|
||||
NetExpr*&ref = parameters_[key];
|
||||
NetExpr* res = ref;
|
||||
ref = expr;
|
||||
return res;
|
||||
}
|
||||
|
||||
const NetExpr* NetScope::get_parameter(const string&key) const
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator idx = parameters_.find(key);
|
||||
if (idx == parameters_.end())
|
||||
return 0;
|
||||
else
|
||||
return (*idx).second;
|
||||
}
|
||||
|
||||
NetScope::TYPE NetScope::type() const
|
||||
|
|
@ -2264,6 +2298,36 @@ string NetScope::name() const
|
|||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a child scope by name. The name is the simple
|
||||
* name of the child, no heirarchy is searched.
|
||||
*/
|
||||
NetScope* NetScope::child(const string&name)
|
||||
{
|
||||
if (sub_ == 0) return 0;
|
||||
|
||||
NetScope*cur = sub_;
|
||||
while (cur->name_ != name) {
|
||||
if (cur->sib_ == 0) return 0;
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::child(const string&name) const
|
||||
{
|
||||
if (sub_ == 0) return 0;
|
||||
|
||||
NetScope*cur = sub_;
|
||||
while (cur->name_ != name) {
|
||||
if (cur->sib_ == 0) return 0;
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::parent() const
|
||||
{
|
||||
return up_;
|
||||
|
|
@ -2561,357 +2625,15 @@ void NetUDP::set_initial(char val)
|
|||
init_ = val;
|
||||
}
|
||||
|
||||
Design:: Design()
|
||||
: errors(0), signals_(0), nodes_(0), procs_(0), lcounter_(0)
|
||||
{
|
||||
}
|
||||
|
||||
Design::~Design()
|
||||
{
|
||||
}
|
||||
|
||||
NetScope* Design::make_root_scope(const string&root)
|
||||
{
|
||||
NetScope*scope = new NetScope(root);
|
||||
scopes_[root] = scope;
|
||||
return scope;
|
||||
}
|
||||
|
||||
NetScope* Design::make_scope(const string&path,
|
||||
NetScope::TYPE t,
|
||||
const string&name)
|
||||
{
|
||||
NetScope*up = find_scope(path);
|
||||
assert(up);
|
||||
|
||||
NetScope*scope = new NetScope(up, name, t);
|
||||
scopes_[scope->name()] = scope;
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
NetScope* Design::find_scope(const string&key)
|
||||
{
|
||||
map<string,NetScope*>::const_iterator tmp = scopes_.find(key);
|
||||
if (tmp == scopes_.end())
|
||||
return 0;
|
||||
else
|
||||
return (*tmp).second;
|
||||
}
|
||||
|
||||
void Design::set_parameter(const string&key, NetExpr*expr)
|
||||
{
|
||||
parameters_[key] = expr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a parameter from within a specified context. If the name is
|
||||
* not here, keep looking up until I run out of up to look at.
|
||||
*/
|
||||
const NetExpr* Design::find_parameter(const string&path,
|
||||
const string&name) const
|
||||
{
|
||||
string root = path;
|
||||
|
||||
for (;;) {
|
||||
string fulname = root + "." + name;
|
||||
map<string,NetExpr*>::const_iterator cur
|
||||
= parameters_.find(fulname);
|
||||
|
||||
if (cur != parameters_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string Design::get_flag(const string&key) const
|
||||
{
|
||||
map<string,string>::const_iterator tmp = flags_.find(key);
|
||||
if (tmp == flags_.end())
|
||||
return "";
|
||||
else
|
||||
return (*tmp).second;
|
||||
}
|
||||
|
||||
void Design::add_signal(NetNet*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
if (signals_ == 0) {
|
||||
net->sig_next_ = net;
|
||||
net->sig_prev_ = net;
|
||||
} else {
|
||||
net->sig_next_ = signals_->sig_next_;
|
||||
net->sig_prev_ = signals_;
|
||||
net->sig_next_->sig_prev_ = net;
|
||||
net->sig_prev_->sig_next_ = net;
|
||||
}
|
||||
signals_ = net;
|
||||
net->design_ = this;
|
||||
}
|
||||
|
||||
void Design::del_signal(NetNet*net)
|
||||
{
|
||||
assert(net->design_ == this);
|
||||
if (signals_ == net)
|
||||
signals_ = net->sig_prev_;
|
||||
|
||||
if (signals_ == net) {
|
||||
signals_ = 0;
|
||||
} else {
|
||||
net->sig_prev_->sig_next_ = net->sig_next_;
|
||||
net->sig_next_->sig_prev_ = net->sig_prev_;
|
||||
}
|
||||
net->design_ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method looks for a string given a current context as a
|
||||
* starting point.
|
||||
*/
|
||||
NetNet* Design::find_signal(const string&path, const string&name)
|
||||
{
|
||||
if (signals_ == 0)
|
||||
return 0;
|
||||
|
||||
string root = path;
|
||||
for (;;) {
|
||||
|
||||
string fulname = root + "." + name;
|
||||
NetNet*cur = signals_;
|
||||
do {
|
||||
if (cur->name() == fulname)
|
||||
return cur;
|
||||
|
||||
cur = cur->sig_prev_;
|
||||
} while (cur != signals_);
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_memory(NetMemory*mem)
|
||||
{
|
||||
memories_[mem->name()] = mem;
|
||||
}
|
||||
|
||||
NetMemory* Design::find_memory(const string&path, const string&name)
|
||||
{
|
||||
string root = path;
|
||||
|
||||
for (;;) {
|
||||
string fulname = root + "." + name;
|
||||
map<string,NetMemory*>::const_iterator cur
|
||||
= memories_.find(fulname);
|
||||
|
||||
if (cur != memories_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_function(const string&key, NetFuncDef*def)
|
||||
{
|
||||
funcs_[key] = def;
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(const string&path, const string&name)
|
||||
{
|
||||
string root = path;
|
||||
for (;;) {
|
||||
string key = root + "." + name;
|
||||
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
||||
if (cur != funcs_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(const string&key)
|
||||
{
|
||||
map<string,NetFuncDef*>::const_iterator cur = funcs_.find(key);
|
||||
if (cur != funcs_.end())
|
||||
return (*cur).second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_task(const string&key, NetTaskDef*def)
|
||||
{
|
||||
tasks_[key] = def;
|
||||
}
|
||||
|
||||
NetTaskDef* Design::find_task(const string&path, const string&name)
|
||||
{
|
||||
string root = path;
|
||||
for (;;) {
|
||||
string key = root + "." + name;
|
||||
map<string,NetTaskDef*>::const_iterator cur = tasks_.find(key);
|
||||
if (cur != tasks_.end())
|
||||
return (*cur).second;
|
||||
|
||||
unsigned pos = root.rfind('.');
|
||||
if (pos > root.length())
|
||||
break;
|
||||
|
||||
root = root.substr(0, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetTaskDef* Design::find_task(const string&key)
|
||||
{
|
||||
map<string,NetTaskDef*>::const_iterator cur = tasks_.find(key);
|
||||
if (cur == tasks_.end())
|
||||
return 0;
|
||||
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
void Design::add_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
if (nodes_ == 0) {
|
||||
net->node_next_ = net;
|
||||
net->node_prev_ = net;
|
||||
} else {
|
||||
net->node_next_ = nodes_->node_next_;
|
||||
net->node_prev_ = nodes_;
|
||||
net->node_next_->node_prev_ = net;
|
||||
net->node_prev_->node_next_ = net;
|
||||
}
|
||||
nodes_ = net;
|
||||
net->design_ = this;
|
||||
}
|
||||
|
||||
void Design::del_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == this);
|
||||
if (nodes_ == net)
|
||||
nodes_ = net->node_prev_;
|
||||
|
||||
if (nodes_ == net) {
|
||||
nodes_ = 0;
|
||||
} else {
|
||||
net->node_next_->node_prev_ = net->node_prev_;
|
||||
net->node_prev_->node_next_ = net->node_next_;
|
||||
}
|
||||
|
||||
net->design_ = 0;
|
||||
}
|
||||
|
||||
void Design::add_process(NetProcTop*pro)
|
||||
{
|
||||
pro->next_ = procs_;
|
||||
procs_ = pro;
|
||||
}
|
||||
|
||||
void Design::delete_process(NetProcTop*top)
|
||||
{
|
||||
assert(top);
|
||||
if (procs_ == top) {
|
||||
procs_ = top->next_;
|
||||
|
||||
} else {
|
||||
NetProcTop*cur = procs_;
|
||||
while (cur->next_ != top) {
|
||||
assert(cur->next_);
|
||||
cur = cur->next_;
|
||||
}
|
||||
|
||||
cur->next_ = top->next_;
|
||||
}
|
||||
|
||||
if (procs_idx_ == top)
|
||||
procs_idx_ = top->next_;
|
||||
|
||||
delete top;
|
||||
}
|
||||
|
||||
void Design::clear_node_marks()
|
||||
{
|
||||
if (nodes_ == 0)
|
||||
return;
|
||||
|
||||
NetNode*cur = nodes_;
|
||||
do {
|
||||
cur->set_mark(false);
|
||||
cur = cur->node_next_;
|
||||
} while (cur != nodes_);
|
||||
}
|
||||
|
||||
void Design::clear_signal_marks()
|
||||
{
|
||||
if (signals_ == 0)
|
||||
return;
|
||||
|
||||
NetNet*cur = signals_;
|
||||
do {
|
||||
cur->set_mark(false);
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_);
|
||||
}
|
||||
|
||||
NetNode* Design::find_node(bool (*func)(const NetNode*))
|
||||
{
|
||||
if (nodes_ == 0)
|
||||
return 0;
|
||||
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
do {
|
||||
if ((cur->test_mark() == false) && func(cur))
|
||||
return cur;
|
||||
|
||||
cur = cur->node_next_;
|
||||
} while (cur != nodes_->node_next_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||
{
|
||||
if (signals_ == 0)
|
||||
return 0;
|
||||
|
||||
NetNet*cur = signals_->sig_next_;
|
||||
do {
|
||||
if ((cur->test_mark() == false) && func(cur))
|
||||
return cur;
|
||||
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_->sig_next_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.106 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.105 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
@ -2951,295 +2673,5 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
|||
*
|
||||
* Revision 1.93 1999/11/24 04:01:59 steve
|
||||
* Detect and list scope names.
|
||||
*
|
||||
* Revision 1.92 1999/11/21 18:03:35 steve
|
||||
* Fix expression width of memory references.
|
||||
*
|
||||
* Revision 1.91 1999/11/21 17:35:37 steve
|
||||
* Memory name lookup handles scopes.
|
||||
*
|
||||
* Revision 1.90 1999/11/21 00:13:08 steve
|
||||
* Support memories in continuous assignments.
|
||||
*
|
||||
* Revision 1.89 1999/11/19 05:02:37 steve
|
||||
* handle duplicate connect to a nexus.
|
||||
*
|
||||
* Revision 1.88 1999/11/19 03:02:25 steve
|
||||
* Detect flip-flops connected to opads and turn
|
||||
* them into OUTFF devices. Inprove support for
|
||||
* the XNF-LCA attribute in the process.
|
||||
*
|
||||
* Revision 1.87 1999/11/18 03:52:19 steve
|
||||
* Turn NetTmp objects into normal local NetNet objects,
|
||||
* and add the nodangle functor to clean up the local
|
||||
* symbols generated by elaboration and other steps.
|
||||
*
|
||||
* Revision 1.86 1999/11/14 23:43:45 steve
|
||||
* Support combinatorial comparators.
|
||||
*
|
||||
* Revision 1.85 1999/11/14 20:24:28 steve
|
||||
* Add support for the LPM_CLSHIFT device.
|
||||
*
|
||||
* Revision 1.84 1999/11/13 03:46:52 steve
|
||||
* Support the LPM_MUX in vvm.
|
||||
*
|
||||
* Revision 1.83 1999/11/05 04:40:40 steve
|
||||
* Patch to synthesize LPM_ADD_SUB from expressions,
|
||||
* Thanks to Larry Doolittle. Also handle constants
|
||||
* in expressions.
|
||||
*
|
||||
* Synthesize adders in XNF, based on a patch from
|
||||
* Larry. Accept synthesis of constants from Larry
|
||||
* as is.
|
||||
*
|
||||
* Revision 1.82 1999/11/04 03:53:26 steve
|
||||
* Patch to synthesize unary ~ and the ternary operator.
|
||||
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.
|
||||
*
|
||||
* Add the LPM_MUX device, and integrate it with the
|
||||
* ternary synthesis from Larry. Replace the lpm_mux
|
||||
* generator in t-xnf.cc to use XNF EQU devices to
|
||||
* put muxs into function units.
|
||||
*
|
||||
* Rewrite elaborate_net for the PETernary class to
|
||||
* also use the LPM_MUX device.
|
||||
*
|
||||
* Revision 1.81 1999/11/04 01:12:42 steve
|
||||
* Elaborate combinational UDP devices.
|
||||
*
|
||||
* Revision 1.80 1999/11/02 04:55:34 steve
|
||||
* Add the synthesize method to NetExpr to handle
|
||||
* synthesis of expressions, and use that method
|
||||
* to improve r-value handling of LPM_FF synthesis.
|
||||
*
|
||||
* Modify the XNF target to handle LPM_FF objects.
|
||||
*
|
||||
* Revision 1.79 1999/11/01 02:07:40 steve
|
||||
* Add the synth functor to do generic synthesis
|
||||
* and add the LPM_FF device to handle rows of
|
||||
* flip-flops.
|
||||
*
|
||||
* Revision 1.78 1999/10/31 04:11:27 steve
|
||||
* Add to netlist links pin name and instance number,
|
||||
* and arrange in vvm for pin connections by name
|
||||
* and instance number.
|
||||
*
|
||||
* Revision 1.77 1999/10/10 23:29:37 steve
|
||||
* Support evaluating + operator at compile time.
|
||||
*
|
||||
* Revision 1.76 1999/10/10 01:59:55 steve
|
||||
* Structural case equals device.
|
||||
*
|
||||
* Revision 1.75 1999/10/07 05:25:34 steve
|
||||
* Add non-const bit select in l-value of assignment.
|
||||
*
|
||||
* Revision 1.74 1999/10/06 05:06:16 steve
|
||||
* Move the rvalue into NetAssign_ common code.
|
||||
*
|
||||
* Revision 1.73 1999/10/05 04:02:10 steve
|
||||
* Relaxed width handling for <= assignment.
|
||||
*
|
||||
* Revision 1.72 1999/09/30 21:28:34 steve
|
||||
* Handle mutual reference of tasks by elaborating
|
||||
* task definitions in two passes, like functions.
|
||||
*
|
||||
* Revision 1.71 1999/09/29 18:36:03 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.70 1999/09/28 03:11:29 steve
|
||||
* Get the bit widths of unary operators that return one bit.
|
||||
*
|
||||
* Revision 1.69 1999/09/23 03:56:57 steve
|
||||
* Support shift operators.
|
||||
*
|
||||
* Revision 1.68 1999/09/23 00:21:54 steve
|
||||
* Move set_width methods into a single file,
|
||||
* Add the NetEBLogic class for logic expressions,
|
||||
* Fix error setting with of && in if statements.
|
||||
*
|
||||
* Revision 1.67 1999/09/21 00:13:40 steve
|
||||
* Support parameters that reference other paramters.
|
||||
*
|
||||
* Revision 1.66 1999/09/20 02:21:10 steve
|
||||
* Elaborate parameters in phases.
|
||||
*
|
||||
* Revision 1.65 1999/09/18 01:53:08 steve
|
||||
* Detect constant lessthen-equal expressions.
|
||||
*
|
||||
* Revision 1.64 1999/09/16 04:18:15 steve
|
||||
* elaborate concatenation repeats.
|
||||
*
|
||||
* Revision 1.63 1999/09/16 00:33:45 steve
|
||||
* Handle implicit !=0 in if statements.
|
||||
*
|
||||
* Revision 1.62 1999/09/15 01:55:06 steve
|
||||
* Elaborate non-blocking assignment to memories.
|
||||
*
|
||||
* Revision 1.61 1999/09/13 03:10:59 steve
|
||||
* Clarify msb/lsb in context of netlist. Properly
|
||||
* handle part selects in lval and rval of expressions,
|
||||
* and document where the least significant bit goes
|
||||
* in NetNet objects.
|
||||
*
|
||||
* Revision 1.60 1999/09/12 01:16:51 steve
|
||||
* Pad r-values in certain assignments.
|
||||
*
|
||||
* Revision 1.59 1999/09/11 04:43:17 steve
|
||||
* Support ternary and <= operators in vvm.
|
||||
*
|
||||
* Revision 1.58 1999/09/08 04:05:30 steve
|
||||
* Allow assign to not match rvalue width.
|
||||
*
|
||||
* Revision 1.57 1999/09/04 01:57:15 steve
|
||||
* Generate fake adder code in vvm.
|
||||
*
|
||||
* Revision 1.56 1999/09/03 04:28:38 steve
|
||||
* elaborate the binary plus operator.
|
||||
*
|
||||
* Revision 1.55 1999/09/01 20:46:19 steve
|
||||
* Handle recursive functions and arbitrary function
|
||||
* references to other functions, properly pass
|
||||
* function parameters and save function results.
|
||||
*
|
||||
* Revision 1.54 1999/08/31 22:38:29 steve
|
||||
* Elaborate and emit to vvm procedural functions.
|
||||
*
|
||||
* Revision 1.53 1999/08/25 22:22:41 steve
|
||||
* elaborate some aspects of functions.
|
||||
*
|
||||
* Revision 1.52 1999/08/06 04:05:28 steve
|
||||
* Handle scope of parameters.
|
||||
*
|
||||
* Revision 1.51 1999/08/01 21:48:11 steve
|
||||
* set width of procedural r-values when then
|
||||
* l-value is a memory word.
|
||||
*
|
||||
* Revision 1.50 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.49 1999/07/31 03:16:54 steve
|
||||
* move binary operators to derived classes.
|
||||
*
|
||||
* Revision 1.48 1999/07/24 02:11:20 steve
|
||||
* Elaborate task input ports.
|
||||
*
|
||||
* Revision 1.47 1999/07/18 21:17:50 steve
|
||||
* Add support for CE input to XNF DFF, and do
|
||||
* complete cleanup of replaced design nodes.
|
||||
*
|
||||
* Revision 1.46 1999/07/18 05:52:46 steve
|
||||
* xnfsyn generates DFF objects for XNF output, and
|
||||
* properly rewrites the Design netlist in the process.
|
||||
*
|
||||
* Revision 1.45 1999/07/17 19:51:00 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.44 1999/07/17 18:06:02 steve
|
||||
* Better handling of bit width of + operators.
|
||||
*
|
||||
* Revision 1.43 1999/07/17 03:08:31 steve
|
||||
* part select in expressions.
|
||||
*
|
||||
* Revision 1.42 1999/07/16 04:33:41 steve
|
||||
* set_width for NetESubSignal.
|
||||
*
|
||||
* Revision 1.41 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.40 1999/06/24 05:02:36 steve
|
||||
* Properly terminate signal matching scan.
|
||||
*
|
||||
* Revision 1.39 1999/06/24 04:24:18 steve
|
||||
* Handle expression widths for EEE and NEE operators,
|
||||
* add named blocks and scope handling,
|
||||
* add registers declared in named blocks.
|
||||
*
|
||||
* Revision 1.38 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.37 1999/06/13 23:51:16 steve
|
||||
* l-value part select for procedural assignments.
|
||||
*
|
||||
* Revision 1.36 1999/06/13 16:30:06 steve
|
||||
* Unify the NetAssign constructors a bit.
|
||||
*
|
||||
* Revision 1.35 1999/06/10 05:33:28 steve
|
||||
* Handle a few more operator bit widths.
|
||||
*
|
||||
* Revision 1.34 1999/06/09 03:00:06 steve
|
||||
* Add support for procedural concatenation expression.
|
||||
*
|
||||
* Revision 1.33 1999/06/07 02:23:31 steve
|
||||
* Support non-blocking assignment down to vvm.
|
||||
*
|
||||
* Revision 1.32 1999/06/06 20:45:38 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.31 1999/06/03 05:16:25 steve
|
||||
* Compile time evalutation of constant expressions.
|
||||
*
|
||||
* Revision 1.30 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
* Revision 1.29 1999/05/30 01:11:46 steve
|
||||
* Exressions are trees that can duplicate, and not DAGS.
|
||||
*
|
||||
* Revision 1.28 1999/05/27 04:13:08 steve
|
||||
* Handle expression bit widths with non-fatal errors.
|
||||
*
|
||||
* Revision 1.27 1999/05/20 05:07:37 steve
|
||||
* Line number info with match error message.
|
||||
*
|
||||
* Revision 1.26 1999/05/16 05:08:42 steve
|
||||
* Redo constant expression detection to happen
|
||||
* after parsing.
|
||||
*
|
||||
* Parse more operators and expressions.
|
||||
*
|
||||
* Revision 1.25 1999/05/13 04:02:09 steve
|
||||
* More precise handling of verinum bit lengths.
|
||||
*
|
||||
* Revision 1.24 1999/05/12 04:03:19 steve
|
||||
* emit NetAssignMem objects in vvm target.
|
||||
*
|
||||
* Revision 1.23 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.22 1999/05/01 02:57:53 steve
|
||||
* Handle much more complex event expressions.
|
||||
*
|
||||
* Revision 1.21 1999/04/25 00:44:10 steve
|
||||
* Core handles subsignal expressions.
|
||||
*
|
||||
* Revision 1.20 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.19 1999/03/15 02:43:32 steve
|
||||
* Support more operators, especially logical.
|
||||
*
|
||||
* Revision 1.18 1999/03/01 03:27:53 steve
|
||||
* Prevent the duplicate allocation of ESignal objects.
|
||||
*
|
||||
* Revision 1.17 1999/02/21 17:01:57 steve
|
||||
* Add support for module parameters.
|
||||
*
|
||||
* Revision 1.16 1999/02/08 02:49:56 steve
|
||||
* Turn the NetESignal into a NetNode so
|
||||
* that it can connect to the netlist.
|
||||
* Implement the case statement.
|
||||
* Convince t-vvm to output code for
|
||||
* the case statement.
|
||||
*
|
||||
* Revision 1.15 1999/02/03 04:20:11 steve
|
||||
* Parse and elaborate the Verilog CASE statement.
|
||||
*/
|
||||
|
||||
|
|
|
|||
352
netlist.h
352
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.h,v 1.110 2000/02/23 02:56:55 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.111 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1201,13 +1201,14 @@ class NetForever : public NetProc {
|
|||
class NetFuncDef {
|
||||
|
||||
public:
|
||||
NetFuncDef(const string&, const svector<NetNet*>&po);
|
||||
NetFuncDef(NetScope*, const svector<NetNet*>&po);
|
||||
~NetFuncDef();
|
||||
|
||||
void set_proc(NetProc*st);
|
||||
|
||||
const string& name() const;
|
||||
const string name() const;
|
||||
const NetProc*proc() const;
|
||||
NetScope*scope();
|
||||
|
||||
unsigned port_count() const;
|
||||
const NetNet*port(unsigned idx) const;
|
||||
|
|
@ -1215,7 +1216,7 @@ class NetFuncDef {
|
|||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
NetScope*scope_;
|
||||
NetProc*statement_;
|
||||
svector<NetNet*>ports_;
|
||||
};
|
||||
|
|
@ -1389,7 +1390,7 @@ class NetEUFunc : public NetExpr {
|
|||
NetEUFunc(NetFuncDef*, NetESignal*, svector<NetExpr*>&);
|
||||
~NetEUFunc();
|
||||
|
||||
const string& name() const;
|
||||
const string name() const;
|
||||
|
||||
const NetESignal*result() const;
|
||||
unsigned parm_count() const;
|
||||
|
|
@ -1718,7 +1719,7 @@ class NetEConcat : public NetExpr {
|
|||
class NetEParam : public NetExpr {
|
||||
public:
|
||||
NetEParam();
|
||||
NetEParam(class Design*des, const string&path, const string&name);
|
||||
NetEParam(class Design*des, NetScope*scope, const string&name);
|
||||
~NetEParam();
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
|
|
@ -1730,7 +1731,7 @@ class NetEParam : public NetExpr {
|
|||
|
||||
private:
|
||||
Design*des_;
|
||||
string path_;
|
||||
NetScope*scope_;
|
||||
string name_;
|
||||
};
|
||||
|
||||
|
|
@ -1980,21 +1981,52 @@ class NetESubSignal : public NetExpr {
|
|||
class NetScope {
|
||||
|
||||
public:
|
||||
enum TYPE { MODULE, BEGIN_END, FORK_JOIN };
|
||||
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN };
|
||||
NetScope(const string&root);
|
||||
NetScope(NetScope*up, const string&name, TYPE t);
|
||||
~NetScope();
|
||||
|
||||
/* Parameters exist within a scope, and these methods allow
|
||||
one to manipulate the set. In these cases, the name is the
|
||||
*simple* name of the paramter, the heirarchy is implicit in
|
||||
the scope. The return value from set_parameter is the
|
||||
previous expression, if there was one. */
|
||||
|
||||
NetExpr* set_parameter(const string&name, NetExpr*val);
|
||||
const NetExpr*get_parameter(const string&name) const;
|
||||
|
||||
|
||||
/* The parent and child() methods allow users of NetScope
|
||||
objects to locate nearby scopes. */
|
||||
NetScope* child(const string&name);
|
||||
const NetScope* parent() const;
|
||||
const NetScope* child(const string&name) const;
|
||||
|
||||
TYPE type() const;
|
||||
string name() const;
|
||||
const NetScope* parent() const;
|
||||
|
||||
void run_defparams(class Design*);
|
||||
void evaluate_parameters(class Design*);
|
||||
|
||||
void dump(ostream&) const;
|
||||
void emit_scope(ostream&o, struct target_t*tgt) const;
|
||||
|
||||
|
||||
/* This member is used during elaboration to pass defparam
|
||||
assignments from the scope pass to the parameter evaluation
|
||||
step. After that, it is not used. */
|
||||
|
||||
map<string,NetExpr*>defparams;
|
||||
|
||||
private:
|
||||
TYPE type_;
|
||||
string name_;
|
||||
|
||||
map<string,NetExpr*>parameters_;
|
||||
|
||||
NetScope*up_;
|
||||
NetScope*sib_;
|
||||
NetScope*sub_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -2025,8 +2057,14 @@ class Design {
|
|||
NetScope* find_scope(const string&path);
|
||||
|
||||
// PARAMETERS
|
||||
void set_parameter(const string&, NetExpr*);
|
||||
const NetExpr*find_parameter(const string&path, const string&name) const;
|
||||
|
||||
/* This method searches for a parameter, starting in the given
|
||||
scope. This method handles the upward searches that the
|
||||
NetScope class itself does not support. */
|
||||
const NetExpr*find_parameter(const NetScope*, const string&name) const;
|
||||
|
||||
void run_defparams();
|
||||
void evaluate_parameters();
|
||||
|
||||
// SIGNALS
|
||||
void add_signal(NetNet*);
|
||||
|
|
@ -2074,11 +2112,9 @@ class Design {
|
|||
string local_symbol(const string&path);
|
||||
|
||||
private:
|
||||
map<string,NetScope*> scopes_;
|
||||
|
||||
// List all the parameters in the design. This table includes
|
||||
// the parameters of instantiated modules in canonical names.
|
||||
map<string,NetExpr*> parameters_;
|
||||
// Keep a tree of scopes. The NetScope class handles the wide
|
||||
// tree and per-hop searches for me.
|
||||
NetScope*root_scope_;
|
||||
|
||||
// List all the signals in the design.
|
||||
NetNet*signals_;
|
||||
|
|
@ -2152,6 +2188,13 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.111 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.110 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
@ -2175,282 +2218,5 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
*
|
||||
* Revision 1.103 1999/12/17 03:38:46 steve
|
||||
* NetConst can now hold wide constants.
|
||||
*
|
||||
* Revision 1.102 1999/12/16 02:42:15 steve
|
||||
* Simulate carry output on adders.
|
||||
*
|
||||
* Revision 1.101 1999/12/12 06:03:14 steve
|
||||
* Allow memories without indices in expressions.
|
||||
*
|
||||
* Revision 1.100 1999/12/09 06:00:00 steve
|
||||
* Fix const/non-const errors.
|
||||
*
|
||||
* Revision 1.99 1999/12/05 19:30:43 steve
|
||||
* Generate XNF RAMS from synthesized memories.
|
||||
*
|
||||
* Revision 1.98 1999/12/05 02:24:09 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.97 1999/12/01 06:06:16 steve
|
||||
* Redo synth to use match_proc_t scanner.
|
||||
*
|
||||
* Revision 1.96 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.95 1999/11/27 19:07:58 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.94 1999/11/24 04:01:59 steve
|
||||
* Detect and list scope names.
|
||||
*
|
||||
* Revision 1.93 1999/11/21 17:35:37 steve
|
||||
* Memory name lookup handles scopes.
|
||||
*
|
||||
* Revision 1.92 1999/11/21 00:13:09 steve
|
||||
* Support memories in continuous assignments.
|
||||
*
|
||||
* Revision 1.91 1999/11/19 05:02:37 steve
|
||||
* handle duplicate connect to a nexus.
|
||||
*
|
||||
* Revision 1.90 1999/11/19 03:02:25 steve
|
||||
* Detect flip-flops connected to opads and turn
|
||||
* them into OUTFF devices. Inprove support for
|
||||
* the XNF-LCA attribute in the process.
|
||||
*
|
||||
* Revision 1.89 1999/11/18 03:52:19 steve
|
||||
* Turn NetTmp objects into normal local NetNet objects,
|
||||
* and add the nodangle functor to clean up the local
|
||||
* symbols generated by elaboration and other steps.
|
||||
*
|
||||
* Revision 1.88 1999/11/14 23:43:45 steve
|
||||
* Support combinatorial comparators.
|
||||
*
|
||||
* Revision 1.87 1999/11/14 20:24:28 steve
|
||||
* Add support for the LPM_CLSHIFT device.
|
||||
*
|
||||
* Revision 1.86 1999/11/05 04:40:40 steve
|
||||
* Patch to synthesize LPM_ADD_SUB from expressions,
|
||||
* Thanks to Larry Doolittle. Also handle constants
|
||||
* in expressions.
|
||||
*
|
||||
* Synthesize adders in XNF, based on a patch from
|
||||
* Larry. Accept synthesis of constants from Larry
|
||||
* as is.
|
||||
*
|
||||
* Revision 1.85 1999/11/04 03:53:26 steve
|
||||
* Patch to synthesize unary ~ and the ternary operator.
|
||||
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.
|
||||
*
|
||||
* Add the LPM_MUX device, and integrate it with the
|
||||
* ternary synthesis from Larry. Replace the lpm_mux
|
||||
* generator in t-xnf.cc to use XNF EQU devices to
|
||||
* put muxs into function units.
|
||||
*
|
||||
* Rewrite elaborate_net for the PETernary class to
|
||||
* also use the LPM_MUX device.
|
||||
*
|
||||
* Revision 1.84 1999/11/04 01:12:42 steve
|
||||
* Elaborate combinational UDP devices.
|
||||
*
|
||||
* Revision 1.83 1999/11/02 04:55:34 steve
|
||||
* Add the synthesize method to NetExpr to handle
|
||||
* synthesis of expressions, and use that method
|
||||
* to improve r-value handling of LPM_FF synthesis.
|
||||
*
|
||||
* Modify the XNF target to handle LPM_FF objects.
|
||||
*
|
||||
* Revision 1.82 1999/11/01 02:07:40 steve
|
||||
* Add the synth functor to do generic synthesis
|
||||
* and add the LPM_FF device to handle rows of
|
||||
* flip-flops.
|
||||
*
|
||||
* Revision 1.81 1999/10/31 04:11:27 steve
|
||||
* Add to netlist links pin name and instance number,
|
||||
* and arrange in vvm for pin connections by name
|
||||
* and instance number.
|
||||
*
|
||||
* Revision 1.80 1999/10/10 23:29:37 steve
|
||||
* Support evaluating + operator at compile time.
|
||||
*
|
||||
* Revision 1.79 1999/10/10 01:59:55 steve
|
||||
* Structural case equals device.
|
||||
*
|
||||
* Revision 1.78 1999/10/07 05:25:34 steve
|
||||
* Add non-const bit select in l-value of assignment.
|
||||
*
|
||||
* Revision 1.77 1999/10/06 05:06:16 steve
|
||||
* Move the rvalue into NetAssign_ common code.
|
||||
*
|
||||
* Revision 1.76 1999/09/30 21:28:34 steve
|
||||
* Handle mutual reference of tasks by elaborating
|
||||
* task definitions in two passes, like functions.
|
||||
*
|
||||
* Revision 1.75 1999/09/30 02:43:02 steve
|
||||
* Elaborate ~^ and ~| operators.
|
||||
*
|
||||
* Revision 1.74 1999/09/29 18:36:03 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.73 1999/09/28 03:11:30 steve
|
||||
* Get the bit widths of unary operators that return one bit.
|
||||
*
|
||||
* Revision 1.72 1999/09/25 02:57:30 steve
|
||||
* Parse system function calls.
|
||||
*
|
||||
* Revision 1.71 1999/09/23 03:56:57 steve
|
||||
* Support shift operators.
|
||||
*
|
||||
* Revision 1.70 1999/09/23 00:21:55 steve
|
||||
* Move set_width methods into a single file,
|
||||
* Add the NetEBLogic class for logic expressions,
|
||||
* Fix error setting with of && in if statements.
|
||||
*
|
||||
* Revision 1.69 1999/09/22 16:57:23 steve
|
||||
* Catch parallel blocks in vvm emit.
|
||||
*
|
||||
* Revision 1.68 1999/09/21 00:13:40 steve
|
||||
* Support parameters that reference other paramters.
|
||||
*
|
||||
* Revision 1.67 1999/09/20 02:21:10 steve
|
||||
* Elaborate parameters in phases.
|
||||
*
|
||||
* Revision 1.66 1999/09/18 01:53:08 steve
|
||||
* Detect constant lessthen-equal expressions.
|
||||
*
|
||||
* Revision 1.65 1999/09/16 04:18:15 steve
|
||||
* elaborate concatenation repeats.
|
||||
*
|
||||
* Revision 1.64 1999/09/15 01:55:06 steve
|
||||
* Elaborate non-blocking assignment to memories.
|
||||
*
|
||||
* Revision 1.63 1999/09/13 03:10:59 steve
|
||||
* Clarify msb/lsb in context of netlist. Properly
|
||||
* handle part selects in lval and rval of expressions,
|
||||
* and document where the least significant bit goes
|
||||
* in NetNet objects.
|
||||
*
|
||||
* Revision 1.62 1999/09/11 04:43:17 steve
|
||||
* Support ternary and <= operators in vvm.
|
||||
*
|
||||
* Revision 1.61 1999/09/08 04:05:30 steve
|
||||
* Allow assign to not match rvalue width.
|
||||
*
|
||||
* Revision 1.60 1999/09/03 04:28:38 steve
|
||||
* elaborate the binary plus operator.
|
||||
*
|
||||
* Revision 1.59 1999/09/01 20:46:19 steve
|
||||
* Handle recursive functions and arbitrary function
|
||||
* references to other functions, properly pass
|
||||
* function parameters and save function results.
|
||||
*
|
||||
* Revision 1.58 1999/08/31 22:38:29 steve
|
||||
* Elaborate and emit to vvm procedural functions.
|
||||
*
|
||||
* Revision 1.57 1999/08/25 22:22:41 steve
|
||||
* elaborate some aspects of functions.
|
||||
*
|
||||
* Revision 1.56 1999/08/18 04:00:02 steve
|
||||
* Fixup spelling and some error messages. <LRDoolittle@lbl.gov>
|
||||
*
|
||||
* Revision 1.55 1999/08/06 04:05:28 steve
|
||||
* Handle scope of parameters.
|
||||
*
|
||||
* Revision 1.54 1999/08/01 21:48:11 steve
|
||||
* set width of procedural r-values when then
|
||||
* l-value is a memory word.
|
||||
*
|
||||
* Revision 1.53 1999/08/01 16:34:50 steve
|
||||
* Parse and elaborate rise/fall/decay times
|
||||
* for gates, and handle the rules for partial
|
||||
* lists of times.
|
||||
*
|
||||
* Revision 1.52 1999/07/31 03:16:54 steve
|
||||
* move binary operators to derived classes.
|
||||
*
|
||||
* Revision 1.51 1999/07/24 02:11:20 steve
|
||||
* Elaborate task input ports.
|
||||
*
|
||||
* Revision 1.50 1999/07/18 21:17:50 steve
|
||||
* Add support for CE input to XNF DFF, and do
|
||||
* complete cleanup of replaced design nodes.
|
||||
*
|
||||
* Revision 1.49 1999/07/18 05:52:47 steve
|
||||
* xnfsyn generates DFF objects for XNF output, and
|
||||
* properly rewrites the Design netlist in the process.
|
||||
*
|
||||
* Revision 1.48 1999/07/17 22:01:13 steve
|
||||
* Add the functor interface for functor transforms.
|
||||
*
|
||||
* Revision 1.47 1999/07/17 19:51:00 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.46 1999/07/17 03:08:32 steve
|
||||
* part select in expressions.
|
||||
*
|
||||
* Revision 1.45 1999/07/16 04:33:41 steve
|
||||
* set_width for NetESubSignal.
|
||||
*
|
||||
* Revision 1.44 1999/07/07 04:20:57 steve
|
||||
* Emit vvm for user defined tasks.
|
||||
*
|
||||
* Revision 1.43 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.42 1999/06/24 04:24:18 steve
|
||||
* Handle expression widths for EEE and NEE operators,
|
||||
* add named blocks and scope handling,
|
||||
* add registers declared in named blocks.
|
||||
*
|
||||
* Revision 1.41 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.40 1999/06/13 23:51:16 steve
|
||||
* l-value part select for procedural assignments.
|
||||
*
|
||||
* Revision 1.39 1999/06/13 17:30:23 steve
|
||||
* More unary operators.
|
||||
*
|
||||
* Revision 1.38 1999/06/13 16:30:06 steve
|
||||
* Unify the NetAssign constructors a bit.
|
||||
*
|
||||
* Revision 1.37 1999/06/09 03:00:06 steve
|
||||
* Add support for procedural concatenation expression.
|
||||
*
|
||||
* Revision 1.36 1999/06/06 20:45:38 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.35 1999/06/03 05:16:25 steve
|
||||
* Compile time evalutation of constant expressions.
|
||||
*
|
||||
* Revision 1.34 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
* Revision 1.33 1999/05/30 01:11:46 steve
|
||||
* Exressions are trees that can duplicate, and not DAGS.
|
||||
*
|
||||
* Revision 1.32 1999/05/27 04:13:08 steve
|
||||
* Handle expression bit widths with non-fatal errors.
|
||||
*
|
||||
* Revision 1.31 1999/05/16 05:08:42 steve
|
||||
* Redo constant expression detection to happen
|
||||
* after parsing.
|
||||
*
|
||||
* Parse more operators and expressions.
|
||||
*
|
||||
* Revision 1.30 1999/05/12 04:03:19 steve
|
||||
* emit NetAssignMem objects in vvm target.
|
||||
*
|
||||
* Revision 1.29 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
32
netlist.txt
32
netlist.txt
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: netlist.txt,v 1.7 1999/11/28 23:42:02 steve Exp $"
|
||||
#ident "$Id: netlist.txt,v 1.8 2000/03/08 04:36:54 steve Exp $"
|
||||
|
||||
|
||||
Note that the netlist.h header contains detailed descriptions of how
|
||||
|
|
@ -229,6 +229,29 @@ can operate globally, with optimizations freely crossing module
|
|||
boundaries. This makes coding of netlist transform functions such as
|
||||
constant propagation more effective and easier to write.
|
||||
|
||||
|
||||
SCOPE REPRESENTATION IN NETLISTS
|
||||
|
||||
In spite of the literal flattening of the design, scope information is
|
||||
preserved in the netlist, with the NetScope class. The Design class
|
||||
keeps a single pointer to the root scope of the design. This is the
|
||||
scope of the root module. Scopes that are then created within that
|
||||
(or any nested) module are placed as children of the root scope, and
|
||||
those children can have further children, and so on.
|
||||
|
||||
Each scope in the tree carries its own name, and its relationship to
|
||||
its parent and children. This makes it possible to walk the tree of
|
||||
scopes. In practice, the walking of the scopes is handled by recursive
|
||||
methods.
|
||||
|
||||
Each scope also carries the parameters that are applicable to the
|
||||
scope itself. The parameter expression (possibly evaluated) can be
|
||||
located by name, given the scope object itself. The scan of the pform
|
||||
to generate scopes also places the parameters that are declared in the
|
||||
scope. Overrides are managed during the scan, and once the scan is
|
||||
complete, defparam overrides are applied.
|
||||
|
||||
|
||||
TASKS IN NETLISTS
|
||||
|
||||
The flattening of the design does not include tasks and named
|
||||
|
|
@ -240,6 +263,13 @@ some task calls. C++ programmers recognize this as inlining a task.)
|
|||
|
||||
|
||||
$Log: netlist.txt,v $
|
||||
Revision 1.8 2000/03/08 04:36:54 steve
|
||||
Redesign the implementation of scopes and parameters.
|
||||
I now generate the scopes and notice the parameters
|
||||
in a separate pass over the pform. Once the scopes
|
||||
are generated, I can process overrides and evalutate
|
||||
paremeters before elaboration begins.
|
||||
|
||||
Revision 1.7 1999/11/28 23:42:02 steve
|
||||
NetESignal object no longer need to be NetNode
|
||||
objects. Let them keep a pointer to NetNet objects.
|
||||
|
|
|
|||
5
parse.y
5
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.84 2000/03/05 18:26:51 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.85 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -261,9 +261,8 @@ defparam_assign
|
|||
delete tmp;
|
||||
tmp = 0;
|
||||
}
|
||||
yyerror(@1, "sorry: defparam assignments not supported.");
|
||||
pform_set_defparam($1, $3);
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
16
pform.cc
16
pform.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.cc,v 1.54 2000/02/23 02:56:55 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.55 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compiler.h"
|
||||
|
|
@ -727,10 +727,17 @@ void pform_set_net_range(list<string>*names, const svector<PExpr*>*range)
|
|||
|
||||
void pform_set_parameter(const string&name, PExpr*expr)
|
||||
{
|
||||
assert(expr);
|
||||
pform_cur_module->parameters[name] = expr;
|
||||
pform_cur_module->param_names.push_back(name);
|
||||
}
|
||||
|
||||
void pform_set_defparam(const string&name, PExpr*expr)
|
||||
{
|
||||
assert(expr);
|
||||
pform_cur_module->defparms[name] = expr;
|
||||
}
|
||||
|
||||
void pform_set_port_type(list<string>*names, NetNet::PortType pt)
|
||||
{
|
||||
for (list<string>::const_iterator cur = names->begin()
|
||||
|
|
@ -820,6 +827,13 @@ int pform_parse(const char*path, map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.55 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.54 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
10
pform.h
10
pform.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.h,v 1.35 2000/02/23 02:56:55 steve Exp $"
|
||||
#ident "$Id: pform.h,v 1.36 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -133,6 +133,7 @@ extern void pform_set_attrib(const string&name, const string&key,
|
|||
extern void pform_set_type_attrib(const string&name, const string&key,
|
||||
const string&value);
|
||||
extern void pform_set_parameter(const string&name, PExpr*expr);
|
||||
extern void pform_set_defparam(const string&name, PExpr*expr);
|
||||
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
|
||||
|
||||
extern svector<PWire*>* pform_make_udp_input_ports(list<string>*);
|
||||
|
|
@ -180,6 +181,13 @@ extern void pform_dump(ostream&out, Module*mod);
|
|||
|
||||
/*
|
||||
* $Log: pform.h,v $
|
||||
* Revision 1.36 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.35 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform_dump.cc,v 1.49 2000/02/23 02:56:55 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.50 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -609,6 +609,15 @@ void Module::dump(ostream&out) const
|
|||
out << "/* ERROR */;" << endl;
|
||||
}
|
||||
|
||||
for (parm_iter_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; cur ++) {
|
||||
out << " defparam " << (*cur).first << " = ";
|
||||
if ((*cur).second)
|
||||
out << *(*cur).second << ";" << endl;
|
||||
else
|
||||
out << "/* ERROR */;" << endl;
|
||||
}
|
||||
|
||||
// Iterate through and display all the wires.
|
||||
for (map<string,PWire*>::const_iterator wire = wires_.begin()
|
||||
; wire != wires_.end()
|
||||
|
|
@ -702,6 +711,13 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.50 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.49 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
15
t-vvm.cc
15
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-vvm.cc,v 1.106 2000/02/29 05:20:21 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.107 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -691,6 +691,12 @@ void target_vvm::scope(ostream&os, const NetScope*scope)
|
|||
case NetScope::MODULE:
|
||||
type_code = "vpiModule";
|
||||
break;
|
||||
case NetScope::TASK:
|
||||
type_code = "vpiTask";
|
||||
break;
|
||||
case NetScope::FUNC:
|
||||
type_code = "vpiFunction";
|
||||
break;
|
||||
case NetScope::BEGIN_END:
|
||||
type_code = "vpiNamedBegin";
|
||||
break;
|
||||
|
|
@ -2168,6 +2174,13 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.107 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.106 2000/02/29 05:20:21 steve
|
||||
* Remove excess variable.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vpi_user.h,v 1.13 2000/02/23 02:56:56 steve Exp $"
|
||||
#ident "$Id: vpi_user.h,v 1.14 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -99,6 +99,7 @@ typedef struct t_vpi_value {
|
|||
|
||||
/* OBJECT CODES */
|
||||
#define vpiConstant 7
|
||||
#define vpiFunction 20
|
||||
#define vpiIterator 27
|
||||
#define vpiMemory 29
|
||||
#define vpiMemoryWord 30
|
||||
|
|
@ -108,6 +109,7 @@ typedef struct t_vpi_value {
|
|||
#define vpiNet 36
|
||||
#define vpiReg 48
|
||||
#define vpiSysTaskCall 57
|
||||
#define vpiTask 59
|
||||
#define vpiTimeVar 63
|
||||
#define vpiSysTfCall 85
|
||||
#define vpiArgument 89
|
||||
|
|
@ -228,6 +230,13 @@ extern void (*vlog_startup_routines[])();
|
|||
|
||||
/*
|
||||
* $Log: vpi_user.h,v $
|
||||
* Revision 1.14 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.13 2000/02/23 02:56:56 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vpi_scope.c,v 1.5 2000/02/23 02:56:56 steve Exp $"
|
||||
#ident "$Id: vpi_scope.c,v 1.6 2000/03/08 04:36:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
|
|
@ -47,6 +47,26 @@ static const struct __vpirt vpip_module_rt = {
|
|||
module_iter
|
||||
};
|
||||
|
||||
static const struct __vpirt vpip_task_rt = {
|
||||
vpiTask,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
static const struct __vpirt vpip_function_rt = {
|
||||
vpiFunction,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
static const struct __vpirt vpip_named_begin_rt = {
|
||||
vpiNamedBegin,
|
||||
0,
|
||||
|
|
@ -69,6 +89,12 @@ vpiHandle vpip_make_scope(struct __vpiScope*ref, int type, const char*name)
|
|||
case vpiNamedBegin:
|
||||
ref->base.vpi_type = &vpip_named_begin_rt;
|
||||
break;
|
||||
case vpiTask:
|
||||
ref->base.vpi_type = &vpip_task_rt;
|
||||
break;
|
||||
case vpiFunction:
|
||||
ref->base.vpi_type = &vpip_function_rt;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -90,6 +116,13 @@ void vpip_attach_to_scope(struct __vpiScope*ref, vpiHandle obj)
|
|||
|
||||
/*
|
||||
* $Log: vpi_scope.c,v $
|
||||
* Revision 1.6 2000/03/08 04:36:54 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.5 2000/02/23 02:56:56 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue