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:
steve 2000-03-08 04:36:53 +00:00
parent 0fbca815b4
commit e7efc2709a
27 changed files with 1545 additions and 1390 deletions

View File

@ -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 \

View File

@ -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
View File

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

View File

@ -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
View File

@ -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
View File

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

View File

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

View File

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

View File

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

View File

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

53
elab_pexpr.cc Normal file
View File

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

242
elab_scope.cc Normal file
View File

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

View File

@ -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
View File

@ -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
View File

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

View File

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

533
net_design.cc Normal file
View File

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

View File

@ -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
View File

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

View File

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

View File

@ -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;
}
;

View File

@ -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
View File

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

View File

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

View File

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

View File

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

View File

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