/**Function************************************************************* Synopsis [Cycles the circuit to create a new initial state.] Description [Simulates the circuit with random input for the given number of timeframes to get a better initial state.] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkCycleInitState( Abc_Ntk_t * pNtk, int nFrames, int fVerbose ) { Abc_Obj_t * pObj; int i, f; assert( Abc_NtkIsStrash(pNtk) ); srand( 0x12341234 ); // initialize the values Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 ); Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_XsimRand2() ); Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchIsInit1(pObj)? XVS1 : XVS0 ); // simulate for the given number of timeframes for ( f = 0; f < nFrames; f++ ) { Abc_AigForEachAnd( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_XsimAnd(Abc_ObjGetXsimFanin0(pObj), Abc_ObjGetXsimFanin1(pObj)) ); Abc_NtkForEachCo( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_ObjGetXsimFanin0(pObj) ); // assign input values Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_XsimRand2() ); // transfer the latch values Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) ); } // set the final values Abc_NtkForEachLatch( pNtk, pObj, i ) pObj->pData = (void *)Abc_ObjGetXsim(Abc_ObjFanout0(pObj)); }
/**Function************************************************************* Synopsis [Performs X-valued simulation of the sequential network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose ) { Abc_Obj_t * pObj; int i, f; assert( Abc_NtkIsStrash(pNtk) ); srand( 0x12341234 ); // start simulation Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 ); if ( fInputs ) { Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, XVSX ); Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) ); } else { Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_XsimRand2() ); Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_ObjSetXsim( Abc_ObjFanout0(pObj), XVSX ); } // simulate and print the result fprintf( stdout, "Frame : Inputs : Latches : Outputs\n" ); for ( f = 0; f < nFrames; f++ ) { Abc_AigForEachAnd( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_XsimAnd(Abc_ObjGetXsimFanin0(pObj), Abc_ObjGetXsimFanin1(pObj)) ); Abc_NtkForEachCo( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_ObjGetXsimFanin0(pObj) ); // print out fprintf( stdout, "%2d : ", f ); Abc_NtkForEachPi( pNtk, pObj, i ) Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) ); fprintf( stdout, " : " ); Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_XsimPrint( stdout, Abc_ObjGetXsim(Abc_ObjFanout0(pObj)) ); fprintf( stdout, " : " ); Abc_NtkForEachPo( pNtk, pObj, i ) Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) ); fprintf( stdout, "\n" ); // assign input values if ( fInputs ) Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, XVSX ); else Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjSetXsim( pObj, Abc_XsimRand2() ); // transfer the latch values Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) ); } }
/**Function************************************************************* Synopsis [Test-bench for the max-flow computation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ) { Vec_Ptr_t * vMinCut; Abc_Obj_t * pObj; int i; // forward flow Abc_NtkForEachPo( pNtk, pObj, i ) pObj->fMarkA = 1; Abc_NtkForEachLatch( pNtk, pObj, i ) pObj->fMarkA = Abc_ObjFanin0(pObj)->fMarkA = 1; // Abc_ObjFanin0(pObj)->fMarkA = 1; vMinCut = Abc_NtkMaxFlow( pNtk, 1, 1 ); Vec_PtrFree( vMinCut ); Abc_NtkCleanMarkA( pNtk ); // backward flow Abc_NtkForEachPi( pNtk, pObj, i ) pObj->fMarkA = 1; Abc_NtkForEachLatch( pNtk, pObj, i ) pObj->fMarkA = Abc_ObjFanout0(pObj)->fMarkA = 1; // Abc_ObjFanout0(pObj)->fMarkA = 1; vMinCut = Abc_NtkMaxFlow( pNtk, 0, 1 ); Vec_PtrFree( vMinCut ); Abc_NtkCleanMarkA( pNtk ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ) { Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; Abc_Ntk_t * pMainNtk = NULL; Abc_Obj_t * pMainObj, * pMainTemp; char Buffer[5000]; // start the network pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); // duplicate the name and the spec pMainNtk->pName = Extra_UtilStrsav(pNtk->pName); // create primary inputs Wlc_NtkForEachCi( pNtk, pObj, i ) { if ( pObj->Type != WLC_OBJ_FO ) continue; nRange = Wlc_ObjRange(pObj); for ( k = 0; k < nRange; k++ ) { nNum = Vec_IntEntry(vInv, nBits + k); if ( nNum ) break; } if ( k == nRange ) { nBits += nRange; continue; } //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); for ( k = 0; k < nRange; k++ ) { nNum = Vec_IntEntry( vInv, nBits + k ); if ( nNum == 0 ) continue; //printf( " [%d] -> %d", k, nNum ); pMainObj = Abc_NtkCreatePi( pMainNtk ); sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); Abc_ObjAssignName( pMainObj, Buffer, NULL ); } //printf( "\n"); nBits += nRange; } //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); assert( Vec_IntSize(vInv) == nBits ); // create node pMainObj = Abc_NtkCreateNode( pMainNtk ); Abc_NtkForEachPi( pMainNtk, pMainTemp, i ) Abc_ObjAddFanin( pMainObj, pMainTemp ); pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) ); // create PO pMainTemp = Abc_NtkCreatePo( pMainNtk ); Abc_ObjAddFanin( pMainTemp, pMainObj ); Abc_ObjAssignName( pMainTemp, "inv", NULL ); return pMainNtk; }
/**Function************************************************************* Synopsis [This procedure also finalizes construction of the ABC network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void ABC_Network_Finalize( ABC_Manager mng ) { Abc_Ntk_t * pNtk = mng->pNtk; Abc_Obj_t * pObj; int i; Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjAssignName( pObj, ABC_GetNodeName(mng, pObj), NULL ); Abc_NtkForEachPo( pNtk, pObj, i ) Abc_ObjAssignName( pObj, ABC_GetNodeName(mng, pObj), NULL ); assert( Abc_NtkLatchNum(pNtk) == 0 ); }
/**Function************************************************************* Synopsis [Constructs the network isomorphic to the given BDD.] Description [Assumes that the BDD depends on the variables whose indexes correspond to the names in the array (pNamesPi). Otherwise, returns NULL. The resulting network comes with one node, whose functionality is equal to the given BDD. To decompose this BDD into the network of multiplexers use Abc_NtkBddToMuxes(). To decompose this BDD into an And-Inverter Graph, use Abc_NtkStrash().] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd0, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ) { DdManager * dd = (DdManager *)dd0; Abc_Ntk_t * pNtk; Vec_Ptr_t * vNamesPiFake = NULL; Abc_Obj_t * pNode, * pNodePi, * pNodePo; DdNode * bSupp, * bTemp; char * pName; int i; // supply fake names if real names are not given if ( pNamePo == NULL ) pNamePo = "F"; if ( vNamesPi == NULL ) { vNamesPiFake = Abc_NodeGetFakeNames( dd->size ); vNamesPi = vNamesPiFake; } // make sure BDD depends on the variables whose index // does not exceed the size of the array with PI names bSupp = Cudd_Support( dd, (DdNode *)bFunc ); Cudd_Ref( bSupp ); for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) ) if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) ) break; Cudd_RecursiveDeref( dd, bSupp ); if ( bTemp != Cudd_ReadOne(dd) ) return NULL; // start the network pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_BDD, 1 ); pNtk->pName = Extra_UtilStrsav(pNamePo); // make sure the new manager has enough inputs Cudd_bddIthVar( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vNamesPi) ); // add the PIs corresponding to the names Vec_PtrForEachEntry( char *, vNamesPi, pName, i ) Abc_ObjAssignName( Abc_NtkCreatePi(pNtk), pName, NULL ); // create the node pNode = Abc_NtkCreateNode( pNtk ); pNode->pData = (DdNode *)Cudd_bddTransfer( dd, (DdManager *)pNtk->pManFunc, (DdNode *)bFunc ); Cudd_Ref((DdNode *)pNode->pData); Abc_NtkForEachPi( pNtk, pNodePi, i ) Abc_ObjAddFanin( pNode, pNodePi ); // create the only PO pNodePo = Abc_NtkCreatePo( pNtk ); Abc_ObjAddFanin( pNodePo, pNode ); Abc_ObjAssignName( pNodePo, pNamePo, NULL ); // make the network minimum base Abc_NtkMinimumBase( pNtk ); if ( vNamesPiFake ) Abc_NodeFreeNames( vNamesPiFake ); if ( !Abc_NtkCheck( pNtk ) ) fprintf( stdout, "Abc_NtkDeriveFromBdd(): Network check has failed.\n" ); return pNtk; }
/**Function************************************************************* Synopsis [Transforms the sequential AIG to take fanout sharing into account.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Seq_NtkShareFanouts( Abc_Ntk_t * pNtk ) { Vec_Ptr_t * vNodes; Abc_Obj_t * pObj; int i; vNodes = Vec_PtrAlloc( 10 ); // share the PI latches Abc_NtkForEachPi( pNtk, pObj, i ) Seq_NodeShareFanouts( pObj, vNodes ); // share the node latches Abc_NtkForEachNode( pNtk, pObj, i ) Seq_NodeShareFanouts( pObj, vNodes ); Vec_PtrFree( vNodes ); }
/**Function************************************************************* Synopsis [Starts a new network using existing network as a model.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj; int i; if ( pNtk == NULL ) return NULL; assert( Type != ABC_NTK_NETLIST ); // start the network pNtkNew = Abc_NtkAlloc( Type, Func, 1 ); // duplicate the name and the spec pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); // clean the node copy fields Abc_NtkCleanCopy( pNtk ); // map the constant nodes if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // clone CIs/CIs/boxes Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkDupObj( pNtkNew, pObj, 1 ); Abc_NtkForEachPo( pNtk, pObj, i ) Abc_NtkDupObj( pNtkNew, pObj, 1 ); Abc_NtkForEachAssert( pNtk, pObj, i ) Abc_NtkDupObj( pNtkNew, pObj, 1 ); Abc_NtkForEachBox( pNtk, pObj, i ) { if ( Abc_ObjIsLatch(pObj) ) continue; Abc_NtkDupBox(pNtkNew, pObj, 1); } // transfer the names // Abc_NtkTrasferNamesNoLatches( pNtk, pNtkNew ); Abc_ManTimeDup( pNtk, pNtkNew ); // check that the CI/CO/latches are copied correctly assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) ); assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) ); return pNtkNew; }
/**Function************************************************************* Synopsis [Prints PIs/POs and LIs/LOs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) ); Abc_NtkForEachPi( pNtk, pObj, i ) fprintf( pFile, " %s", Abc_ObjName(pObj) ); // fprintf( pFile, " %s(%d)", Abc_ObjName(pObj), Abc_ObjFanoutNum(pObj) ); fprintf( pFile, "\n" ); fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) ); Abc_NtkForEachPo( pNtk, pObj, i ) fprintf( pFile, " %s", Abc_ObjName(pObj) ); fprintf( pFile, "\n" ); fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) ); Abc_NtkForEachLatch( pNtk, pObj, i ) fprintf( pFile, " %s(%s=%s)", Abc_ObjName(pObj), Abc_ObjName(Abc_ObjFanout0(pObj)), Abc_ObjName(Abc_ObjFanin0(pObj)) ); fprintf( pFile, "\n" ); }
/**Function************************************************************* Synopsis [Connect one box.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model ) { Vec_Ptr_t * pNames; Abc_Ntk_t * pNtkModel; Abc_Obj_t * pObj, * pNet; char * pName = NULL, * pActual; int i, Length, Start = -1; // get the model for this box pNames = (Vec_Ptr_t *)pBox->pData; if ( !stmm_lookup( tName2Model, (char *)Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Cannot find the model for subcircuit %s.", (char*)Vec_PtrEntry(pNames, 0) ); Io_ReadBlifPrintErrorMessage( p ); return 1; } // create the fanins of the box Abc_NtkForEachPi( pNtkModel, pObj, i ) pObj->pCopy = NULL; if ( Abc_NtkPiNum(pNtkModel) == 0 ) Start = 1; else { Vec_PtrForEachEntryStart( char *, pNames, pName, i, 1 ) { pActual = Io_ReadBlifCleanName(pName); if ( pActual == NULL ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName ); Io_ReadBlifPrintErrorMessage( p ); return 1; } Length = pActual - pName - 1; pName[Length] = 0; // find the PI net with this name pObj = Abc_NtkFindNet( pNtkModel, pName ); if ( pObj == NULL ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, (char*)Vec_PtrEntry(pNames, 0) ); Io_ReadBlifPrintErrorMessage( p ); return 1; } // get the PI pObj = Abc_ObjFanin0(pObj); // quit if this is not a PI net if ( !Abc_ObjIsPi(pObj) ) { pName[Length] = '='; Start = i; break; } // remember the actual name in the net if ( pObj->pCopy != NULL ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName ); Io_ReadBlifPrintErrorMessage( p ); return 1; } pObj->pCopy = (Abc_Obj_t *)pActual; // quit if we processed all PIs if ( i == Abc_NtkPiNum(pNtkModel) ) { Start = i+1; break; } } } // create the fanins of the box Abc_NtkForEachPi( pNtkModel, pObj, i ) { pActual = (char *)pObj->pCopy; if ( pActual == NULL ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, (char*)Vec_PtrEntry(pNames, 0) ); Io_ReadBlifPrintErrorMessage( p ); return 1; } pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual ); Abc_ObjAddFanin( pBox, pNet ); }
/**Function************************************************************* Synopsis [Starts the record for the given network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkRecStart( Abc_Ntk_t * pNtk, int nVars, int nCuts ) { Abc_ManRec_t * p; Abc_Obj_t * pObj, ** ppSpot; char Buffer[10]; unsigned * pTruth; int i, RetValue; int clkTotal = clock(), clk; assert( s_pMan == NULL ); if ( pNtk == NULL ) { assert( nVars > 2 && nVars <= 16 ); pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); pNtk->pName = Extra_UtilStrsav( "record" ); } else { if ( Abc_NtkGetChoiceNum(pNtk) > 0 ) { printf( "The starting record should be a network without choice nodes.\n" ); return; } if ( Abc_NtkPiNum(pNtk) > 16 ) { printf( "The starting record should be a network with no more than %d primary inputs.\n", 16 ); return; } if ( Abc_NtkPiNum(pNtk) > nVars ) printf( "The starting record has %d inputs (warning only).\n", Abc_NtkPiNum(pNtk) ); pNtk = Abc_NtkDup( pNtk ); } // create the primary inputs for ( i = Abc_NtkPiNum(pNtk); i < nVars; i++ ) { pObj = Abc_NtkCreatePi( pNtk ); Buffer[0] = 'a' + i; Buffer[1] = 0; Abc_ObjAssignName( pObj, Buffer, NULL ); } Abc_NtkCleanCopy( pNtk ); Abc_NtkCleanEquiv( pNtk ); // start the manager p = ABC_ALLOC( Abc_ManRec_t, 1 ); memset( p, 0, sizeof(Abc_ManRec_t) ); p->pNtk = pNtk; p->nVars = Abc_NtkPiNum(pNtk); p->nWords = Kit_TruthWordNum( p->nVars ); p->nCuts = nCuts; p->nVarsInit = nVars; // create elementary truth tables p->vTtElems = Vec_PtrAlloc( 0 ); assert( p->vTtElems->pArray == NULL ); p->vTtElems->nSize = p->nVars; p->vTtElems->nCap = p->nVars; p->vTtElems->pArray = (void *)Extra_TruthElementary( p->nVars ); // allocate room for node truth tables if ( Abc_NtkObjNum(pNtk) > (1<<14) ) p->vTtNodes = Vec_PtrAllocSimInfo( 2 * Abc_NtkObjNum(pNtk), p->nWords ); else p->vTtNodes = Vec_PtrAllocSimInfo( 1<<14, p->nWords ); // create hash table p->nBins = 50011; p->pBins = ABC_ALLOC( Abc_Obj_t *, p->nBins ); memset( p->pBins, 0, sizeof(Abc_Obj_t *) * p->nBins ); // set elementary tables Kit_TruthFill( Vec_PtrEntry(p->vTtNodes, 0), p->nVars ); Abc_NtkForEachPi( pNtk, pObj, i ) Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, pObj->Id), Vec_PtrEntry(p->vTtElems, i), p->nVars ); // compute the tables clk = clock(); Abc_AigForEachAnd( pNtk, pObj, i ) { RetValue = Abc_NtkRecComputeTruth( pObj, p->vTtNodes, p->nVars ); assert( RetValue ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p ) { ProgressBar * pProgress; Vec_Ptr_t * vTokens; Abc_Ntk_t * pNtk; Abc_Obj_t * pTermPi, * pTermPo, * pNode; Vec_Str_t ** ppSops; char Buffer[100]; int nInputs = -1, nOutputs = -1, nProducts = -1; char * pCubeIn, * pCubeOut; int i, k, iLine, nDigits, nCubes; // allocate the empty network pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) ); // go through the lines of the file nCubes = 0; pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) ); for ( iLine = 0; vTokens = Extra_FileReaderGetTokens(p); iLine++ ) { Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL ); // if it is the end of file, quit the loop if ( strcmp( vTokens->pArray[0], ".e" ) == 0 ) break; if ( vTokens->nSize == 1 ) { printf( "%s (line %d): Wrong number of token.\n", Extra_FileReaderGetFileName(p), iLine+1 ); Abc_NtkDelete( pNtk ); return NULL; } if ( strcmp( vTokens->pArray[0], ".i" ) == 0 ) nInputs = atoi(vTokens->pArray[1]); else if ( strcmp( vTokens->pArray[0], ".o" ) == 0 ) nOutputs = atoi(vTokens->pArray[1]); else if ( strcmp( vTokens->pArray[0], ".p" ) == 0 ) nProducts = atoi(vTokens->pArray[1]); else if ( strcmp( vTokens->pArray[0], ".ilb" ) == 0 ) { if ( vTokens->nSize - 1 != nInputs ) printf( "Warning: Mismatch between the number of PIs on the .i line (%d) and the number of PIs on the .ilb line (%d).\n", nInputs, vTokens->nSize - 1 ); for ( i = 1; i < vTokens->nSize; i++ ) Io_ReadCreatePi( pNtk, vTokens->pArray[i] ); } else if ( strcmp( vTokens->pArray[0], ".ob" ) == 0 ) { if ( vTokens->nSize - 1 != nOutputs ) printf( "Warning: Mismatch between the number of POs on the .o line (%d) and the number of POs on the .ob line (%d).\n", nOutputs, vTokens->nSize - 1 ); for ( i = 1; i < vTokens->nSize; i++ ) Io_ReadCreatePo( pNtk, vTokens->pArray[i] ); } else { // check if the input/output names are given if ( Abc_NtkPiNum(pNtk) == 0 ) { if ( nInputs == -1 ) { printf( "%s: The number of inputs is not specified.\n", Extra_FileReaderGetFileName(p) ); Abc_NtkDelete( pNtk ); return NULL; } nDigits = Extra_Base10Log( nInputs ); for ( i = 0; i < nInputs; i++ ) { sprintf( Buffer, "x%0*d", nDigits, i ); Io_ReadCreatePi( pNtk, Buffer ); } } if ( Abc_NtkPoNum(pNtk) == 0 ) { if ( nOutputs == -1 ) { printf( "%s: The number of outputs is not specified.\n", Extra_FileReaderGetFileName(p) ); Abc_NtkDelete( pNtk ); return NULL; } nDigits = Extra_Base10Log( nOutputs ); for ( i = 0; i < nOutputs; i++ ) { sprintf( Buffer, "z%0*d", nDigits, i ); Io_ReadCreatePo( pNtk, Buffer ); } } if ( Abc_NtkNodeNum(pNtk) == 0 ) { // first time here // create the PO drivers and add them // start the SOP covers ppSops = ALLOC( Vec_Str_t *, nOutputs ); Abc_NtkForEachPo( pNtk, pTermPo, i ) { ppSops[i] = Vec_StrAlloc( 100 ); // create the node pNode = Abc_NtkCreateNode(pNtk); // connect the node to the PO net Abc_ObjAddFanin( Abc_ObjFanin0Ntk(pTermPo), pNode ); // connect the node to the PI nets Abc_NtkForEachPi( pNtk, pTermPi, k ) Abc_ObjAddFanin( pNode, Abc_ObjFanout0Ntk(pTermPi) ); } } // read the cubes if ( vTokens->nSize != 2 ) { printf( "%s (line %d): Input and output cubes are not specified.\n", Extra_FileReaderGetFileName(p), iLine+1 ); Abc_NtkDelete( pNtk ); return NULL; } pCubeIn = vTokens->pArray[0]; pCubeOut = vTokens->pArray[1]; if ( strlen(pCubeIn) != (unsigned)nInputs ) { printf( "%s (line %d): Input cube length (%d) differs from the number of inputs (%d).\n", Extra_FileReaderGetFileName(p), iLine+1, strlen(pCubeIn), nInputs ); Abc_NtkDelete( pNtk ); return NULL; } if ( strlen(pCubeOut) != (unsigned)nOutputs ) { printf( "%s (line %d): Output cube length (%d) differs from the number of outputs (%d).\n", Extra_FileReaderGetFileName(p), iLine+1, strlen(pCubeOut), nOutputs ); Abc_NtkDelete( pNtk ); return NULL; } for ( i = 0; i < nOutputs; i++ ) { if ( pCubeOut[i] == '1' ) { Vec_StrAppend( ppSops[i], pCubeIn ); Vec_StrAppend( ppSops[i], " 1\n" ); } } nCubes++; }