/**Function************************************************************* Synopsis [Write one network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteEqnOne( FILE * pFile, Abc_Ntk_t * pNtk ) { Vec_Vec_t * vLevels; ProgressBar * pProgress; Abc_Obj_t * pNode, * pFanin; int i, k; // write the PIs fprintf( pFile, "INORDER =" ); Io_NtkWriteEqnCis( pFile, pNtk ); fprintf( pFile, ";\n" ); // write the POs fprintf( pFile, "OUTORDER =" ); Io_NtkWriteEqnCos( pFile, pNtk ); fprintf( pFile, ";\n" ); // write each internal node vLevels = Vec_VecAlloc( 10 ); pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); fprintf( pFile, "%s = ", Abc_ObjName(Abc_ObjFanout0(pNode)) ); // set the input names Abc_ObjForEachFanin( pNode, pFanin, k ) Hop_IthVar((Hop_Man_t *)pNtk->pManFunc, k)->pData = Abc_ObjName(pFanin); // write the formula Hop_ObjPrintEqn( pFile, (Hop_Obj_t *)pNode->pData, vLevels, 0 ); fprintf( pFile, ";\n" ); }
Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); // if ( Abc_NodeIsConst(pNode) ) // continue; Abc_NodeSuperChoice( pNtkNew, pNode ); }
/**Function************************************************************* Synopsis [Derives truth tables for each cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_MappingTruths( Map_Man_t * pMan ) { ProgressBar * pProgress; Map_Node_t * pNode; Map_Cut_t * pCut; int nNodes, i; // compute the cuts for the POs nNodes = pMan->vAnds->nSize; pProgress = Extra_ProgressBarStart( stdout, nNodes ); for ( i = 0; i < nNodes; i++ ) { pNode = pMan->vAnds->pArray[i]; if ( !Map_NodeIsAnd( pNode ) ) continue; assert( pNode->pCuts ); assert( pNode->pCuts->nLeaves == 1 ); // match the simple cut pNode->pCuts->M[0].uPhase = 0; pNode->pCuts->M[0].pSupers = pMan->pSuperLib->pSuperInv; pNode->pCuts->M[0].uPhaseBest = 0; pNode->pCuts->M[0].pSuperBest = pMan->pSuperLib->pSuperInv; pNode->pCuts->M[1].uPhase = 0; pNode->pCuts->M[1].pSupers = pMan->pSuperLib->pSuperInv; pNode->pCuts->M[1].uPhaseBest = 1; pNode->pCuts->M[1].pSuperBest = pMan->pSuperLib->pSuperInv; // match the rest of the cuts for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext ) Map_TruthsCut( pMan, pCut ); Extra_ProgressBarUpdate( pProgress, i, "Tables ..." ); } Extra_ProgressBarStop( pProgress ); }
/**Function************************************************************* Synopsis [Converts the network to MUXes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { ProgressBar * pProgress; Abc_Obj_t * pNode, * pNodeNew; Vec_Ptr_t * vNodes; int i; // perform conversion in the topological order vNodes = Abc_NtkDfs( pNtk, 0 ); pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); // convert one node assert( Abc_ObjIsNode(pNode) ); pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew ); // mark the old node with the new one assert( pNode->pCopy == NULL ); pNode->pCopy = pNodeNew; }
Vec_PtrForEachEntry( vNodes, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); // add the node to the mapper pNodeFpga = Fpga_NodeAnd( pMan, Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); assert( pNode->pCopy == NULL ); // remember the node pNode->pCopy = (Abc_Obj_t *)pNodeFpga; if ( pSwitching ) Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] ); // set up the choice node if ( Abc_AigNodeIsChoice( pNode ) ) for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) { Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy ); Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy ); } }
/**Function************************************************************* Synopsis [Transforms the AIG into nodes.] Description [Threhold is the max number of nodes duplicated at a node.] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkMultiInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { ProgressBar * pProgress; Abc_Obj_t * pNode, * pConst1, * pNodeNew; int i; // set the constant node pConst1 = Abc_AigConst1(pNtk); if ( Abc_ObjFanoutNum(pConst1) > 0 ) { pNodeNew = Abc_NtkCreateNode( pNtkNew ); pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc ); Cudd_Ref( pNodeNew->pData ); pConst1->pCopy = pNodeNew; } // perform renoding for POs pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); Abc_NtkForEachCo( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) ) continue; Abc_NtkMulti_rec( pNtkNew, Abc_ObjFanin0(pNode) ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) { ProgressBar * pProgress; Vec_Ptr_t * vTokens; Abc_Ntk_t * pNtk; Abc_Obj_t * pNode, * pNet; Vec_Str_t * vString; unsigned uTruth[8]; char * pType, ** ppNames, * pString; int iLine, nNames, nDigits, fLutsPresent = 0; // allocate the empty network pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) ); // go through the lines of the file vString = Vec_StrAlloc( 100 ); pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) ); for ( iLine = 0; (vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p)); iLine++ ) { Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL ); if ( vTokens->nSize == 1 ) { printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } // get the type of the line if ( strncmp( (char *)vTokens->pArray[0], "INPUT", 5 ) == 0 ) Io_ReadCreatePi( pNtk, (char *)vTokens->pArray[1] ); else if ( strncmp( (char *)vTokens->pArray[0], "OUTPUT", 5 ) == 0 ) Io_ReadCreatePo( pNtk, (char *)vTokens->pArray[1] ); else { // get the node name and the node type pType = (char *)vTokens->pArray[1]; if ( strncmp(pType, "DFF", 3) == 0 ) // works for both DFF and DFFRSE { pNode = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[2], (char *)vTokens->pArray[0] ); // Abc_LatchSetInit0( pNode ); if ( pType[3] == '0' ) Abc_LatchSetInit0( pNode ); else if ( pType[3] == '1' ) Abc_LatchSetInit1( pNode ); else Abc_LatchSetInitDc( pNode ); } else if ( strcmp(pType, "LUT") == 0 ) { fLutsPresent = 1; ppNames = (char **)vTokens->pArray + 3; nNames = vTokens->nSize - 3; // check the number of inputs if ( nNames > 8 ) { printf( "%s: Currently cannot read truth tables with more than 8 inputs (%d).\n", Extra_FileReaderGetFileName(p), nNames ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } // get the hex string pString = (char *)vTokens->pArray[2]; if ( strncmp( pString, "0x", 2 ) ) { printf( "%s: The LUT signature (%s) does not look like a hexadecimal beginning with \"0x\".\n", Extra_FileReaderGetFileName(p), pString ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } pString += 2; // pad the string with zero's if needed nDigits = (1 << nNames) / 4; if ( nDigits == 0 ) nDigits = 1; if ( strlen(pString) < (unsigned)nDigits ) { Vec_StrFill( vString, nDigits - strlen(pString), '0' ); Vec_StrPrintStr( vString, pString ); Vec_StrPush( vString, 0 ); pString = Vec_StrArray( vString ); } // read the hex number from the string if ( !Extra_ReadHexadecimal( uTruth, pString, nNames ) ) { printf( "%s: Reading hexadecimal number (%s) has failed.\n", Extra_FileReaderGetFileName(p), pString ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } // check if the node is a constant node if ( Extra_TruthIsConst0(uTruth, nNames) ) { pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 ); Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) ); } else if ( Extra_TruthIsConst1(uTruth, nNames) ) { pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 ); Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) ); } else { // create the node pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames ); assert( nNames > 0 ); if ( nNames > 1 ) Abc_ObjSetData( pNode, Abc_SopCreateFromTruth((Mem_Flex_t *)pNtk->pManFunc, nNames, uTruth) ); else if ( pString[0] == '2' ) Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else if ( pString[0] == '1' ) Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else { printf( "%s: Reading truth table (%s) of single-input node has failed.\n", Extra_FileReaderGetFileName(p), pString ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } } } else { // create a new node and add it to the network ppNames = (char **)vTokens->pArray + 2; nNames = vTokens->nSize - 2; pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames ); // assign the cover if ( strcmp(pType, "AND") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "OR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "NAND") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "NOR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "XOR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strncmp(pType, "BUF", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strcmp(pType, "NOT") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strncmp(pType, "MUX", 3) == 0 ) // Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") ); Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, "0-1 1\n11- 1\n") ); else if ( strncmp(pType, "gnd", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) ); else if ( strncmp(pType, "vdd", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) ); else { printf( "Io_ReadBenchNetwork(): Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } } } } Extra_ProgressBarStop( pProgress ); Vec_StrFree( vString ); // check if constant 0 is present if ( (pNet = Abc_NtkFindNet( pNtk, "gnd" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) Io_ReadCreateConst( pNtk, "gnd", 0 ); } if ( (pNet = Abc_NtkFindNet( pNtk, "1" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) { printf( "Io_ReadBenchNetwork(): Adding constant 0 fanin to non-driven net \"1\".\n" ); Io_ReadCreateConst( pNtk, "1", 0 ); } } // check if constant 1 is present if ( (pNet = Abc_NtkFindNet( pNtk, "vdd" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) Io_ReadCreateConst( pNtk, "vdd", 1 ); } if ( (pNet = Abc_NtkFindNet( pNtk, "2" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) { printf( "Io_ReadBenchNetwork(): Adding constant 1 fanin to non-driven net \"2\".\n" ); Io_ReadCreateConst( pNtk, "2", 1 ); } } Abc_NtkFinalizeRead( pNtk ); // if LUTs are present, collapse the truth tables into cubes if ( fLutsPresent ) { if ( !Abc_NtkToBdd(pNtk) ) { printf( "Io_ReadBenchNetwork(): Converting to BDD has failed.\n" ); Abc_NtkDelete( pNtk ); return NULL; } if ( !Abc_NtkToSop(pNtk, 0) ) { printf( "Io_ReadBenchNetwork(): Converting to SOP has failed.\n" ); Abc_NtkDelete( pNtk ); return NULL; } } return pNtk; }
/**Function************************************************************* Synopsis [Reads one (main or exdc) network from the BLIF file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) { ProgressBar * pProgress = NULL; Abc_Ntk_t * pNtk; char * pDirective; int iLine, fTokensReady, fStatus; // make sure the tokens are present assert( p->vTokens != NULL ); // create the new network p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 ); // read the model name if ( strcmp( (char *)p->vTokens->pArray[0], ".model" ) == 0 ) { char * pToken, * pPivot; if ( Vec_PtrSize(p->vTokens) != 2 ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); sprintf( p->sError, "The .model line does not have exactly two entries." ); Io_ReadBlifPrintErrorMessage( p ); return NULL; } for ( pPivot = pToken = (char *)Vec_PtrEntry(p->vTokens, 1); *pToken; pToken++ ) if ( *pToken == '/' || *pToken == '\\' ) pPivot = pToken+1; pNtk->pName = Extra_UtilStrsav( pPivot ); } else if ( strcmp( (char *)p->vTokens->pArray[0], ".exdc" ) != 0 ) { printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName, Extra_FileReaderGetLineNumber(p->pReader, 0), (char*)p->vTokens->pArray[0] ); Abc_NtkDelete(pNtk); p->pNtkCur = NULL; return NULL; } // read the inputs/outputs if ( p->pNtkMaster == NULL ) pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) ); fTokensReady = fStatus = 0; for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ ) { if ( p->pNtkMaster == NULL && iLine % 1000 == 0 ) Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL ); // consider different line types fTokensReady = 0; pDirective = (char *)p->vTokens->pArray[0]; if ( !strcmp( pDirective, ".names" ) ) { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; } else if ( !strcmp( pDirective, ".gate" ) ) fStatus = Io_ReadBlifNetworkGate( p, p->vTokens ); else if ( !strcmp( pDirective, ".latch" ) ) fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens ); else if ( !strcmp( pDirective, ".inputs" ) ) fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens ); else if ( !strcmp( pDirective, ".outputs" ) ) fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens ); else if ( !strcmp( pDirective, ".input_arrival" ) ) fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens ); else if ( !strcmp( pDirective, ".output_required" ) ) fStatus = Io_ReadBlifNetworkOutputRequired( p, p->vTokens ); else if ( !strcmp( pDirective, ".default_input_arrival" ) ) fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens ); else if ( !strcmp( pDirective, ".default_output_required" ) ) fStatus = Io_ReadBlifNetworkDefaultOutputRequired( p, p->vTokens ); else if ( !strcmp( pDirective, ".and_gate_delay" ) ) fStatus = Io_ReadBlifNetworkAndGateDelay( p, p->vTokens ); // else if ( !strcmp( pDirective, ".subckt" ) ) // fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens ); else if ( !strcmp( pDirective, ".exdc" ) ) break; else if ( !strcmp( pDirective, ".end" ) ) { p->vTokens = Io_ReadBlifGetTokens(p); break; } else if ( !strcmp( pDirective, ".blackbox" ) ) { pNtk->ntkType = ABC_NTK_NETLIST; pNtk->ntkFunc = ABC_FUNC_BLACKBOX; Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 ); pNtk->pManFunc = NULL; } else printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName, Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective ); if ( p->vTokens == NULL ) // some files do not have ".end" in the end break; if ( fStatus == 1 ) { Extra_ProgressBarStop( pProgress ); Abc_NtkDelete( pNtk ); return NULL; } } if ( p->pNtkMaster == NULL ) Extra_ProgressBarStop( pProgress ); return pNtk; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars ) { Dar_Man_t * p; ProgressBar * pProgress; Dar_Cut_t * pCut; Aig_Obj_t * pObj, * pObjNew; int i, k, nNodesOld, nNodeBefore, nNodeAfter, Required; int clk = 0, clkStart; // prepare the library Dar_LibPrepare( pPars->nSubgMax ); // create rewriting manager p = Dar_ManStart( pAig, pPars ); // remove dangling nodes Aig_ManCleanup( pAig ); // if updating levels is requested, start fanout and timing if ( p->pPars->fFanout ) Aig_ManFanoutStart( pAig ); if ( p->pPars->fUpdateLevel ) Aig_ManStartReverseLevels( pAig, 0 ); // set elementary cuts for the PIs Dar_ManCutsStart( p ); // resynthesize each node once clkStart = clock(); p->nNodesInit = Aig_ManNodeNum(pAig); nNodesOld = Vec_PtrSize( pAig->vObjs ); pProgress = Extra_ProgressBarStart( stdout, nNodesOld ); Aig_ManForEachObj( pAig, pObj, i ) // pProgress = Extra_ProgressBarStart( stdout, 100 ); // Aig_ManOrderStart( pAig ); // Aig_ManForEachNodeInOrder( pAig, pObj ) { // Extra_ProgressBarUpdate( pProgress, 100*pAig->nAndPrev/pAig->nAndTotal, NULL ); Extra_ProgressBarUpdate( pProgress, i, NULL ); if ( !Aig_ObjIsNode(pObj) ) continue; if ( i > nNodesOld ) break; // consider freeing the cuts // if ( (i & 0xFFF) == 0 && Aig_MmFixedReadMemUsage(p->pMemCuts)/(1<<20) > 100 ) // Dar_ManCutsStart( p ); // compute cuts for the node p->nNodesTried++; clk = clock(); Dar_ObjComputeCuts_rec( p, pObj ); p->timeCuts += clock() - clk; // check if there is a trivial cut Dar_ObjForEachCut( pObj, pCut, k ) if ( pCut->nLeaves == 0 || (pCut->nLeaves == 1 && pCut->pLeaves[0] != pObj->Id && Aig_ManObj(p->pAig, pCut->pLeaves[0])) ) break; if ( k < (int)pObj->nCuts ) { assert( pCut->nLeaves < 2 ); if ( pCut->nLeaves == 0 ) // replace by constant { assert( pCut->uTruth == 0 || pCut->uTruth == 0xFFFF ); pObjNew = Aig_NotCond( Aig_ManConst1(p->pAig), pCut->uTruth==0 ); } else { assert( pCut->uTruth == 0xAAAA || pCut->uTruth == 0x5555 ); pObjNew = Aig_NotCond( Aig_ManObj(p->pAig, pCut->pLeaves[0]), pCut->uTruth==0x5555 ); } // remove the old cuts Dar_ObjSetCuts( pObj, NULL ); // replace the node Aig_ObjReplace( pAig, pObj, pObjNew, 1, p->pPars->fUpdateLevel ); continue; } // evaluate the cuts p->GainBest = -1; Required = pAig->vLevelR? Aig_ObjRequiredLevel(pAig, pObj) : AIG_INFINITY; Dar_ObjForEachCut( pObj, pCut, k ) Dar_LibEval( p, pObj, pCut, Required ); // check the best gain if ( !(p->GainBest > 0 || (p->GainBest == 0 && p->pPars->fUseZeros)) ) { // Aig_ObjOrderAdvance( pAig ); continue; } // remove the old cuts Dar_ObjSetCuts( pObj, NULL ); // if we end up here, a rewriting step is accepted nNodeBefore = Aig_ManNodeNum( pAig ); pObjNew = Dar_LibBuildBest( p ); // pObjNew can be complemented! pObjNew = Aig_NotCond( pObjNew, Aig_ObjPhaseReal(pObjNew) ^ pObj->fPhase ); assert( (int)Aig_Regular(pObjNew)->Level <= Required ); // replace the node Aig_ObjReplace( pAig, pObj, pObjNew, 1, p->pPars->fUpdateLevel ); // compare the gains nNodeAfter = Aig_ManNodeNum( pAig ); assert( p->GainBest <= nNodeBefore - nNodeAfter ); // count gains of this class p->ClassGains[p->ClassBest] += nNodeBefore - nNodeAfter; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars ) { extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); Bdc_Par_t Pars = {0}, * pDecPars = &Pars; ProgressBar * pProgress; Mfs_Man_t * p; Abc_Obj_t * pObj; Vec_Vec_t * vLevels; Vec_Ptr_t * vNodes; int i, k, nNodes, nFaninMax; abctime clk = Abc_Clock(), clk2; int nTotalNodesBeg = Abc_NtkNodeNum(pNtk); int nTotalEdgesBeg = Abc_NtkGetTotalFanins(pNtk); assert( Abc_NtkIsLogic(pNtk) ); nFaninMax = Abc_NtkGetFaninMax(pNtk); if ( pPars->fResub ) { if ( nFaninMax > 8 ) { printf( "Nodes with more than %d fanins will not be processed.\n", 8 ); nFaninMax = 8; } } else { if ( nFaninMax > MFS_FANIN_MAX ) { printf( "Nodes with more than %d fanins will not be processed.\n", MFS_FANIN_MAX ); nFaninMax = MFS_FANIN_MAX; } } // perform the network sweep // Abc_NtkSweep( pNtk, 0 ); // convert into the AIG if ( !Abc_NtkToAig(pNtk) ) { fprintf( stdout, "Converting to AIGs has failed.\n" ); return 0; } assert( Abc_NtkHasAig(pNtk) ); // start the manager p = Mfs_ManAlloc( pPars ); p->pNtk = pNtk; p->nFaninMax = nFaninMax; // precomputer power-aware metrics if ( pPars->fPower ) { extern Vec_Int_t * Abc_NtkPowerEstimate( Abc_Ntk_t * pNtk, int fProbOne ); if ( pPars->fResub ) p->vProbs = Abc_NtkPowerEstimate( pNtk, 0 ); else p->vProbs = Abc_NtkPowerEstimate( pNtk, 1 ); #if 0 printf( "Total switching before = %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) ); #else p->TotalSwitchingBeg = Abc_NtkMfsTotalSwitching(pNtk); #endif } if ( pNtk->pExcare ) { Abc_Ntk_t * pTemp; if ( Abc_NtkPiNum((Abc_Ntk_t *)pNtk->pExcare) != Abc_NtkCiNum(pNtk) ) printf( "The PI count of careset (%d) and logic network (%d) differ. Careset is not used.\n", Abc_NtkPiNum((Abc_Ntk_t *)pNtk->pExcare), Abc_NtkCiNum(pNtk) ); else { pTemp = Abc_NtkStrash( (Abc_Ntk_t *)pNtk->pExcare, 0, 0, 0 ); p->pCare = Abc_NtkToDar( pTemp, 0, 0 ); Abc_NtkDelete( pTemp ); p->vSuppsInv = Aig_ManSupportsInverse( p->pCare ); } } if ( p->pCare != NULL ) printf( "Performing optimization with %d external care clauses.\n", Aig_ManCoNum(p->pCare) ); // prepare the BDC manager if ( !pPars->fResub ) { pDecPars->nVarsMax = (nFaninMax < 3) ? 3 : nFaninMax; pDecPars->fVerbose = pPars->fVerbose; p->vTruth = Vec_IntAlloc( 0 ); p->pManDec = Bdc_ManAlloc( pDecPars ); } // label the register outputs if ( p->pCare ) { Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pData = (void *)(ABC_PTRUINT_T)i; } // compute levels Abc_NtkLevel( pNtk ); Abc_NtkStartReverseLevels( pNtk, pPars->nGrowthLevel ); // compute don't-cares for each node nNodes = 0; p->nTotalNodesBeg = nTotalNodesBeg; p->nTotalEdgesBeg = nTotalEdgesBeg; if ( pPars->fResub ) { #if 0 printf( "TotalSwitching (%7.2f --> ", Abc_NtkMfsTotalSwitching(pNtk) ); #endif if (pPars->fPower) { Abc_NtkMfsPowerResub( p, pPars); } else { pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); Abc_NtkForEachNode( pNtk, pObj, i ) { if ( p->pPars->nDepthMax && (int)pObj->Level > p->pPars->nDepthMax ) continue; if ( Abc_ObjFaninNum(pObj) < 2 || Abc_ObjFaninNum(pObj) > nFaninMax ) continue; if ( !p->pPars->fVeryVerbose ) Extra_ProgressBarUpdate( pProgress, i, NULL ); if ( pPars->fResub ) Abc_NtkMfsResub( p, pObj ); else Abc_NtkMfsNode( p, pObj ); } Extra_ProgressBarStop( pProgress ); #if 0 printf( " %7.2f )\n", Abc_NtkMfsTotalSwitching(pNtk) ); #endif } } else
/**Function************************************************************* Synopsis [Computes the best matches of the nodes.] Description [Uses parameter p->fMappingMode to decide how to assign the matches for both polarities of the node. While the matches are being assigned, one of them may turn out to be better than the other (in terms of delay, for example). In this case, the worse match can be permanently dropped, and the corresponding pointer set to NULL.] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_MappingMatches( Map_Man_t * p ) { ProgressBar * pProgress; Map_Node_t * pNode; int i; assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 ); // use the externally given PI arrival times if ( p->fMappingMode == 0 ) Map_MappingSetPiArrivalTimes( p ); // estimate the fanouts if ( p->fMappingMode == 0 ) Map_MappingEstimateRefsInit( p ); else if ( p->fMappingMode == 1 ) Map_MappingEstimateRefs( p ); // the PI cuts are matched in the cut computation package // in the loop below we match the internal nodes pProgress = Extra_ProgressBarStart( stdout, p->vAnds->nSize ); for ( i = 0; i < p->vAnds->nSize; i++ ) { // skip primary inputs and secondary nodes if mapping with choices pNode = p->vAnds->pArray[i]; if ( !Map_NodeIsAnd( pNode ) || pNode->pRepr ) continue; // make sure that at least one non-trival cut is present if ( pNode->pCuts->pNext == NULL ) { Extra_ProgressBarStop( pProgress ); printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" ); return 0; } // match negative phase if ( !Map_MatchNodePhase( p, pNode, 0 ) ) { Extra_ProgressBarStop( pProgress ); return 0; } // match positive phase if ( !Map_MatchNodePhase( p, pNode, 1 ) ) { Extra_ProgressBarStop( pProgress ); return 0; } // make sure that at least one phase is mapped if ( pNode->pCutBest[0] == NULL && pNode->pCutBest[1] == NULL ) { printf( "\nError: Could not match both phases of AIG node %d.\n", pNode->Num ); printf( "Please make sure that the supergate library has equivalents of AND2 or NAND2.\n" ); printf( "If such supergates exist in the library, report a bug.\n" ); Extra_ProgressBarStop( pProgress ); return 0; } // if both phases are assigned, check if one of them can be dropped Map_NodeTryDroppingOnePhase( p, pNode ); // set the arrival times of the node using the best cuts Map_NodeTransferArrivalTimes( p, pNode ); // update the progress bar Extra_ProgressBarUpdate( pProgress, i, "Matches ..." ); } Extra_ProgressBarStop( pProgress ); return 1; }
/**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++; }
/**Function************************************************************* Synopsis [Reads the library file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_LibraryReadFile( Map_SuperLib_t * pLib, FILE * pFile ) { ProgressBar * pProgress; char pBuffer[5000]; FILE * pFileGen; Map_Super_t * pGate; char * pTemp = NULL; // Suppress "might be used uninitialized" char * pLibName; int nCounter, nGatesTotal; unsigned uCanon[2]; int RetValue; // skip empty and comment lines while ( fgets( pBuffer, 2000, pFile ) != NULL ) { // skip leading spaces for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ ); // skip comment lines and empty lines if ( *pTemp != 0 && *pTemp != '#' ) break; } // get the genlib file name pLibName = strtok( pTemp, " \t\r\n" ); if ( strcmp( pLibName, "GATE" ) == 0 ) { printf( "The input file \"%s\" looks like a genlib file and not a supergate library file.\n", pLib->pName ); return 0; } pFileGen = fopen( pLibName, "r" ); if ( pFileGen == NULL ) { printf( "Cannot open the genlib file \"%s\".\n", pLibName ); return 0; } fclose( pFileGen ); // read the genlib library pLib->pGenlib = Mio_LibraryRead( pLibName, NULL, 0, 0 ); if ( pLib->pGenlib == NULL ) { printf( "Cannot read genlib file \"%s\".\n", pLibName ); return 0; } // read the number of variables RetValue = fscanf( pFile, "%d\n", &pLib->nVarsMax ); if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 ) { printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax ); return 0; } // read the number of gates RetValue = fscanf( pFile, "%d\n", &nGatesTotal ); if ( nGatesTotal < 1 || nGatesTotal > 10000000 ) { printf( "Suspicious number of gates (%d).\n", nGatesTotal ); return 0; } // read the lines nCounter = 0; pProgress = Extra_ProgressBarStart( stdout, nGatesTotal ); while ( fgets( pBuffer, 5000, pFile ) != NULL ) { for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ ); if ( pTemp[0] == '\0' ) continue; // get the gate pGate = Map_LibraryReadGate( pLib, pTemp, pLib->nVarsMax ); assert( pGate->Num == nCounter + 1 ); // count the number of parentheses in the formula - this is the number of gates for ( pTemp = pGate->pFormula; *pTemp; pTemp++ ) pGate->nGates += (*pTemp == '('); // verify the truth table assert( Map_LibraryTruthVerify(pLib, pGate) ); // find the N-canonical form of this supergate pGate->nPhases = Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, pLib->nVarsMax, pGate->uTruth, pGate->uPhases, uCanon ); // add the supergate into the table by its N-canonical table Map_SuperTableInsertC( pLib->tTableC, uCanon, pGate ); // update the progress bar Extra_ProgressBarUpdate( pProgress, ++nCounter, NULL ); } Extra_ProgressBarStop( pProgress ); pLib->nSupersAll = nCounter; if ( nCounter != nGatesTotal ) printf( "The number of gates read (%d) is different what the file says (%d).\n", nGatesTotal, nCounter ); return 1; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p ) { ProgressBar * pProgress; Vec_Ptr_t * vTokens; Abc_Ntk_t * pNtk; Abc_Obj_t * pNet, * pObj, * pFanout; char * pGateName, * pNetName; int fTokensReady, iLine, i; // read the first line vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); if ( strcmp( (char *)vTokens->pArray[0], "edif" ) != 0 ) { printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) ); return NULL; } // allocate the empty network pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) ); // go through the lines of the file fTokensReady = 0; pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) ); for ( iLine = 1; fTokensReady || (vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p)); iLine++ ) { Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL ); // get the type of the line fTokensReady = 0; if ( strcmp( (char *)vTokens->pArray[0], "instance" ) == 0 ) { pNetName = (char *)vTokens->pArray[1]; pNet = Abc_NtkFindOrCreateNet( pNtk, pNetName ); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); pGateName = (char *)vTokens->pArray[1]; if ( strncmp( pGateName, "Flip", 4 ) == 0 ) { pObj = Abc_NtkCreateLatch( pNtk ); Abc_LatchSetInit0( pObj ); } else { pObj = Abc_NtkCreateNode( pNtk ); // pObj->pData = Abc_NtkRegisterName( pNtk, pGateName ); pObj->pData = Extra_UtilStrsav( pGateName ); // memory leak!!! } Abc_ObjAddFanin( pNet, pObj ); } else if ( strcmp( (char *)vTokens->pArray[0], "net" ) == 0 ) { pNetName = (char *)vTokens->pArray[1]; if ( strcmp( pNetName, "CK" ) == 0 || strcmp( pNetName, "RESET" ) == 0 ) continue; if ( strcmp( pNetName + strlen(pNetName) - 4, "_out" ) == 0 ) pNetName[strlen(pNetName) - 4] = 0; pNet = Abc_NtkFindNet( pNtk, pNetName ); assert( pNet ); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); while ( strcmp( (char *)vTokens->pArray[0], "portRef" ) == 0 ) { if ( strcmp( pNetName, (char *)vTokens->pArray[3] ) != 0 ) { pFanout = Abc_NtkFindNet( pNtk, (char *)vTokens->pArray[3] ); Abc_ObjAddFanin( Abc_ObjFanin0(pFanout), pNet ); } vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); } fTokensReady = 1; } else if ( strcmp( (char *)vTokens->pArray[0], "library" ) == 0 ) { vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); while ( strcmp( (char *)vTokens->pArray[0], "port" ) == 0 ) { pNetName = (char *)vTokens->pArray[1]; if ( strcmp( pNetName, "CK" ) == 0 || strcmp( pNetName, "RESET" ) == 0 ) { vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); continue; } if ( strcmp( pNetName + strlen(pNetName) - 3, "_PO" ) == 0 ) pNetName[strlen(pNetName) - 3] = 0; if ( strcmp( (char *)vTokens->pArray[3], "INPUT" ) == 0 ) Io_ReadCreatePi( pNtk, (char *)vTokens->pArray[1] ); else if ( strcmp( (char *)vTokens->pArray[3], "OUTPUT" ) == 0 ) Io_ReadCreatePo( pNtk, (char *)vTokens->pArray[1] ); else { printf( "%s (line %d): Wrong interface specification.\n", Extra_FileReaderGetFileName(p), iLine ); Abc_NtkDelete( pNtk ); return NULL; } vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p); } } else if ( strcmp( (char *)vTokens->pArray[0], "design" ) == 0 ) { ABC_FREE( pNtk->pName ); pNtk->pName = (char *)Extra_UtilStrsav( (char *)vTokens->pArray[3] ); break; } } Extra_ProgressBarStop( pProgress ); // assign logic functions Abc_NtkForEachNode( pNtk, pObj, i ) { if ( strncmp( (char *)pObj->pData, "And", 3 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); else if ( strncmp( (char *)pObj->pData, "Or", 2 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); else if ( strncmp( (char *)pObj->pData, "Nand", 4 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Nor", 3 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Exor", 4 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Exnor", 5 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Inv", 3 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strncmp( (char *)pObj->pData, "Buf", 3 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else { printf( "%s: Unknown gate type \"%s\".\n", Extra_FileReaderGetFileName(p), (char*)pObj->pData ); Abc_NtkDelete( pNtk ); return NULL; } } // check if constants have been added // if ( pNet = Abc_NtkFindNet( pNtk, "VDD" ) ) // Io_ReadCreateConst( pNtk, "VDD", 1 ); // if ( pNet = Abc_NtkFindNet( pNtk, "GND" ) ) // Io_ReadCreateConst( pNtk, "GND", 0 ); Abc_NtkFinalizeRead( pNtk ); return pNtk; }
/**Function************************************************************* Synopsis [Performs incremental rewriting of the AIG.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ) { extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Cut_Man_t * pManCut; Rwr_Man_t * pManRwr; Abc_Obj_t * pNode; // Vec_Ptr_t * vAddedCells = NULL, * vUpdatedNets = NULL; Dec_Graph_t * pGraph; int i, nNodes, nGain, fCompl; abctime clk, clkStart = Abc_Clock(); assert( Abc_NtkIsStrash(pNtk) ); // cleanup the AIG Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); /* { Vec_Vec_t * vParts; vParts = Abc_NtkPartitionSmart( pNtk, 50, 1 ); Vec_VecFree( vParts ); } */ // start placement package // if ( fPlaceEnable ) // { // Abc_PlaceBegin( pNtk ); // vAddedCells = Abc_AigUpdateStart( pNtk->pManFunc, &vUpdatedNets ); // } // start the rewriting manager pManRwr = Rwr_ManStart( 0 ); if ( pManRwr == NULL ) return 0; // compute the reverse levels if level update is requested if ( fUpdateLevel ) Abc_NtkStartReverseLevels( pNtk, 0 ); // start the cut manager clk = Abc_Clock(); pManCut = Abc_NtkStartCutManForRewrite( pNtk ); Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); pNtk->pManCut = pManCut; if ( fVeryVerbose ) Rwr_ScoresClean( pManRwr ); // resynthesize each node once pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); nNodes = Abc_NtkObjNumMax(pNtk); pProgress = Extra_ProgressBarStart( stdout, nNodes ); Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); // stop if all nodes have been tried once if ( i >= nNodes ) break; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; // for each cut, try to resynthesize it nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); if ( !(nGain > 0 || (nGain == 0 && fUseZeros)) ) continue; // if we end up here, a rewriting step is accepted // get hold of the new subgraph to be added to the AIG pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); fCompl = Rwr_ManReadCompl(pManRwr); // reset the array of the changed nodes if ( fPlaceEnable ) Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); // complement the FF if needed if ( fCompl ) Dec_GraphComplement( pGraph ); clk = Abc_Clock(); Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); if ( fCompl ) Dec_GraphComplement( pGraph ); // use the array of changed nodes to update placement // if ( fPlaceEnable ) // Abc_PlaceUpdate( vAddedCells, vUpdatedNets ); }