Handle case generate under a conditional generate that is unnamed.

When a conditional statement is unnamed, it doesn't create a scope
and we get into "direct" generate scheme elaboration. This direct
elaboration needs to handle case generate schemes.
This commit is contained in:
Stephen Williams 2012-04-30 16:00:25 -07:00
parent 8ea1e49768
commit 69c10c4722
3 changed files with 68 additions and 15 deletions

View File

@ -961,6 +961,12 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
return true;
}
if (debug_scopes) {
cerr << get_fileline() << ": PGenerate::generate_scope_case_: "
<< "Generate subscope " << use_name
<< " and elaborate." << endl;
}
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
scope->set_line(get_file(), get_lineno());
@ -1030,7 +1036,13 @@ void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; ++ cur ) {
(*cur) -> generate_scope(des, scope);
PGenerate*curp = *cur;
if (debug_scopes) {
cerr << get_fileline() << ": elaborate_subscope_direct_: "
<< "Elaborate direct subscope " << curp->scope_name
<< " within scope " << scope_name << endl;
}
curp -> generate_scope(des, scope);
}
}
@ -1082,7 +1094,7 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
if (debug_scopes)
cerr << get_fileline() << ": debug: Generated scope " << scope_path(scope)
<< " by generate block " << scope_name << endl;
<< " for generate block " << scope_name << endl;
// Save the scope that we created, for future use.
scope_list_.push_back(scope);

View File

@ -387,11 +387,22 @@ bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; ++ cur ) {
PGenerate*item = *cur;
if (item->scheme_type == PGenerate::GS_CASE) {
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t icur = item->generate_schemes.begin()
; icur != item->generate_schemes.end() ; ++ icur ) {
PGenerate*case_item = *icur;
if (case_item->direct_nested_ || !case_item->scope_list_.empty()) {
flag &= case_item->elaborate_sig(des, container);
}
}
} else {
if (item->direct_nested_ || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate_sig(des, container);
}
}
}
return flag;
}

View File

@ -4539,15 +4539,18 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
bool flag = true;
if (debug_elaborate) {
cerr << get_fileline() << ": PGenerate::elaborate: "
"generate " << scheme_type
<< " elaborating in scope " << scope_path(container)
<< "." << endl;
}
// Handle the special case that this is a CASE scheme. In this
// case the PGenerate itself does not have the generated
// item. Look instead for the case ITEM that has a scope
// generated for it.
if (scheme_type == PGenerate::GS_CASE) {
if (debug_elaborate)
cerr << get_fileline() << ": debug: generate case"
<< " elaborating in scope "
<< scope_path(container) << "." << endl;
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
@ -4593,25 +4596,52 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
{
if (debug_elaborate)
bool flag = true;
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "Direct nesting elaborate in scope "
<< scope_path(container) << "." << endl;
<< scope_path(container)
<< ", scheme_type=" << scheme_type << endl;
}
// Elaborate for a direct nested generated scheme knows
// that there are only sub_schemes to be elaborated. There
// should be exactly 1 active generate scheme, search for it
// using this loop.
bool flag = true;
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; ++ cur ) {
PGenerate*item = *cur;
if (debug_elaborate) {
cerr << get_fileline() << ": PGenerate::elaborate_direct_: "
<< "item->scope_name=" << item->scope_name
<< ", item->scheme_type=" << item->scheme_type
<< ", item->direct_nested_=" << item->direct_nested_
<< ", item->scope_list_.size()=" << item->scope_list_.size()
<< "." << endl;
}
// Special case: If this is a case generate scheme, then
// the PGenerate object (item) does not acctually
// contain anything. Instead scan the case items, which
// are listed as sub-schemes of the item.
if (item->scheme_type == PGenerate::GS_CASE) {
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t icur = item->generate_schemes.begin()
; icur != item->generate_schemes.end() ; ++ icur ) {
PGenerate*case_item = *icur;
if (case_item->direct_nested_ || !case_item->scope_list_.empty()) {
flag &= case_item->elaborate(des, container);
}
}
} else {
if (item->direct_nested_ || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate(des, container);
}
}
}
return flag;
}