/**Function************************************************************* Synopsis [Computes equivalence classes of objects in pNtk1 and pNtk2.] Description [Returns the array (Vec_Ptr_t) of integer arrays (Vec_Int_t). Each of the integer arrays contains entries of one equivalence class. Each entry contains the following information: the network number (0/1), the polarity (0/1) and the object ID in the the network (0 <= num < MaxId) where MaxId is the largest number of an ID of an object in that network.] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Abc_NtkDressComputeEquivs( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConflictLimit, int fVerbose ) { Dch_Pars_t Pars, * pPars = &Pars; Abc_Ntk_t * pAig1, * pAig2; Aig_Man_t * pMan1, * pMan2, * pMiter; Vec_Ptr_t * vRes; assert( !Abc_NtkIsStrash(pNtk1) ); assert( !Abc_NtkIsStrash(pNtk2) ); // convert network into AIG pAig1 = Abc_NtkStrash( pNtk1, 1, 1, 0 ); pAig2 = Abc_NtkStrash( pNtk2, 1, 1, 0 ); pMan1 = Abc_NtkToDar( pAig1, 0, 0 ); pMan2 = Abc_NtkToDar( pAig2, 0, 0 ); // derive the miter pMiter = Aig_ManCreateDualOutputMiter( pMan1, pMan2 ); // set up parameters for SAT sweeping Dch_ManSetDefaultParams( pPars ); pPars->nBTLimit = nConflictLimit; pPars->fVerbose = fVerbose; // perform SAT sweeping Dch_ComputeEquivalences( pMiter, pPars ); // now, pMiter is annotated with the equivl class info // convert this info into the resulting array vRes = Abc_NtkDressMapIds( pMiter, pNtk1, pNtk2 ); Aig_ManStop( pMiter ); Aig_ManStop( pMan1 ); Aig_ManStop( pMan2 ); Abc_NtkDelete( pAig1 ); Abc_NtkDelete( pAig2 ); return vRes; }
/**Function************************************************************* Synopsis [Derives the miter of two networks.] Description [Preprocesses the networks to make sure that they are strashed.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, int nPartSize, int fImplic, int fMulti ) { Abc_Ntk_t * pTemp = NULL; int fRemove1, fRemove2; assert( Abc_NtkHasOnlyLatchBoxes(pNtk1) ); assert( Abc_NtkHasOnlyLatchBoxes(pNtk2) ); // check that the networks have the same PIs/POs/latches if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 0, fComb ) ) return NULL; // make sure the circuits are strashed fRemove1 = (!Abc_NtkIsStrash(pNtk1) || Abc_NtkGetChoiceNum(pNtk1)) && (pNtk1 = Abc_NtkStrash(pNtk1, 0, 0, 0)); fRemove2 = (!Abc_NtkIsStrash(pNtk2) || Abc_NtkGetChoiceNum(pNtk2)) && (pNtk2 = Abc_NtkStrash(pNtk2, 0, 0, 0)); if ( pNtk1 && pNtk2 ) pTemp = Abc_NtkMiterInt( pNtk1, pNtk2, fComb, nPartSize, fImplic, fMulti ); if ( fRemove1 ) Abc_NtkDelete( pNtk1 ); if ( fRemove2 ) Abc_NtkDelete( pNtk2 ); return pTemp; }
/**Function************************************************************* Synopsis [Initialize the solver internal data structure.] Description [Prepares the solver to work on one specific target set by calling ABC_AddTarget before.] SideEffects [] SeeAlso [] ***********************************************************************/ void ABC_SolveInit( ABC_Manager mng ) { // check if the target is available assert( mng->nog == Vec_PtrSize(mng->vNodes) ); if ( mng->nog == 0 ) { printf( "ABC_SolveInit: Target is not specified by ABC_AddTarget().\n" ); return; } // free the previous target network if present if ( mng->pTarget ) Abc_NtkDelete( mng->pTarget ); // set the new target network // mng->pTarget = Abc_NtkCreateTarget( mng->pNtk, mng->vNodes, mng->vValues ); mng->pTarget = Abc_NtkStrash( mng->pNtk, 0, 1, 0 ); }
/**Function************************************************************* Synopsis [Dumps the original network into the BENCH file.] Description [This procedure should be modified to dump the target.] SideEffects [] SeeAlso [] ***********************************************************************/ void ABC_Dump_Bench_File( ABC_Manager mng ) { Abc_Ntk_t * pNtkTemp, * pNtkAig; const char * pFileName; // derive the netlist pNtkAig = Abc_NtkStrash( mng->pNtk, 0, 0, 0 ); pNtkTemp = Abc_NtkToNetlistBench( pNtkAig ); Abc_NtkDelete( pNtkAig ); if ( pNtkTemp == NULL ) { printf( "ABC_Dump_Bench_File: Dumping BENCH has failed.\n" ); return; } pFileName = mng->pDumpFileName? mng->pDumpFileName: "abc_test.bench"; Io_WriteBench( pNtkTemp, pFileName ); Abc_NtkDelete( pNtkTemp ); }
/**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 [Transfers names from one netlist to the other.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkDress( Abc_Ntk_t * pNtkLogic, char * pFileName, int fVerbose ) { Abc_Ntk_t * pNtkOrig, * pNtkLogicOrig; Abc_Ntk_t * pMiter, * pMiterFraig; stmm_table * tMapping; assert( Abc_NtkIsLogic(pNtkLogic) ); // get the original netlist pNtkOrig = Io_ReadNetlist( pFileName, Io_ReadFileType(pFileName), 1 ); if ( pNtkOrig == NULL ) return; assert( Abc_NtkIsNetlist(pNtkOrig) ); Abc_NtkCleanCopy(pNtkLogic); Abc_NtkCleanCopy(pNtkOrig); // convert it into the logic network pNtkLogicOrig = Abc_NtkToLogic( pNtkOrig ); // check that the networks have the same PIs/POs/latches if ( !Abc_NtkCompareSignals( pNtkLogic, pNtkLogicOrig, 1, 1 ) ) { Abc_NtkDelete( pNtkOrig ); Abc_NtkDelete( pNtkLogicOrig ); return; } // convert the current logic network into an AIG pMiter = Abc_NtkStrash( pNtkLogic, 1, 0, 0 ); // convert it into the AIG and make the netlist point to the AIG Abc_NtkAppend( pMiter, pNtkLogicOrig, 1 ); Abc_NtkTransferCopy( pNtkOrig ); Abc_NtkDelete( pNtkLogicOrig ); if ( fVerbose ) { printf( "After mitering:\n" ); printf( "Logic: Nodes = %5d. Copy = %5d. \n", Abc_NtkNodeNum(pNtkLogic), Abc_NtkCountCopy(pNtkLogic) ); printf( "Orig: Nodes = %5d. Copy = %5d. \n", Abc_NtkNodeNum(pNtkOrig), Abc_NtkCountCopy(pNtkOrig) ); } // fraig the miter (miter nodes point to the fraiged miter) pMiterFraig = Abc_NtkIvyFraig( pMiter, 100, 1, 0, 1, 0 ); // make netlists point to the fraiged miter Abc_NtkTransferCopy( pNtkLogic ); Abc_NtkTransferCopy( pNtkOrig ); Abc_NtkDelete( pMiter ); if ( fVerbose ) { printf( "After fraiging:\n" ); printf( "Logic: Nodes = %5d. Copy = %5d. \n", Abc_NtkNodeNum(pNtkLogic), Abc_NtkCountCopy(pNtkLogic) ); printf( "Orig: Nodes = %5d. Copy = %5d. \n", Abc_NtkNodeNum(pNtkOrig), Abc_NtkCountCopy(pNtkOrig) ); } // derive mapping from the fraiged nodes into their prototype nodes in the original netlist tMapping = Abc_NtkDressDeriveMapping( pNtkOrig ); // transfer the names to the new netlist Abc_NtkDressTransferNames( pNtkLogic, tMapping, fVerbose ); // clean up stmm_free_table( tMapping ); Abc_NtkDelete( pMiterFraig ); Abc_NtkDelete( pNtkOrig ); }