Multiple passes for run_defparams.

It is possible for defparams to not find their target the first time
around, because the elaboration of the target scope is not yet done.
So retry the defparams once for each scope by putting it on a work
item in the elaborator_work_items list.
This commit is contained in:
Stephen Williams 2008-06-25 22:02:22 -07:00
parent 4251979e8b
commit da2c4b0fa1
5 changed files with 99 additions and 37 deletions

44
HName.h
View File

@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2008 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
@ -18,11 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
#endif
# include <iostream>
# include <list>
# include "StringHeap.h"
#ifdef __GNUC__
#if __GNUC__ > 2
@ -70,30 +68,16 @@ extern bool operator == (const hname_t&, const hname_t&);
extern bool operator != (const hname_t&, const hname_t&);
extern ostream& operator<< (ostream&, const hname_t&);
/*
* $Log: HName.h,v $
* Revision 1.7 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.6 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.5 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.4 2002/11/02 03:27:51 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
inline ostream& operator<< (ostream&out, const list<hname_t>&ll)
{
list<hname_t>::const_iterator cur = ll.begin();
out << *cur;
cur ++;
while (cur != ll.end()) {
out << "." << *cur;
cur ++;
}
return out;
}
#endif

View File

@ -1063,7 +1063,7 @@ void NetScope::dump(ostream&o) const
/* Dump the saved defparam assignments here. */
{
map<pform_name_t,NetExpr*>::const_iterator pp;
list<pair<pform_name_t,NetExpr*> >::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
@ -1071,6 +1071,15 @@ void NetScope::dump(ostream&o) const
}
}
{
list<pair<list<hname_t>,NetExpr*> >::const_iterator pp;
for (pp = defparams_later.begin()
; pp != defparams_later.end() ; pp ++ ) {
o << " defparam(later) " << pp->first << " = " <<
*(pp->second) << ";" << endl;
}
}
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="

View File

@ -294,7 +294,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
NetExpr*val = ex->elaborate_pexpr(des, scope);
if (val == 0) continue;
scope->defparams[(*cur).first] = val;
scope->defparams.push_back(make_pair(cur->first, val));
}
// Evaluate the attributes. Evaluate them in the scope of the
@ -675,6 +675,11 @@ class delayed_elaborate_scope_mod_instances : public elaborator_work_item_t {
void delayed_elaborate_scope_mod_instances::elaborate_runrun()
{
if (debug_scopes)
cerr << obj_->get_fileline() << ": debug: "
<< "Resume scope elaboration of instances of "
<< mod_->mod_name() << "." << endl;
obj_->elaborate_scope_mod_instances_(des, mod_, sc_);
}

View File

@ -199,6 +199,22 @@ void Design::run_defparams()
(*scope)->run_defparams(this);
}
class run_defparams_later_t : public elaborator_work_item_t {
public:
run_defparams_later_t(Design*des, NetScope*scope)
: elaborator_work_item_t(des), scope_(scope)
{ }
void elaborate_runrun();
private:
NetScope*scope_;
};
void run_defparams_later_t::elaborate_runrun()
{
scope_->run_defparams_later(des);
}
void NetScope::run_defparams(Design*des)
{
{ NetScope*cur = sub_;
@ -208,10 +224,12 @@ void NetScope::run_defparams(Design*des)
}
}
map<pform_name_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
NetExpr*val = (*pp).second;
pform_name_t path = (*pp).first;
while (! defparams.empty()) {
pair<pform_name_t,NetExpr*> pp = defparams.front();
defparams.pop_front();
pform_name_t path = pp.first;
NetExpr*val = pp.second;
perm_string perm_name = peek_tail_name(path);
path.pop_back();
@ -224,6 +242,13 @@ void NetScope::run_defparams(Design*des)
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
// later. It is possible for the scope lookup to
// fail if the scope being defparam'd into is
// generated by an index array for generate.
eval_path.push_back(hname_t(perm_name));
defparams_later.push_back(make_pair(eval_path,val));
continue;
}
@ -239,6 +264,41 @@ void NetScope::run_defparams(Design*des)
}
}
if (! defparams_later.empty()) {
des->elaboration_work_list.push_back(new run_defparams_later_t(des, this));
}
}
void NetScope::run_defparams_later(Design*des)
{
while (! defparams_later.empty()) {
pair<list<hname_t>,NetExpr*> cur = defparams_later.front();
defparams_later.pop_front();
list<hname_t>eval_path = cur.first;
perm_string name = eval_path.back().peek_name();
eval_path.pop_back();
NetExpr*val = cur.second;
NetScope*targ_scope = des->find_scope(this, eval_path);
if (targ_scope == 0) {
cerr << val->get_fileline() << ": warning: scope of " <<
eval_path << "." << name << " not found." << endl;
continue;
}
// Once placed in the parameter map, the expression may
// be deleted when evaluated, so give it a copy of this
// expression, not the original.
val = val->dup_expr();
bool flag = targ_scope->replace_parameter(name, val);
if (! flag) {
cerr << val->get_fileline() << ": warning: parameter "
<< name << " not found in "
<< scope_path(targ_scope) << "." << endl;
}
}
}
void Design::evaluate_parameters()

View File

@ -29,6 +29,7 @@
# include <map>
# include <list>
# include <vector>
# include <utility>
# include "ivl_target.h"
# include "pform_types.h"
# include "config.h"
@ -718,6 +719,8 @@ class NetScope : public Attrib {
const hname_t& fullname() const { return name_; }
void run_defparams(class Design*);
void run_defparams_later(class Design*);
void evaluate_parameters(class Design*);
/* This method generates a non-hierarchical name that is
@ -737,7 +740,8 @@ class NetScope : public Attrib {
assignments from the scope pass to the parameter evaluation
step. After that, it is not used. */
map<pform_name_t,NetExpr*>defparams;
list<pair<pform_name_t,NetExpr*> > defparams;
list<pair<list<hname_t>,NetExpr*> > defparams_later;
public:
struct range_t {