vlog95: Add checks for missing assignments with opcodes

SystemVerilog supports using assignments with opcodes (e.g. +=). This
patch checks for these in a few common places and prints a warning
that they are not currently supported. Eventually the simple cases
will be converted.
This commit is contained in:
Cary R 2012-08-06 19:15:48 -07:00
parent 62412700aa
commit 8158153ea4
1 changed files with 50 additions and 0 deletions

View File

@ -318,6 +318,38 @@ static unsigned is_delayed_or_event_assign(ivl_scope_t scope,
return 1;
}
/*
* Get the string version for the assignment operator prefix.
*/
static char * get_assign_oper_string(ivl_statement_t stmt)
{
assert (ivl_statement_type(stmt) == IVL_ST_ASSIGN);
switch (ivl_stmt_opcode(stmt)) {
case 0: assert(0); /* There must be an opcode! */
case '+': return "+";
case '-': return "-";
case '*': return "*";
case '/': return "/";
case '%': return "%";
case '&': return "&";
case '|': return "|";
case '^': return "^";
case 'l': return "<<";
case 'r': return ">>";
// HERE: This is only allowed if we are emitting signed information.
case 'R': return ">>>";
default:
vlog_errors += 1;
fprintf(stderr, "%s:%u: vlog95 error: unknown assignment operator "
"(%c).\n",
ivl_stmt_file(stmt), ivl_stmt_lineno(stmt),
ivl_stmt_opcode(stmt));
}
return "<unknown>";
}
/*
* Icarus translated for(<assign>; <cond>; <incr_assign>) <body> into
*
@ -334,6 +366,7 @@ static unsigned is_delayed_or_event_assign(ivl_scope_t scope,
static unsigned is_for_loop(ivl_scope_t scope, ivl_statement_t stmt)
{
unsigned wid;
char opcode;
ivl_statement_t assign, while_lp, while_blk, body, incr_assign;
/* We must have two block elements. */
@ -382,6 +415,14 @@ static unsigned is_for_loop(ivl_scope_t scope, ivl_statement_t stmt)
// done this for us.
wid = emit_stmt_lval(scope, incr_assign);
fprintf(vlog_out, " = ");
opcode = ivl_stmt_opcode(incr_assign);
if (opcode) {
fprintf(stderr, "%s:%u: vlog95 sorry: assignment operator %s= is "
"not currently translated.\n",
ivl_stmt_file(stmt), ivl_stmt_lineno(stmt),
get_assign_oper_string(incr_assign));
vlog_errors += 1;
}
emit_expr(scope, ivl_stmt_rval(incr_assign), wid);
fprintf(vlog_out, ")");
emit_stmt_file_line(stmt);
@ -728,11 +769,20 @@ static unsigned is_utask_call_with_args(ivl_scope_t scope,
static void emit_stmt_assign(ivl_scope_t scope, ivl_statement_t stmt)
{
unsigned wid;
char opcode;
fprintf(vlog_out, "%*c", get_indent(), ' ');
// HERE: Do we need to calculate the width? The compiler should have already
// done this for us.
wid = emit_stmt_lval(scope, stmt);
fprintf(vlog_out, " = ");
opcode = ivl_stmt_opcode(stmt);
if (opcode) {
fprintf(stderr, "%s:%u: vlog95 sorry: assignment operator %s= is "
"not currently translated.\n",
ivl_stmt_file(stmt), ivl_stmt_lineno(stmt),
get_assign_oper_string(stmt));
vlog_errors += 1;
}
emit_expr(scope, ivl_stmt_rval(stmt), wid);
fprintf(vlog_out, ";");
emit_stmt_file_line(stmt);