diff --git a/PExpr.h b/PExpr.h index 5dfc9d2a3..5be59918b 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.h,v 1.72 2005/11/10 13:28:11 steve Exp $" +#ident "$Id: PExpr.h,v 1.73 2005/11/27 05:56:20 steve Exp $" #endif # include @@ -255,7 +255,9 @@ class PEIdent : public PExpr { NetExpr*elaborate_expr_param(Design*des, NetScope*scope, const NetExpr*par, - NetScope*found) const; + NetScope*found, + const NetExpr*par_msb, + const NetExpr*par_lsb) const; NetExpr*elaborate_expr_net(Design*des, NetScope*scope, NetNet*net, @@ -543,6 +545,9 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.73 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.72 2005/11/10 13:28:11 steve * Reorganize signal part select handling, and add support for * indexed part selects. diff --git a/elab_expr.cc b/elab_expr.cc index 9c410a9a5..3b53622cc 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.100 2005/11/14 22:11:52 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.101 2005/11/27 05:56:20 steve Exp $" #endif # include "config.h" @@ -493,13 +493,16 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, const NetExpr*par = 0; NetEvent* eve = 0; + const NetExpr*ex1, *ex2; + NetScope*found_in = symbol_search(des, scope, path_, - net, mem, par, eve); + net, mem, par, eve, + ex1, ex2); // If the identifier name is a parameter name, then return // a reference to the parameter expression. if (par != 0) - return elaborate_expr_param(des, scope, par, found_in); + return elaborate_expr_param(des, scope, par, found_in, ex1, ex2); // If the identifier names a signal (a register or wire) @@ -592,10 +595,17 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, return 0; } +/* + * Handle the case that the identifier is a parameter reference. The + * parameter expression has already been located for us (as the par + * argument) so we just need to process the sub-expression. + */ NetExpr* PEIdent::elaborate_expr_param(Design*des, NetScope*scope, const NetExpr*par, - NetScope*found_in) const + NetScope*found_in, + const NetExpr*par_msb, + const NetExpr*par_lsb) const { NetExpr*tmp; @@ -604,7 +614,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, if (sel_ == SEL_PART) { assert(msb_ && lsb_); - /* If the parameter has a part select, we support + /* If the identifier has a part select, we support it by pulling the right bits out and making a sized unsigned constant. This code assumes the lsb of a parameter is 0 and the msb is the @@ -700,7 +710,10 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, tmp = new NetESelect(tmp, idx_ex, wid); - } else if (msb_) { + } else if (sel_ == SEL_BIT) { + assert(msb_); + assert(!lsb_); + /* Handle the case where a parameter has a bit select attached to it. Generate a NetESelect object to select the bit as desired. */ @@ -722,6 +735,8 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, NetEConst*re = dynamic_cast(mtmp); if (le && re) { + /* Argument and bit select are constant. Calculate + the final result. */ verinum lv = le->value(); verinum rv = re->value(); verinum::V rb = verinum::Vx; @@ -744,6 +759,31 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, } else { + const NetEConst*par_me =dynamic_cast(par_msb); + const NetEConst*par_le =dynamic_cast(par_lsb); + + assert(par_me || !par_msb); + assert(par_le || !par_lsb); + assert(par_me || !par_le); + + if (par_me) { + long par_mv = par_me->value().as_long(); + long par_lv = par_le->value().as_long(); + if (par_mv >= par_lv) { + mtmp = par_lv + ? make_add_expr(mtmp, 0-par_lv) + : mtmp; + } else { + if (par_lv != 0) + mtmp = make_add_expr(mtmp, 0-par_mv); + mtmp = make_sub_expr(par_lv-par_mv, mtmp); + } + } + + /* The value is constant, but the bit select + expression is not. Elaborate a NetESelect to + evaluate the select at run-time. */ + NetESelect*stmp = new NetESelect(tmp, mtmp, 1); tmp->set_line(*this); tmp = stmp; @@ -1228,6 +1268,9 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const /* * $Log: elab_expr.cc,v $ + * Revision 1.101 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.100 2005/11/14 22:11:52 steve * Fix compile warning. * diff --git a/elab_pexpr.cc b/elab_pexpr.cc index ba9730e96..8588f2bed 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_pexpr.cc,v 1.21 2004/02/20 06:22:56 steve Exp $" +#ident "$Id: elab_pexpr.cc,v 1.22 2005/11/27 05:56:20 steve Exp $" #endif # include "config.h" @@ -140,7 +140,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const perm_string perm_name = lex_strings.make(name); delete name; - const NetExpr*ex = pscope->get_parameter(perm_name); + const NetExpr*ex_msb; + const NetExpr*ex_lsb; + const NetExpr*ex = pscope->get_parameter(perm_name, ex_msb, ex_lsb); if (ex == 0) { cerr << get_line() << ": error: identifier ``" << path_ << "'' is not a parameter in " << scope->name() << "." << endl; @@ -231,6 +233,9 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const /* * $Log: elab_pexpr.cc,v $ + * Revision 1.22 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.21 2004/02/20 06:22:56 steve * parameter keys are per_strings. * diff --git a/eval.cc b/eval.cc index f4742f846..fd82d0768 100644 --- a/eval.cc +++ b/eval.cc @@ -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.36 2003/06/21 01:21:43 steve Exp $" +#ident "$Id: eval.cc,v 1.37 2005/11/27 05:56:20 steve Exp $" #endif # include "config.h" @@ -26,6 +26,7 @@ # include "PExpr.h" # include "netlist.h" +# include "netmisc.h" # include "compiler.h" verinum* PExpr::eval_const(const Design*, const NetScope*) const @@ -151,7 +152,13 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const { assert(scope); - const NetExpr*expr = des->find_parameter(scope, path_); + //const NetExpr*expr = des->find_parameter(scope, path_); + NetNet*net; + NetMemory*mem; + NetEvent*eve; + const NetExpr*expr; + NetScope*found_in = symbol_search(des, scope, path_, + net, mem, expr, eve); if (expr == 0) return 0; @@ -240,6 +247,9 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const /* * $Log: eval.cc,v $ + * Revision 1.37 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.36 2003/06/21 01:21:43 steve * Harmless fixup of warnings. * diff --git a/eval_tree.cc b/eval_tree.cc index d2ed0cd02..775c342d3 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -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.66 2005/11/10 13:28:12 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.67 2005/11/27 05:56:20 steve Exp $" #endif # include "config.h" @@ -1171,7 +1171,9 @@ NetExpr* NetEParam::eval_tree() return 0; assert(scope_); - const NetExpr*expr = scope_->get_parameter(name_); + const NetExpr*expr_msb; + const NetExpr*expr_lsb; + const NetExpr*expr = scope_->get_parameter(name_, expr_msb, expr_lsb); if (expr == 0) { cerr << get_line() << ": internal error: Unable to match " << "parameter " << name_ << " in scope " @@ -1599,6 +1601,9 @@ NetEConst* NetEUReduce::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.67 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.66 2005/11/10 13:28:12 steve * Reorganize signal part select handling, and add support for * indexed part selects. diff --git a/net_design.cc b/net_design.cc index b3feea155..eea0fedfb 100644 --- a/net_design.cc +++ b/net_design.cc @@ -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.47 2005/09/14 02:53:14 steve Exp $" +#ident "$Id: net_design.cc,v 1.48 2005/11/27 05:56:20 steve Exp $" #endif # include "config.h" @@ -173,71 +173,6 @@ NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const return find_scope(path); } -/* - * 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. - * - * The expression value of the parameter is returned as the result, - * and the scope that contains the parameter is returned in the out - * argument found_in. - */ -const NetExpr* Design::find_parameter(NetScope*scope, - const hname_t&path, - NetScope*&found_in) const -{ - for ( ; scope ; scope = scope->parent()) { - unsigned hidx = 0; - - NetScope*cur = scope; - while (path.peek_name(hidx+1)) { - cur = cur->child(path.peek_name(hidx)); - if (cur == 0) - break; - hidx += 1; - } - - if (cur == 0) - continue; - - if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx))) { - found_in = cur; - return res; - } - } - - return 0; -} - -const NetExpr* Design::find_parameter(const NetScope*scope, - const hname_t&path) const -{ - for ( ; scope ; scope = scope->parent()) { - unsigned hidx = 0; - - const NetScope*cur = scope; - while (path.peek_name(hidx+1)) { - cur = cur->child(path.peek_name(hidx)); - if (cur == 0) - break; - hidx += 1; - } - - if (cur == 0) - continue; - - if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx))) - return res; - - } - - return 0; -} - - /* * This method runs through the scope, noticing the defparam * statements that were collected during the elaborate_scope pass and @@ -619,6 +554,9 @@ void Design::delete_process(NetProcTop*top) /* * $Log: net_design.cc,v $ + * Revision 1.48 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.47 2005/09/14 02:53:14 steve * Support bool expressions and compares handle them optimally. * diff --git a/net_scope.cc b/net_scope.cc index e08bbd289..6f7bd41ea 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -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.34 2005/07/11 16:56:50 steve Exp $" +#ident "$Id: net_scope.cc,v 1.35 2005/11/27 05:56:20 steve Exp $" #endif # include "config.h" @@ -132,17 +132,25 @@ NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr) * perm_string::literal method to fake the compiler into doing the * compare without actually creating a perm_string. */ -const NetExpr* NetScope::get_parameter(const char* key) const +const NetExpr* NetScope::get_parameter(const char* key, + const NetExpr*&msb, + const NetExpr*&lsb) const { map::const_iterator idx; idx = parameters.find(perm_string::literal(key)); - if (idx != parameters.end()) + if (idx != parameters.end()) { + msb = (*idx).second.msb; + lsb = (*idx).second.lsb; return (*idx).second.expr; + } idx = localparams.find(perm_string::literal(key)); - if (idx != localparams.end()) + if (idx != localparams.end()) { + msb = (*idx).second.msb; + lsb = (*idx).second.lsb; return (*idx).second.expr; + } return 0; } @@ -449,6 +457,9 @@ string NetScope::local_hsymbol() /* * $Log: net_scope.cc,v $ + * Revision 1.35 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.34 2005/07/11 16:56:50 steve * Remove NetVariable and ivl_variable_t structures. * diff --git a/netlist.h b/netlist.h index 80d1a50b1..f0cd5119b 100644 --- a/netlist.h +++ b/netlist.h @@ -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.352 2005/11/26 00:35:43 steve Exp $" +#ident "$Id: netlist.h,v 1.353 2005/11/27 05:56:20 steve Exp $" #endif /* @@ -3146,7 +3146,10 @@ class NetScope : public Attrib { NetExpr* set_parameter(perm_string name, NetExpr*val, NetExpr*msb, NetExpr*lsb, bool signed_flag); NetExpr* set_localparam(perm_string name, NetExpr*val); - const NetExpr*get_parameter(const char* name) const; + + const NetExpr*get_parameter(const char* name, + const NetExpr*&msb, + const NetExpr*&lsb) const; /* These are used by defparam elaboration to replace the expression with a new expression, without affecting the @@ -3344,16 +3347,6 @@ class Design { // PARAMETERS - /* 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. - - The scope of the located expression is stored in the - found_in argument. */ - const NetExpr*find_parameter( NetScope*, const hname_t&path, - NetScope*&found_in) const; - const NetExpr*find_parameter( const NetScope*, const hname_t&path) const; - void run_defparams(); void evaluate_parameters(); @@ -3458,6 +3451,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.353 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.352 2005/11/26 00:35:43 steve * More precise about r-value width of constants. * diff --git a/netmisc.h b/netmisc.h index 1a10a5fb1..a07580d41 100644 --- a/netmisc.h +++ b/netmisc.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netmisc.h,v 1.23 2005/07/11 16:56:51 steve Exp $" +#ident "$Id: netmisc.h,v 1.24 2005/11/27 05:56:20 steve Exp $" #endif # include "netlist.h" @@ -33,12 +33,30 @@ * If the symbol was not found, return 0. The output arguments * get 0 except for the pointer to the object that represents * the located symbol. + * + * The ex1 and ex2 output arguments are extended results. If the + * symbol is a parameter (par!=0) then ex1 is the msb expression and + * ex2 is the lsb expression for the range. If there is no range, then + * these values are set to 0. */ -extern NetScope* symbol_search(Design*des, NetScope*start, hname_t path, +extern NetScope* symbol_search(const Design*des, + NetScope*start, hname_t path, NetNet*&net, /* net/reg */ NetMemory*&mem, /* memory */ const NetExpr*&par,/* parameter */ - NetEvent*&eve /* named event */); + NetEvent*&eve, /* named event */ + const NetExpr*&ex1, const NetExpr*&ex2); + +inline NetScope* symbol_search(const Design*des, + NetScope*start, const hname_t&path, + NetNet*&net, /* net/reg */ + NetMemory*&mem, /* memory */ + const NetExpr*&par,/* parameter */ + NetEvent*&eve /* named event */) +{ + const NetExpr*ex1, *ex2; + return symbol_search(des, start, path, net, mem, par, eve, ex1, ex2); +} /* * This function transforms an expression by padding the high bits @@ -100,6 +118,9 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe); /* * $Log: netmisc.h,v $ + * Revision 1.24 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.23 2005/07/11 16:56:51 steve * Remove NetVariable and ivl_variable_t structures. * diff --git a/symbol_search.cc b/symbol_search.cc index 5c2c5e094..e93c3b0f5 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: symbol_search.cc,v 1.2 2005/07/11 16:56:51 steve Exp $" +#ident "$Id: symbol_search.cc,v 1.3 2005/11/27 05:56:20 steve Exp $" #endif # include "netlist.h" @@ -27,11 +27,12 @@ /* * Search for the hierarchical name. */ -NetScope*symbol_search(Design*des, NetScope*scope, hname_t path, +NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path, NetNet*&net, NetMemory*&mem, const NetExpr*&par, - NetEvent*&eve) + NetEvent*&eve, + const NetExpr*&ex1, const NetExpr*&ex2) { assert(scope); @@ -65,7 +66,7 @@ NetScope*symbol_search(Design*des, NetScope*scope, hname_t path, return scope; } - if ( (par = scope->get_parameter(key)) ) { + if ( (par = scope->get_parameter(key, ex1, ex2)) ) { delete key; return scope; } @@ -82,6 +83,9 @@ NetScope*symbol_search(Design*des, NetScope*scope, hname_t path, /* * $Log: symbol_search.cc,v $ + * Revision 1.3 2005/11/27 05:56:20 steve + * Handle bit select of parameter with ranges. + * * Revision 1.2 2005/07/11 16:56:51 steve * Remove NetVariable and ivl_variable_t structures. *