Add support for the 1364-2001 generate of a named block.

This is obsolete in 1364-2005, but is supported 1364-2001.
Icarus already supported generate with unnamed block.
This commit is contained in:
Cary R 2008-11-14 18:35:39 -08:00 committed by Stephen Williams
parent 1d41037009
commit 407ce5e152
6 changed files with 68 additions and 3 deletions

View File

@ -65,7 +65,7 @@ class PGenerate : public LineInfo, public LexicalScope {
PScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM};
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
scheme_t scheme_type;
// generate loops have an index variable and three
@ -102,6 +102,7 @@ class PGenerate : public LineInfo, public LexicalScope {
bool generate_scope_loop_(Design*des, NetScope*container);
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container);
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);

View File

@ -461,7 +461,9 @@ bool PGenerate::generate_scope(Design*des, NetScope*container)
case GS_CASE:
return generate_scope_case_(des, container);
return true;
case GS_NBLOCK:
return generate_scope_nblock_(des, container);
case GS_CASE_ITEM:
cerr << get_fileline() << ": internal error: "
@ -718,6 +720,29 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
return true;
}
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
{
hname_t use_name (scope_name);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< scope_name << " already used in this context."
<< endl;
des->errors += 1;
return false;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate named block "
<< ": Generate scope=" << use_name << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
scope->set_line(get_file(), get_lineno());
elaborate_subscope_(des, scope);
return true;
}
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
{
// Scan the generated scope for nested generate schemes,

10
parse.y
View File

@ -2235,6 +2235,16 @@ module_item
cerr << @2 << ": warning: Anachronistic use of begin/end to surround generate schemes." << endl;
}
}
| K_generate K_begin ':' IDENTIFIER {
pform_start_generate_nblock(@1, $4);
} module_item_list_opt K_end K_endgenerate
{ /* Detect and warn about anachronistic named begin/end use */
if (generation_flag > GN_VER2001) {
warn_count += 1;
cerr << @2 << ": warning: Anachronistic use of named begin/end to surround generate schemes." << endl;
}
pform_endgenerate();
}
/* specify blocks are parsed but ignored. */

View File

@ -530,6 +530,28 @@ void pform_start_generate_case(const struct vlltype&li, PExpr*expr)
pform_cur_generate->loop_step = 0;
}
/*
* The named block generate case.
*/
void pform_start_generate_nblock(const struct vlltype&li, char*name)
{
PGenerate*gen = new PGenerate(scope_generate_counter++);
FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_NBLOCK;
pform_cur_generate->loop_init = 0;
pform_cur_generate->loop_test = 0;
pform_cur_generate->loop_step = 0;
pform_cur_generate->scope_name = lex_strings.make(name);
delete[]name;
}
/*
* The generate case item is a special case schema that takes its id
* from the case schema that it is a part of. The idea is that the

View File

@ -204,6 +204,7 @@ extern void pform_start_generate_for(const struct vlltype&li,
extern void pform_start_generate_if(const struct vlltype&li, PExpr*test);
extern void pform_start_generate_else(const struct vlltype&li);
extern void pform_start_generate_case(const struct vlltype&lp, PExpr*test);
extern void pform_start_generate_nblock(const struct vlltype&lp, char*name);
extern void pform_generate_case_item(const struct vlltype&lp, PExpr*test);
extern void pform_generate_block_name(char*name);
extern void pform_endgenerate();

View File

@ -1002,6 +1002,8 @@ void PGenerate::dump(ostream&out, unsigned indent) const
else
out << " default:";
break;
case GS_NBLOCK:
out << " begin";
}
if (scope_name)
@ -1035,7 +1037,11 @@ void PGenerate::dump(ostream&out, unsigned indent) const
(*idx)->dump(out, indent+2);
}
out << setw(indent) << "" << "endgenerate" << endl;
if (scheme_type == GS_NBLOCK) {
out << setw(indent) << "" << "end endgenerate" << endl;
} else {
out << setw(indent) << "" << "endgenerate" << endl;
}
}
void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const