diff --git a/tgt-vlog95/stmt.c b/tgt-vlog95/stmt.c
index 4d0f9cef9..5ad614fef 100644
--- a/tgt-vlog95/stmt.c
+++ b/tgt-vlog95/stmt.c
@@ -250,8 +250,8 @@ static unsigned emit_stmt_lval(ivl_scope_t scope, ivl_statement_t stmt)
* This routine looks for this pattern and turns it back into the
* appropriate blocking assignment.
*/
-static unsigned find_delayed_or_event_assign(ivl_scope_t scope,
- ivl_statement_t stmt)
+static unsigned is_delayed_or_event_assign(ivl_scope_t scope,
+ ivl_statement_t stmt)
{
unsigned wid;
ivl_statement_t assign, delay, delayed_assign;
@@ -289,13 +289,18 @@ static unsigned find_delayed_or_event_assign(ivl_scope_t scope,
/* It must not be an array word. */
if (ivl_expr_oper1(rval)) return 0;
rsig = ivl_expr_signal(rval);
- /* And finally the two signals must be the same. */
+ /* The two signals must be the same. */
if (lsig != rsig) return 0;
+ /* And finally the three statements must have the same line number
+ * as the block. */
+ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) ||
+ (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(delay)) ||
+ (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(delayed_assign))) {
+ return 0;
+ }
/* The pattern matched so generate the appropriate code. */
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, delayed_assign);
fprintf(vlog_out, " = ");
if (delay_type == IVL_ST_DELAYX) {
@@ -324,11 +329,10 @@ static unsigned find_delayed_or_event_assign(ivl_scope_t scope,
* This routine looks for this pattern and turns it back into the
* appropriate blocking assignment.
*/
-static unsigned find_repeat_event_assign(ivl_scope_t scope,
- ivl_statement_t stmt)
+static unsigned is_repeat_event_assign(ivl_scope_t scope, ivl_statement_t stmt)
{
unsigned wid;
- ivl_statement_t assign, event, event_assign, repeat = 0;
+ ivl_statement_t assign, event, event_assign, repeat;
ivl_lval_t lval;
ivl_expr_t rval;
ivl_signal_t lsig, rsig;
@@ -339,13 +343,11 @@ static unsigned find_repeat_event_assign(ivl_scope_t scope,
assign = ivl_stmt_block_stmt(stmt, 0);
if (ivl_statement_type(assign) != IVL_ST_ASSIGN) return 0;
/* The second must be a repeat with an event or an event. */
- event = ivl_stmt_block_stmt(stmt, 1);
- if (ivl_statement_type(event) != IVL_ST_REPEAT) return 0;
- if (ivl_statement_type(event) == IVL_ST_REPEAT) {
- repeat = event;
- event = ivl_stmt_sub_stmt(repeat);
- if (ivl_statement_type(event) != IVL_ST_WAIT) return 0;
- }
+ repeat = ivl_stmt_block_stmt(stmt, 1);
+ if (ivl_statement_type(repeat) != IVL_ST_REPEAT) return 0;
+ /* The repeat must have an event statement. */
+ event = ivl_stmt_sub_stmt(repeat);
+ if (ivl_statement_type(event) != IVL_ST_WAIT) return 0;
/* The third must be an assign. */
event_assign = ivl_stmt_block_stmt(stmt, 2);
if (ivl_statement_type(event_assign) != IVL_ST_ASSIGN) return 0;
@@ -365,16 +367,21 @@ static unsigned find_repeat_event_assign(ivl_scope_t scope,
/* It must not be an array word. */
if (ivl_expr_oper1(rval)) return 0;
rsig = ivl_expr_signal(rval);
- /* And finally the two signals must be the same. */
+ /* The two signals must be the same. */
if (lsig != rsig) return 0;
+ /* And finally the four statements must have the same line number
+ * as the block. */
+ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) ||
+ (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(repeat)) ||
+ (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(event)) ||
+ (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(event_assign))) {
+ return 0;
+ }
/* The pattern matched so generate the appropriate code. */
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, event_assign);
fprintf(vlog_out, " =");
- single_indent = 1;
if (repeat) {
fprintf(vlog_out, " repeat (");
emit_expr(scope, ivl_stmt_cond_expr(repeat), 0);
@@ -400,7 +407,7 @@ static unsigned find_repeat_event_assign(ivl_scope_t scope,
* This routine looks for this pattern and turns it back into a
* wait statement.
*/
-static unsigned find_wait(ivl_scope_t scope, ivl_statement_t stmt)
+static unsigned is_wait(ivl_scope_t scope, ivl_statement_t stmt)
{
ivl_statement_t while_wait, wait, wait_stmt;
ivl_expr_t while_expr, expr;
@@ -419,7 +426,7 @@ static unsigned find_wait(ivl_scope_t scope, ivl_statement_t stmt)
while_expr = ivl_stmt_cond_expr(while_wait);
if (ivl_expr_type(while_expr) != IVL_EX_BINARY) return 0;
if (ivl_expr_opcode(while_expr) != 'N') return 0;
- /* And has a second operator that is a constant 1'b1. */
+ /* Has a second operator that is a constant 1'b1. */
expr = ivl_expr_oper2(while_expr);
if (ivl_expr_type(expr) != IVL_EX_NUMBER) return 0;
if (ivl_expr_width(expr) != 1) return 0;
@@ -427,6 +434,12 @@ static unsigned find_wait(ivl_scope_t scope, ivl_statement_t stmt)
if (*bits != '1') return 0;
// HERE: There is no easy way to verify that the @ sensitivity list
// matches the first expression so we don't check for that yet.
+ /* And finally the two statements that represent the wait must
+ * have the same line number as the block. */
+ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(while_wait)) ||
+ (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(wait))) {
+ return 0;
+ }
/* The pattern matched so generate the appropriate code. */
fprintf(vlog_out, "%*cwait(", get_indent(), ' ');
@@ -534,9 +547,8 @@ static void emit_port(ivl_scope_t scope, struct port_expr_s port_expr)
}
}
-
/*
- * Icarus encodes a task call with arguments as:
+ * Icarus encodes a user task call with arguments as:
* begin
* =
* ...
@@ -556,6 +568,7 @@ static unsigned is_utask_call_with_args(ivl_scope_t scope,
{
unsigned idx, ports, task_idx = 0;
unsigned count = ivl_stmt_block_count(stmt);
+ unsigned lineno = ivl_stmt_lineno(stmt);
ivl_scope_t task_scope = 0;
port_expr_t port_exprs;
/* Check to see if the block is of the basic form first. */
@@ -581,21 +594,22 @@ static unsigned is_utask_call_with_args(ivl_scope_t scope,
port_exprs[idx].type = IVL_SIP_NONE;
port_exprs[idx].rval = 0;
}
- /* Now do a detailed check that the arguments are correct. */
+ /* Check that the input arguments are correct. */
for (idx = 0; idx < task_idx; idx += 1) {
ivl_statement_t assign = ivl_stmt_block_stmt(stmt, idx);
unsigned port = utask_in_port_idx(task_scope, assign);
- if (port == ports) {
+ if ((port == ports) || (lineno != ivl_stmt_lineno(assign))) {
free(port_exprs);
return 0;
}
port_exprs[port].type = IVL_SIP_INPUT;
port_exprs[port].rval = ivl_stmt_rval(assign);
}
+ /* Check that the output arguments are correct. */
for (idx = task_idx + 1; idx < count; idx += 1) {
ivl_statement_t assign = ivl_stmt_block_stmt(stmt, idx);
unsigned port = utask_out_port_idx(task_scope, assign);
- if (port == ports) {
+ if ((port == ports) || (lineno != ivl_stmt_lineno(assign))) {
free(port_exprs);
return 0;
}
@@ -608,6 +622,11 @@ static unsigned is_utask_call_with_args(ivl_scope_t scope,
}
port_exprs[port].lval = assign;
}
+ /* Check that the task call has the correct line number. */
+ if (lineno != ivl_stmt_lineno(ivl_stmt_block_stmt(stmt, task_idx))) {
+ free(port_exprs);
+ return 0;
+ }
/* Verify that all the ports were defined. */
for (idx = 0; idx < ports; idx += 1) {
@@ -664,7 +683,6 @@ static void emit_stmt_assign_nb(ivl_scope_t scope, ivl_statement_t stmt)
static void emit_stmt_block(ivl_scope_t scope, ivl_statement_t stmt)
{
- if (is_utask_call_with_args(scope, stmt)) return;
fprintf(vlog_out, "%*cbegin", get_indent(), ' ');
emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n");
@@ -982,9 +1000,10 @@ void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt)
if (ivl_stmt_block_scope(stmt)) {
emit_stmt_block_named(scope, stmt);
} else {
- if (find_delayed_or_event_assign(scope, stmt)) break;
- if (find_repeat_event_assign(scope, stmt)) break;
- if (find_wait(scope, stmt)) break;
+ if (is_delayed_or_event_assign(scope, stmt)) break;
+ if (is_repeat_event_assign(scope, stmt)) break;
+ if (is_wait(scope, stmt)) break;
+ if (is_utask_call_with_args(scope, stmt)) break;
emit_stmt_block(scope, stmt);
}
break;
diff --git a/tgt-vlog95/vlog95.c b/tgt-vlog95/vlog95.c
index 4d69e6642..5b00f7739 100644
--- a/tgt-vlog95/vlog95.c
+++ b/tgt-vlog95/vlog95.c
@@ -105,7 +105,7 @@ int target_design(ivl_design_t des)
char *eptr;
long fl_value = strtol(fileline, &eptr, 0);
/* Nothing usable in the file/line string. */
- if (spacing == eptr) {
+ if (fileline == eptr) {
fprintf(stderr, "vlog95 error: Unable to extract file/line "
"information from string: %s\n", fileline);
return 1;