/** * convert_logic_vector_to_int() - Convert a multibit signal into the * corresponding numerical value * * @vec: std_logic_vector signal to convert * * Return: 32-bit integer equivalent to the input signal */ int convert_logic_vector_to_int(mtiSignalIdT vec) { mtiSignalIdT *elems_list; mtiTypeIdT sig_type; mtiInt32T num_elems; int data; int i; /* Get an handle to the type of the given signal */ sig_type = mti_GetSignalType(vec); /* Get the number of elements that compose the vector */ num_elems = mti_TickLength(sig_type); assert(num_elems <= 25); /* Extract the list of individual elements */ elems_list = mti_GetSignalSubelements(vec, 0); data = 0; for (i = 0; i < num_elems; ++i) { /* If a 1 is received, increment the corresponding bit of the result */ if (mti_GetSignalValue(elems_list[i]) == STD_LOGIC_1) { data += 1 << (num_elems - i - 1); } } mti_VsimFree(elems_list); return data; }
/** * @name Find the root handle * @brief Find the root handle using an optional name * * Get a handle to the root simulator object. This is usually the toplevel. * * If no name is provided, we return the first root instance. * * If name is provided, we check the name against the available objects until * we find a match. If no match is found we return NULL */ GpiObjHdl *FliImpl::get_root_handle(const char *name) { mtiRegionIdT root; char *rgn_name; char *rgn_fullname; std::string root_name; std::string root_fullname; PLI_INT32 accType; PLI_INT32 accFullType; for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) { LOG_DEBUG("Iterating over: %s", mti_GetRegionName(root)); if (name == NULL || !strcmp(name, mti_GetRegionName(root))) break; } if (!root) { goto error; } rgn_name = mti_GetRegionName(root); rgn_fullname = mti_GetRegionFullName(root); root_name = rgn_name; root_fullname = rgn_fullname; mti_VsimFree(rgn_fullname); LOG_DEBUG("Found toplevel: %s, creating handle....", root_name.c_str()); accType = acc_fetch_type(root); accFullType = acc_fetch_fulltype(root); return create_gpi_obj_from_handle(root, root_name, root_fullname, accType, accFullType); error: LOG_ERROR("FLI: Couldn't find root handle %s", name); for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) { if (name == NULL) break; LOG_ERROR("FLI: Toplevel instances: %s != %s...", name, mti_GetRegionName(root)); } return NULL; }
/** * @name Find the root handle * @brief Find the root handle using an optional name * * Get a handle to the root simulator object. This is usually the toplevel. * * If no name is provided, we return the first root instance. * * If name is provided, we check the name against the available objects until * we find a match. If no match is found we return NULL */ GpiObjHdl *FliImpl::get_root_handle(const char *name) { mtiRegionIdT root; GpiObjHdl *rv; char *rgn_name; std::string root_name; for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) { LOG_DEBUG("Iterating over: %s", mti_GetRegionName(root)); if (name == NULL || !strcmp(name, mti_GetRegionName(root))) break; } if (!root) { goto error; } rgn_name = mti_GetRegionFullName(root); root_name = rgn_name; mti_VsimFree(rgn_name); LOG_DEBUG("Found toplevel: %s, creating handle....", root_name.c_str()); rv = new FliRegionObjHdl(this, root); rv->initialise(root_name); LOG_DEBUG("Returning root handle %p", rv); return rv; error: LOG_CRITICAL("FLI: Couldn't find root handle %s", name); for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) { if (name == NULL) break; LOG_CRITICAL("FLI: Toplevel instances: %s != %s...", name, mti_GetRegionName(root)); } return NULL; }
void FliIterator::populate_handle_list(FliIterator::OneToMany childType) { switch (childType) { case FliIterator::OTM_CONSTANTS: { mtiRegionIdT parent = m_parent->get_handle<mtiRegionIdT>(); mtiVariableIdT id; for (id = mti_FirstVarByRegion(parent); id; id = mti_NextVar()) { if (id) { m_vars.push_back(id); } } } break; case FliIterator::OTM_SIGNALS: { mtiRegionIdT parent = m_parent->get_handle<mtiRegionIdT>(); mtiSignalIdT id; for (id = mti_FirstSignal(parent); id; id = mti_NextSignal()) { if (id) { m_sigs.push_back(id); } } } break; case FliIterator::OTM_REGIONS: { mtiRegionIdT parent = m_parent->get_handle<mtiRegionIdT>(); mtiRegionIdT id; for (id = mti_FirstLowerRegion(parent); id; id = mti_NextRegion(id)) { if (id) { m_regs.push_back(id); } } } break; case FliIterator::OTM_SIGNAL_SUB_ELEMENTS: if (m_parent->get_type() == GPI_STRUCTURE) { mtiSignalIdT parent = m_parent->get_handle<mtiSignalIdT>(); mtiTypeIdT type = mti_GetSignalType(parent); mtiSignalIdT *ids = mti_GetSignalSubelements(parent,NULL); LOG_DEBUG("GPI_STRUCTURE: %d fields", mti_TickLength(type)); for (int i = 0; i < mti_TickLength(type); i++) { m_sigs.push_back(ids[i]); } mti_VsimFree(ids); } else if (m_parent->get_indexable()) { FliValueObjHdl *fli_obj = reinterpret_cast<FliValueObjHdl *>(m_parent); int left = m_parent->get_range_left(); int right = m_parent->get_range_right(); if (left > right) { for (int i = left; i >= right; i--) { m_sigs.push_back(static_cast<mtiSignalIdT>(fli_obj->get_sub_hdl(i))); } } else { for (int i = left; i <= right; i++) { m_sigs.push_back(static_cast<mtiSignalIdT>(fli_obj->get_sub_hdl(i))); } } } break; case FliIterator::OTM_VARIABLE_SUB_ELEMENTS: if (m_parent->get_type() == GPI_STRUCTURE) { mtiVariableIdT parent = m_parent->get_handle<mtiVariableIdT>(); mtiTypeIdT type = mti_GetVarType(parent); mtiVariableIdT *ids = mti_GetVarSubelements(parent,NULL); LOG_DEBUG("GPI_STRUCTURE: %d fields", mti_TickLength(type)); for (int i = 0; i < mti_TickLength(type); i++) { m_vars.push_back(ids[i]); } mti_VsimFree(ids); } else if (m_parent->get_indexable()) { FliValueObjHdl *fli_obj = reinterpret_cast<FliValueObjHdl *>(m_parent); int left = m_parent->get_range_left(); int right = m_parent->get_range_right(); if (left > right) { for (int i = left; i >= right; i--) { m_vars.push_back(static_cast<mtiVariableIdT>(fli_obj->get_sub_hdl(i))); } } else { for (int i = left; i <= right; i++) { m_vars.push_back(static_cast<mtiVariableIdT>(fli_obj->get_sub_hdl(i))); } } } break; default: LOG_WARN("Unhandled OneToMany Type (%d)", childType); } }
GpiIterator::Status FliIterator::next_handle(std::string &name, GpiObjHdl **hdl, void **raw_hdl) { HANDLE obj; GpiObjHdl *new_obj; if (!selected) return GpiIterator::END; gpi_objtype_t obj_type = m_parent->get_type(); std::string parent_name = m_parent->get_name(); /* We want the next object in the current mapping. * If the end of mapping is reached then we want to * try next one until a new object is found */ do { obj = NULL; if (m_iterator != m_currentHandles->end()) { obj = *m_iterator++; /* For GPI_GENARRAY, only allow the generate statements through that match the name * of the generate block. */ if (obj_type == GPI_GENARRAY) { if (acc_fetch_fulltype(obj) == accForGenerate) { std::string rgn_name = mti_GetRegionName(static_cast<mtiRegionIdT>(obj)); if (rgn_name.compare(0,parent_name.length(),parent_name) != 0) { obj = NULL; continue; } } else { obj = NULL; continue; } } break; } else { LOG_DEBUG("No more valid handles in the current OneToMany=%d iterator", *one2many); } if (++one2many >= selected->end()) { obj = NULL; break; } /* GPI_GENARRAY are pseudo-regions and all that should be searched for are the sub-regions */ if (obj_type == GPI_GENARRAY && *one2many != FliIterator::OTM_REGIONS) { LOG_DEBUG("fli_iterator OneToMany=%d skipped for GPI_GENARRAY type", *one2many); continue; } populate_handle_list(*one2many); switch (*one2many) { case FliIterator::OTM_CONSTANTS: case FliIterator::OTM_VARIABLE_SUB_ELEMENTS: m_currentHandles = &m_vars; m_iterator = m_vars.begin(); break; case FliIterator::OTM_SIGNALS: case FliIterator::OTM_SIGNAL_SUB_ELEMENTS: m_currentHandles = &m_sigs; m_iterator = m_sigs.begin(); break; case FliIterator::OTM_REGIONS: m_currentHandles = &m_regs; m_iterator = m_regs.begin(); break; default: LOG_WARN("Unhandled OneToMany Type (%d)", *one2many); } } while (!obj); if (NULL == obj) { LOG_DEBUG("No more children, all relationships tested"); return GpiIterator::END; } char *c_name; PLI_INT32 accType = 0; PLI_INT32 accFullType = 0; switch (*one2many) { case FliIterator::OTM_CONSTANTS: case FliIterator::OTM_VARIABLE_SUB_ELEMENTS: c_name = mti_GetVarName(static_cast<mtiVariableIdT>(obj)); accFullType = accType = mti_GetVarKind(static_cast<mtiVariableIdT>(obj)); break; case FliIterator::OTM_SIGNALS: c_name = mti_GetSignalName(static_cast<mtiSignalIdT>(obj)); accType = acc_fetch_type(obj); accFullType = acc_fetch_fulltype(obj); break; case FliIterator::OTM_SIGNAL_SUB_ELEMENTS: c_name = mti_GetSignalNameIndirect(static_cast<mtiSignalIdT>(obj), NULL, 0); accType = acc_fetch_type(obj); accFullType = acc_fetch_fulltype(obj); break; case FliIterator::OTM_REGIONS: c_name = mti_GetRegionName(static_cast<mtiRegionIdT>(obj)); accType = acc_fetch_type(obj); accFullType = acc_fetch_fulltype(obj); break; default: LOG_WARN("Unhandled OneToMany Type (%d)", *one2many); } if (!c_name) { if (!VS_TYPE_IS_VHDL(accFullType)) { *raw_hdl = (void *)obj; return GpiIterator::NOT_NATIVE_NO_NAME; } return GpiIterator::NATIVE_NO_NAME; } /* * If the parent is not a generate loop, then watch for generate handles and create * the pseudo-region. * * NOTE: Taking advantage of the "caching" to only create one pseudo-region object. * Otherwise a list would be required and checked while iterating */ if (*one2many == FliIterator::OTM_REGIONS && obj_type != GPI_GENARRAY && accFullType == accForGenerate) { std::string idx_str = c_name; std::size_t found = idx_str.find_last_of("("); if (found != std::string::npos && found != 0) { FliObj *fli_obj = dynamic_cast<FliObj *>(m_parent); name = idx_str.substr(0,found); obj = m_parent->get_handle<HANDLE>(); accType = fli_obj->get_acc_type(); accFullType = fli_obj->get_acc_full_type(); } else { LOG_WARN("Unhandled Generate Loop Format - %s", name.c_str()); name = c_name; } } else { name = c_name; } if (*one2many == FliIterator::OTM_SIGNAL_SUB_ELEMENTS) { mti_VsimFree(c_name); } std::string fq_name = m_parent->get_fullname(); if (fq_name == "/") { fq_name += name; } else if (*one2many == FliIterator::OTM_SIGNAL_SUB_ELEMENTS || *one2many == FliIterator::OTM_VARIABLE_SUB_ELEMENTS || obj_type == GPI_GENARRAY) { std::size_t found; if (obj_type == GPI_STRUCTURE) { found = name.find_last_of("."); } else { found = name.find_last_of("("); } if (found != std::string::npos) { fq_name += name.substr(found); if (obj_type != GPI_GENARRAY) { name = name.substr(found+1); } } else { LOG_WARN("Unhandled Sub-Element Format - %s", name.c_str()); fq_name += "/" + name; } } else { fq_name += "/" + name; } FliImpl *fli_impl = reinterpret_cast<FliImpl *>(m_impl); new_obj = fli_impl->create_gpi_obj_from_handle(obj, name, fq_name, accType, accFullType); if (new_obj) { *hdl = new_obj; return GpiIterator::NATIVE; } else { return GpiIterator::NOT_NATIVE; } }