void CPersCtl::PersCtl() { if (PR_htValid) { switch (PR_htInst) { case CTL_INST1: { BUSY_RETRY(SendCallBusy_inst1()); SendCall_inst1(CTL_INST2); break; } case CTL_INST2: { BUSY_RETRY(SendCallBusy_Inst22()); SendCall_Inst22(CTL_RTN); break; } case CTL_RTN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(); break; } default: assert(0); } } }
/** * @brief queries the database for a set of records to be inserted into a given tree * * @param searchTree pointer to a tree where insertions will be performed; can be NULL * @param query set of ports that a database record must match to be inserted into the tree * * The query method browses through the database, extracts all the descriptors matching * the given query parameter and inserts them into the given learning tree. * Note that this is an append procedure, the given tree needs not to be empty. * A "descriptor matching the query" is a descriptor whose port id is in the query map. * If the given tree is empty (NULL) a new tree is created and returned. * * @return the tree root * * @internal */ IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries) { HashIterator iterator; UINT32 entryCount = 0; /* browse database */ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); while (IS_ITERATOR_VALID(&iterator)) { MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ", mac2string(descriptor->macAddress), descriptor->portID); if ((descriptor->type & recordFilter) != 0 && IS_PORT_INCLUDED(descriptor->portID, query)) { MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor); IX_ETH_DB_UPDATE_TRACE("match\n"); if (descriptorClone != NULL) { /* add descriptor to tree */ searchTree = ixEthDBTreeInsert(searchTree, descriptorClone); entryCount++; } } else { IX_ETH_DB_UPDATE_TRACE("no match\n"); } if (entryCount < maxEntries) { /* advance to the next record */ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); } else { /* the NPE won't accept more entries so we can stop now */ ixEthDBReleaseHashIterator(&iterator); IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n"); break; } } IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount); return ixEthDBTreeRebalance(searchTree); }
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) { IxEthDBPortMap triggerPorts; HashIterator iterator; if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS) { return IX_ETH_DB_INVALID_PORT; } /* check if the user passes some extra bits */ if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES) { return IX_ETH_DB_INVALID_ARG; } SET_EMPTY_DEPENDENCY_MAP(triggerPorts); /* browse database and age entries */ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); while (IS_ITERATOR_VALID(&iterator)) { MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS)) && ((descriptor->type & recordType) != 0)) { /* add to trigger if automatic updates are required */ if (ixEthDBPortUpdateRequired[descriptor->type]) { /* add port to the set of update trigger ports */ JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID); } /* delete entry */ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); } else { /* move to the next record */ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); } } /* update ports which lost records */ ixEthDBUpdatePortLearningTrees(triggerPorts); return IX_ETH_DB_SUCCESS; }
void CPersVadd::PersVadd() { if (PR_htValid) { switch (PR_htInst) { case VADD_ENTER: { BUSY_RETRY(ReadStreamBusy_A()); BUSY_RETRY(ReadStreamBusy_B()); BUSY_RETRY(WriteStreamBusy_C()); S_sum = 0; if (!PR_vecLen) { HtContinue(VADD_RETURN); break; } MemAddr_t addrA = SR_op1Addr + PR_offset * sizeof(uint64_t); MemAddr_t addrB = SR_op2Addr + PR_offset * sizeof(uint64_t); MemAddr_t addrC = SR_resAddr + PR_offset * sizeof(uint64_t); ReadStreamOpen_A(addrA, PR_vecLen); ReadStreamOpen_B(addrB, PR_vecLen); WriteStreamOpen_C(addrC, PR_vecLen); WriteStreamPause_C(VADD_RETURN); break; } case VADD_RETURN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(S_sum); } break; default: assert(0); } } if (ReadStreamReady_A() && ReadStreamReady_B() && WriteStreamReady_C()) { uint64_t a = ReadStream_A(); uint64_t b = ReadStream_B(); uint64_t c = a + b; S_sum += c; WriteStream_C(c); } }
void CPersRelu::PersRelu() { if (PR_htValid) { switch (PR_htInst) { case RELU_LD1: { BUSY_RETRY(ReadMemBusy()); // Memory read request //printf("calculate address idx: %u", P_vecIdx); fflush(stdout); MemAddr_t memRdAddr = SR_op1Addr + (P_vecIdx << 3); //printf("About to read "); ReadMem_op1(memRdAddr); ReadMemPause(RELU_ST); } break; case RELU_ST: { BUSY_RETRY(WriteMemBusy()); uint64_t basemask = 0x000000000000FFFF; P_result = 0; for(int i = 0; i < 64; i+=16){ if((int16_t)(PR_op1 >> i) > 0){ P_result = P_result | (PR_op1 & (basemask << i)); }else{ //Rectify the i'th element to 0 //P_result = 0; } } //printf("ST op1: %ld => %ld\n",PR_op1, P_result); // Memory write request MemAddr_t memWrAddr = SR_resAddr + (P_vecIdx << 3); WriteMem(memWrAddr, P_result); WriteMemPause(RELU_RTN); } break; case RELU_RTN: { BUSY_RETRY(SendReturnBusy_relu()); SendReturn_relu(); } break; default: assert(0); } }
void CPersOver::PersOver() { if (PR_htValid) { switch (PR_htInstr) { case OVER_RD: { BUSY_RETRY(ReadMemBusy()); ReadMem_data(P_addr); ReadMemPause(OVER_WR); } break; case OVER_WR: { BUSY_RETRY(WriteMemBusy()); WriteMem(P_addr, ~PR_data); WriteMemPause(OVER_RSM); } break; case OVER_RSM: { S_bResume = true; HtPause(OVER_RTN); } break; case OVER_RTN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(); } break; default: assert(0); } } if (SR_bResume) { S_bResume = false; HtResume(0); } }
void CPersCtl::PersCtl() { if (PR_htValid) { switch (PR_htInst) { case CTL_ENTRY: { S_sum = 0; P_result = 0; HtContinue(CTL_ADD); } break; case CTL_ADD: { BUSY_RETRY(SendCallBusy_add()); if (P_vecIdx < SR_vecLen) { SendCallFork_add(CTL_JOIN, P_vecIdx); HtContinue(CTL_ADD); P_vecIdx += P_vecStride; } else { RecvReturnPause_add(CTL_RTN); } } break; case CTL_JOIN: { S_sum += P_result; RecvReturnJoin_add(); } break; case CTL_RTN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(S_sum); } break; default: assert(0); } } }
void CPersCtl::PersCtl() { if (PR_htValid) { switch (PR_htInst) { case CTL_ENTRY: { printf("Task: %d\n",PR_task); if(PR_task == CONV_FORWARD ){ BUSY_RETRY(SendCallBusy_conv_fwd()); SendCall_conv_fwd(CTL_RTN, PR_rank, PR_rankStride); } else if(PR_task == CONV_BACKWARD_DATA ){ BUSY_RETRY(SendCallBusy_load_filters()); SendCall_load_filters(CTL_RTN, PR_rank, PR_rankStride, PR_task); } else if(PR_task == CONV_BACKWARD_BIAS && PR_rank == 0 ){ BUSY_RETRY(SendCallBusy_conv_back_bias()); SendCall_conv_back_bias(CTL_RTN); } else if(PR_task == CONV_BACKWARD_FILTER ){ BUSY_RETRY(SendCallBusy_load_filters()); SendCall_load_filters(CTL_RTN, PR_rank, PR_rankStride, PR_task); } else{ HtContinue(CTL_RTN); } } break; case CTL_RTN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(); } break; default: assert(0); } } }
void CPersGupsCore::PersGupsCore() { MemAddr_t rndIdx = SR_base + ((PR_ran & (SR_tblSize - 1)) << 3); // QW index if (PR_htValid) { switch (PR_htInst) { case PGC_ENTRY: { P_ran = (uint64_t)(PR_ran << 1) ^ ((int64_t) PR_ran < 0 ? POLY : 0); HtContinue(PGC_READ); break; } case PGC_READ: { BUSY_RETRY(ReadMemBusy()); ReadMem_intData(rndIdx); ReadMemPause(PGC_WRITE); break; } case PGC_WRITE: { BUSY_RETRY(WriteMemBusy()); WriteMem(rndIdx, PR_intData^PR_ran, /*orderChk=*/ false); P_ran = (uint64_t)(PR_ran << 1) ^ ((int64_t) PR_ran < 0 ? POLY : 0); P_vecIdx += 1; if (P_vecIdx < SR_vecLen) { HtContinue(PGC_READ); } else HtContinue(PGC_RTN); break; } case PGC_RTN: { BUSY_RETRY(SendReturnBusy_GupsCore()); SendReturn_GupsCore(); break; } default: assert(0); } } }
void CPersRepl::PersRepl() { if (PR_htValid) { switch (PR_htInstr) { case REPL_RTN: { BUSY_RETRY(SendReturnBusy_repl()); printf("InstInstID %d, InstReplID %d, ReplReplID %d\n", PR_instInstId, PR_instReplId, SR_replId); SendReturn_repl(); } break; default: assert(0); } } }
void CPersInst::PersInst() { if (PR_htValid) { switch (PR_htInst) { case INST_ENTRY: { HtContinue(INST_RTN); break; } case INST_RTN: { BUSY_RETRY(SendReturnBusy_inst()); SendReturn_inst(); } break; default: assert(0); } } }
/** * @brief search a record in the Ethernet datbase * * @param macAddress MAC address to perform the search on * @param portID port ID to perform the search on * @param typeFilter type of records to consider for matching * * @warning if searching is successful an implicit write lock * to the search result is granted, therefore unlock the * entry using @ref ixEthDBReleaseHashNode() as soon as possible. * * @see ixEthDBReleaseHashNode() * * @return the search result, or NULL if a record with the given * MAC address/port ID combination was not found * * @internal */ IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter) { HashNode *searchResult = NULL; MacDescriptor reference; if (macAddress == NULL) { return NULL; } /* fill search fields */ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); reference.portID = portID; /* set acceptable record types */ reference.type = typeFilter; BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult)); return searchResult; }
/** * @brief search a record in the Ethernet datbase * * @param macAddress MAC address to perform the search on * @param vlanID VLAN ID to perform the search on * @param typeFilter type of records to consider for matching * * @warning if searching is successful an implicit write lock * to the search result is granted, therefore unlock the * entry using @ref ixEthDBReleaseHashNode() as soon as possible. * * @see ixEthDBReleaseHashNode() * * @return the search result, or NULL if a record with the given * MAC address/VLAN ID combination was not found * * @internal */ IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter) { HashNode *searchResult = NULL; MacDescriptor reference; if (macAddress == NULL) { return NULL; } /* fill search fields */ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); reference.recordData.filteringVlanData.ieee802_1qTag = IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID); /* set acceptable record types */ reference.type = typeFilter; BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult)); return searchResult; }
/** * @brief search a record in the Ethernet datbase * * @param macAddress MAC address to perform the search on * @param typeFilter type of records to consider for matching * * @warning if searching is successful an implicit write lock * to the search result is granted, therefore unlock the * entry using @ref ixEthDBReleaseHashNode() as soon as possible. * * @see ixEthDBReleaseHashNode() * * @return the search result, or NULL if a record with the given * MAC address was not found * * @internal */ IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter) { HashNode *searchResult = NULL; MacDescriptor reference; TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; if (macAddress == NULL) { return NULL; } /* fill search fields */ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); /* set acceptable record types */ reference.type = typeFilter; BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult)); return searchResult; }
void CPersVadd::PersVadd() { if (PR_htValid) { switch (PR_htInst) { case VADD_RESET: if (SR_msgDelay < 500 || SendHostMsgBusy()) { S_msgDelay += 1; HtRetry(); break; } SendHostMsg(VADD_TYPE_SIZE, (XDIM_LEN << 8) | TYPE_SIZE); HtTerminate(); break; case VADD_ENTER: S_yIdx[PR_htId] = 0; S_yDimLen[PR_htId] = PR_yDimLen; S_xIdx[PR_htId] = 0; S_xDimLen[PR_htId] = PR_xDimLen; S_sum[PR_htId] = 0; P_addrA = SR_addrA + PR_yAddrOff; P_addrB = SR_addrB + PR_yAddrOff; P_addrC = SR_addrC + PR_yAddrOff; HtContinue(VADD_OPEN); break; case VADD_OPEN: // Open read stream A, once for each xDim to be processed if (PR_yOpenAIdx < PR_yDimLen && !ReadStreamBusy_A(PR_htId)) { ht_uint32 remLen = (ht_uint32)((PR_yDimLen - PR_yOpenAIdx) * PR_xDimLen); ReadStreamOpen_A(PR_htId, PR_addrA, remLen > 0x3f ? (ht_uint6)0x3f : (ht_uint6)remLen, P_yOpenAIdx); P_addrA+= PR_xDimLen * TYPE_SIZE; P_yOpenAIdx += 1; } // Open read stream B, once for each xDim to be processed if (PR_yOpenBIdx < PR_yDimLen && !ReadStreamBusy_B(PR_htId)) { ReadStreamOpen_B(PR_htId, PR_addrB, PR_xDimLen); P_addrB += PR_xDimLen * TYPE_SIZE; P_yOpenBIdx += 1; } // Open write stream, once for each xDim to be processed if (PR_yOpenCIdx < SR_yDimLen[PR_htId] && !WriteStreamBusy_C(PR_htId)) { #if VADD_STRM_RSP_GRP_HTID == 0 && VADD_HTID_W == 0 && VADD_RSP_GRP_W > 0 WriteStreamOpen_C(PR_htId, 1u, PR_addrC); #elif VADD_STRM_RSP_GRP_HTID || VADD_HTID_W == 0 WriteStreamOpen_C(PR_htId, PR_addrC); #else WriteStreamOpen_C(PR_htId, PR_htId ^ 1, PR_addrC); #endif P_addrC += PR_xDimLen * TYPE_SIZE; P_yOpenCIdx += 1; } if (PR_yOpenAIdx == PR_yDimLen && PR_yOpenBIdx == PR_yDimLen && PR_yOpenCIdx == PR_yDimLen) #if VADD_STRM_RSP_GRP_HTID == 0 && VADD_HTID_W == 0 && VADD_RSP_GRP_W > 0 WriteStreamPause_C(1, VADD_RETURN); #elif VADD_STRM_RSP_GRP_HTID || VADD_HTID_W == 0 WriteStreamPause_C(VADD_RETURN); #else WriteStreamPause_C(PR_htId ^ 1, VADD_RETURN); #endif else HtContinue(VADD_OPEN); break; case VADD_RETURN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(S_sum[PR_htId]); } break; default: assert(0); } }
/** * @brief adds a new entry to the Ethernet database * * @param newRecordTemplate address of the record template to use * @param updateTrigger port map containing the update triggers * resulting from this update operation * * Creates a new database entry, populates it with the data * copied from the given template and adds the record to the * database hash table. * It also checks whether the new record type is registered to trigger * automatic updates; if it is, the update trigger will contain the * port on which the record insertion was performed, as well as the * old port in case the addition was a record migration (from one port * to the other). The caller can use the updateTrigger to trigger * automatic updates on the ports changed as a result of this addition. * * @retval IX_ETH_DB_SUCCESS addition successful * @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool * @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking * * @internal */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger) { IxEthDBStatus result; MacDescriptor *newDescriptor; IxEthDBPortId originalPortID; HashNode *node = NULL; BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node)); TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; if (node == NULL) { /* not found, create a new one */ newDescriptor = ixEthDBAllocMacDescriptor(); if (newDescriptor == NULL) { return IX_ETH_DB_NOMEM; /* no memory */ } /* old port does not exist, avoid unnecessary updates */ originalPortID = newRecordTemplate->portID; } else { /* a node with the same key exists, will update node */ newDescriptor = (MacDescriptor *) node->data; /* save original port id */ originalPortID = newDescriptor->portID; } /* copy/update fields into new record */ memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr)); memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData)); newDescriptor->type = newRecordTemplate->type; newDescriptor->portID = newRecordTemplate->portID; newDescriptor->user = newRecordTemplate->user; if (node == NULL) { /* new record, insert into hashtable */ BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result); if (result != IX_ETH_DB_SUCCESS) { ixEthDBFreeMacDescriptor(newDescriptor); return result; /* insertion failed */ } } if (node != NULL) { /* release access */ ixEthDBReleaseHashNode(node); } /* trigger add/remove update if required by type */ if (updateTrigger != NULL && ixEthDBPortUpdateRequired[newRecordTemplate->type]) { /* add new port to update list */ JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID); /* check if record has moved, we'll need to update the old port as well */ if (originalPortID != newDescriptor->portID) { JOIN_PORT_TO_MAP(updateTrigger, originalPortID); } } return IX_ETH_DB_SUCCESS; }
/** * @brief disables a port * * @param portID ID of the port to disable * * This function is fully documented in the * main header file, IxEthDB.h * * @return IX_ETH_DB_SUCCESS if disabling was * successful or an appropriate error message * otherwise */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) { HashIterator iterator; IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */ BOOL result; PortInfo *portInfo; IxEthDBFeature learningEnabled; IxEthDBPriorityTable classZeroTable; IX_ETH_DB_CHECK_PORT_EXISTS(portID); IX_ETH_DB_CHECK_SINGLE_NPE(portID); portInfo = &ixEthDBPortInfo[portID]; if (!portInfo->enabled) { /* redundant */ return IX_ETH_DB_SUCCESS; } if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) { /* save filtering state */ ixEthDBPortState[portID].firewallMode = portInfo->firewallMode; ixEthDBPortState[portID].frameFilter = portInfo->frameFilter; ixEthDBPortState[portID].taggingAction = portInfo->taggingAction; ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked; ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled; ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize; ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize; memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet)); memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet)); memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable)); ixEthDBPortState[portID].saved = TRUE; /* now turn off all EthDB filtering features on the port */ /* VLAN & QoS */ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) { ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, FALSE); ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH); memset(classZeroTable, 0, sizeof (classZeroTable)); ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable); } /* STP */ if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) { ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, FALSE); } /* Firewall */ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) { ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST); ixEthDBFirewallTableDownload((IxEthDBPortId) portID); ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, FALSE); } /* Frame size filter */ ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE); /* WiFi */ if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) { ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID); } /* save and disable the learning feature bit */ learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING; portInfo->featureStatus &= ~IX_ETH_DB_LEARNING; } else { /* save the learning feature bit */ learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING; } SET_EMPTY_DEPENDENCY_MAP(triggerPorts); ixEthDBUpdateLock(); /* wipe out current entries for this port */ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); while (IS_ITERATOR_VALID(&iterator)) { MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; /* check if the port match. If so, remove the entry */ if (descriptor->portID == portID && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) && !descriptor->recordData.filteringData.staticEntry) { /* delete entry */ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); /* add port to the set of update trigger ports */ JOIN_PORT_TO_MAP(triggerPorts, portID); } else { /* move to the next record */ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); } } if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) { if (portInfo->updateMethod.searchTree != NULL) { ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree); portInfo->updateMethod.searchTree = NULL; } ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD); } /* mark as disabled */ portInfo->enabled = FALSE; /* disable updates unless the user has specifically altered the default behavior */ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) { if (!portInfo->updateMethod.userControlled) { portInfo->updateMethod.updateEnabled = FALSE; } /* make sure we re-initialize the NPE learning tree when the port is re-enabled */ portInfo->updateMethod.treeInitialized = FALSE; } ixEthDBUpdateUnlock(); /* restore learning feature bit */ portInfo->featureStatus |= learningEnabled; /* if we've removed any records or lost any events make sure to force an update */ IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts); if (!result) { ixEthDBUpdatePortLearningTrees(triggerPorts); } return IX_ETH_DB_SUCCESS; }
void CPersVwrk::PersVwrk() { VertImages_t p1_vImgIdx = PR1_imageIdx & VERT_IMAGES_MASK; // staging for memAddr to allow Vivado to infer a DSP for the multiply T1_blkCol = (McuCols_t)((P1_outMcuColStart << (S_jobInfo[p1_vImgIdx].m_vcp[P1_compIdx].m_blkColsPerMcu == 2 ? 1 : 0)) | P1_preMcuBlkCol); T1_blkRow = (McuRows_t)((P1_preMcuRow << (S_jobInfo[p1_vImgIdx].m_vcp[P1_compIdx].m_blkRowsPerMcu == 2 ? 1 : 0)) | P1_preMcuBlkRow); T1_inCompBlkCols = S_jobInfo[p1_vImgIdx].m_vcp[P1_compIdx].m_inCompBlkCols; VertImages_t p2_vImgIdx = PR2_imageIdx & VERT_IMAGES_MASK; T2_jobInfo = S_jobInfo[p2_vImgIdx]; // use signed math since the DSP adder is signed T2_memAddrSum1 = (ht_int48)(T2_jobInfo.m_vcp[P2_compIdx].m_pInCompBuf + (T2_blkCol << MEM_LINE_SIZE_W)); T2_memAddrSum2 = (ht_int48)(T2_blkRow * (T2_inCompBlkCols << MEM_LINE_SIZE_W)); T3_memAddr = T3_memAddrSum1 + T3_memAddrSum2; // will not use DSP adder because no output reg before use? T2_loopVcp = T2_jobInfo.m_vcp[P2_compIdx]; T1_bReadMem = false; // fix timing for memory read instructions T2_preMcuRow_lt_inMcuRowEnd = PR2_preMcuRow < PR2_inMcuRowEnd; T2_pendMcuRow_lt_inMcuRowEnd = PR2_pendMcuRow < PR2_inMcuRowEnd; T2_mcuBufInUseCnt_lt_VERT_PREFETCH_MCUS = S_mcuBufInUseCnt[PR2_htId] < VERT_PREFETCH_MCUS_FULL; T2_preMcuBlkColP1_eq_blkColsPerMcu = PR2_preMcuBlkCol+1 == S_jobInfo[p2_vImgIdx].m_vcp[PR2_compIdx].m_blkColsPerMcu; if (PR3_htValid) { switch (PR3_htInst) { case VWRK_ENTRY: { if (!PR3_bHtIdPushed) { S_readOrderQue.push(PR3_htId); S_pendOrderQue.push(PR3_htId); P3_bHtIdPushed = true; } VertState vrs; vrs.m_bUpScale = T3_jobInfo.m_maxBlkRowsPerMcu == 2 && T3_loopVcp.m_blkRowsPerMcu == 1; ImageRows_t outRow = (ImageRows_t)(P3_outMcuRowStart * DCTSIZE << (T3_loopVcp.m_blkRowsPerMcu == 2 ? 1 : 0)); ImageRows_t outRowEnd = (ImageRows_t)(outRow + ((4 * DCTSIZE) << (T3_loopVcp.m_blkRowsPerMcu == 2 ? 1 : 0))); if (outRowEnd > T3_loopVcp.m_outCompRows) outRowEnd = T3_loopVcp.m_outCompRows; ht_uint1 mcuBlkRowFirst; if (vrs.m_bUpScale) { PntWghtCpInt_t filterWidth = (PntWghtCpInt_t)((T3_jobInfo.m_filterWidth >> 1) + 1); PntWghtCpInt_t filterOffset = (PntWghtCpInt_t)(18 - (filterWidth << 1)); PntWghtCpInt_t negFilterOffset = -filterOffset; bool bInRowSel = P3_pntWghtStart < negFilterOffset; vrs.m_inRow = bInRowSel ? 0 : ((P3_pntWghtStart + filterOffset) >> 1); vrs.m_rowDataPos = bInRowSel ? (PntWghtCpInt_t)-18 : (PntWghtCpInt_t)((P3_pntWghtStart & ~1) - (filterWidth << 1)); vrs.m_inRowOutDiff = 0; vrs.m_inRowIgnore = 0; mcuBlkRowFirst = 0; } else { PntWghtCpInt_t filterWidth = (PntWghtCpInt_t)T3_jobInfo.m_filterWidth; PntWghtCpInt_t filterOffset = (PntWghtCpInt_t)(17 - filterWidth); PntWghtCpInt_t negFilterOffset = -filterOffset; bool bInRowSel = P3_pntWghtStart < negFilterOffset; vrs.m_inRow = bInRowSel ? (ImageRows_t)0 : (ImageRows_t)(P3_pntWghtStart + filterOffset); vrs.m_rowDataPos = bInRowSel ? -17 : (P3_pntWghtStart - filterWidth); vrs.m_inRowOutDiff = 0; vrs.m_inRowIgnore = 0; mcuBlkRowFirst = (ht_uint1)((vrs.m_inRow >> 3) & (T3_loopVcp.m_blkRowsPerMcu-1)); } P3_preMcuBlkRowFirst[P3_compIdx] = mcuBlkRowFirst; P3_wrkMcuBlkRowFirst[P3_compIdx] = mcuBlkRowFirst; // setup for VWRK_LOOP P3_preMcuRow = (McuRows_t)(P3_inImageRowStart >> ((T3_jobInfo.m_maxBlkRowsPerMcu == 2 ? 1 : 0) + DCTSIZE_W)); P3_pendMcuRow = P3_preMcuRow; P3_inMcuRowEnd = (McuRows_t)((P3_inImageRowEnd + (T3_jobInfo.m_maxBlkRowsPerMcu == 2 ? 2 : 1) * DCTSIZE - 1) >> ((T3_jobInfo.m_maxBlkRowsPerMcu == 2 ? 1 : 0) + DCTSIZE_W)); P3_readBufIdx = 0; P3_pendBufIdx = 0; S_mcuBufInUseCnt[PR3_htId] = 0; P3_preMcuBlkRow = P3_preMcuBlkRowFirst[0]; P3_preMcuBlkCol = 0; P3_rdReqGrpId = PR3_htId << VERT_PREFETCH_MCUS_W; P3_rdPollGrpId = PR3_htId << VERT_PREFETCH_MCUS_W; P3_mcuReadPendCnt = 0; P3_bFirstWorkMcu = true; P3_mcuBlkCol += 1; if (P3_mcuBlkCol == T3_loopVcp.m_blkColsPerMcu) { P3_mcuBlkCol = 0; P3_compIdx += 1; if (P3_compIdx == T3_jobInfo.m_compCnt) { P3_compIdx = 0; HtContinue(VWRK_PREREAD_WAIT); break; } } HtContinue(VWRK_ENTRY); } break; case VWRK_PREREAD_WAIT: { // wait for other threads to complete reads if (S_readBusy != 0 || S_readOrderQue.front() != PR3_htId) { S_readPaused[PR3_htId] = true; HtPause(VWRK_PREREAD_WAIT); } else { S_readPaused[PR3_htId] = false; S_readBusy = true; S_readHtId = PR3_htId; S_readOrderQue.pop(); HtContinue(VWRK_PREREAD); } } break; case VWRK_PREREAD: { T1_bMcuBufFull = S_mcuBufInUseCnt[PR3_htId] == VERT_PREFETCH_MCUS_FULL; T1_bMcuRowEnd = P3_preMcuRow == P3_inMcuRowEnd; T1_bReadMemBusy = ReadMemBusy(); // issue reads until all needed reads are issued or buffer space is exceeded BUSY_RETRY(ReadMemBusy()); #ifndef _HTV // these next statements were moved to the P1 stage to give the multiple additional registers stages McuRows_t blkRow = (McuRows_t)(P3_preMcuRow * (T3_loopVcp.m_blkRowsPerMcu == 2 ? 2 : 1) | P3_preMcuBlkRow); McuCols_t blkCol = (McuCols_t)(P3_outMcuColStart * (T3_loopVcp.m_blkColsPerMcu == 2 ? 2 : 1) | P3_preMcuBlkCol); ht_uint26 pos = (ht_uint26)((blkRow * T3_loopVcp.m_inCompBlkCols + blkCol) * MEM_LINE_SIZE); ht_uint48 memAddr = T3_loopVcp.m_pInCompBuf + pos; assert(memAddr == T3_memAddr); #endif if (SR_mcuBufInUseCnt[PR3_htId] < VERT_PREFETCH_MCUS_FULL && PR3_preMcuRow < PR3_inMcuRowEnd) { sc_uint<4+VERT_PREFETCH_MCUS_W> bufIdx = (P3_compIdx << (VERT_PREFETCH_MCUS_W+2)) | (P3_preMcuBlkRow << (VERT_PREFETCH_MCUS_W+1)) | (P3_preMcuBlkCol << VERT_PREFETCH_MCUS_W) | P3_readBufIdx; ReadMem_rowPref(T3_memAddr, bufIdx, PR3_htId, 0, 8); T1_bReadMem = true; if (TR3_preMcuBlkColP1_eq_blkColsPerMcu) { P3_preMcuBlkCol = 0; if (P3_preMcuBlkRow+1 == T3_loopVcp.m_blkRowsPerMcu) { if (P3_compIdx+1 == T3_jobInfo.m_compCnt) { P3_compIdx = 0; P3_preMcuRow += 1; P3_rdReqGrpId = (PR3_htId << VERT_PREFETCH_MCUS_W) | ((P3_rdReqGrpId+1) & (VERT_PREFETCH_MCUS-1)); P3_preMcuBlkRowFirst[P3_compIdx] = 0; P3_readBufIdx += 1; P3_mcuReadPendCnt += 1; S_mcuBufInUseCnt[PR3_htId] += 1; } else P3_compIdx += 1; P3_preMcuBlkRow = P3_preMcuBlkRowFirst[P3_compIdx]; } else P3_preMcuBlkRow += 1; } else P3_preMcuBlkCol += 1; HtContinue(VWRK_PREREAD); } else { if (PR3_preMcuRow == PR3_inMcuRowEnd) { // free read interface for next thread S_readBusy = false; } HtContinue(VWRK_VRS_WAIT); } } break; case VWRK_VRS_WAIT: { // wait until a vrs structure is available, we double buffer BUSY_RETRY(S_pendOrderQue.front() != PR3_htId || S_vrsAvl == 0); P3_vrsIdx = (S_vrsAvl & 1) ? 0 : 1; S_vrsAvl &= (S_vrsAvl & 1) ? 2u : 1u; HtContinue(VWRK_VRS_INIT); } break; case VWRK_VRS_INIT: { // init vrs structure VertState vrs; vrs.m_bUpScale = T3_jobInfo.m_maxBlkRowsPerMcu == 2 && T3_loopVcp.m_blkRowsPerMcu == 1; ImageRows_t outRow = (ImageRows_t)(P3_outMcuRowStart * DCTSIZE << (T3_loopVcp.m_blkRowsPerMcu == 2 ? 1 : 0)); ImageRows_t outRowEnd = (ImageRows_t)(outRow + ((4 * DCTSIZE) << (T3_loopVcp.m_blkRowsPerMcu == 2 ? 1 : 0))); if (outRowEnd > T3_loopVcp.m_outCompRows) outRowEnd = T3_loopVcp.m_outCompRows; if (vrs.m_bUpScale) { PntWghtCpInt_t filterWidth = (PntWghtCpInt_t)((T3_jobInfo.m_filterWidth >> 1) + 1); PntWghtCpInt_t filterOffset = (PntWghtCpInt_t)(18 - (filterWidth << 1)); PntWghtCpInt_t negFilterOffset = -filterOffset; bool bInRowSel = P3_pntWghtStart < negFilterOffset; vrs.m_inRow = bInRowSel ? 0 : ((P3_pntWghtStart + filterOffset) >> 1); vrs.m_rowDataPos = bInRowSel ? (PntWghtCpInt_t)-18 : (PntWghtCpInt_t)((P3_pntWghtStart & ~1) - (filterWidth << 1)); vrs.m_inRowOutDiff = 0; vrs.m_inRowIgnore = 0; } else {
void CPersStencil::PersStencil() { if (PR_htValid) { switch (PR_htInst) { case STENCIL_ENTER: { // Split offset calucation from source stencil to destination location over // two cytles for timing. OFF = ((Y_ORIGIN * (PR_cols + X_SIZE-1) + X_ORIGIN) * sizeof(StType_t); // uint32_t offset = Y_ORIGIN * (PR_cols + X_SIZE-1); S_rdAddr = PR_rdAddr; S_wrAddr = offset; S_rdRowIdx = 0; S_wrRowIdx = Y_ORIGIN; S_cols = PR_cols; S_rows = PR_rows; S_coef = PR_coef; HtContinue(STENCIL_START); } break; case STENCIL_START: { S_bStart = true; S_wrAddr = ((uint32_t)S_wrAddr + X_ORIGIN) * sizeof(StType_t) + PR_wrAddr; StencilBufferInit_5x5r2((ht_uint11)PR_cols, (ht_uint11)PR_rows); HtContinue(STENCIL_WAIT); } break; case STENCIL_WAIT: { if (S_wrRowIdx == S_rows) WriteStreamPause(STENCIL_RETURN); else HtContinue(STENCIL_WAIT); } break; case STENCIL_RETURN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(); } break; default: assert(0); } } // start read stream per row if (SR_bStart && SR_rdRowIdx < SR_rows + Y_SIZE-1 && !ReadStreamBusy()) { ReadStreamOpen(SR_rdAddr, SR_cols + X_SIZE-1); S_rdAddr += (SR_cols + X_SIZE-1) * sizeof(StType_t); S_rdRowIdx += 1; } // start write stream per row if (SR_bStart && SR_wrRowIdx < SR_rows + Y_ORIGIN && !WriteStreamBusy()) { WriteStreamOpen(SR_wrAddr, SR_cols); S_wrAddr += (SR_cols + X_SIZE-1) * sizeof(StType_t); S_wrRowIdx += 1; } CStencilBufferIn_5x5r2 stIn; stIn.m_bValid = ReadStreamReady() && WriteStreamReady(); stIn.m_data = stIn.m_bValid ? ReadStream() : 0; CStencilBufferOut_5x5r2 stOut; StencilBuffer_5x5r2(stIn, stOut); // // compute stencil // T1_bValid = stOut.m_bValid; for (uint32_t x = 0; x < X_SIZE; x += 1) for (uint32_t y = 0; y < Y_SIZE; y += 1) T1_mult[y][x] = (StType_t)(stOut.m_data[y][x] * SR_coef.m_coef[y][x]); for (uint32_t x = 0; x < X_SIZE; x += 1) { T2_ysum[x] = 0; for (uint32_t y = 0; y < Y_SIZE; y += 1) T2_ysum[x] += T2_mult[y][x]; } T3_rslt = 0; for (uint32_t x = 0; x < X_SIZE; x += 1) T3_rslt += T3_ysum[x]; if (T3_bValid) WriteStream(T3_rslt); }
IX_ETH_DB_PUBLIC void ixEthDBDatabaseMaintenance() { HashIterator iterator; UINT32 portIndex; BOOL agingRequired = FALSE; /* ports who will have deleted records and therefore will need updating */ IxEthDBPortMap triggerPorts; if (IX_FEATURE_CTRL_SWCONFIG_ENABLED != ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) { return; } SET_EMPTY_DEPENDENCY_MAP(triggerPorts); /* check if there's at least a port that needs aging */ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled) { agingRequired = TRUE; } } if (agingRequired) { /* ask each NPE port to write back the database for aging inspection */ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE && ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled) { IxNpeMhMessage message; IX_STATUS result; /* send EDB_GetMACAddressDatabase message */ FILL_GETMACADDRESSDATABASE(message, 0 /* unused */, IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone)); IX_ETHDB_SEND_NPE_MSG(IX_ETHNPE_PHYSICAL_ID_TO_NODE(portIndex), message, result); if (result == IX_SUCCESS) { /* analyze NPE copy */ ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE); IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex); } else { ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "EthDB: (Maintenance) warning, Clearing Database records for all types for port %d\n", portIndex, 0, 0, 0, 0, 0); ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES); } } } /* browse database and age entries */ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); while (IS_ITERATOR_VALID(&iterator)) { MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; UINT32 *age = NULL; BOOL staticEntry = TRUE; if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) { age = &descriptor->recordData.filteringData.age; staticEntry = descriptor->recordData.filteringData.staticEntry; } else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) { age = &descriptor->recordData.filteringVlanData.age; staticEntry = descriptor->recordData.filteringVlanData.staticEntry; } else { staticEntry = TRUE; } if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == FALSE)) { /* manually increment the age if the port has no such capability */ if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0) { *age += (IX_ETH_DB_MAINTENANCE_TIME / 60); } /* age entry if it exceeded the maximum time to live */ if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60)) { /* add port to the set of update trigger ports */ JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID); /* delete entry */ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); } else { /* move to the next record */ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); } } else { /* move to the next record */ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); } } /* update ports which lost records */ ixEthDBUpdatePortLearningTrees(triggerPorts); } }
void CPersVadd::PersVadd() { if (PR_htValid) { switch (PR_htInst) { case VADD_RESET: if (SR_msgDelay < 500 || SendHostMsgBusy()) { S_msgDelay += 1; HtRetry(); break; } SendHostMsg(VADD_TYPE_SIZE, (XDIM_LEN << 8) | TYPE_SIZE); HtTerminate(); break; case VADD_ENTER: S_yIdx = 0; S_yDimLen = PR_yDimLen; S_xIdx = 0; S_xDimLen = PR_xDimLen; S_sum = 0; S_addrA += PR_yAddrOff; S_addrB += PR_yAddrOff; S_addrC += PR_yAddrOff; WriteStreamPause_C(VADD_OPEN); break; case VADD_OPEN: // Open read stream A, once for each xDim to be processed if (PR_yOpenAIdx < PR_yDimLen && !ReadStreamBusy_A()) { ht_uint32 remLen = (ht_uint32)((PR_yDimLen - PR_yOpenAIdx) * PR_xDimLen); ReadStreamOpen_A(SR_addrA, remLen > 0x3f ? (ht_uint6)0x3f : (ht_uint6)remLen, P_yOpenAIdx); S_addrA += PR_xDimLen * TYPE_SIZE; P_yOpenAIdx += 1; } // Open read stream B, once for each xDim to be processed if (PR_yOpenBIdx < PR_yDimLen && !ReadStreamBusy_B()) { ReadStreamOpen_B(SR_addrB, PR_xDimLen); S_addrB += PR_xDimLen * TYPE_SIZE; P_yOpenBIdx += 1; } // Open write stream, once for each xDim to be processed if (PR_yOpenCIdx < SR_yDimLen && !WriteStreamBusy_C()) { WriteStreamOpen_C(SR_addrC); S_addrC += PR_xDimLen * TYPE_SIZE; P_yOpenCIdx += 1; } if (PR_yOpenAIdx == PR_yDimLen && PR_yOpenBIdx == PR_yDimLen && PR_yOpenCIdx == PR_yDimLen) WriteStreamPause_C(VADD_RETURN); else HtContinue(VADD_OPEN); break; case VADD_RETURN: { BUSY_RETRY(SendReturnBusy_htmain()); SendReturn_htmain(S_sum); } break; default: assert(0); } } if (SR_yIdx < SR_yDimLen && ReadStreamReady_A() && ReadStreamReady_B() && WriteStreamReady_C()) { PersType_t a, b; a = ReadStream_A(); b = ReadStream_B(); PersType_t c = a + b; S_sum += (ht_uint32)c; WriteStream_C(c); assert_msg(SR_yIdx == ReadStreamTag_A(), "ReadStreamTag_A() error"); if (SR_xIdx + 1 < SR_xDimLen) S_xIdx += 1; else { ReadStreamClose_A(); WriteStreamClose_C(); S_xIdx = 0; S_yIdx += 1; } } }
void CPersHsmw::PersHsmw() { if (PR_htValid) { switch (PR_htInst) { case HSMW_ENTRY: { P_compIdx = 0; P_mcuBlkRow = 0; P_mcuBlkCol = 0; P_rowInBlk = 0; P_mcuPendCnt = 0; P_readDone = false; P_pollDone = false; P_bRstFirst = true; P_rdReqGrpId = (PR_htId << 1) | S_readBufIdx[PR_htId]; P_mcuCol = 0; P_mcuRow = P_rstIdx; HtContinue(HSMW_LOOP); } break; case HSMW_LOOP: { if (S_bufInUse[PR_htId] < 2 && !P_readDone && !ReadMemBusy() ) { // issue read ht_uint13 compRow = (ht_uint13)((P_mcuRow * S_dec.m_dcp[P_compIdx].m_blkRowsPerMcu + P_mcuBlkRow) * 8 + P_rowInBlk); if (compRow < S_dec.m_dcp[P_compIdx].m_compRows) { ht_uint27 rowPos = (ht_uint27)(compRow * S_dec.m_dcp[P_compIdx].m_compBufColLines * MEM_LINE_SIZE); ht_uint13 colPos = (ht_uint13)((P_mcuCol * S_dec.m_dcp[P_compIdx].m_blkColsPerMcu + (P_mcuBlkCol * 8)) * 8); assert(rowPos + colPos < S_dec.m_dcp[P_compIdx].m_compRows * S_dec.m_dcp[P_compIdx].m_compBufColLines * MEM_LINE_SIZE); ht_uint48 memAddr = S_dec.m_dcp[P_compIdx].m_pCompBuf + rowPos + colPos; sc_uint<HSMW_HTID_W+5> varAddr1 = (PR_htId << 5) | (S_readBufIdx[PR_htId] << 4) | (P_compIdx << 2) | (P_mcuBlkRow << 1) | P_mcuBlkCol; //printf("Read offset ci %d, mcuBlkCol %d, mcuBlkRow %d, rowPos %d, colPos %d, varAddr1 0x%x\n", // (int)P_compIdx, (int)P_mcuBlkCol, (int)P_mcuBlkRow, (int)rowPos, (int)colPos, (int)varAddr1); ReadMem_mcuBuf(memAddr, varAddr1, 0, P_rowInBlk, 8); } if (P_rowInBlk+1 == DCTSIZE) { P_rowInBlk = 0; if (P_mcuBlkCol+1 == S_dec.m_dcp[P_compIdx].m_blkColsPerMcu) { P_mcuBlkCol = 0; if (P_mcuBlkRow+1 == S_dec.m_dcp[P_compIdx].m_blkRowsPerMcu) { P_mcuBlkRow = 0; if (P_compIdx+1 == S_dec.m_compCnt) { P_compIdx = 0; S_readBufIdx[PR_htId] ^= 1; P_rdReqGrpId = (PR_htId << 1) | S_readBufIdx[PR_htId]; P_mcuPendCnt += 1; S_bufInUse[PR_htId] += 1; if (P_mcuCol+8 >= S_dec.m_mcuCols) { P_mcuCol = 0; P_mcuRow += 1; P_readDone = S_dec.m_rstMcuCnt > 0 || P_mcuRow >= S_dec.m_mcuRows; } else P_mcuCol += 8; //printf("McuRead done: PR_htId %d, S_mcuBufInUseCnt[%d] %d, P_mcuReadPendCnt %d, P_readBufIdx %d\n", // (int)PR_htId, (int)PR_htId, (int)S_mcuBufInUseCnt[PR_htId], (int)P_mcuReadPendCnt, (int)P_readBufIdx); } else P_compIdx += 1; } else P_mcuBlkRow += 1; } else P_mcuBlkCol += 1; } else P_rowInBlk += 1; } sc_uint<HSMW_HTID_W+1> pollReqGrpId = (PR_htId << 1) | S_pollBufIdx[PR_htId]; if (P_mcuPendCnt > 0 && !S_hsmwIhufQue[PR_htId].full() && !ReadMemPoll(pollReqGrpId)) { HsmwIhufMsg msg; msg.m_jobId = 0; msg.m_imageIdx = P_imageIdx; msg.m_rstIdx = (ht_uint10)P_rstIdx; msg.m_bufIdx = S_pollBufIdx[PR_htId]; msg.m_bRstFirst = P_bRstFirst; msg.m_bRstLast = false; msg.m_bEndOfImage = false; P_bRstFirst = false; S_hsmwIhufQue[PR_htId].push( msg ); P_mcuPendCnt -= 1; S_pollBufIdx[PR_htId] ^= 1; } if (P_readDone && P_mcuPendCnt == 0) HtContinue(HSMW_RETURN); else HtContinue(HSMW_LOOP); } break; case HSMW_RETURN: { BUSY_RETRY( SendReturnBusy_hsmw() ); SendReturn_hsmw(); } break; default: assert(0); } } T1_bPushJdm = false; if (!GR_htReset && !S_hsmwIhufQue[S_ihufQueIdx].empty() && !SendMsgBusy_jdm()) { HsmwIhufMsg msg = S_hsmwIhufQue[S_ihufQueIdx].front(); if (msg.m_bRstFirst) S_mcuRow[S_ihufQueIdx] = msg.m_rstIdx; T1_bPushJdm = true; T1_jdm.m_compIdx = S_compIdx[S_ihufQueIdx]; T1_jdm.m_decPipeId = S_ihufQueIdx; // ihuf index T1_jdm.m_rstIdx = msg.m_rstIdx; T1_jdm.m_bRstLast = false; // last data for restart T1_jdm.m_bEndOfImage = false; // last data for image T1_jdm.m_bEndOfMcuRow = false; T1_jdm.m_imageIdx = msg.m_imageIdx; // image index for double buffering T1_jdm.m_jobId = msg.m_jobId; // host job info index (for debug) T1_outCol = S_outCol[S_ihufQueIdx]; T1_mcuCol = S_mcuCol[S_ihufQueIdx]; T1_mcuBlkCol = S_mcuBlkCol[S_ihufQueIdx]; T1_mcuBlkRow = S_mcuBlkRow[S_ihufQueIdx]; ht_uint10 blkInRow = (ht_uint10)(S_mcuCol[S_ihufQueIdx] * S_dec.m_dcp[S_compIdx[S_ihufQueIdx]].m_blkColsPerMcu + S_mcuBlkCol[S_ihufQueIdx]); ht_uint1 blkColSel = S_dec.m_dcp[S_compIdx[S_ihufQueIdx]].m_blkColsPerMcu == 1 ? 0 : ((S_mcuCol[S_ihufQueIdx] >> 2) & 1); sc_uint<HSMW_HTID_W+5> varAddr1 = (sc_uint<HSMW_HTID_W+5>)((S_ihufQueIdx << 5) | (msg.m_bufIdx << 4) | (S_compIdx[S_ihufQueIdx] << 2) | (S_mcuBlkRow[S_ihufQueIdx] << 1) | blkColSel); for (int r = 0; r < 8; r += 1) S_mcuBuf[r].read_addr(varAddr1, blkInRow & 7); if (S_outCol[S_ihufQueIdx] == 7) { S_outCol[S_ihufQueIdx] = 0; if (S_mcuBlkCol[S_ihufQueIdx]+1 == S_dec.m_dcp[S_compIdx[S_ihufQueIdx]].m_blkColsPerMcu) { S_mcuBlkCol[S_ihufQueIdx] = 0; if (S_mcuBlkRow[S_ihufQueIdx]+1 == S_dec.m_dcp[S_compIdx[S_ihufQueIdx]].m_blkRowsPerMcu) { S_mcuBlkRow[S_ihufQueIdx] = 0; if (S_compIdx[S_ihufQueIdx]+1 == S_dec.m_compCnt) { S_compIdx[S_ihufQueIdx] = 0; if ((S_mcuCol[S_ihufQueIdx] & 7) == 7 || S_mcuCol[S_ihufQueIdx]+1 == S_dec.m_mcuCols) { //printf("S_mcuRow 0x%x, S_mcuCol 0x%x\n", (int)S_mcuRow[S_ihufQueIdx], (int)S_mcuCol[S_ihufQueIdx]); if (S_mcuCol[S_ihufQueIdx]+1 == S_dec.m_mcuCols) { S_mcuCol[S_ihufQueIdx] = 0; T1_jdm.m_bEndOfMcuRow = true; if (S_dec.m_rstMcuCnt > 0) T1_jdm.m_bRstLast = true; if (S_mcuRow[S_ihufQueIdx]+1 == S_dec.m_mcuRows) { S_mcuRow[S_ihufQueIdx] = 0; T1_jdm.m_bEndOfImage = true; T1_jdm.m_bRstLast = true; } else S_mcuRow[S_ihufQueIdx] += 1; } else S_mcuCol[S_ihufQueIdx] += 1; S_bufInUse[S_ihufQueIdx] -= 1; S_hsmwIhufQue[S_ihufQueIdx].pop(); } else S_mcuCol[S_ihufQueIdx] += 1; //printf("McuRead done: PR_htId %d, S_mcuBufInUseCnt[%d] %d, P_mcuReadPendCnt %d, P_readBufIdx %d\n", // (int)PR_htId, (int)PR_htId, (int)S_mcuBufInUseCnt[PR_htId], (int)P_mcuReadPendCnt, (int)P_readBufIdx); } else S_compIdx[S_ihufQueIdx] += 1; } else S_mcuBlkRow[S_ihufQueIdx] += 1; } else S_mcuBlkCol[S_ihufQueIdx] += 1; if (S_skipIdx == 4) S_skipIdx = 0; else #if HSMW_HTID_W==0 S_ihufQueIdx = 0; #else S_ihufQueIdx = S_ihufQueIdx + 1u; #endif } else S_outCol[S_ihufQueIdx] += 1; } else
/** * @brief displays all the filtering records belonging to a port * * @param portID ID of the port to display * * Note that this function is documented in the main component * header file, IxEthDB.h. * * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() * instead. Calling this function is equivalent to calling * ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD) */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) { IxEthDBStatus local_result; HashIterator iterator; PortInfo *portInfo; UINT32 recordCount = 0; IX_ETH_DB_CHECK_PORT(portID); IX_ETH_DB_CHECK_SINGLE_NPE(portID); portInfo = &ixEthDBPortInfo[portID]; /* display table header */ printf("Ethernet database records for port ID [%d]\n", portID); ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap); if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) { printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled"); } else { printf("updates disabled (not an NPE)\n\n"); } printf(" MAC address | Age | Type \n"); printf("___________________________________\n"); /* browse database */ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); while (IS_ITERATOR_VALID(&iterator)) { MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD) { recordCount++; /* display entry */ printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n", descriptor->macAddress[0], descriptor->macAddress[1], descriptor->macAddress[2], descriptor->macAddress[3], descriptor->macAddress[4], descriptor->macAddress[5], descriptor->recordData.filteringData.age, descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); } /* move to the next record */ BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result); /* debug */ if (local_result == IX_ETH_DB_BUSY) { return IX_ETH_DB_FAIL; } } /* display number of records */ printf("\nFound %d records\n", recordCount); return IX_ETH_DB_SUCCESS; }