static int draw_realnum_real(ivl_expr_t exp) { int res = allocate_word(); double value = ivl_expr_dvalue(exp); double fract; int expo, vexp; unsigned long mant; int sign = 0; if (value < 0) { sign = 0x4000; value *= -1; } fract = frexp(value, &expo); fract = ldexp(fract, 31); mant = fract; expo -= 31; vexp = expo + 0x1000; assert(vexp >= 0); assert(vexp < 0x2000); vexp += sign; fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%f\n", res, mant, vexp, ivl_expr_dvalue(exp)); /* Capture the residual bits, if there are any. Note that an IEEE754 mantissa has 52 bits, 31 of which were accounted for already. */ fract -= floor(fract); fract = ldexp(fract, 22); mant = fract; expo -= 22; vexp = expo + 0x1000; assert(vexp >= 0); assert(vexp < 0x2000); vexp += sign; if (mant != 0) { int tmp_word = allocate_word(); fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%f\n", tmp_word, mant, vexp, ivl_expr_dvalue(exp)); fprintf(vvp_out, " %%add/wr %d, %d;\n", res, tmp_word); clr_word(tmp_word); } return res; }
/* * Check to see if the real expression is of the form (expr) * <scale> */ static unsigned check_scaled_real_expr(ivl_expr_t expr, double scale) { double scale_val; if ((ivl_expr_type(expr) != IVL_EX_BINARY) || (ivl_expr_opcode(expr) != '*') || (ivl_expr_type(ivl_expr_oper2(expr)) != IVL_EX_REALNUM)) { fprintf(stderr, "%s:%u: vlog95 error: Variable real time unit " " expression/value cannot be scaled.\n ", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return 0; } scale_val = ivl_expr_dvalue(ivl_expr_oper2(expr)); if (scale != scale_val) { fprintf(stderr, "%s:%u: vlog95 error: Variable real time unit " "expression/value scale coefficient did not " "match expected value (%g != %g).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), scale, scale_val); vlog_errors += 1; return 0; } /* Yes, this expression is of the correct form. */ return 1; }
void show_expression(ivl_expr_t net, unsigned ind) { assert(net); unsigned idx; ivl_parameter_t par = ivl_expr_parameter(net); const ivl_expr_type_t code = ivl_expr_type(net); unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*sized = ivl_expr_sized(net)? "sized" : "unsized"; const char*vt = vt_type_string(net); switch (code) { case IVL_EX_ARRAY: show_array_expression(net, ind); break; case IVL_EX_ARRAY_PATTERN: show_array_pattern_expression(net, ind); break; case IVL_EX_BACCESS: show_branch_access_expression(net, ind); break; case IVL_EX_BINARY: show_binary_expression(net, ind); break; case IVL_EX_CONCAT: fprintf(out, "%*s<concat repeat=%u, width=%u, %s, type=%s>\n", ind, "", ivl_expr_repeat(net), width, sign, vt); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) show_expression(ivl_expr_parm(net, idx), ind+3); break; case IVL_EX_ENUMTYPE: show_enumtype_expression(net, ind); break; case IVL_EX_MEMORY: show_memory_expression(net, ind); break; case IVL_EX_NEW: show_new_expression(net, ind); break; case IVL_EX_NULL: show_null_expression(net, ind); break; case IVL_EX_PROPERTY: show_property_expression(net, ind); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(net); fprintf(out, "%*s<number=%u'b", ind, "", width); for (idx = width ; idx > 0 ; idx -= 1) fprintf(out, "%c", bits[idx-1]); fprintf(out, ", %s %s %s", sign, sized, vt); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); break; } case IVL_EX_SELECT: show_select_expression(net, ind); break; case IVL_EX_STRING: fprintf(out, "%*s<string=\"%s\", width=%u", ind, "", ivl_expr_string(net), ivl_expr_width(net)); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ", type=%s>\n", vt); break; case IVL_EX_SFUNC: fprintf(out, "%*s<function=\"%s\", width=%u, %s, type=%s file=%s:%u>\n", ind, "", ivl_expr_name(net), width, sign, vt, ivl_expr_file(net), ivl_expr_lineno(net)); { unsigned cnt = ivl_expr_parms(net); unsigned jdx; for (jdx = 0 ; jdx < cnt ; jdx += 1) show_expression(ivl_expr_parm(net, jdx), ind+3); } break; case IVL_EX_SIGNAL: show_signal_expression(net, ind); break; case IVL_EX_TERNARY: show_ternary_expression(net, ind); break; case IVL_EX_UNARY: show_unary_expression(net, ind); break; case IVL_EX_UFUNC: show_function_call(net, ind); break; case IVL_EX_REALNUM: { int jdx; union foo { double rv; unsigned char bv[sizeof(double)]; } tmp; tmp.rv = ivl_expr_dvalue(net); fprintf(out, "%*s<realnum=%f (", ind, "", tmp.rv); for (jdx = sizeof(double) ; jdx > 0 ; jdx -= 1) fprintf(out, "%02x", tmp.bv[jdx-1]); fprintf(out, ")"); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); } break; case IVL_EX_SHALLOWCOPY: show_shallowcopy(net, ind); break; default: fprintf(out, "%*s<expr_type=%d>\n", ind, "", code); break; } }
void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { switch (ivl_expr_type(expr)) { case IVL_EX_ARRAY: emit_expr_array(scope, expr, wid); break; case IVL_EX_BINARY: emit_expr_binary(scope, expr, wid); break; case IVL_EX_CONCAT: emit_expr_concat(scope, expr, wid); break; case IVL_EX_DELAY: emit_expr_delay(scope, expr, wid); break; case IVL_EX_ENUMTYPE: fprintf(vlog_out, "<enum>"); fprintf(stderr, "%s:%u: vlog95 error: Enum expressions " "are not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case IVL_EX_EVENT: emit_expr_event(scope, expr, wid); break; case IVL_EX_NUMBER: emit_number(ivl_expr_bits(expr), ivl_expr_width(expr), ivl_expr_signed(expr), ivl_expr_file(expr), ivl_expr_lineno(expr)); break; case IVL_EX_REALNUM: emit_real_number(ivl_expr_dvalue(expr)); break; case IVL_EX_SCOPE: emit_expr_scope(scope, expr, wid); break; case IVL_EX_SELECT: emit_expr_select(scope, expr, wid); break; case IVL_EX_SFUNC: fprintf(vlog_out, "%s", ivl_expr_name(expr)); emit_expr_func(scope, expr, wid); break; case IVL_EX_SIGNAL: emit_expr_signal(scope, expr, wid); break; case IVL_EX_STRING: emit_string(ivl_expr_string(expr)); break; case IVL_EX_TERNARY: emit_expr_ternary(scope, expr, wid); break; case IVL_EX_UFUNC: emit_scope_path(scope, ivl_expr_def(expr)); emit_expr_func(scope, expr, wid); break; case IVL_EX_UNARY: emit_expr_unary(scope, expr, wid); break; default: fprintf(vlog_out, "<unknown>"); fprintf(stderr, "%s:%u: vlog95 error: Unknown expression " "type (%d).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), (int)ivl_expr_type(expr)); vlog_errors += 1; break; } }
int draw_scope(ivl_scope_t net, ivl_scope_t parent) { unsigned idx; const char *type; const char*prefix = ivl_scope_is_auto(net) ? "auto" : ""; switch (ivl_scope_type(net)) { case IVL_SCT_MODULE: type = "module"; break; case IVL_SCT_FUNCTION: type = "function"; break; case IVL_SCT_TASK: type = "task"; break; case IVL_SCT_BEGIN: type = "begin"; break; case IVL_SCT_FORK: type = "fork"; break; case IVL_SCT_GENERATE: type = "generate"; break; default: type = "?"; assert(0); } fprintf(vvp_out, "S_%p .scope %s%s, \"%s\" \"%s\" %d %d", net, prefix, type, vvp_mangle_name(ivl_scope_basename(net)), ivl_scope_tname(net), ivl_file_table_index(ivl_scope_file(net)), ivl_scope_lineno(net)); if (parent) { fprintf(vvp_out, ", %d %d, S_%p;\n", ivl_file_table_index(ivl_scope_def_file(net)), ivl_scope_def_lineno(net), parent); } else { fprintf(vvp_out, ";\n"); } fprintf(vvp_out, " .timescale %d %d;\n", ivl_scope_time_units(net), ivl_scope_time_precision(net)); for (idx = 0 ; idx < ivl_scope_params(net) ; idx += 1) { ivl_parameter_t par = ivl_scope_param(net, idx); ivl_expr_t pex = ivl_parameter_expr(par); switch (ivl_expr_type(pex)) { case IVL_EX_STRING: fprintf(vvp_out, "P_%p .param/str \"%s\" %d %d, \"%s\";\n", par, ivl_parameter_basename(par), ivl_file_table_index(ivl_parameter_file(par)), ivl_parameter_lineno(par), ivl_expr_string(pex)); break; case IVL_EX_NUMBER: fprintf(vvp_out, "P_%p .param/l \"%s\" %d %d, %sC4<", par, ivl_parameter_basename(par), ivl_file_table_index(ivl_parameter_file(par)), ivl_parameter_lineno(par), ivl_expr_signed(pex)? "+":""); { const char*bits = ivl_expr_bits(pex); unsigned nbits = ivl_expr_width(pex); unsigned bb; for (bb = 0 ; bb < nbits; bb += 1) fprintf(vvp_out, "%c", bits[nbits-bb-1]); } fprintf(vvp_out, ">;\n"); break; case IVL_EX_REALNUM: fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; value=%g\n", par, ivl_parameter_basename(par), ivl_file_table_index(ivl_parameter_file(par)), ivl_parameter_lineno(par), draw_Cr_to_string(ivl_expr_dvalue(pex)), ivl_expr_dvalue(pex)); break; default: fprintf(vvp_out, "; parameter type %d unsupported\n", ivl_expr_type(pex)); break; } } /* Scan the scope for logic devices. For each device, draw out a functor that connects pin 0 to the output, and the remaining pins to inputs. */ for (idx = 0 ; idx < ivl_scope_logs(net) ; idx += 1) { ivl_net_logic_t lptr = ivl_scope_log(net, idx); draw_logic_in_scope(lptr); } /* Scan the signals (reg and net) and draw the appropriate statements to make the signal function. */ for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(net, idx); switch (ivl_signal_type(sig)) { case IVL_SIT_REG: draw_reg_in_scope(sig); break; default: draw_net_in_scope(sig); break; } } for (idx = 0 ; idx < ivl_scope_events(net) ; idx += 1) { ivl_event_t event = ivl_scope_event(net, idx); draw_event_in_scope(event); } for (idx = 0 ; idx < ivl_scope_lpms(net) ; idx += 1) { ivl_lpm_t lpm = ivl_scope_lpm(net, idx); draw_lpm_in_scope(lpm); } for (idx = 0 ; idx < ivl_scope_switches(net) ; idx += 1) { ivl_switch_t sw = ivl_scope_switch(net, idx); draw_switch_in_scope(sw); } if (ivl_scope_type(net) == IVL_SCT_TASK) draw_task_definition(net); if (ivl_scope_type(net) == IVL_SCT_FUNCTION) draw_func_definition(net); ivl_scope_children(net, (ivl_scope_f*) draw_scope, net); return 0; }
void show_expression(ivl_expr_t net, unsigned ind) { unsigned idx; const ivl_expr_type_t code = ivl_expr_type(net); ivl_parameter_t par = ivl_expr_parameter(net); unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*sized = ivl_expr_sized(net)? "sized" : "unsized"; const char*vt = vt_type_string(net); switch (code) { case IVL_EX_ARRAY: show_array_expression(net, ind); break; case IVL_EX_BACCESS: show_branch_access_expression(net, ind); break; case IVL_EX_BINARY: show_binary_expression(net, ind); break; case IVL_EX_CONCAT: fprintf(out, "%*s<concat repeat=%u, width=%u, %s, type=%s>\n", ind, "", ivl_expr_repeat(net), width, sign, vt); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) show_expression(ivl_expr_parm(net, idx), ind+3); break; case IVL_EX_MEMORY: show_memory_expression(net, ind); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(net); fprintf(out, "%*s<number=%u'b", ind, "", width); for (idx = width ; idx > 0 ; idx -= 1) fprintf(out, "%c", bits[idx-1]); fprintf(out, ", %s %s %s", sign, sized, vt); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); break; } case IVL_EX_SELECT: /* The SELECT expression can be used to express part select, or if the base is null vector extension. */ if (ivl_expr_oper2(net)) { fprintf(out, "%*s<select: width=%u, %s>\n", ind, "", width, sign); show_expression(ivl_expr_oper1(net), ind+3); show_expression(ivl_expr_oper2(net), ind+3); } else { fprintf(out, "%*s<expr pad: width=%u, %s>\n", ind, "", width, sign); show_expression(ivl_expr_oper1(net), ind+3); } break; case IVL_EX_STRING: fprintf(out, "%*s<string=\"%s\", width=%u", ind, "", ivl_expr_string(net), ivl_expr_width(net)); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ", type=%s>\n", vt); break; case IVL_EX_SFUNC: fprintf(out, "%*s<function=\"%s\", width=%u, %s, type=%s file=%s:%u>\n", ind, "", ivl_expr_name(net), width, sign, vt, ivl_expr_file(net), ivl_expr_lineno(net)); { unsigned cnt = ivl_expr_parms(net); unsigned jdx; for (jdx = 0 ; jdx < cnt ; jdx += 1) show_expression(ivl_expr_parm(net, jdx), ind+3); } break; case IVL_EX_SIGNAL: show_signal_expression(net, ind); break; case IVL_EX_TERNARY: show_ternary_expression(net, ind); break; case IVL_EX_UNARY: show_unary_expression(net, ind); break; case IVL_EX_UFUNC: show_function_call(net, ind); break; case IVL_EX_REALNUM: { int jdx; union foo { double rv; unsigned char bv[sizeof(double)]; } tmp; tmp.rv = ivl_expr_dvalue(net); fprintf(out, "%*s<realnum=%f (", ind, "", tmp.rv); for (jdx = sizeof(double) ; jdx > 0 ; jdx -= 1) fprintf(out, "%02x", tmp.bv[jdx-1]); fprintf(out, ")"); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); } break; default: fprintf(out, "%*s<expr_type=%u>\n", ind, "", code); break; } }