Skip to content

Commit

Permalink
Prevent non-blocking assignment in program blocks.
Browse files Browse the repository at this point in the history
  • Loading branch information
steveicarus committed May 28, 2012
1 parent 0833d9e commit 580c44c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 50 deletions.
110 changes: 60 additions & 50 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions pform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions pform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 580c44c

Please sign in to comment.