/** * @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); } }
/** * @name Native Check Create * @brief Determine whether a simulation object is native to FLI and create * a handle if it is */ GpiObjHdl* FliImpl::native_check_create(std::string &name, GpiObjHdl *parent) { bool search_rgn = false; bool search_sig = false; bool search_var = false; std::string fq_name = parent->get_fullname(); gpi_objtype_t obj_type = parent->get_type(); if (fq_name == "/") { fq_name += name; search_rgn = true; search_sig = true; search_var = true; } else if (obj_type == GPI_MODULE) { fq_name += "/" + name; search_rgn = true; search_sig = true; search_var = true; } else if (obj_type == GPI_STRUCTURE) { FliValueObjHdl *fli_obj = reinterpret_cast<FliValueObjHdl *>(parent); fq_name += "." + name; search_rgn = false; search_var = fli_obj->is_var(); search_sig = !search_var; } else { LOG_ERROR("FLI: Parent of type %d must be of type GPI_MODULE or GPI_STRUCTURE to have a child.", obj_type); return NULL; } LOG_DEBUG("Looking for child %s from %s", name.c_str(), parent->get_name_str()); std::vector<char> writable(fq_name.begin(), fq_name.end()); writable.push_back('\0'); HANDLE hdl = NULL; PLI_INT32 accType; PLI_INT32 accFullType; if (search_rgn && (hdl = mti_FindRegion(&writable[0])) != NULL) { accType = acc_fetch_type(hdl); accFullType = acc_fetch_fulltype(hdl); LOG_DEBUG("Found region %s -> %p", fq_name.c_str(), hdl); LOG_DEBUG(" Type: %d", accType); LOG_DEBUG(" Full Type: %d", accFullType); } else if (search_sig && (hdl = mti_FindSignal(&writable[0])) != NULL) { accType = acc_fetch_type(hdl); accFullType = acc_fetch_fulltype(hdl); LOG_DEBUG("Found a signal %s -> %p", fq_name.c_str(), hdl); LOG_DEBUG(" Type: %d", accType); LOG_DEBUG(" Full Type: %d", accFullType); } else if (search_var && (hdl = mti_FindVar(&writable[0])) != NULL) { accFullType = accType = mti_GetVarKind(static_cast<mtiVariableIdT>(hdl)); LOG_DEBUG("Found a variable %s -> %p", fq_name.c_str(), hdl); LOG_DEBUG(" Type: %d", accType); LOG_DEBUG(" Full Type: %d", accFullType); } else if (search_rgn){ mtiRegionIdT rgn; /* If not found, check to see if the name of a generate loop and create a pseudo-region */ for (rgn = mti_FirstLowerRegion(parent->get_handle<mtiRegionIdT>()); rgn != NULL; rgn = mti_NextRegion(rgn)) { if (acc_fetch_fulltype(rgn) == accForGenerate) { std::string rgn_name = mti_GetRegionName(static_cast<mtiRegionIdT>(rgn)); if (rgn_name.compare(0,name.length(),name) == 0) { FliObj *fli_obj = dynamic_cast<FliObj *>(parent); return create_gpi_obj_from_handle(parent->get_handle<HANDLE>(), name, fq_name, fli_obj->get_acc_type(), fli_obj->get_acc_full_type()); } } } } if (NULL == hdl) { LOG_DEBUG("Didn't find anything named %s", &writable[0]); return NULL; } /* Generate Loops have inconsistent behavior across fli. A "name" * without an index, i.e. dut.loop vs dut.loop(0), will attempt to map * to index 0, if index 0 exists. If it doesn't then it won't find anything. * * If this unique case is hit, we need to create the Pseudo-region, with the handle * being equivalent to the parent handle. */ if (accFullType == accForGenerate) { FliObj *fli_obj = dynamic_cast<FliObj *>(parent); return create_gpi_obj_from_handle(parent->get_handle<HANDLE>(), name, fq_name, fli_obj->get_acc_type(), fli_obj->get_acc_full_type()); } return create_gpi_obj_from_handle(hdl, name, fq_name, accType, accFullType); }