vlog95: Rework delayx to handle a CA vs using emit_expr_signal().
It was incorrect to extend emit_expr_signal() to handle a local signal (a continuous assignment). The only way this should ever happen is when evaluating a variable delay expression. It is better to do this checking in the delayx evaluation where we know if we are processing a delay for a statement or a continuous assignment. This keeps the emit_expr_signal() routine cleaner and we only allow a CA delay for a continuous assignment.
This commit is contained in:
parent
88cec4d6f6
commit
28c10311f6
|
|
@ -351,18 +351,14 @@ static void emit_expr_sfunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
if (ivl_signal_local(sig)) {
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0));
|
||||
} else {
|
||||
emit_scope_module_path(scope, ivl_signal_scope(sig));
|
||||
fprintf(vlog_out, "%s", ivl_signal_basename(sig));
|
||||
if (ivl_signal_dimensions(sig)) {
|
||||
int lsb = ivl_signal_array_base(sig);
|
||||
int msb = lsb + ivl_signal_array_count(sig);
|
||||
fprintf(vlog_out, "[");
|
||||
emit_scaled_expr(scope, ivl_expr_oper1(expr), msb, lsb);
|
||||
fprintf(vlog_out, "]");
|
||||
}
|
||||
emit_scope_module_path(scope, ivl_signal_scope(sig));
|
||||
fprintf(vlog_out, "%s", ivl_signal_basename(sig));
|
||||
if (ivl_signal_dimensions(sig)) {
|
||||
int lsb = ivl_signal_array_base(sig);
|
||||
int msb = lsb + ivl_signal_array_count(sig);
|
||||
fprintf(vlog_out, "[");
|
||||
emit_scaled_expr(scope, ivl_expr_oper1(expr), msb, lsb);
|
||||
fprintf(vlog_out, "]");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,21 @@ void emit_scaled_delay(ivl_scope_t scope, uint64_t delay)
|
|||
free(frac);
|
||||
}
|
||||
|
||||
static void emit_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt)
|
||||
{
|
||||
/* A delay in a continuous assignment can also be a continuous
|
||||
* assignment expression. */
|
||||
if (ivl_expr_type(expr) == IVL_EX_SIGNAL) {
|
||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
if (ivl_signal_local(sig)) {
|
||||
assert(! is_stmt);
|
||||
emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
emit_expr(scope, expr, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit a constant or variable delay that has been rescaled to the given
|
||||
* scopes timescale.
|
||||
|
|
@ -93,7 +108,7 @@ void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt)
|
|||
} else {
|
||||
int exponent = ivl_scope_time_units(scope) - sim_precision;
|
||||
assert(exponent >= 0);
|
||||
if (exponent == 0) emit_expr(scope, expr, 0);
|
||||
if (exponent == 0) emit_delay(scope, expr, is_stmt);
|
||||
/* A real delay variable is not scaled by the compiler. */
|
||||
else if (ivl_expr_type(expr) == IVL_EX_SIGNAL) {
|
||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
|
|
@ -106,8 +121,7 @@ void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt)
|
|||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
emit_expr(scope, expr, 0);
|
||||
return;
|
||||
emit_delay(scope, expr, is_stmt);
|
||||
} else {
|
||||
// HERE: If we have a statement delay then a real variable delay has already
|
||||
// been encoded as int((real expr) * tu_tp_scale) * tp_sim_scale. So
|
||||
|
|
@ -169,7 +183,7 @@ void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt)
|
|||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
emit_expr(scope, ivl_expr_oper1(expr), 0);
|
||||
emit_delay(scope, ivl_expr_oper1(expr), is_stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue