From 95c8115fc767a14fed77999940addcac8de26dcd Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 26 Aug 2004 04:02:03 +0000 Subject: [PATCH] Add support for localparam ranges. --- elab_scope.cc | 25 +++++++++++++++++++++++-- parse.y | 29 +++++++++++++++++++++-------- pform.cc | 23 ++++++++++++++++++----- pform.h | 10 ++++++++-- 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index 6fc6dbdb3..ba56635f4 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.32 2004/06/13 04:56:54 steve Exp $" +#ident "$Id: elab_scope.cc,v 1.33 2004/08/26 04:02:03 steve Exp $" #endif # include "config.h" @@ -129,7 +129,25 @@ 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, 0, 0, false); + 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 + result. Then make sure the constant expression of the + parameter value is coerced to have the correct + and defined width. */ + if ((*cur).second.msb) { + msb = (*cur).second.msb ->elaborate_pexpr(des, scope); + assert(msb); + lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope); + signed_flag = (*cur).second.signed_flag; + } + + val->cast_signed(signed_flag); + val = scope->set_parameter((*cur).first, val, + msb, lsb, signed_flag); assert(val); delete val; } @@ -550,6 +568,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const /* * $Log: elab_scope.cc,v $ + * Revision 1.33 2004/08/26 04:02:03 steve + * Add support for localparam ranges. + * * Revision 1.32 2004/06/13 04:56:54 steve * Add support for the default_nettype directive. * diff --git a/parse.y b/parse.y index 54852a546..db709d292 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: parse.y,v 1.196 2004/05/31 23:34:38 steve Exp $" +#ident "$Id: parse.y,v 1.197 2004/08/26 04:02:03 steve Exp $" #endif # include "config.h" @@ -327,7 +327,7 @@ block_item_decl { pform_make_reals($2, @1.text, @1.first_line); } | K_parameter parameter_assign_decl ';' - | K_localparam localparam_assign_list ';' + | K_localparam localparam_assign_decl ';' /* Recover from errors that happen within variable lists. Use the trailing semi-colon to resync the parser. */ @@ -1847,23 +1847,36 @@ localparam_assign "must be constant."); delete tmp; tmp = 0; + } else { + pform_set_localparam(lex_strings.make($1), + active_signed, + active_range, tmp); } - pform_set_localparam(lex_strings.make($1), tmp); delete $1; } ; +localparam_assign_decl + : localparam_assign_list + | range { active_range = $1; active_signed = false; } + localparam_assign_list + { active_range = 0; + active_signed = false; + } + | K_signed range { active_range = $2; active_signed = true; } + localparam_assign_list + { active_range = 0; + active_signed = false; + } + ; + localparam_assign_list : localparam_assign - | range localparam_assign - { yywarn(@1, "Ranges in localparam definition " - "are not supported."); - delete $1; - } | localparam_assign_list ',' localparam_assign ; + /* The parameters of a module instance can be overridden by writing a list of expressions in a syntax much like a delay list. (The difference being the list can have any length.) The pform that diff --git a/pform.cc b/pform.cc index fab56a8b8..990f3d261 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.127 2004/06/13 04:56:55 steve Exp $" +#ident "$Id: pform.cc,v 1.128 2004/08/26 04:02:04 steve Exp $" #endif # include "config.h" @@ -1399,13 +1399,23 @@ void pform_set_parameter(perm_string name, bool signed_flag, pform_cur_module->param_names.push_back(name); } -void pform_set_localparam(perm_string name, PExpr*expr) +void pform_set_localparam(perm_string name, bool signed_flag, + svector*range, PExpr*expr) { assert(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; + + if (range) { + assert(range->count() == 2); + assert((*range)[0]); + assert((*range)[1]); + pform_cur_module->localparams[name].msb = (*range)[0]; + pform_cur_module->localparams[name].lsb = (*range)[1]; + } else { + pform_cur_module->localparams[name].msb = 0; + pform_cur_module->localparams[name].lsb = 0; + } + pform_cur_module->localparams[name].signed_flag = signed_flag; } void pform_set_specparam(perm_string name, PExpr*expr) @@ -1587,6 +1597,9 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.128 2004/08/26 04:02:04 steve + * Add support for localparam ranges. + * * Revision 1.127 2004/06/13 04:56:55 steve * Add support for the default_nettype directive. * diff --git a/pform.h b/pform.h index bccd17ed8..ef97ff9ab 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.80 2004/06/13 04:56:56 steve Exp $" +#ident "$Id: pform.h,v 1.81 2004/08/26 04:02:04 steve Exp $" #endif # include "netlist.h" @@ -223,7 +223,10 @@ extern void pform_set_parameter(perm_string name, bool signed_flag, svector*range, PExpr*expr); -extern void pform_set_localparam(perm_string name, PExpr*expr); +extern void pform_set_localparam(perm_string name, + bool signed_flag, + svector*range, + PExpr*expr); extern void pform_set_defparam(const hname_t&name, PExpr*expr); /* @@ -295,6 +298,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.81 2004/08/26 04:02:04 steve + * Add support for localparam ranges. + * * Revision 1.80 2004/06/13 04:56:56 steve * Add support for the default_nettype directive. *