V0.9: Fix for pr3557493.

defparam assignments found inside a generate block were being stored
in the enclosing module scope. They should be stored in the generate
block scope.
This commit is contained in:
Martin Whitaker 2012-08-17 08:43:56 +01:00 committed by Cary R
parent e8b40e14b9
commit a3987a112b
4 changed files with 45 additions and 5 deletions

View File

@ -1,7 +1,7 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2006-2009,2012 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
@ -80,6 +80,10 @@ class PGenerate : public LineInfo, public LexicalScope {
// test value.
std::valarray<PExpr*> item_test;
// defparam assignments found in this scope.
typedef pair<pform_name_t,PExpr*> named_expr_t;
list<named_expr_t>defparms;
list<PGate*> gates;
void add_gate(PGate*);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2012 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
@ -1025,6 +1025,29 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
// for use as parameter values.
elaborate_scope_localparams_(des, scope, localparams);
// Run through the defparams for this module, elaborate the
// expressions in this context and save the result is a table
// for later final override.
// It is OK to elaborate the expressions of the defparam here
// because Verilog requires that the expressions only use
// local parameter names. It is *not* OK to do the override
// here because the parameter receiving the assignment may be
// in a scope not discovered by this pass.
typedef list<PGenerate::named_expr_t>::const_iterator defparms_iter_t;
for (defparms_iter_t cur = defparms.begin()
; cur != defparms.end() ; cur ++) {
PExpr*ex = cur->second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
if (val == 0) continue;
scope->defparams.push_back(make_pair(cur->first, val));
}
// Scan the generated scope for nested generate schemes,
// and *generate* new scopes, which is slightly different
// from simple elaboration.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2012 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
@ -1967,7 +1967,10 @@ void pform_set_specparam(perm_string name, PExpr*expr)
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
{
assert(expr);
pform_cur_module->defparms.push_back(make_pair(name,expr));
if (pform_cur_generate)
pform_cur_generate->defparms.push_back(make_pair(name,expr));
else
pform_cur_module->defparms.push_back(make_pair(name,expr));
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2012 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
@ -1018,6 +1018,16 @@ void PGenerate::dump(ostream&out, unsigned indent) const
dump_localparams_(out, indent+2);
typedef list<PGenerate::named_expr_t>::const_iterator parm_hiter_t;
for (parm_hiter_t cur = defparms.begin()
; cur != defparms.end() ; ++ cur ) {
out << setw(indent+2) << "" << "defparam " << (*cur).first << " = ";
if ((*cur).second)
out << *(*cur).second << ";" << endl;
else
out << "/* ERROR */;" << endl;
}
dump_events_(out, indent+2);
dump_wires_(out, indent+2);