/* * Given a nexus, look for a signal that has module delay * paths. Return that signal. (There should be no more than 1.) If we * don't find any, then return nil. */ static ivl_signal_t find_modpath(ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex,idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; if (ivl_signal_npath(sig) == 0) continue; return sig; } return 0; }
void clsAnalysis::SignalAliasAnalysis() { vector<clsNexus *>::iterator it_pNexus; vector<clsSignal *>::iterator it_pSignal; int flagFoundModulePort; unsigned int iNumberOfSigPaths; unsigned int iIndex; for (it_pNexus = clsIr::m_pNexuses.begin(); it_pNexus != clsIr::m_pNexuses.end(); ++it_pNexus) { flagFoundModulePort = 0; for (it_pSignal = (*it_pNexus)->m_pSignals.begin(); it_pSignal != (*it_pNexus)->m_pSignals.end(); ++it_pSignal) { if ( (*it_pSignal)->m_pScope->m_IsRoot && (*it_pSignal)->m_PortType != CMODELGEN_PORT_NONE) { _Assert(flagFoundModulePort == 0 && "Frontend Error: More than one port of root modules are mapped to the same nexus."); flagFoundModulePort = 1; (*it_pNexus)->m_pSignal = *it_pSignal; } iNumberOfSigPaths = ivl_signal_npath( (*it_pSignal)->m_ivl_Signal); for (iIndex = 0; iIndex < iNumberOfSigPaths; ++iIndex) { #ifdef CMODELGEN_DEBUG ivl_delaypath_t Obj = ivl_signal_path( (*it_pSignal)->m_ivl_Signal, iIndex); _DebugPrint("Signal %s has a delay path of (%u, %u, %u) that is unsupported.", (*it_pSignal)->m_sName, ivl_path_is_condit(Obj), ivl_path_source_posedge(Obj), ivl_path_source_negedge(Obj) ); #endif } } if (flagFoundModulePort == 0) { (*it_pNexus)->m_pSignal = *( (*it_pNexus)->m_pSignals.begin() ); } } }
/* * Draw a .modpath record. The label is the label to use for this * record. The driver is the label of the net that feeds into the * modpath device. (Note that there is only 1 driver.) The path_sig is * the signal that is the output of this modpath. From that signal we * can find all the modpath source nodes to generate the complete * modpath record. */ static void draw_modpath_record(const char*label, const char*driver, ivl_signal_t path_sig) { unsigned idx; typedef const char*ccharp; ccharp*src_drivers; ccharp*con_drivers; unsigned width = ivl_signal_width(path_sig); src_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); con_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); for (idx = 0 ; idx < ivl_signal_npath(path_sig) ; idx += 1) { ivl_delaypath_t path = ivl_signal_path(path_sig, idx); ivl_nexus_t src = ivl_path_source(path); ivl_nexus_t con = ivl_path_condit(path); src_drivers[idx] = draw_net_input(src); if (con) con_drivers[idx] = draw_net_input(con); else if (ivl_path_is_condit(path)) con_drivers[idx] = ""; else con_drivers[idx] = 0; } fprintf(vvp_out, " .scope S_%p;\n", ivl_path_scope(ivl_signal_path(path_sig,0))); fprintf(vvp_out, "%s .modpath %u %s v%p_0", label, width, driver, path_sig); for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) { ivl_delaypath_t path = ivl_signal_path(path_sig, idx); int ppos = ivl_path_source_posedge(path); int pneg = ivl_path_source_negedge(path); const char*edge = ppos? " +" : pneg ? " -" : ""; ivl_signal_t src_sig; fprintf(vvp_out, ",\n %s%s", src_drivers[idx], edge); fprintf(vvp_out, " (%"PRIu64",%"PRIu64",%"PRIu64 ", %"PRIu64",%"PRIu64",%"PRIu64 ", %"PRIu64",%"PRIu64",%"PRIu64 ", %"PRIu64",%"PRIu64",%"PRIu64, ivl_path_delay(path, IVL_PE_01), ivl_path_delay(path, IVL_PE_10), ivl_path_delay(path, IVL_PE_0z), ivl_path_delay(path, IVL_PE_z1), ivl_path_delay(path, IVL_PE_1z), ivl_path_delay(path, IVL_PE_z0), ivl_path_delay(path, IVL_PE_0x), ivl_path_delay(path, IVL_PE_x1), ivl_path_delay(path, IVL_PE_1x), ivl_path_delay(path, IVL_PE_x0), ivl_path_delay(path, IVL_PE_xz), ivl_path_delay(path, IVL_PE_zx)); if (con_drivers[idx]) { fprintf(vvp_out, " ? %s", con_drivers[idx]); } fprintf(vvp_out, ")"); src_sig = find_path_source_port(path); fprintf(vvp_out, " v%p_0", src_sig); } fprintf(vvp_out, ";\n"); free(src_drivers); free(con_drivers); }
static void show_signal(ivl_signal_t net) { unsigned idx; const char*type = "?"; const char*port = ""; const char*data_type = "?"; const char*sign = ivl_signal_signed(net)? "signed" : "unsigned"; switch (ivl_signal_type(net)) { case IVL_SIT_REG: type = "reg"; break; case IVL_SIT_TRI: type = "tri"; break; case IVL_SIT_TRI0: type = "tri0"; break; case IVL_SIT_TRI1: type = "tri1"; break; case IVL_SIT_UWIRE: type = "uwire"; break; default: break; } switch (ivl_signal_port(net)) { case IVL_SIP_INPUT: port = "input "; break; case IVL_SIP_OUTPUT: port = "output "; break; case IVL_SIP_INOUT: port = "inout "; break; case IVL_SIP_NONE: break; } switch (ivl_signal_data_type(net)) { case IVL_VT_BOOL: data_type = "bool"; break; case IVL_VT_LOGIC: data_type = "logic"; break; case IVL_VT_REAL: data_type = "real"; break; default: data_type = "?data?"; break; } const char*discipline_txt = "NONE"; if (ivl_signal_discipline(net)) { ivl_discipline_t dis = ivl_signal_discipline(net); discipline_txt = ivl_discipline_name(dis); } for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) { ivl_nexus_t nex = ivl_signal_nex(net, idx); fprintf(out, " %s %s %s%s[%d:%d] %s[word=%u, adr=%d] " "<width=%u%s> <discipline=%s> ", type, sign, port, data_type, ivl_signal_msb(net), ivl_signal_lsb(net), ivl_signal_basename(net), idx, ivl_signal_array_base(net)+idx, ivl_signal_width(net), ivl_signal_local(net)? ", local":"", discipline_txt); if (nex == NULL) { fprintf(out, "nexus=<virtual>\n"); continue; } else { fprintf(out, "nexus=%p\n", nex); } show_nexus_details(net, nex); } for (idx = 0 ; idx < ivl_signal_npath(net) ; idx += 1) { ivl_delaypath_t path = ivl_signal_path(net,idx); ivl_nexus_t nex = ivl_path_source(path); ivl_nexus_t con = ivl_path_condit(path); int posedge = ivl_path_source_posedge(path); int negedge = ivl_path_source_negedge(path); fprintf(out, " path %p", nex); if (posedge) fprintf(out, " posedge"); if (negedge) fprintf(out, " negedge"); if (con) fprintf(out, " (if %p)", con); else if (ivl_path_is_condit(path)) fprintf(out, " (ifnone)"); fprintf(out, " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64, ivl_path_delay(path, IVL_PE_01), ivl_path_delay(path, IVL_PE_10), ivl_path_delay(path, IVL_PE_0z), ivl_path_delay(path, IVL_PE_z1), ivl_path_delay(path, IVL_PE_1z), ivl_path_delay(path, IVL_PE_z0), ivl_path_delay(path, IVL_PE_0x), ivl_path_delay(path, IVL_PE_x1), ivl_path_delay(path, IVL_PE_1x), ivl_path_delay(path, IVL_PE_x0), ivl_path_delay(path, IVL_PE_xz), ivl_path_delay(path, IVL_PE_zx)); fprintf(out, " scope=%s\n", ivl_scope_name(ivl_path_scope(path))); } for (idx = 0 ; idx < ivl_signal_attr_cnt(net) ; idx += 1) { ivl_attribute_t atr = ivl_signal_attr_val(net, idx); switch (atr->type) { case IVL_ATT_STR: fprintf(out, " %s = %s\n", atr->key, atr->val.str); break; case IVL_ATT_NUM: fprintf(out, " %s = %ld\n", atr->key, atr->val.num); break; case IVL_ATT_VOID: fprintf(out, " %s\n", atr->key); break; } } }