Emit useful error message for pr2362211

This prints out an error message rather than crashing out with
an assertion failure when a function assigns to a non-local
variable, which cannot be done in VHDL.
This commit is contained in:
Nick Gasson 2008-12-07 18:06:07 +00:00 committed by Stephen Williams
parent d689c93879
commit 712e08ebe8
2 changed files with 36 additions and 0 deletions

View File

@ -535,6 +535,14 @@ static int draw_function(ivl_scope_t scope, ivl_scope_t parent)
// The return type is worked out from the output port
vhdl_function *func = new vhdl_function(funcname, NULL);
// Set the parent scope of this function to be the containing
// architecture. This allows us to look up non-local variables
// referenced in the body, but if we do the `impure' flag must
// be set on the function
// (There are actually two VHDL scopes in a function: the local
// variables and the formal parameters hence the call to get_parent)
func->get_scope()->get_parent()->set_parent(ent->get_arch()->get_scope());
int nsigs = ivl_scope_sigs(scope);
for (int i = 0; i < nsigs; i++) {

View File

@ -179,6 +179,25 @@ assign_for(vhdl_decl::assign_type_t atype, vhdl_var_ref *lhs, vhdl_expr *rhs)
}
}
/*
* Check that this assignment type is valid within the context of `proc'.
* For example, a <= assignment is not valid within a function.
*/
bool check_valid_assignment(vhdl_decl::assign_type_t atype, vhdl_procedural *proc,
ivl_statement_t stmt)
{
if (atype == vhdl_decl::ASSIGN_NONBLOCK &&
!proc->get_scope()->allow_signal_assignment()) {
error("Unable to translate assignment at %s:%d\n"
" Translating this would require generating a non-blocking (<=)\n"
" assignment in a VHDL context where this is disallowed (e.g.\n"
" a function).", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt));
return false;
}
else
return true;
}
/*
* Generate an assignment of type T for the Verilog statement stmt.
*/
@ -228,6 +247,9 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
vhdl_if_stmt *vhdif = new vhdl_if_stmt(test);
if (!check_valid_assignment(decl->assignment_type(), proc, stmt))
return;
// True part
{
vhdl_abstract_assign_stmt *a =
@ -283,6 +305,9 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
}
}
if (!check_valid_assignment(decl->assignment_type(), proc, stmt))
return;
vhdl_abstract_assign_stmt *a =
assign_for(decl->assignment_type(), lhs, rhs);
container->add_stmt(a);
@ -327,6 +352,9 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
// a variable, etc?)
vhdl_decl *decl = proc->get_scope()->get_decl((*it)->get_name());
if (!check_valid_assignment(decl->assignment_type(), proc, stmt))
return;
vhdl_abstract_assign_stmt *a =
assign_for(decl->assignment_type(), *it, tmp_rhs);
if (after)