Disallow modules/gates in program blocks.

This commit is contained in:
Stephen Williams 2012-05-14 19:13:57 -07:00
parent 8154ce2a4a
commit c0f35cbe62
3 changed files with 65 additions and 52 deletions

88
parse.y
View File

@ -1082,6 +1082,14 @@ integer_vector_type /* IEEE1800-2005: A.2.2.1 */
| K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */
;
join_keyword /* IEEE1800-2005: A.6.3 */
: K_join
| K_join_none
{ yyerror(@1, "sorry: join_none not supported."); }
| K_join_any
{ yyerror(@1, "sorry: join_any not supported."); }
;
jump_statement /* IEEE1800-2005: A.6.5 */
: K_break ';'
{ yyerror(@1, "sorry: break statements not supported.");
@ -4056,66 +4064,50 @@ module_item
two/three-value delay. These rules handle the different cases.
We check that the actual number of delays is correct later. */
| attribute_list_opt gatetype gate_instance_list ';'
{ pform_makegates($2, str_strength, 0, $3, $1);
}
| attribute_list_opt gatetype gate_instance_list ';'
{ pform_makegates(@2, $2, str_strength, 0, $3, $1); }
| attribute_list_opt gatetype delay3 gate_instance_list ';'
{ pform_makegates($2, str_strength, $3, $4, $1);
}
| attribute_list_opt gatetype delay3 gate_instance_list ';'
{ pform_makegates(@2, $2, str_strength, $3, $4, $1); }
| attribute_list_opt gatetype drive_strength gate_instance_list ';'
{ pform_makegates($2, $3, 0, $4, $1);
}
| attribute_list_opt gatetype drive_strength gate_instance_list ';'
{ pform_makegates(@2, $2, $3, 0, $4, $1); }
| attribute_list_opt gatetype drive_strength delay3 gate_instance_list ';'
{ pform_makegates($2, $3, $4, $5, $1);
}
| attribute_list_opt gatetype drive_strength delay3 gate_instance_list ';'
{ pform_makegates(@2, $2, $3, $4, $5, $1); }
/* The switch type gates do not support a strength. */
| attribute_list_opt switchtype gate_instance_list ';'
{ pform_makegates($2, str_strength, 0, $3, $1);
}
| attribute_list_opt switchtype gate_instance_list ';'
{ pform_makegates(@2, $2, str_strength, 0, $3, $1); }
| attribute_list_opt switchtype delay3 gate_instance_list ';'
{ pform_makegates($2, str_strength, $3, $4, $1);
}
| attribute_list_opt switchtype delay3 gate_instance_list ';'
{ pform_makegates(@2, $2, str_strength, $3, $4, $1); }
/* Pullup and pulldown devices cannot have delays, and their
strengths are limited. */
| K_pullup gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, pull_strength, 0,
$2, 0);
}
| K_pulldown gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, pull_strength,
0, $2, 0);
}
| K_pullup gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLUP, pull_strength, 0, $2, 0); }
| K_pulldown gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLDOWN, pull_strength, 0, $2, 0); }
| K_pullup '(' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $3, 0, $5, 0);
}
| K_pullup '(' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLUP, $3, 0, $5, 0); }
| K_pullup '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $3, 0, $7, 0);
}
| K_pullup '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLUP, $3, 0, $7, 0); }
| K_pullup '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $5, 0, $7, 0);
}
| K_pullup '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLUP, $5, 0, $7, 0); }
| K_pulldown '(' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $5, 0);
}
| K_pulldown '(' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLDOWN, $3, 0, $5, 0); }
| K_pulldown '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $5, 0, $7, 0);
}
| K_pulldown '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLDOWN, $5, 0, $7, 0); }
| K_pulldown '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $7, 0);
}
| K_pulldown '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(@1, PGBuiltin::PULLDOWN, $3, 0, $7, 0); }
/* This rule handles instantiations of modules and user defined
primitives. These devices to not have delay lists or strengths,
@ -4124,7 +4116,7 @@ module_item
| attribute_list_opt
IDENTIFIER parameter_value_opt gate_instance_list ';'
{ perm_string tmp1 = lex_strings.make($2);
pform_make_modgates(tmp1, $3, $4);
pform_make_modgates(@2, tmp1, $3, $4);
delete[]$2;
if ($1) delete $1;
}
@ -5342,12 +5334,12 @@ statement_item /* This is roughly statement_item in the LRM */
need to do is remember that this is a parallel block so that the
code generator can do the right thing. */
| K_fork K_join
| K_fork join_keyword
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_fork statement_or_null_list K_join
| K_fork statement_or_null_list join_keyword
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1);
tmp->set_statement(*$2);
@ -5360,7 +5352,7 @@ statement_item /* This is roughly statement_item in the LRM */
current_block_stack.push(tmp);
}
block_item_decls_opt
statement_or_null_list_opt K_join
statement_or_null_list_opt join_keyword
{ pform_pop_scope();
assert(! current_block_stack.empty());
PBlock*tmp = current_block_stack.top();

View File

@ -820,6 +820,10 @@ void pform_startmodule(const struct vlltype&loc, const char*name,
error_count += 1;
}
if (gn_system_verilog() && pform_cur_module.size() > 0 && pform_cur_module.front()->program_block) {
cerr << loc << ": error: Program blocks cannot contain nested modules/program blocks." << endl;
error_count += 1;
}
perm_string lex_name = lex_strings.make(name);
Module*cur_module = new Module(lexical_scope, lex_name);
@ -1677,12 +1681,20 @@ static void pform_makegate(PGBuiltin::Type type,
pform_cur_module.front()->add_gate(cur);
}
void pform_makegates(PGBuiltin::Type type,
void pform_makegates(const struct vlltype&loc,
PGBuiltin::Type type,
struct str_pair_t str,
list<PExpr*>*delay,
svector<lgate>*gates,
list<named_pexpr_t>*attr)
{
assert(pform_cur_module.size() > 0);
if (pform_cur_module.front()->program_block) {
cerr << loc << ": error: Gates and switches may not be instantiated"
<< " in program blocks." << endl;
error_count += 1;
}
for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) {
pform_makegate(type, str, delay, (*gates)[idx], attr);
}
@ -1787,10 +1799,17 @@ static void pform_make_modgate(perm_string type,
pform_cur_module.front()->add_gate(cur);
}
void pform_make_modgates(perm_string type,
void pform_make_modgates(const struct vlltype&loc,
perm_string type,
struct parmvalue_t*overrides,
svector<lgate>*gates)
{
assert(pform_cur_module.size() > 0);
if (pform_cur_module.front()->program_block) {
cerr << loc << ": error: Module instantiations are not allowed"
<< " in program blocks." << endl;
error_count += 1;
}
for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) {
lgate cur = (*gates)[idx];

View File

@ -377,13 +377,15 @@ extern void pform_make_reals(list<perm_string>*names,
* The makegate function creates a new gate (which need not have a
* name) and connects it to the specified wires.
*/
extern void pform_makegates(PGBuiltin::Type type,
extern void pform_makegates(const struct vlltype&loc,
PGBuiltin::Type type,
struct str_pair_t str,
list<PExpr*>*delay,
svector<lgate>*gates,
list<named_pexpr_t>*attr);
extern void pform_make_modgates(perm_string type,
extern void pform_make_modgates(const struct vlltype&loc,
perm_string type,
struct parmvalue_t*overrides,
svector<lgate>*gates);