static void emit_stmt_delay(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c#", get_indent(), ' '); emit_scaled_delay(scope, ivl_stmt_delay_val(stmt)); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); }
/* * Emit a constant or variable delay that has been rescaled to the given * scopes timescale. */ void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt) { ivl_expr_type_t type = ivl_expr_type(expr); if (type == IVL_EX_DELAY) { emit_scaled_delay(scope, ivl_expr_delay_val(expr)); } else if (type == IVL_EX_NUMBER) { assert(! ivl_expr_signed(expr)); int rtype; uint64_t value = get_uint64_from_number(expr, &rtype); if (rtype > 0) { fprintf(vlog_out, "<invalid>"); fprintf(stderr, "%s:%u: vlog95 error: Time value is " "greater than 64 bits (%u) and cannot be " "safely represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), rtype); vlog_errors += 1; return; } if (rtype < 0) { fprintf(vlog_out, "<invalid>"); fprintf(stderr, "%s:%u: vlog95 error: Time value has an " "undefined bit and cannot be represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return; } emit_scaled_delay(scope, value); } else { int exponent = ivl_scope_time_units(scope) - sim_precision; assert(exponent >= 0); if ((exponent == 0) && (type == IVL_EX_SIGNAL)) { emit_delay(scope, expr, is_stmt); /* A real delay variable is not scaled by the compiler. */ } else if (type == IVL_EX_SIGNAL) { if (is_stmt) { fprintf(vlog_out, "<invalid>"); fprintf(stderr, "%s:%u: vlog95 error: Only continuous " "assignment delay variables are scaled " "at run time.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return; } emit_delay(scope, expr, is_stmt); } else { uint64_t iscale = 1; unsigned rtn; assert(! ivl_expr_signed(expr)); /* Calculate the integer time scaling coefficient. */ while (exponent > 0) { iscale *= 10; exponent -= 1; } /* Check to see if this is an integer time value. */ rtn = check_scaled_expr(expr, iscale, "Variable time", 0); /* This may be a scaled real value. */ if (rtn == 2){ ivl_expr_t tmp_expr; uint64_t rprec = 1; /* This could be a scaled real time so calculate * the real time scaling coefficients and check * that the expression matches (statements only). */ exponent = ivl_scope_time_precision(scope) - sim_precision; assert(exponent >= 0); while (exponent > 0) { rprec *= 10; exponent -= 1; } /* Verify that the precision scaling is correct. */ if (! check_scaled_expr(expr, rprec, "Variable real time prec.", 1)) { fprintf(vlog_out, "<invalid>"); return; } /* Verify that the left operator is a real to * integer cast. */ tmp_expr = ivl_expr_oper1(expr); if ((ivl_expr_type(tmp_expr) != IVL_EX_UNARY) || (ivl_expr_opcode(tmp_expr) != 'v')) { fprintf(vlog_out, "<invalid>"); fprintf(stderr, "%s:%u: vlog95 error: Real time " "value does not have a cast to " "integer.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return; } /* Check that the cast value is scaled correctly. */ assert(iscale >= rprec); tmp_expr = ivl_expr_oper1(tmp_expr); assert(ivl_expr_value(tmp_expr) == IVL_VT_REAL); if (! check_scaled_real_expr(tmp_expr, iscale/rprec)) { fprintf(vlog_out, "<invalid>"); return; } assert(is_stmt); emit_delay(scope, ivl_expr_oper1(tmp_expr), is_stmt); return; } else if (rtn == 1) { emit_delay(scope, ivl_expr_oper1(expr), is_stmt); return; } fprintf(vlog_out, "<invalid>"); } } }
static void emit_expr_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { emit_scaled_delay(scope, ivl_expr_delay_val(expr)); }