Disallow modules/gates in program blocks.
This commit is contained in:
parent
8154ce2a4a
commit
c0f35cbe62
88
parse.y
88
parse.y
|
|
@ -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();
|
||||||
|
|
|
||||||
23
pform.cc
23
pform.cc
|
|
@ -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];
|
||||||
|
|
|
||||||
6
pform.h
6
pform.h
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue