diff --git a/parse.y b/parse.y index 290c13565..d62490b95 100644 --- a/parse.y +++ b/parse.y @@ -2425,9 +2425,19 @@ module_item /* A generate region can contain further module items. Actually, it is supposed to be limited to certain kinds of module items, but - the semantic tests will check that for us. */ + the semantic tests will check that for us. Do check that the + generate/endgenerate regions do not nest. Generate schemes nest, + but generate regions do not. */ | K_generate module_item_list_opt K_endgenerate + { // Test for bad nesting. I understand it, but it is illegal. + if (pform_parent_generate()) { + cerr << @1 << ": error: Generate/endgenerate regions cannot nest." << endl; + cerr << @1 << ": : Try removing optional generate/endgenerate keywords," << endl; + cerr << @1 << ": : or move them to surround the parent generate scheme." << endl; + error_count += 1; + } + } | K_genvar list_of_identifiers ';' { pform_genvars(@1, $2); } diff --git a/pform.cc b/pform.cc index 47b212cb2..fc5170e34 100644 --- a/pform.cc +++ b/pform.cc @@ -342,6 +342,11 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt) return block; } +PGenerate* pform_parent_generate(void) +{ + return pform_cur_generate; +} + void pform_bind_attributes(map&attributes, svector*attr) { diff --git a/pform.h b/pform.h index acfa58bf0..83bf6301f 100644 --- a/pform.h +++ b/pform.h @@ -214,6 +214,12 @@ extern void pform_generate_case_item(const struct vlltype&lp, svector*te extern void pform_generate_block_name(char*name); extern void pform_endgenerate(); +/* + * This function returns the lexically containing generate scheme, if + * there is one. The parser may use this to check if we are within a + * generate scheme. + */ +extern PGenerate* pform_parent_generate(void); /* * The makewire functions announce to the pform code new wires. These