Handle indexed defparams.

The l-value of a defparam assignment is a hierarchical name that may
include array selects to select scopes from module arrays. Therefore
it makes no sense to store parsed defparams in a map. Instead, they
should go into an ordered list. This also maked more sense because later
defparams *may* have the same name as a previous defparam, and will
override the previous defparam. So replace the map of parsed defparams
with a list of parsed defparams.

Also, as soon as the defparam expression is elaborated, the list entry
is no longer needed, so delete it. Save memory.
This commit is contained in:
Stephen Williams 2008-06-28 09:30:09 -07:00
parent da2c4b0fa1
commit 1ef7994ae2
7 changed files with 15 additions and 30 deletions

View File

@ -22,6 +22,7 @@
# include <list> # include <list>
# include <map> # include <map>
# include <utility>
# include "svector.h" # include "svector.h"
# include "StringHeap.h" # include "StringHeap.h"
# include "HName.h" # include "HName.h"
@ -118,7 +119,8 @@ class Module : public PScope, public LineInfo {
new parameters within the module, but may be used to set new parameters within the module, but may be used to set
values within this module (when instantiated) or in other values within this module (when instantiated) or in other
instantiated modules. */ instantiated modules. */
map<pform_name_t,PExpr*>defparms; typedef pair<pform_name_t,PExpr*> named_expr_t;
list<named_expr_t>defparms;
/* Parameters may be overridden at instantiation time; /* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names, the overrides do not contain explicit parameter names,
@ -169,7 +171,7 @@ class Module : public PScope, public LineInfo {
bool elaborate(Design*, NetScope*scope) const; bool elaborate(Design*, NetScope*scope) const;
typedef map<perm_string,NetExpr*> replace_t; typedef map<perm_string,NetExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const; bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
bool elaborate_sig(Design*, NetScope*scope) const; bool elaborate_sig(Design*, NetScope*scope) const;

View File

@ -182,7 +182,7 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
} }
bool Module::elaborate_scope(Design*des, NetScope*scope, bool Module::elaborate_scope(Design*des, NetScope*scope,
const replace_t&replacements) const const replace_t&replacements)
{ {
if (debug_scopes) { if (debug_scopes) {
cerr << get_fileline() << ": debug: Elaborate scope " cerr << get_fileline() << ": debug: Elaborate scope "
@ -201,8 +201,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// place of the elaborated expression. // place of the elaborated expression.
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t; typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
// This loop scans the parameters in the module, and creates // This loop scans the parameters in the module, and creates
// stub parameter entries in the scope for the parameter name. // stub parameter entries in the scope for the parameter name.
@ -286,15 +284,17 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// here because the parameter receiving the assignment may be // here because the parameter receiving the assignment may be
// in a scope not discovered by this pass. // in a scope not discovered by this pass.
for (pform_parm_it_t cur = defparms.begin() while (! defparms.empty()) {
; cur != defparms.end() ; cur ++ ) { Module::named_expr_t cur = defparms.front();
defparms.pop_front();
PExpr*ex = (*cur).second; PExpr*ex = cur.second;
assert(ex); assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope); NetExpr*val = ex->elaborate_pexpr(des, scope);
delete ex;
if (val == 0) continue; if (val == 0) continue;
scope->defparams.push_back(make_pair(cur->first, val)); scope->defparams.push_back(make_pair(cur.first, val));
} }
// Evaluate the attributes. Evaluate them in the scope of the // Evaluate the attributes. Evaluate them in the scope of the

View File

@ -240,8 +240,6 @@ void NetScope::run_defparams(Design*des)
is the current scope. */ is the current scope. */
NetScope*targ_scope = des->find_scope(this, eval_path); NetScope*targ_scope = des->find_scope(this, eval_path);
if (targ_scope == 0) { if (targ_scope == 0) {
cerr << val->get_fileline() << ": warning: scope of " <<
path << "." << perm_name << " not found." << endl;
// Push the defparam onto a list for retry // Push the defparam onto a list for retry
// later. It is possible for the scope lookup to // later. It is possible for the scope lookup to

View File

@ -1760,7 +1760,7 @@ void pform_set_specparam(perm_string name, PExpr*expr)
void pform_set_defparam(const pform_name_t&name, PExpr*expr) void pform_set_defparam(const pform_name_t&name, PExpr*expr)
{ {
assert(expr); assert(expr);
pform_cur_module->defparms[name] = expr; pform_cur_module->defparms.push_back(make_pair(name,expr));
} }
/* /*

View File

@ -991,7 +991,6 @@ void Module::dump(ostream&out) const
} }
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t; typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
typedef map<pform_name_t,PExpr*>::const_iterator parm_hiter_t;
for (parm_iter_t cur = parameters.begin() for (parm_iter_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) { ; cur != parameters.end() ; cur ++) {
out << " parameter " << (*cur).second.type << " "; out << " parameter " << (*cur).second.type << " ";
@ -1068,6 +1067,7 @@ void Module::dump(ostream&out) const
<< *(*cur).second << ";" << endl; << *(*cur).second << ";" << endl;
} }
typedef list<Module::named_expr_t>::const_iterator parm_hiter_t;
for (parm_hiter_t cur = defparms.begin() for (parm_hiter_t cur = defparms.begin()
; cur != defparms.end() ; cur ++) { ; cur != defparms.end() ; cur ++) {
out << " defparam " << (*cur).first << " = "; out << " defparam " << (*cur).first << " = ";

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com) * Copyright (c) 2007-2008 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,17 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_types.cc,v 1.1 2007/05/24 04:07:12 steve Exp $"
#endif
# include "pform_types.h" # include "pform_types.h"
bool operator < (const name_component_t&lef, const name_component_t&rig)
{
if (lef.name < rig.name)
return true;
return false;
}

View File

@ -1,7 +1,7 @@
#ifndef __pform_types_H #ifndef __pform_types_H
#define __pform_types_H #define __pform_types_H
/* /*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com) * Copyright (c) 2007-2008 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_types.h,v 1.2 2007/06/04 02:19:07 steve Exp $"
#endif
// This for the perm_string type. // This for the perm_string type.
# include "StringHeap.h" # include "StringHeap.h"
@ -50,7 +47,6 @@ struct name_component_t {
std::list<index_component_t>index; std::list<index_component_t>index;
}; };
extern bool operator < (const name_component_t&lef, const name_component_t&rig);
/* /*
* The pform_name_t is the general form for a hierarchical * The pform_name_t is the general form for a hierarchical