📄 ioreadnet.c
字号:
if ( pNode && !Ntk_NodeIsCi(pNode) ) { p->LineCur = p->pDotOutputs[Line]; sprintf( p->sError, "Re-definion of primary output \"%s\".", pTemp ); Io_ReadPrintErrorMessage( p ); return 1; } if ( pNode == NULL ) pNode = Ntk_NetworkFindOrAddNodeByName( pNet, pTemp, MV_NODE_INT ); if ( p->fParsingExdcNet ) { if ( !Ntk_NetworkFindNodeByName( p->pNet, pTemp ) ) { p->LineCur = p->pDotInputs[Line]; sprintf( p->sError, "CO \"%s\" of the EXDC network is missing in the primary network.", pTemp ); Io_ReadPrintErrorMessage( p ); return 1; } } array_insert_last( Ntk_Node_t *, p->aOutputs, pNode ); } return 0;}/**Function************************************************************* Synopsis [Adds the latch structure to the network.] Description [] SideEffects [] SeeAlso []***********************************************************************/int Io_ReadNetworkLatchInputOutput( Io_Read_t * p, int Latch, Ntk_Network_t * pNet ){ Io_Latch_t * pIoLatch; Ntk_Node_t * pInput, * pOutput; // get the Io_Latch_t pointer pIoLatch = p->pIoLatches + Latch; // check if latch output already exist as a PI pOutput = Ntk_NetworkFindNodeByName( pNet, pIoLatch->pOutputName ); if ( pOutput == NULL ) { // create a new PI node to be driven by the latch pOutput = Ntk_NetworkFindOrAddNodeByName( pNet, pIoLatch->pOutputName, MV_NODE_CI ); // mark the PO as only belonging to the latch Ntk_NodeSetSubtype( pOutput, MV_BELONGS_TO_LATCH ); } else { assert( Ntk_NodeIsInternal(pOutput) ); // this is a special case when the latch output is also a PO // transform the PO node to PI // this way, it will later be given a different name // this case is similar to those cases when // the same CI and CO name appears in some benchmarks Ntk_NetworkTransformNodeIntToCi( pNet, pOutput ); // mark the PO as only belonging to the latch Ntk_NodeSetSubtype( pOutput, MV_BELONGS_TO_LATCH ); } assert( Ntk_NodeIsCi(pOutput) ); // check if latch input already exist as a PO pInput = Ntk_NetworkFindNodeByName( pNet, pIoLatch->pInputName ); if ( pInput == NULL ) { // create a new internal node to drive the latch pInput = Ntk_NetworkFindOrAddNodeByName( pNet, pIoLatch->pInputName, MV_NODE_INT ); // mark the PO as only belonging to the latch Ntk_NodeSetSubtype( pInput, MV_BELONGS_TO_LATCH ); array_insert_last( Ntk_Node_t *, p->aOutputs, pInput ); } assert( Ntk_NodeIsInternal(pInput) ); return 0;}/**Function************************************************************* Synopsis [Reads the internal node.] Description [This procedure creates the internal node using the information available from preparsing. This procedure does not derive the functionality of the node.] SideEffects [] SeeAlso []***********************************************************************/int Io_ReadNetworkInternalNode( Io_Read_t * p, int Node, Ntk_Network_t * pNet ){ Io_Node_t * pIoNode; Ntk_Node_t * pNode, * pFanin; char * pLine, * pTemp, * pPrev; // set the current parsing line pIoNode = p->pIoNodes + Node; p->LineCur = pIoNode->LineNames; // find or create the node by name pNode = Ntk_NetworkFindOrAddNodeByName( pNet, pIoNode->pOutput, MV_NODE_INT ); // make sure the node is not assigned yet if ( Ntk_NodeReadFaninNum(pNode) ) { sprintf( p->sError, "Node \"%s\" is multiply defined.", Ntk_NodeReadName(pNode) ); Io_ReadPrintErrorMessage( p ); return 1; } // get the .names line of the node pLine = p->pLines[ pIoNode->LineNames ]; // make sure this is indeed the .names line assert( strncmp( pLine, ".names", 6 ) == 0 || p->Type == IO_FILE_BLIF_MV && strncmp( pLine, ".table", 6 ) == 0 ); // skip the ".names" word pTemp = strtok( pLine, " \t" ); pPrev = NULL; // read the fanins names, one by one while ( pTemp = strtok( NULL, " \t" ) ) { if ( pPrev ) { // find or create the fanin by name pFanin = Ntk_NetworkFindOrAddNodeByName( pNet, pPrev, MV_NODE_INT ); // add the fanin to the fanin list of the node Ntk_NodeAddFanin( pNode, pFanin ); } // store the current pointer pPrev = pTemp; } // make sure the last signal is the output assert( strcmp( pPrev, Ntk_NodeReadName(pNode) ) == 0 ); // store the pointer to the Io_Node_t structure with the node pIoNode = p->pIoNodes + Node; Ntk_NodeSetData( pNode, (char*)pIoNode ); // if this is BLIF-MVS, we need to get the number of values // of each non-binary variable, including the PIs if ( p->Type == IO_FILE_BLIF_MVS ) if ( Io_ReadNetworkInternalNodeMvs( p, pNode ) ) return 1; // assign the default value and the number of values Ntk_NodeSetValueNum( pNode, pIoNode->nValues ); // update the largest fanin count if ( p->nFaninsMax < Ntk_NodeReadFaninNum(pNode) ) p->nFaninsMax = Ntk_NodeReadFaninNum(pNode); return 0;}/**Function************************************************************* Synopsis [Adds the latch structure to the network.] Description [] SideEffects [] SeeAlso []***********************************************************************/int Io_ReadNetworkLatch( Io_Read_t * p, int Latch, Ntk_Network_t * pNet ){ Io_Latch_t * pIoLatch; Io_Node_t * pIoNode; Ntk_Latch_t * pLatch; Ntk_Node_t * pNode, * pFanin; char * pLine, * pTemp, * pPrev; // get the IO latch pointer pIoLatch = p->pIoLatches + Latch; pIoNode = &pIoLatch->IoNode; if ( p->Type == IO_FILE_BLIF ) { pLatch = Ntk_LatchCreate( pNet, NULL, pIoLatch->pInputName, pIoLatch->pOutputName ); Ntk_NetworkAddLatch( pNet, pLatch ); return 0; } // set the current parsing line p->LineCur = pIoNode->LineNames; // read the reset table // create the new node pNode = Ntk_NodeCreate( pNet, NULL, MV_NODE_INT, pIoNode->nValues ); Ntk_NodeSetData( pNode, (char*)pIoNode ); // get the .res line of the latch pLine = p->pLines[ pIoNode->LineNames ]; // get the first word on the line pTemp = strtok( pLine, " \t" ); assert( strncmp( pTemp, ".r", 2 ) == 0 ); // read the fanins names, one by one pPrev = NULL; while ( pTemp = strtok( NULL, " \t" ) ) { if ( pPrev ) { // get the node with this name if ( (pFanin = Ntk_NetworkFindNodeByName( pNet, pPrev )) == NULL ) { sprintf( p->sError, "Fanin \"%s\" of reset table is not in the network.", pPrev ); Io_ReadPrintErrorMessage( p ); return 1; } // add the fanin Ntk_NodeAddFanin( pNode, pFanin ); } // store the current pointer pPrev = pTemp; } // make sure the last signal is the output assert( strcmp( pPrev, pIoLatch->pOutputName ) == 0 ); // update the largest fanin count if ( p->nFaninsMax < Ntk_NodeReadFaninNum(pNode) ) p->nFaninsMax = Ntk_NodeReadFaninNum(pNode); // create the variable map of the node Ntk_NodeAssignVm( pNode ); // derive the functionality of this node Ntk_NodeSetName( pNode, pIoLatch->pOutputName ); Io_ReadNodeFunctions( p, pNode ); Ntk_NodeSetName( pNode, NULL ); // finally add the latch with this node pLatch = Ntk_LatchCreate( pNet, pNode, pIoLatch->pInputName, pIoLatch->pOutputName ); Ntk_NetworkAddLatch( pNet, pLatch ); return 0;}/**Function************************************************************* Synopsis [Sets the number of values of the primary inputs.] Description [] SideEffects [] SeeAlso []***********************************************************************/void Io_ReadNetworkCiSetValue( Io_Read_t * p, Ntk_Node_t * pNode ){ int nValues; nValues = 2; if ( p->tName2Values ) st_lookup( p->tName2Values, (char *)Ntk_NodeReadName(pNode), (char**)&nValues ); Ntk_NodeSetValueNum( pNode, nValues ); if ( p->nValuesMax < nValues ) p->nValuesMax = nValues;}/**Function************************************************************* Synopsis [Determine the number of values by scanning the first line of the table.] Description [] SideEffects [] SeeAlso []***********************************************************************/int Io_ReadNetworkInternalNodeMvs( Io_Read_t * p, Ntk_Node_t * pNode ){ Io_Node_t * pIoNode; Ntk_Pin_t * pPin; Ntk_Node_t * pFanin; char * pEnd, * pTemp; int nValues, i; // remember the place in the first line where the end should be pIoNode = (Io_Node_t *)Ntk_NodeReadData(pNode); assert( pIoNode->LineTable + 1 < p->nLines ); // set the current parsing line p->LineCur = pIoNode->LineTable; // start iterating through the cubes // and at the same time iterate through the fanins pTemp = strtok( p->pLines[ pIoNode->LineTable ], " \t" ); nValues = strlen(pTemp); Ntk_NodeForEachFanin( pNode, pPin, pFanin ) { if ( pTemp == NULL ) { sprintf( p->sError, "Not enough literals in the cube." ); Io_ReadPrintErrorMessage( p ); return 1; } if ( nValues > 2 ) Io_ReadLinesAddNumValues( p, Ntk_NodeReadName(pFanin), nValues ); pTemp = strtok( NULL, " \t" ); nValues = strlen(pTemp); } // add the output name if ( pTemp == NULL ) { sprintf( p->sError, "Not enough literals in the cube." ); Io_ReadPrintErrorMessage( p ); return 1; } if ( nValues > 2 ) Io_ReadLinesAddNumValues( p, pIoNode->pOutput, nValues ); // set the given number of values at the node pIoNode->nValues = nValues; // get the default value pIoNode->Default = -1; for ( i = 0; i < nValues; i++ ) if ( pTemp[i] == 'D' || pTemp[i] == 'd' ) pIoNode->Default = i; // check if something remains in the cube pTemp = strtok( NULL, " \t" ); if ( pTemp != NULL ) { sprintf( p->sError, "Trailing symbols after the last literal (%s).", pTemp ); Io_ReadPrintErrorMessage( p ); return 1; } // strtok() has broken the cube into pieces; fix it pEnd = p->pLines[ pIoNode->LineTable + 1 ] - 1; for ( pTemp = p->pLines[ pIoNode->LineTable ]; pTemp < pEnd; pTemp++ ) if ( *pTemp == '\0' ) *pTemp = ' '; // make sure there is 0 before the beginning of the next cube *pTemp = '\0'; return 0;}/////////////////////////////////////////////////////////////////////////// END OF FILE ///////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -