Prevent non-blocking assignment in program blocks.
This commit is contained in:
parent
0833d9e37a
commit
580c44c015
110
parse.y
110
parse.y
|
|
@ -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
|
||||
|
|
|
|||
17
pform.cc
17
pform.cc
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
pform.h
4
pform.h
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue