Redo the parameter vector support to allow

parameter names in range expressions.
This commit is contained in:
steve 2002-10-19 22:59:49 +00:00
parent c0c67a101a
commit 43501809b1
9 changed files with 262 additions and 172 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.133 2002/08/19 00:06:11 steve Exp $"
#ident "$Id: design_dump.cc,v 1.134 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -699,17 +699,26 @@ void NetScope::dump(ostream&o) const
/* Dump the parameters for this scope. */
{
map<string,NetExpr*>::const_iterator pp;
map<string,param_expr_t>::const_iterator pp;
for (pp = parameters_.begin()
; pp != parameters_.end() ; pp ++) {
o << " parameter " << (*pp).first << " = " <<
*(*pp).second << ";" << endl;
o << " parameter ";
if ((*pp).second.signed_flag)
o << "signed ";
if ((*pp).second.msb)
o << "[" << *(*pp).second.msb
<< ":" << *(*pp).second.lsb << "] ";
o << (*pp).first << " = " <<
*(*pp).second.expr << ";" << endl;
}
for (pp = localparams_.begin()
; pp != localparams_.end() ; pp ++) {
o << " localparam " << (*pp).first << " = " <<
*(*pp).second << ";" << endl;
*(*pp).second.expr << ";" << endl;
}
}
@ -925,7 +934,10 @@ void NetEMemory::dump(ostream&o) const
void NetEParam::dump(ostream&o) const
{
o << "<" << scope_->name() << "." << name_ << ">";
if (scope_ != 0)
o << "<" << scope_->name() << "." << name_ << ">";
else
o << "<" << name_ << ">";
}
void NetETernary::dump(ostream&o) const
@ -991,6 +1003,10 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.134 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.133 2002/08/19 00:06:11 steve
* Allow release to handle removal of target net.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_scope.cc,v 1.16 2002/09/01 03:01:48 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.17 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -68,7 +68,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp);
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
for (mparm_it_t cur = localparams.begin()
@ -78,7 +78,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp);
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
@ -94,6 +94,9 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
@ -101,37 +104,15 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
verinum*msb = (*cur).second.msb ->eval_const(des, scope);
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
verinum*lsb = (*cur).second.lsb ->eval_const(des, scope);
assert(lsb);
long msl = msb->as_long();
long lsl = lsb->as_long();
delete msb;
delete lsb;
unsigned width;
if (msl >= lsl)
width = msl - lsl + 1;
else
width = lsl - msl + 1;
if (NetEConst*tmp = dynamic_cast<NetEConst*>(val)) {
verinum tval (tmp->value(), width);
tval.has_sign((*cur).second.signed_flag);
val = new NetEConst(tval);
delete tmp;
}
/* If the parameter has a range, then the
signedness is taken from the parameter
declaration, and the signedness of the
expression is ignored. */
val->cast_signed( (*cur).second.signed_flag );
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val = scope->set_parameter((*cur).first, val);
val->cast_signed(signed_flag);
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
assert(val);
delete val;
}
@ -143,7 +124,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
val = scope->set_parameter((*cur).first, val);
val = scope->set_parameter((*cur).first, val, 0, 0, false);
assert(val);
delete val;
}
@ -351,9 +332,12 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
val = my_scope->set_parameter((*cur).first, val);
assert(val);
delete val;
bool flag = my_scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< sc->name() << "." << endl;
}
}
}
@ -512,6 +496,10 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.17 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.16 2002/09/01 03:01:48 steve
* Properly cast signedness of parameters with ranges.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval.cc,v 1.31 2002/10/13 05:01:07 steve Exp $"
#ident "$Id: eval.cc,v 1.32 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -145,7 +145,8 @@ verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
if (eval == 0) {
cerr << get_line() << ": internal error: Unable to evaluate "
<< "constant expression: " << *expr << endl;
<< "constant expression (parameter=" << path_
<< "): " << *expr << endl;
return 0;
}
@ -225,6 +226,10 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
/*
* $Log: eval.cc,v $
* Revision 1.32 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.31 2002/10/13 05:01:07 steve
* More verbose eval_const assert message.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_tree.cc,v 1.41 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.42 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -884,7 +884,7 @@ NetExpr* NetEParam::eval_tree()
// The result can be saved as the value of the parameter for
// future reference, and return a copy to the caller.
scope_->set_parameter(name_.peek_name(0), res);
scope_->replace_parameter(name_.peek_name(0), res);
return res->dup_expr();
}
@ -1134,6 +1134,10 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.42 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.41 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_design.cc,v 1.27 2002/08/16 05:18:27 steve Exp $"
#ident "$Id: net_design.cc,v 1.28 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -242,13 +242,11 @@ void NetScope::run_defparams(Design*des)
continue;
}
NetExpr*tmp = targ_scope->set_parameter(name, val);
if (tmp == 0) {
bool flag = targ_scope->replace_parameter(name, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< name << " not found in " << targ_scope->name()
<< "." << endl;
} else {
delete tmp;
<< name << " not found in "
<< targ_scope->name() << "." << endl;
}
delete[]name;
@ -276,34 +274,129 @@ void NetScope::evaluate_parameters(Design*des)
// 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;
typedef map<string,param_expr_t>::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);
long msb = 0;
long lsb = 0;
bool range_flag = false;
NetExpr*expr;
// If it's already a NetEConst, then this parameter is done.
if (dynamic_cast<const NetEConst*>(expr))
continue;
/* Evaluate the msb expression, if it is present. */
expr = (*cur).second.msb;
// 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;
if (expr) {
NetEConst*tmp = dynamic_cast<NetEConst*>(expr);
if (! tmp) {
NetExpr*nexpr = expr->eval_tree();
if (nexpr == 0) {
cerr << (*cur).second.expr->get_line()
<< ": internal error: "
<< "unable to evaluate msb expression "
<< "for parameter " << (*cur).first << ": "
<< *expr << endl;
des->errors += 1;
continue;
}
assert(nexpr);
delete expr;
(*cur).second.msb = nexpr;
tmp = dynamic_cast<NetEConst*>(nexpr);
}
assert(tmp);
msb = tmp->value().as_long();
range_flag = true;
}
// The evaluate worked, replace the old expression with
// this constant value.
assert(nexpr);
delete expr;
(*cur).second = nexpr;
/* Evaluate the lsb expression, if it is present. */
expr = (*cur).second.lsb;
if (expr) {
NetEConst*tmp = dynamic_cast<NetEConst*>(expr);
if (! tmp) {
NetExpr*nexpr = expr->eval_tree();
if (nexpr == 0) {
cerr << (*cur).second.expr->get_line()
<< ": internal error: "
<< "unable to evaluate lsb expression "
<< "for parameter " << (*cur).first << ": "
<< *expr << endl;
des->errors += 1;
continue;
}
assert(nexpr);
delete expr;
(*cur).second.lsb = nexpr;
tmp = dynamic_cast<NetEConst*>(nexpr);
}
assert(tmp);
lsb = tmp->value().as_long();
assert(range_flag);
}
/* Evaluate the parameter expression, if necessary. */
expr = (*cur).second.expr;
assert(expr);
if (! dynamic_cast<const NetEConst*>(expr)) {
// Try to evaluate the expression.
NetExpr*nexpr = expr->eval_tree();
if (nexpr == 0) {
cerr << (*cur).second.expr->get_line()
<< ": internal error: "
"unable to evaluate parameter value: " <<
*expr << endl;
des->errors += 1;
continue;
}
// The evaluate worked, replace the old expression with
// this constant value.
assert(nexpr);
delete expr;
(*cur).second.expr = nexpr;
// Set the signedness flag.
(*cur).second.expr->cast_signed( (*cur).second.signed_flag );
}
/* If the parameter has range information, then make
sure the value is set right. */
if (range_flag) {
long wid = (msb >= lsb)? msb - lsb : lsb - msb;
wid += 1;
NetEConst*val = dynamic_cast<NetEConst*>((*cur).second.expr);
assert(val);
verinum value = val->value();
if (! (value.has_len()
&& (value.len() == wid)
&& (value.has_sign() == (*cur).second.signed_flag))) {
verinum tmp (value, wid);
tmp.has_sign ( (*cur).second.signed_flag );
delete val;
val = new NetEConst(tmp);
(*cur).second.expr = val;
}
}
}
}
@ -500,6 +593,10 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.28 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.27 2002/08/16 05:18:27 steve
* Fix intermix of node functors and node delete.
*
@ -518,86 +615,5 @@ void Design::delete_process(NetProcTop*top)
*
* Revision 1.22 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.21 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.20 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.19 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.18 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.17 2000/12/16 01:45:48 steve
* Detect recursive instantiations (PR#2)
*
* Revision 1.16 2000/09/24 17:41:13 steve
* fix null pointer when elaborating undefined task.
*
* Revision 1.15 2000/08/26 00:54:03 steve
* Get at gate information for ivl_target interface.
*
* Revision 1.14 2000/08/12 17:59:48 steve
* Limit signal scope search at module boundaries.
*
* Revision 1.13 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.12 2000/07/23 02:41:32 steve
* Excessive assert.
*
* Revision 1.11 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.10 2000/07/16 04:56:08 steve
* Handle some edge cases during node scans.
*
* Revision 1.9 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.8 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.7 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*
* Revision 1.6 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.5 2000/04/28 16:50:53 steve
* Catch memory word parameters to tasks.
*
* Revision 1.4 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.3 2000/03/11 03:25:52 steve
* Locate scopes in statements.
*
* Revision 1.2 2000/03/10 06:20:48 steve
* Handle defparam to partial hierarchical names.
*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_expr.cc,v 1.7 2002/09/01 03:01:48 steve Exp $"
#ident "$Id: net_expr.cc,v 1.8 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -111,7 +111,7 @@ unsigned NetEConcat::repeat() const
}
NetEParam::NetEParam()
: des_(0)
: des_(0), scope_(0)
{
}
@ -171,6 +171,10 @@ bool NetESelect::set_width(unsigned w)
/*
* $Log: net_expr.cc,v $
* Revision 1.8 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.7 2002/09/01 03:01:48 steve
* Properly cast signedness of parameters with ranges.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_scope.cc,v 1.19 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: net_scope.cc,v 1.20 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -78,33 +78,63 @@ NetScope::~NetScope()
free(module_name_);
}
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr)
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr,
NetExpr*msb, NetExpr*lsb, bool signed_flag)
{
NetExpr*&ref = parameters_[key];
NetExpr* res = ref;
ref = expr;
param_expr_t&ref = parameters_[key];
NetExpr* res = ref.expr;
ref.expr = expr;
ref.msb = msb;
ref.lsb = lsb;
ref.signed_flag = signed_flag;
return res;
}
/*
* Return false if this creates a new parameter.
*/
bool NetScope::replace_parameter(const string&key, NetExpr*expr)
{
bool flag = true;
param_expr_t&ref = parameters_[key];
NetExpr* res = ref.expr;
if (res) {
delete res;
} else {
flag = false;
ref.msb = 0;
ref.lsb = 0;
ref.signed_flag = false;
}
ref.expr = expr;
return flag;
}
NetExpr* NetScope::set_localparam(const string&key, NetExpr*expr)
{
NetExpr*&ref = localparams_[key];
NetExpr* res = ref;
ref = expr;
param_expr_t&ref = localparams_[key];
NetExpr* res = ref.expr;
ref.expr = expr;
ref.msb = 0;
ref.lsb = 0;
ref.signed_flag = false;
return res;
}
const NetExpr* NetScope::get_parameter(const string&key) const
{
map<string,NetExpr*>::const_iterator idx;
map<string,param_expr_t>::const_iterator idx;
idx = parameters_.find(key);
if (idx != parameters_.end())
return (*idx).second;
return (*idx).second.expr;
idx = localparams_.find(key);
if (idx != localparams_.end())
return (*idx).second;
return (*idx).second.expr;
return 0;
}
@ -402,6 +432,10 @@ string NetScope::local_hsymbol()
/*
* $Log: net_scope.cc,v $
* Revision 1.20 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.19 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.264 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: netlist.h,v 1.265 2002/10/19 22:59:49 steve Exp $"
#endif
/*
@ -2764,10 +2764,17 @@ class NetScope {
the scope. The return value from set_parameter is the
previous expression, if there was one. */
NetExpr* set_parameter(const string&name, NetExpr*val);
NetExpr* set_parameter(const string&name, NetExpr*val,
NetExpr*msb, NetExpr*lsb, bool signed_flag);
NetExpr* set_localparam(const string&name, NetExpr*val);
const NetExpr*get_parameter(const string&name) const;
/* These are used by defparam elaboration to replace the
expression with a new expression, without affecting the
range or signed_flag. Return false if the name does not
exist. */
bool replace_parameter(const string&name, NetExpr*val);
/* These methods set or access events that live in this
scope. */
@ -2868,8 +2875,14 @@ class NetScope {
signed char time_unit_, time_prec_;
map<string,NetExpr*>parameters_;
map<string,NetExpr*>localparams_;
struct param_expr_t {
NetExpr*expr;
NetExpr*msb;
NetExpr*lsb;
bool signed_flag;
};
map<string,param_expr_t>parameters_;
map<string,param_expr_t>localparams_;
NetEvent *events_;
NetNet *signals_;
@ -3057,6 +3070,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.265 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.264 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_dump.cc,v 1.76 2002/08/19 02:39:17 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.77 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@ -712,6 +712,8 @@ void Module::dump(ostream&out) const
for (parm_iter_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
out << " parameter ";
if ((*cur).second.signed_flag)
out << "signed ";
if ((*cur).second.msb)
out << "[" << *(*cur).second.msb << ":"
<< *(*cur).second.lsb << "] ";
@ -846,6 +848,10 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.77 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.76 2002/08/19 02:39:17 steve
* Support parameters with defined ranges.
*