static void draw_ufunc_preamble(ivl_expr_t expr) { ivl_scope_t def = ivl_expr_def(expr); unsigned idx; /* If this is an automatic function, allocate the local storage. */ if (ivl_scope_is_auto(def)) { fprintf(vvp_out, " %%alloc S_%p;\n", def); } /* Evaluate the expressions and send the results to the function ports. Do this in two passes - evaluate, then send - this avoids the function input variables being overwritten if the same (non-automatic) function is called in one of the exressions. */ assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1)); for (idx = 0 ; idx < ivl_expr_parms(expr) ; idx += 1) { ivl_signal_t port = ivl_scope_port(def, idx+1); draw_eval_function_argument(port, ivl_expr_parm(expr, idx)); } for (idx = ivl_expr_parms(expr) ; idx > 0 ; idx -= 1) { ivl_signal_t port = ivl_scope_port(def, idx); draw_send_function_argument(port); } /* Call the function */ fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); fprintf(vvp_out, " %%join;\n"); }
static void draw_ufunc_preamble(ivl_expr_t expr) { ivl_scope_t def = ivl_expr_def(expr); unsigned idx; /* If this is an automatic function, allocate the local storage. */ if (ivl_scope_is_auto(def)) { fprintf(vvp_out, " %%alloc S_%p;\n", def); } /* Evaluate the expressions and send the results to the function ports. Do this in two passes - evaluate, then send - this avoids the function input variables being overwritten if the same (non-automatic) function is called in one of the expressions. */ assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1)); for (idx = 0 ; idx < ivl_expr_parms(expr) ; idx += 1) { ivl_signal_t port = ivl_scope_port(def, idx+1); draw_eval_function_argument(port, ivl_expr_parm(expr, idx)); } for (idx = ivl_expr_parms(expr) ; idx > 0 ; idx -= 1) { ivl_signal_t port = ivl_scope_port(def, idx); draw_send_function_argument(port); } /* Call the function */ switch (ivl_expr_value(expr)) { case IVL_VT_VOID: fprintf(vvp_out, " %%callf/void TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_REAL: fprintf(vvp_out, " %%callf/real TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_BOOL: case IVL_VT_LOGIC: fprintf(vvp_out, " %%callf/vec4 TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_STRING: fprintf(vvp_out, " %%callf/str TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_CLASS: case IVL_VT_DARRAY: case IVL_VT_QUEUE: fprintf(vvp_out, " %%callf/obj TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; default: fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); fprintf(vvp_out, " %%join;\n"); break; } }