From 28c10311f6804be72e86064b40cfb9d0c7c1a41c Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 11 Feb 2011 09:30:42 -0800 Subject: [PATCH] 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. --- tgt-vlog95/expr.c | 20 ++++++++------------ tgt-vlog95/misc.c | 22 ++++++++++++++++++---- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/tgt-vlog95/expr.c b/tgt-vlog95/expr.c index c42e0f456..3379194ca 100644 --- a/tgt-vlog95/expr.c +++ b/tgt-vlog95/expr.c @@ -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, "]"); } } diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index 7c54e5a34..b5e8f91b4 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -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); } } }