static void show_lpm_sfunc(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned ports = ivl_lpm_size(net); ivl_variable_type_t data_type = type_of_nexus(ivl_lpm_q(net)); ivl_nexus_t nex; unsigned idx; fprintf(out, " LPM_SFUNC %s: <call=%s, width=%u, type=%s, ports=%u>\n", ivl_lpm_basename(net), ivl_lpm_string(net), width, data_type_string(data_type), ports); nex = ivl_lpm_q(net); if (width != width_of_nexus(nex)) { fprintf(out, " ERROR: Q output nexus width=%u " " does not match part width\n", width_of_nexus(nex)); stub_errors += 1; } fprintf(out, " Q: %p\n", nex); for (idx = 0 ; idx < ports ; idx += 1) { nex = ivl_lpm_data(net, idx); fprintf(out, " D%u: %p <width=%u, type=%s>\n", idx, nex, width_of_nexus(nex), data_type_string(type_of_nexus(nex))); } }
static void show_lpm_cast_real(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); ivl_nexus_t q, a; fprintf(out, " LPM_CAST_REAL %s: <width=%u>\n", ivl_lpm_basename(net), width); q = ivl_lpm_q(net); a = ivl_lpm_data(net,0); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); if (type_of_nexus(q) != IVL_VT_REAL) { fprintf(out, " ERROR: Data type of Q is %s, expecting real\n", data_type_string(type_of_nexus(q))); stub_errors += 1; } if (type_of_nexus(a) == IVL_VT_REAL) { fprintf(out, " ERROR: Data type of A is %s, expecting !real\n", data_type_string(type_of_nexus(a))); stub_errors += 1; } }
static void show_signal_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); ivl_expr_t word = ivl_expr_oper1(net); ivl_signal_t sig = ivl_expr_signal(net); const char*vt_sig = data_type_string(ivl_signal_data_type(sig)); unsigned dimensions = ivl_signal_dimensions(sig); unsigned word_count = ivl_signal_array_count(sig); if (dimensions == 0 && word_count != 1) { fprintf(out, "%*sERROR: Word count = %u for non-array object\n", ind, "", word_count); stub_errors += 1; } fprintf(out, "%*s<signal=%s, words=%u, width=%u, %s type=%s (%s)>\n", ind, "", ivl_expr_name(net), word_count, width, sign, vt, vt_sig); /* If the expression refers to a signal array, then there must also be a word select expression, and if the signal is not an array, there must NOT be a word expression. */ if (dimensions == 0 && word != 0) { fprintf(out, "%*sERROR: Unexpected word expression\n", ind+2, ""); stub_errors += 1; } if (dimensions >= 1 && word == 0) { fprintf(out, "%*sERROR: Missing word expression\n", ind+2, ""); stub_errors += 1; } /* If this is not an array, then the expression with must match the signal width. We have IVL_EX_SELECT expressions for casting signal widths. */ if (dimensions == 0 && ivl_signal_width(sig) != width) { fprintf(out, "%*sERROR: Expression width (%u) doesn't match ivl_signal_width(sig)=%u\n", ind+2, "", width, ivl_signal_width(sig)); stub_errors += 1; } if (word != 0) { fprintf(out, "%*sAddress-0 word address:\n", ind+2, ""); show_expression(word, ind+2); } }
static void show_property_expression(ivl_expr_t net, unsigned ind) { ivl_signal_t sig = ivl_expr_signal(net); const char* pnam = ivl_expr_name(net); char*signed_flag = ivl_expr_signed(net)? "signed" : "unsigned"; if (ivl_expr_value(net) == IVL_VT_REAL) { fprintf(out, "%*s<property base=%s, prop=%s, real>\n", ind, "", ivl_signal_basename(sig), pnam); } else if (ivl_expr_value(net) == IVL_VT_STRING) { fprintf(out, "%*s<property base=%s, prop=%s, string>\n", ind, "", ivl_signal_basename(sig), pnam); } else { fprintf(out, "%*s<property base=%s, prop=%s, width=%u, %s>\n", ind, "", ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag); } if (ivl_signal_data_type(sig) != IVL_VT_CLASS) { fprintf(out, "%*sERROR: Property signal must be IVL_VT_CLASS, got %s.\n", ind+3, "", data_type_string(ivl_signal_data_type(sig))); } }
static const char*vt_type_string(ivl_expr_t net) { return data_type_string(ivl_expr_value(net)); }
void show_switch(ivl_switch_t net) { const char*name = ivl_switch_basename(net); int has_enable = 0; ivl_nexus_t nexa, nexb; ivl_variable_type_t nex_type_a, nex_type_b; switch (ivl_switch_type(net)) { case IVL_SW_TRAN: fprintf(out, " tran %s", name); break; case IVL_SW_RTRAN: fprintf(out, " rtran %s", name); break; case IVL_SW_TRANIF0: fprintf(out, " tranif0 %s", name); has_enable = 1; break; case IVL_SW_RTRANIF0: fprintf(out, " rtranif0 %s", name); has_enable = 1; break; case IVL_SW_TRANIF1: fprintf(out, " tranif1 %s", name); has_enable = 1; break; case IVL_SW_RTRANIF1: fprintf(out, " rtranif1 %s", name); has_enable = 1; break; case IVL_SW_TRAN_VP: fprintf(out, " tran(VP wid=%u, part=%u, off=%u) %s", ivl_switch_width(net), ivl_switch_part(net), ivl_switch_offset(net), name); break; } fprintf(out, " island=%p\n", ivl_switch_island(net)); nexa = ivl_switch_a(net); nex_type_a = nexa? type_of_nexus(nexa) : IVL_VT_NO_TYPE; fprintf(out, " A: %p <type=%s>\n", nexa, data_type_string(nex_type_a)); nexb = ivl_switch_b(net); nex_type_b = nexb? type_of_nexus(nexb) : IVL_VT_NO_TYPE; fprintf(out, " B: %p <type=%s>\n", nexb, data_type_string(nex_type_b)); /* The A/B pins of the switch must be present, and must match. */ if (nex_type_a == IVL_VT_NO_TYPE) { fprintf(out, " A: ERROR: Type missing for pin A\n"); stub_errors += 1; } if (nex_type_b == IVL_VT_NO_TYPE) { fprintf(out, " B: ERROR: Type missing for pin B\n"); stub_errors += 1; } if (nex_type_a != nex_type_b) { fprintf(out, " A/B: ERROR: Type mismatch between pins A and B\n"); stub_errors += 1; } if (ivl_switch_type(net) == IVL_SW_TRAN_VP) { /* The TRAN_VP nodes are special in that the specific width matters for each port and should be exactly right for both. */ if (width_of_nexus(nexa) != ivl_switch_width(net)) { fprintf(out, " A: ERROR: part vector nexus " "width=%u, expecting width=%u\n", width_of_nexus(nexa), ivl_switch_width(net)); stub_errors += 1; } if (width_of_nexus(nexb) != ivl_switch_part(net)) { fprintf(out, " B: ERROR: part select nexus " "width=%u, expecting width=%u\n", width_of_nexus(nexb), ivl_switch_part(net)); stub_errors += 1; } } else { /* All other TRAN nodes will have matching vector widths, but the actual value doesn't matter. */ if (width_of_nexus(nexa) != width_of_nexus(nexb)) { fprintf(out, " A/B: ERROR: Width of ports don't match" ": A=%u, B=%u\n", width_of_nexus(nexa), width_of_nexus(nexb)); stub_errors += 1; } } if (has_enable) { ivl_nexus_t nexe = ivl_switch_enable(net); ivl_variable_type_t nexe_type = type_of_nexus(nexe); fprintf(out, " E: %p <type=%s>\n", nexe, data_type_string(nexe_type)); if (width_of_nexus(nexe) != 1) { fprintf(out, " E: ERROR: Nexus width is %u\n", width_of_nexus(nexe)); } } }