Prevent non-blocking assignment in program blocks.

This commit is contained in:
Stephen Williams 2012-05-06 10:21:51 -07:00
parent 0833d9e37a
commit 580c44c015
3 changed files with 81 additions and 50 deletions

110
parse.y
View File

@ -5484,56 +5484,66 @@ statement_item /* This is roughly statement_item in the LRM */
$$ = tmp;
}
| error '=' expression ';'
{ yyerror(@2, "Syntax in assignment statement l-value.");
yyerrok;
$$ = new PNoop;
}
| lpvalue K_LE expression ';'
{ PAssignNB*tmp = new PAssignNB($1,$3);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| error K_LE expression ';'
{ yyerror(@2, "Syntax in assignment statement l-value.");
yyerrok;
$$ = new PNoop;
}
| lpvalue '=' delay1 expression ';'
{ PExpr*del = $3->front(); $3->pop_front();
assert($3->empty());
PAssign*tmp = new PAssign($1,del,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| lpvalue K_LE delay1 expression ';'
{ PExpr*del = $3->front(); $3->pop_front();
assert($3->empty());
PAssignNB*tmp = new PAssignNB($1,del,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| lpvalue '=' event_control expression ';'
{ PAssign*tmp = new PAssign($1,0,$3,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| lpvalue '=' K_repeat '(' expression ')' event_control expression ';'
{ PAssign*tmp = new PAssign($1,$5,$7,$8);
FILE_NAME(tmp,@1);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lpvalue K_LE event_control expression ';'
{ PAssignNB*tmp = new PAssignNB($1,0,$3,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| lpvalue K_LE K_repeat '(' expression ')' event_control expression ';'
{ PAssignNB*tmp = new PAssignNB($1,$5,$7,$8);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| error '=' expression ';'
{ yyerror(@2, "Syntax in assignment statement l-value.");
yyerrok;
$$ = new PNoop;
}
| lpvalue K_LE expression ';'
{ PAssignNB*tmp = new PAssignNB($1,$3);
FILE_NAME(tmp, @1);
$$ = tmp;
if (pform_in_program_block())
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
}
| error K_LE expression ';'
{ yyerror(@2, "Syntax in assignment statement l-value.");
yyerrok;
$$ = new PNoop;
if (pform_in_program_block())
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
}
| lpvalue '=' delay1 expression ';'
{ PExpr*del = $3->front(); $3->pop_front();
assert($3->empty());
PAssign*tmp = new PAssign($1,del,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| lpvalue K_LE delay1 expression ';'
{ PExpr*del = $3->front(); $3->pop_front();
assert($3->empty());
PAssignNB*tmp = new PAssignNB($1,del,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
if (pform_in_program_block())
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
}
| lpvalue '=' event_control expression ';'
{ PAssign*tmp = new PAssign($1,0,$3,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| lpvalue '=' K_repeat '(' expression ')' event_control expression ';'
{ PAssign*tmp = new PAssign($1,$5,$7,$8);
FILE_NAME(tmp,@1);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lpvalue K_LE event_control expression ';'
{ PAssignNB*tmp = new PAssignNB($1,0,$3,$4);
FILE_NAME(tmp, @1);
$$ = tmp;
if (pform_in_program_block())
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
}
| lpvalue K_LE K_repeat '(' expression ')' event_control expression ';'
{ PAssignNB*tmp = new PAssignNB($1,$5,$7,$8);
FILE_NAME(tmp, @1);
$$ = tmp;
if (pform_in_program_block())
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
}
/* The IEEE1800 standard defines dynamic_array_new assignment as a
different rule from regular assignment. That implies that the

View File

@ -400,6 +400,15 @@ void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
delete attr;
}
bool pform_in_program_block()
{
if (pform_cur_module == 0)
return false;
if (pform_cur_module->program_block)
return true;
return false;
}
static bool pform_at_module_level()
{
return (lexical_scope == pform_cur_module)
@ -2850,6 +2859,14 @@ PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st,
pform_bind_attributes(pp->attributes, attr);
pform_put_behavior_in_scope(pp);
ivl_assert(*st, pform_cur_module);
if (pform_cur_module->program_block && type == IVL_PR_ALWAYS) {
cerr << st->get_fileline() << ": error: Always statements not allowed"
<< " in program blocks." << endl;
error_count += 1;
}
return pp;
}

View File

@ -130,6 +130,10 @@ extern void pform_set_default_nettype(NetNet::Type net,
const char*file,
unsigned lineno);
/* Return true if currently processing a program block. This can be
used to reject statements that cannot exist in program blocks. */
extern bool pform_in_program_block(void);
/*
* Look for the given wire in the current lexical scope. If the wire
* (including variables of any type) cannot be found in the current