diff --git a/Module.h b/Module.h index 639074153..c7a06c8a7 100644 --- a/Module.h +++ b/Module.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: Module.h,v 1.26 2002/08/12 01:34:58 steve Exp $" +#ident "$Id: Module.h,v 1.27 2002/08/19 02:39:16 steve Exp $" #endif # include @@ -67,8 +67,14 @@ class Module : public LineInfo { /* The module has parameters that are evaluated when the module is elaborated. During parsing, I put the parameters into this map. */ - mapparameters; - maplocalparams; + struct param_expr_t { + PExpr*expr; + PExpr*msb; + PExpr*lsb; + bool signed_flag; + }; + mapparameters; + maplocalparams; /* The module also has defparam assignments which don't create new parameters within the module, but may be used to set @@ -145,6 +151,9 @@ class Module : public LineInfo { /* * $Log: Module.h,v $ + * Revision 1.27 2002/08/19 02:39:16 steve + * Support parameters with defined ranges. + * * Revision 1.26 2002/08/12 01:34:58 steve * conditional ident string using autoconfig. * diff --git a/PExpr.cc b/PExpr.cc index 7681ba86d..e335ea4c1 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.cc,v 1.30 2002/08/12 01:34:58 steve Exp $" +#ident "$Id: PExpr.cc,v 1.31 2002/08/19 02:39:16 steve Exp $" #endif # include "config.h" @@ -161,12 +161,12 @@ bool PEIdent::is_constant(Module*mod) const { if (mod == 0) return false; - { map::const_iterator cur; + { map::const_iterator cur; cur = mod->parameters.find(path_.peek_name(0)); if (cur != mod->parameters.end()) return true; } - { map::const_iterator cur; + { map::const_iterator cur; cur = mod->localparams.find(path_.peek_name(0)); if (cur != mod->localparams.end()) return true; } @@ -256,6 +256,9 @@ bool PEUnary::is_constant(Module*m) const /* * $Log: PExpr.cc,v $ + * Revision 1.31 2002/08/19 02:39:16 steve + * Support parameters with defined ranges. + * * Revision 1.30 2002/08/12 01:34:58 steve * conditional ident string using autoconfig. * diff --git a/elab_expr.cc b/elab_expr.cc index 3e9d1acfc..8002ea80e 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_expr.cc,v 1.62 2002/08/12 01:34:58 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.63 2002/08/19 02:39:16 steve Exp $" #endif # include "config.h" @@ -201,7 +201,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const PExpr*expr = parms_[0]; NetExpr*sub = expr->elaborate_expr(des, scope, true); - verinum val (sub->expr_width(), sizeof(unsigned)); + verinum val (sub->expr_width(), 8*sizeof(unsigned)); delete sub; sub = new NetEConst(val); @@ -874,6 +874,9 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const /* * $Log: elab_expr.cc,v $ + * Revision 1.63 2002/08/19 02:39:16 steve + * Support parameters with defined ranges. + * * Revision 1.62 2002/08/12 01:34:58 steve * conditional ident string using autoconfig. * diff --git a/elab_scope.cc b/elab_scope.cc index d8a8b14f2..27b97f232 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -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.14 2002/08/12 01:34:59 steve Exp $" +#ident "$Id: elab_scope.cc,v 1.15 2002/08/19 02:39:16 steve Exp $" #endif # include "config.h" @@ -54,7 +54,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const // the pform and just place a NetEParam placeholder in the // place of the elaborated expression. - typedef map::const_iterator mparm_it_t; + typedef map::const_iterator mparm_it_t; typedef map::const_iterator hparm_it_t; @@ -82,10 +82,40 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const for (mparm_it_t cur = parameters.begin() ; cur != parameters.end() ; cur ++) { - PExpr*ex = (*cur).second; + PExpr*ex = (*cur).second.expr; assert(ex); NetExpr*val = ex->elaborate_pexpr(des, scope); + + /* If the parameter declaration includes msb and lsb, + then use them to calculate a width for the + result. Then make sure the constant expression of the + parameter value is coerced to have the correct + and defined width. */ + if ((*cur).second.msb) { + verinum*msb = (*cur).second.msb ->eval_const(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(val)) { + verinum tval (tmp->value(), width); + val = new NetEConst(tval); + delete tmp; + } + } + val = scope->set_parameter((*cur).first, val); assert(val); delete val; @@ -94,7 +124,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const for (mparm_it_t cur = localparams.begin() ; cur != localparams.end() ; cur ++) { - PExpr*ex = (*cur).second; + PExpr*ex = (*cur).second.expr; assert(ex); NetExpr*val = ex->elaborate_pexpr(des, scope); @@ -467,6 +497,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const /* * $Log: elab_scope.cc,v $ + * Revision 1.15 2002/08/19 02:39:16 steve + * Support parameters with defined ranges. + * * Revision 1.14 2002/08/12 01:34:59 steve * conditional ident string using autoconfig. * diff --git a/parse.y b/parse.y index d5a0fa32d..3fba90d24 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: parse.y,v 1.157 2002/06/21 04:59:35 steve Exp $" +#ident "$Id: parse.y,v 1.158 2002/08/19 02:39:16 steve Exp $" #endif # include "config.h" @@ -30,6 +30,8 @@ extern void lex_start_table(); extern void lex_end_table(); +static svector* active_range = 0; + /* * These are some common strength pairs that are used as defaults when * the user is not otherwise specific. @@ -287,7 +289,7 @@ block_item_decl { delete $2; yyerror(@1, "sorry: realtime variables not supported."); } - | K_parameter parameter_assign_list ';' + | K_parameter parameter_assign_decl ';' | K_localparam localparam_assign_list ';' /* Recover from errors that happen within variable lists. Use the @@ -399,8 +401,7 @@ defparam_assign defparam_assign_list : defparam_assign | range defparam_assign - { yywarn(@1, "Ranges in parameter definition " - "are not supported."); + { yyerror(@1, "error: defparam may not include a range."); delete $1; } | defparam_assign_list ',' defparam_assign @@ -1618,19 +1619,21 @@ parameter_assign delete tmp; tmp = 0; } else { - pform_set_parameter($1, tmp); + pform_set_parameter($1, active_range, tmp); } delete $1; } ; +parameter_assign_decl + : parameter_assign_list + | range { active_range = $1; } parameter_assign_list + { active_range = 0; + } + ; + parameter_assign_list : parameter_assign - | range parameter_assign - { yywarn(@1, "Ranges in parameter definition " - "are not supported."); - delete $1; - } | parameter_assign_list ',' parameter_assign ; diff --git a/pform.cc b/pform.cc index 209f8c2cd..f938bb136 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform.cc,v 1.100 2002/08/12 01:35:00 steve Exp $" +#ident "$Id: pform.cc,v 1.101 2002/08/19 02:39:17 steve Exp $" #endif # include "config.h" @@ -1166,17 +1166,33 @@ void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r) cur->set_memory_idx(l, r); } -void pform_set_parameter(const string&name, PExpr*expr) +void pform_set_parameter(const string&name, svector*range, PExpr*expr) { assert(expr); - pform_cur_module->parameters[name] = expr; + pform_cur_module->parameters[name].expr = expr; + + if (range) { + assert(range->count() == 2); + assert((*range)[0]); + assert((*range)[1]); + pform_cur_module->parameters[name].msb = (*range)[0]; + pform_cur_module->parameters[name].lsb = (*range)[1]; + } else { + pform_cur_module->parameters[name].msb = 0; + pform_cur_module->parameters[name].lsb = 0; + } + pform_cur_module->parameters[name].signed_flag = false; + pform_cur_module->param_names.push_back(name); } void pform_set_localparam(const string&name, PExpr*expr) { assert(expr); - pform_cur_module->localparams[name] = expr; + pform_cur_module->localparams[name].expr = expr; + pform_cur_module->localparams[name].msb = 0; + pform_cur_module->localparams[name].lsb = 0; + pform_cur_module->localparams[name].signed_flag = false; } void pform_set_defparam(const hname_t&name, PExpr*expr) @@ -1343,6 +1359,9 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.101 2002/08/19 02:39:17 steve + * Support parameters with defined ranges. + * * Revision 1.100 2002/08/12 01:35:00 steve * conditional ident string using autoconfig. * diff --git a/pform.h b/pform.h index 7bd1e54c5..56d1c6a45 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform.h,v 1.62 2002/08/12 01:35:00 steve Exp $" +#ident "$Id: pform.h,v 1.63 2002/08/19 02:39:17 steve Exp $" #endif # include "netlist.h" @@ -196,7 +196,9 @@ extern void pform_set_attrib(const char*name, const string&key, extern void pform_set_type_attrib(const string&name, const string&key, char*value); -extern void pform_set_parameter(const string&name, PExpr*expr); +extern void pform_set_parameter(const string&name, + svector*range, + PExpr*expr); extern void pform_set_localparam(const string&name, PExpr*expr); extern void pform_set_defparam(const hname_t&name, PExpr*expr); @@ -256,6 +258,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.63 2002/08/19 02:39:17 steve + * Support parameters with defined ranges. + * * Revision 1.62 2002/08/12 01:35:00 steve * conditional ident string using autoconfig. * diff --git a/pform_dump.cc b/pform_dump.cc index 94a3998a8..c0c98c771 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -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.75 2002/08/12 01:35:00 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.76 2002/08/19 02:39:17 steve Exp $" #endif # include "config.h" @@ -707,22 +707,30 @@ void Module::dump(ostream&out) const out << ")" << endl; } - typedef map::const_iterator parm_iter_t; + typedef map::const_iterator parm_iter_t; typedef map::const_iterator parm_hiter_t; for (parm_iter_t cur = parameters.begin() ; cur != parameters.end() ; cur ++) { - out << " parameter " << (*cur).first << " = "; - if ((*cur).second) - out << *(*cur).second << ";" << endl; + out << " parameter "; + if ((*cur).second.msb) + out << "[" << *(*cur).second.msb << ":" + << *(*cur).second.lsb << "] "; + out << (*cur).first << " = "; + if ((*cur).second.expr) + out << *(*cur).second.expr << ";" << endl; else out << "/* ERROR */;" << endl; } for (parm_iter_t cur = localparams.begin() ; cur != localparams.end() ; cur ++) { - out << " localparam " << (*cur).first << " = "; - if ((*cur).second) - out << *(*cur).second << ";" << endl; + out << " localparam "; + if ((*cur).second.msb) + out << "[" << *(*cur).second.msb << ":" + << *(*cur).second.lsb << "] "; + out << (*cur).first << " = "; + if ((*cur).second.expr) + out << *(*cur).second.expr << ";" << endl; else out << "/* ERROR */;" << endl; } @@ -838,6 +846,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.76 2002/08/19 02:39:17 steve + * Support parameters with defined ranges. + * * Revision 1.75 2002/08/12 01:35:00 steve * conditional ident string using autoconfig. * diff --git a/verinum.cc b/verinum.cc index 964dcb0ca..c5cdb20b7 100644 --- a/verinum.cc +++ b/verinum.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verinum.cc,v 1.34 2002/08/12 01:35:01 steve Exp $" +#ident "$Id: verinum.cc,v 1.35 2002/08/19 02:39:17 steve Exp $" #endif # include "config.h" @@ -95,14 +95,27 @@ verinum::verinum(const verinum&that) verinum::verinum(const verinum&that, unsigned nbits) { - assert(nbits <= that.nbits_); string_flag_ = false; nbits_ = nbits; bits_ = new V[nbits_]; has_len_ = true; - has_sign_ = false; - for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) + has_sign_ = that.has_sign_; + + unsigned copy = nbits; + if (copy > that.nbits_) + copy = that.nbits_; + for (unsigned idx = 0 ; idx < copy ; idx += 1) bits_[idx] = that.bits_[idx]; + + if (copy < nbits_) { + if (has_sign_) { + for (unsigned idx = copy ; idx < nbits_ ; idx += 1) + bits_[idx] = bits_[idx-1]; + } else { + for (unsigned idx = copy ; idx < nbits_ ; idx += 1) + bits_[idx] = verinum::V0; + } + } } verinum::verinum(long that) @@ -802,6 +815,9 @@ verinum::V operator & (verinum::V l, verinum::V r) /* * $Log: verinum.cc,v $ + * Revision 1.35 2002/08/19 02:39:17 steve + * Support parameters with defined ranges. + * * Revision 1.34 2002/08/12 01:35:01 steve * conditional ident string using autoconfig. *