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 */ | 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 */ jump_statement /* IEEE1800-2005: A.6.5 */
: K_break ';' : K_break ';'
{ yyerror(@1, "sorry: break statements not supported."); { yyerror(@1, "sorry: break statements not supported.");
@ -4056,66 +4064,50 @@ module_item
two/three-value delay. These rules handle the different cases. two/three-value delay. These rules handle the different cases.
We check that the actual number of delays is correct later. */ We check that the actual number of delays is correct later. */
| attribute_list_opt gatetype gate_instance_list ';' | attribute_list_opt gatetype gate_instance_list ';'
{ pform_makegates($2, str_strength, 0, $3, $1); { pform_makegates(@2, $2, str_strength, 0, $3, $1); }
}
| attribute_list_opt gatetype delay3 gate_instance_list ';' | attribute_list_opt gatetype delay3 gate_instance_list ';'
{ pform_makegates($2, str_strength, $3, $4, $1); { pform_makegates(@2, $2, str_strength, $3, $4, $1); }
}
| attribute_list_opt gatetype drive_strength gate_instance_list ';' | attribute_list_opt gatetype drive_strength gate_instance_list ';'
{ pform_makegates($2, $3, 0, $4, $1); { pform_makegates(@2, $2, $3, 0, $4, $1); }
}
| attribute_list_opt gatetype drive_strength delay3 gate_instance_list ';' | attribute_list_opt gatetype drive_strength delay3 gate_instance_list ';'
{ pform_makegates($2, $3, $4, $5, $1); { pform_makegates(@2, $2, $3, $4, $5, $1); }
}
/* The switch type gates do not support a strength. */ /* The switch type gates do not support a strength. */
| attribute_list_opt switchtype gate_instance_list ';' | attribute_list_opt switchtype gate_instance_list ';'
{ pform_makegates($2, str_strength, 0, $3, $1); { pform_makegates(@2, $2, str_strength, 0, $3, $1); }
}
| attribute_list_opt switchtype delay3 gate_instance_list ';' | attribute_list_opt switchtype delay3 gate_instance_list ';'
{ pform_makegates($2, str_strength, $3, $4, $1); { pform_makegates(@2, $2, str_strength, $3, $4, $1); }
}
/* Pullup and pulldown devices cannot have delays, and their /* Pullup and pulldown devices cannot have delays, and their
strengths are limited. */ strengths are limited. */
| K_pullup gate_instance_list ';' | K_pullup gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, pull_strength, 0, { pform_makegates(@1, PGBuiltin::PULLUP, pull_strength, 0, $2, 0); }
$2, 0); | K_pulldown gate_instance_list ';'
} { pform_makegates(@1, PGBuiltin::PULLDOWN, pull_strength, 0, $2, 0); }
| K_pulldown gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, pull_strength,
0, $2, 0);
}
| K_pullup '(' dr_strength1 ')' gate_instance_list ';' | K_pullup '(' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $3, 0, $5, 0); { pform_makegates(@1, PGBuiltin::PULLUP, $3, 0, $5, 0); }
}
| K_pullup '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';' | K_pullup '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $3, 0, $7, 0); { pform_makegates(@1, PGBuiltin::PULLUP, $3, 0, $7, 0); }
}
| K_pullup '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';' | K_pullup '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $5, 0, $7, 0); { pform_makegates(@1, PGBuiltin::PULLUP, $5, 0, $7, 0); }
}
| K_pulldown '(' dr_strength0 ')' gate_instance_list ';' | K_pulldown '(' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $5, 0); { pform_makegates(@1, PGBuiltin::PULLDOWN, $3, 0, $5, 0); }
}
| K_pulldown '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';' | K_pulldown '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $5, 0, $7, 0); { pform_makegates(@1, PGBuiltin::PULLDOWN, $5, 0, $7, 0); }
}
| K_pulldown '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';' | K_pulldown '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $7, 0); { pform_makegates(@1, PGBuiltin::PULLDOWN, $3, 0, $7, 0); }
}
/* This rule handles instantiations of modules and user defined /* This rule handles instantiations of modules and user defined
primitives. These devices to not have delay lists or strengths, primitives. These devices to not have delay lists or strengths,
@ -4124,7 +4116,7 @@ module_item
| attribute_list_opt | attribute_list_opt
IDENTIFIER parameter_value_opt gate_instance_list ';' IDENTIFIER parameter_value_opt gate_instance_list ';'
{ perm_string tmp1 = lex_strings.make($2); { perm_string tmp1 = lex_strings.make($2);
pform_make_modgates(tmp1, $3, $4); pform_make_modgates(@2, tmp1, $3, $4);
delete[]$2; delete[]$2;
if ($1) delete $1; 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 need to do is remember that this is a parallel block so that the
code generator can do the right thing. */ code generator can do the right thing. */
| K_fork K_join | K_fork join_keyword
{ PBlock*tmp = new PBlock(PBlock::BL_PAR); { PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| K_fork statement_or_null_list K_join | K_fork statement_or_null_list join_keyword
{ PBlock*tmp = new PBlock(PBlock::BL_PAR); { PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
tmp->set_statement(*$2); tmp->set_statement(*$2);
@ -5360,7 +5352,7 @@ statement_item /* This is roughly statement_item in the LRM */
current_block_stack.push(tmp); current_block_stack.push(tmp);
} }
block_item_decls_opt block_item_decls_opt
statement_or_null_list_opt K_join statement_or_null_list_opt join_keyword
{ pform_pop_scope(); { pform_pop_scope();
assert(! current_block_stack.empty()); assert(! current_block_stack.empty());
PBlock*tmp = current_block_stack.top(); 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; 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); perm_string lex_name = lex_strings.make(name);
Module*cur_module = new Module(lexical_scope, lex_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); 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, struct str_pair_t str,
list<PExpr*>*delay, list<PExpr*>*delay,
svector<lgate>*gates, svector<lgate>*gates,
list<named_pexpr_t>*attr) 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) { for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) {
pform_makegate(type, str, delay, (*gates)[idx], attr); 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); 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, struct parmvalue_t*overrides,
svector<lgate>*gates) 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) { for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) {
lgate cur = (*gates)[idx]; 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 * The makegate function creates a new gate (which need not have a
* name) and connects it to the specified wires. * 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, struct str_pair_t str,
list<PExpr*>*delay, list<PExpr*>*delay,
svector<lgate>*gates, svector<lgate>*gates,
list<named_pexpr_t>*attr); 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, struct parmvalue_t*overrides,
svector<lgate>*gates); svector<lgate>*gates);