00001
00021 #include "abc.h"
00022 #include "main.h"
00023 #include "mio.h"
00024 #include "dec.h"
00025
00026
00030
00034
00046 void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan )
00047 {
00048 void * pUserMan;
00049 Vec_Att_t * pAttrMan;
00050 pAttrMan = Vec_PtrEntry( pNtk->vAttrs, Attr );
00051 Vec_PtrWriteEntry( pNtk->vAttrs, Attr, NULL );
00052 pUserMan = Vec_AttFree( pAttrMan, fFreeMan );
00053 return pUserMan;
00054 }
00055
00067 void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk )
00068 {
00069 Abc_Obj_t * pObj;
00070 int i;
00071 if ( pNtk->nTravIds >= (1<<30)-1 )
00072 {
00073 pNtk->nTravIds = 0;
00074 Abc_NtkForEachObj( pNtk, pObj, i )
00075 pObj->TravId = 0;
00076 }
00077 pNtk->nTravIds++;
00078 }
00079
00091 void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk )
00092 {
00093 Abc_Obj_t * pObj, * pTerm;
00094 int i, k;
00095 Vec_PtrClear( pNtk->vCis );
00096 Vec_PtrClear( pNtk->vCos );
00097 Abc_NtkForEachPi( pNtk, pObj, i )
00098 Vec_PtrPush( pNtk->vCis, pObj );
00099 Abc_NtkForEachPo( pNtk, pObj, i )
00100 Vec_PtrPush( pNtk->vCos, pObj );
00101 Abc_NtkForEachAssert( pNtk, pObj, i )
00102 Vec_PtrPush( pNtk->vCos, pObj );
00103 Abc_NtkForEachBox( pNtk, pObj, i )
00104 {
00105 if ( Abc_ObjIsLatch(pObj) )
00106 continue;
00107 Abc_ObjForEachFanin( pObj, pTerm, k )
00108 Vec_PtrPush( pNtk->vCos, pTerm );
00109 Abc_ObjForEachFanout( pObj, pTerm, k )
00110 Vec_PtrPush( pNtk->vCis, pTerm );
00111 }
00112 Abc_NtkForEachBox( pNtk, pObj, i )
00113 {
00114 if ( !Abc_ObjIsLatch(pObj) )
00115 continue;
00116 Abc_ObjForEachFanin( pObj, pTerm, k )
00117 Vec_PtrPush( pNtk->vCos, pTerm );
00118 Abc_ObjForEachFanout( pObj, pTerm, k )
00119 Vec_PtrPush( pNtk->vCis, pTerm );
00120 }
00121 }
00122
00134 int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
00135 {
00136 Abc_Obj_t * pNode;
00137 int i, nCubes = 0;
00138 assert( Abc_NtkHasSop(pNtk) );
00139 Abc_NtkForEachNode( pNtk, pNode, i )
00140 {
00141 if ( Abc_NodeIsConst(pNode) )
00142 continue;
00143 assert( pNode->pData );
00144 nCubes += Abc_SopGetCubeNum( pNode->pData );
00145 }
00146 return nCubes;
00147 }
00148
00160 int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk )
00161 {
00162 Abc_Obj_t * pNode;
00163 int i, nCubes, nCubePairs = 0;
00164 assert( Abc_NtkHasSop(pNtk) );
00165 Abc_NtkForEachNode( pNtk, pNode, i )
00166 {
00167 if ( Abc_NodeIsConst(pNode) )
00168 continue;
00169 assert( pNode->pData );
00170 nCubes = Abc_SopGetCubeNum( pNode->pData );
00171 nCubePairs += nCubes * (nCubes - 1) / 2;
00172 }
00173 return nCubePairs;
00174 }
00175
00187 int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk )
00188 {
00189 Abc_Obj_t * pNode;
00190 int i, nLits = 0;
00191 assert( Abc_NtkHasSop(pNtk) );
00192 Abc_NtkForEachNode( pNtk, pNode, i )
00193 {
00194 assert( pNode->pData );
00195 nLits += Abc_SopGetLitNum( pNode->pData );
00196 }
00197 return nLits;
00198 }
00199
00211 int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk )
00212 {
00213 Dec_Graph_t * pFactor;
00214 Abc_Obj_t * pNode;
00215 int nNodes, i;
00216 assert( Abc_NtkHasSop(pNtk) );
00217 nNodes = 0;
00218 Abc_NtkForEachNode( pNtk, pNode, i )
00219 {
00220 if ( Abc_NodeIsConst(pNode) )
00221 continue;
00222 pFactor = Dec_Factor( pNode->pData );
00223 nNodes += 1 + Dec_GraphNodeNum(pFactor);
00224 Dec_GraphFree( pFactor );
00225 }
00226 return nNodes;
00227 }
00228
00240 int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk )
00241 {
00242 Abc_Obj_t * pNode;
00243 int i, nNodes = 0;
00244 assert( Abc_NtkIsBddLogic(pNtk) );
00245 Abc_NtkForEachNode( pNtk, pNode, i )
00246 {
00247 assert( pNode->pData );
00248 if ( Abc_ObjFaninNum(pNode) < 2 )
00249 continue;
00250 nNodes += pNode->pData? -1 + Cudd_DagSize( pNode->pData ) : 0;
00251 }
00252 return nNodes;
00253 }
00254
00266 int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk )
00267 {
00268 Abc_Obj_t * pNode;
00269 int i, nNodes = 0;
00270 assert( Abc_NtkIsAigLogic(pNtk) );
00271 Abc_NtkForEachNode( pNtk, pNode, i )
00272 {
00273 assert( pNode->pData );
00274 if ( Abc_ObjFaninNum(pNode) < 2 )
00275 continue;
00276
00277 nNodes += pNode->pData? Hop_DagSize( pNode->pData ) : 0;
00278 }
00279 return nNodes;
00280 }
00281
00293 int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk )
00294 {
00295 Abc_Obj_t * pNode;
00296 DdNode * bCover, * zCover, * bFunc;
00297 DdManager * dd = pNtk->pManFunc;
00298 int i, nClauses = 0;
00299 assert( Abc_NtkIsBddLogic(pNtk) );
00300 Abc_NtkForEachNode( pNtk, pNode, i )
00301 {
00302 assert( pNode->pData );
00303 bFunc = pNode->pData;
00304
00305 bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover );
00306 Cudd_Ref( bCover );
00307 Cudd_Ref( zCover );
00308 nClauses += Abc_CountZddCubes( dd, zCover );
00309 Cudd_RecursiveDeref( dd, bCover );
00310 Cudd_RecursiveDerefZdd( dd, zCover );
00311
00312 bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover );
00313 Cudd_Ref( bCover );
00314 Cudd_Ref( zCover );
00315 nClauses += Abc_CountZddCubes( dd, zCover );
00316 Cudd_RecursiveDeref( dd, bCover );
00317 Cudd_RecursiveDerefZdd( dd, zCover );
00318 }
00319 return nClauses;
00320 }
00321
00333 double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk )
00334 {
00335 Abc_Obj_t * pNode;
00336 double TotalArea;
00337 int i;
00338 assert( Abc_NtkHasMapping(pNtk) );
00339 TotalArea = 0.0;
00340 Abc_NtkForEachNode( pNtk, pNode, i )
00341 {
00342
00343 if ( pNode->pData == NULL )
00344 {
00345 printf( "Node without mapping is encountered.\n" );
00346 continue;
00347 }
00348 TotalArea += Mio_GateReadArea( pNode->pData );
00349 }
00350 return TotalArea;
00351 }
00352
00364 int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk )
00365 {
00366 Abc_Obj_t * pNode;
00367 int i, Counter = 0;
00368 Abc_NtkForEachNode( pNtk, pNode, i )
00369 Counter += pNode->fExor;
00370 return Counter;
00371 }
00372
00384 int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk )
00385 {
00386 Abc_Obj_t * pNode;
00387 int i, Counter = 0;
00388 Abc_NtkForEachNode( pNtk, pNode, i )
00389 Counter += Abc_NodeIsMuxType(pNode);
00390 return Counter;
00391 }
00392
00404 int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk )
00405 {
00406 Abc_Obj_t * pNode;
00407 int i, Counter;
00408 if ( !Abc_NtkIsStrash(pNtk) )
00409 return 0;
00410 Counter = 0;
00411 Abc_NtkForEachNode( pNtk, pNode, i )
00412 Counter += Abc_AigNodeIsChoice( pNode );
00413 return Counter;
00414 }
00415
00427 int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk )
00428 {
00429 Abc_Obj_t * pNode;
00430 int i, nFaninsMax = 0;
00431 Abc_NtkForEachNode( pNtk, pNode, i )
00432 {
00433 if ( nFaninsMax < Abc_ObjFaninNum(pNode) )
00434 nFaninsMax = Abc_ObjFaninNum(pNode);
00435 }
00436 return nFaninsMax;
00437 }
00438
00450 int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk )
00451 {
00452 Abc_Obj_t * pNode;
00453 int i, nFanins = 0;
00454 Abc_NtkForEachNode( pNtk, pNode, i )
00455 nFanins += Abc_ObjFaninNum(pNode);
00456 return nFanins;
00457 }
00458
00470 void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk )
00471 {
00472 Abc_Obj_t * pObj;
00473 int i;
00474 Abc_NtkForEachObj( pNtk, pObj, i )
00475 pObj->pCopy = NULL;
00476 }
00477
00489 void Abc_NtkCleanData( Abc_Ntk_t * pNtk )
00490 {
00491 Abc_Obj_t * pObj;
00492 int i;
00493 Abc_NtkForEachObj( pNtk, pObj, i )
00494 pObj->pData = NULL;
00495 }
00496
00508 void Abc_NtkCleanEquiv( Abc_Ntk_t * pNtk )
00509 {
00510 Abc_Obj_t * pObj;
00511 int i;
00512 Abc_NtkForEachObj( pNtk, pObj, i )
00513 pObj->pEquiv = NULL;
00514 }
00515
00527 int Abc_NtkCountCopy( Abc_Ntk_t * pNtk )
00528 {
00529 Abc_Obj_t * pObj;
00530 int i, Counter = 0;
00531 Abc_NtkForEachObj( pNtk, pObj, i )
00532 {
00533 if ( Abc_ObjIsNode(pObj) )
00534 Counter += (pObj->pCopy != NULL);
00535 }
00536 return Counter;
00537 }
00538
00550 Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk )
00551 {
00552 Vec_Ptr_t * vCopies;
00553 Abc_Obj_t * pObj;
00554 int i;
00555 vCopies = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
00556 Abc_NtkForEachObj( pNtk, pObj, i )
00557 Vec_PtrWriteEntry( vCopies, i, pObj->pCopy );
00558 return vCopies;
00559 }
00560
00572 void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies )
00573 {
00574 Abc_Obj_t * pObj;
00575 int i;
00576 Abc_NtkForEachObj( pNtk, pObj, i )
00577 pObj->pCopy = Vec_PtrEntry( vCopies, i );
00578 }
00579
00591 void Abc_NtkCleanNext( Abc_Ntk_t * pNtk )
00592 {
00593 Abc_Obj_t * pObj;
00594 int i = 0;
00595 Abc_NtkForEachObj( pNtk, pObj, i )
00596 pObj->pNext = NULL;
00597 }
00598
00610 void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk )
00611 {
00612 Abc_Obj_t * pObj;
00613 int i = 0;
00614 Abc_NtkForEachObj( pNtk, pObj, i )
00615 pObj->fMarkA = 0;
00616 }
00617
00629 Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode )
00630 {
00631 Abc_Obj_t * pFanout;
00632 int i;
00633 Abc_ObjForEachFanout( pNode, pFanout, i )
00634 if ( Abc_ObjIsCo(pFanout) )
00635 return pFanout;
00636 return NULL;
00637 }
00638
00650 Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode )
00651 {
00652 Abc_Obj_t * pFanout;
00653 int i;
00654 Abc_ObjForEachFanout( pNode, pFanout, i )
00655 if ( !Abc_ObjIsCo(pFanout) )
00656 return pFanout;
00657 return NULL;
00658 }
00659
00673 Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
00674 {
00675 Abc_Obj_t * pFanout, * pFanoutCo;
00676 int i;
00677 pFanoutCo = NULL;
00678 Abc_ObjForEachFanout( pNode, pFanout, i )
00679 {
00680 if ( !Abc_ObjIsCo(pFanout) )
00681 continue;
00682 if ( Abc_ObjFaninC0(pFanout) )
00683 continue;
00684 if ( pFanoutCo == NULL )
00685 {
00686 assert( Abc_ObjFaninNum(pFanout) == 1 );
00687 assert( Abc_ObjFanin0(pFanout) == pNode );
00688 pFanoutCo = pFanout;
00689 continue;
00690 }
00691 if ( strcmp( Abc_ObjName(pFanoutCo), Abc_ObjName(pFanout) ) )
00692 return NULL;
00693 }
00694 return pFanoutCo;
00695 }
00696
00708 void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fDuplicate )
00709 {
00710 Abc_Ntk_t * pNtk = pDriver->pNtk;
00711 Abc_Obj_t * pDriverNew, * pFanin;
00712 int k;
00713 if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
00714 {
00715 pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
00716 Abc_ObjForEachFanin( pDriver, pFanin, k )
00717 Abc_ObjAddFanin( pDriverNew, pFanin );
00718 if ( Abc_ObjFaninC0(pNodeCo) )
00719 {
00720
00721 Abc_NodeComplement( pDriverNew );
00722 Abc_ObjXorFaninC( pNodeCo, 0 );
00723 }
00724 }
00725 else
00726 {
00727
00728 if ( Abc_ObjFaninC0(pNodeCo) )
00729 {
00730 pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
00731 Abc_ObjXorFaninC( pNodeCo, 0 );
00732 }
00733 else
00734 pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
00735 }
00736
00737 Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
00738 assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
00739
00740
00741 if ( Abc_ObjFanoutNum(pDriver) == 0 )
00742 Abc_NtkDeleteObj( pDriver );
00743 }
00744
00759 bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
00760 {
00761 Abc_Obj_t * pNode, * pDriver;
00762 int i;
00763 assert( Abc_NtkIsLogic(pNtk) );
00764 Abc_NtkIncrementTravId( pNtk );
00765 Abc_NtkForEachCo( pNtk, pNode, i )
00766 {
00767
00768 pDriver = Abc_ObjFanin0(pNode);
00769 if ( Abc_ObjFaninC0(pNode) )
00770 return 0;
00771
00772 if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
00773 return 0;
00774
00775 if ( !Abc_NodeIsTravIdCurrent(pDriver) )
00776 {
00777 pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
00778 Abc_NodeSetTravIdCurrent(pDriver);
00779 continue;
00780 }
00781
00782 if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) )
00783 return 0;
00784 }
00785 return 1;
00786 }
00787
00804 int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate )
00805 {
00806 Abc_Obj_t * pNode, * pDriver;
00807 int i, nDupGates = 0;
00808 assert( Abc_NtkIsLogic(pNtk) );
00809 Abc_NtkIncrementTravId( pNtk );
00810 Abc_NtkForEachCo( pNtk, pNode, i )
00811 {
00812
00813 pDriver = Abc_ObjFanin0(pNode);
00814 if ( Abc_ObjFaninC0(pNode) )
00815 {
00816 Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
00817 nDupGates++;
00818 continue;
00819 }
00820
00821 if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
00822 {
00823 Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
00824 nDupGates++;
00825 continue;
00826 }
00827
00828 if ( !Abc_NodeIsTravIdCurrent(pDriver) )
00829 {
00830 pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
00831 Abc_NodeSetTravIdCurrent(pDriver);
00832 continue;
00833 }
00834
00835 if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) )
00836 {
00837 Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
00838 nDupGates++;
00839 continue;
00840 }
00841 }
00842 assert( Abc_NtkLogicHasSimpleCos(pNtk) );
00843 return nDupGates;
00844 }
00845
00857 void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode )
00858 {
00859 Abc_Obj_t * pNode1, * pNode2;
00860 int i;
00861 if ( Vec_PtrPushUnique(p, pNode) )
00862 return;
00863
00864 for ( i = p->nSize-1; i > 0; i-- )
00865 {
00866 pNode1 = p->pArray[i ];
00867 pNode2 = p->pArray[i-1];
00868 if ( Abc_ObjRegular(pNode1)->Level <= Abc_ObjRegular(pNode2)->Level )
00869 break;
00870 p->pArray[i ] = pNode2;
00871 p->pArray[i-1] = pNode1;
00872 }
00873 }
00874
00875
00876
00888 bool Abc_NodeIsExorType( Abc_Obj_t * pNode )
00889 {
00890 Abc_Obj_t * pNode0, * pNode1;
00891
00892 assert( !Abc_ObjIsComplement(pNode) );
00893
00894 if ( !Abc_AigNodeIsAnd(pNode) )
00895 return 0;
00896
00897 if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
00898 return 0;
00899
00900 pNode0 = Abc_ObjFanin0(pNode);
00901 pNode1 = Abc_ObjFanin1(pNode);
00902
00903 if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
00904 return 0;
00905
00906 return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) || Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1)) &&
00907 (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) || Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1));
00908 }
00909
00921 bool Abc_NodeIsMuxType( Abc_Obj_t * pNode )
00922 {
00923 Abc_Obj_t * pNode0, * pNode1;
00924
00925 assert( !Abc_ObjIsComplement(pNode) );
00926
00927 if ( !Abc_AigNodeIsAnd(pNode) )
00928 return 0;
00929
00930 if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
00931 return 0;
00932
00933 pNode0 = Abc_ObjFanin0(pNode);
00934 pNode1 = Abc_ObjFanin1(pNode);
00935
00936 if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
00937 return 0;
00938
00939 return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
00940 (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1))) ||
00941 (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
00942 (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)));
00943 }
00944
00956 bool Abc_NodeIsMuxControlType( Abc_Obj_t * pNode )
00957 {
00958 Abc_Obj_t * pNode0, * pNode1;
00959
00960 assert( !Abc_ObjIsComplement(pNode) );
00961
00962 if ( Abc_ObjFanoutNum(pNode) != 2 )
00963 return 0;
00964
00965 pNode0 = Abc_ObjFanout( pNode, 0 );
00966 pNode1 = Abc_ObjFanout( pNode, 1 );
00967
00968 if ( Abc_ObjFanoutNum(pNode0) != 1 || Abc_ObjFanoutNum(pNode1) != 1 )
00969 return 0;
00970
00971 return Abc_ObjFanout0(pNode0) == Abc_ObjFanout0(pNode1);
00972 }
00973
00988 Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE )
00989 {
00990 Abc_Obj_t * pNode0, * pNode1;
00991 assert( !Abc_ObjIsComplement(pNode) );
00992 assert( Abc_NodeIsMuxType(pNode) );
00993
00994 pNode0 = Abc_ObjFanin0(pNode);
00995 pNode1 = Abc_ObjFanin1(pNode);
00996
00997
00998 if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
00999 {
01000
01001 if ( Abc_ObjFaninC0(pNode0) )
01002 {
01003 *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));
01004 *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));
01005 return Abc_ObjChild0(pNode1);
01006 }
01007 else
01008 {
01009 *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));
01010 *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));
01011 return Abc_ObjChild0(pNode0);
01012 }
01013 }
01014
01015 else if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
01016 {
01017
01018 if ( Abc_ObjFaninC0(pNode0) )
01019 {
01020 *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));
01021 *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));
01022 return Abc_ObjChild1(pNode1);
01023 }
01024 else
01025 {
01026 *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));
01027 *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));
01028 return Abc_ObjChild0(pNode0);
01029 }
01030 }
01031
01032 else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
01033 {
01034
01035 if ( Abc_ObjFaninC1(pNode0) )
01036 {
01037 *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));
01038 *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));
01039 return Abc_ObjChild0(pNode1);
01040 }
01041 else
01042 {
01043 *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));
01044 *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));
01045 return Abc_ObjChild1(pNode0);
01046 }
01047 }
01048
01049 else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
01050 {
01051
01052 if ( Abc_ObjFaninC1(pNode0) )
01053 {
01054 *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));
01055 *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));
01056 return Abc_ObjChild1(pNode1);
01057 }
01058 else
01059 {
01060 *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));
01061 *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));
01062 return Abc_ObjChild1(pNode0);
01063 }
01064 }
01065 assert( 0 );
01066 return NULL;
01067 }
01068
01080 int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc,
01081 Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 )
01082 {
01083 int fCheck = 1;
01084 FILE * pFile;
01085 Abc_Ntk_t * pNtk1, * pNtk2;
01086 int util_optind = 0;
01087
01088 *pfDelete1 = 0;
01089 *pfDelete2 = 0;
01090 if ( argc == util_optind )
01091 {
01092 if ( pNtk == NULL )
01093 {
01094 fprintf( pErr, "Empty current network.\n" );
01095 return 0;
01096 }
01097 if ( pNtk->pSpec == NULL )
01098 {
01099 fprintf( pErr, "The external spec is not given.\n" );
01100 return 0;
01101 }
01102 pFile = fopen( pNtk->pSpec, "r" );
01103 if ( pFile == NULL )
01104 {
01105 fprintf( pErr, "Cannot open the external spec file \"%s\".\n", pNtk->pSpec );
01106 return 0;
01107 }
01108 else
01109 fclose( pFile );
01110 pNtk1 = pNtk;
01111 pNtk2 = Io_Read( pNtk->pSpec, Io_ReadFileType(pNtk->pSpec), fCheck );
01112 if ( pNtk2 == NULL )
01113 return 0;
01114 *pfDelete2 = 1;
01115 }
01116 else if ( argc == util_optind + 1 )
01117 {
01118 if ( pNtk == NULL )
01119 {
01120 fprintf( pErr, "Empty current network.\n" );
01121 return 0;
01122 }
01123 pNtk1 = pNtk;
01124 pNtk2 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck );
01125 if ( pNtk2 == NULL )
01126 return 0;
01127 *pfDelete2 = 1;
01128 }
01129 else if ( argc == util_optind + 2 )
01130 {
01131 pNtk1 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck );
01132 if ( pNtk1 == NULL )
01133 return 0;
01134 pNtk2 = Io_Read( argv[util_optind+1], Io_ReadFileType(argv[util_optind+1]), fCheck );
01135 if ( pNtk2 == NULL )
01136 {
01137 Abc_NtkDelete( pNtk1 );
01138 return 0;
01139 }
01140 *pfDelete1 = 1;
01141 *pfDelete2 = 1;
01142 }
01143 else
01144 {
01145 fprintf( pErr, "Wrong number of arguments.\n" );
01146 return 0;
01147 }
01148 *ppNtk1 = pNtk1;
01149 *ppNtk2 = pNtk2;
01150 return 1;
01151 }
01152
01153
01165 void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
01166 {
01167 Abc_Obj_t * pFanin;
01168 int i;
01169 Vec_PtrClear(vNodes);
01170 Abc_ObjForEachFanin( pNode, pFanin, i )
01171 Vec_PtrPush( vNodes, pFanin );
01172 }
01173
01185 void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
01186 {
01187 Abc_Obj_t * pFanout;
01188 int i;
01189 Vec_PtrClear(vNodes);
01190 Abc_ObjForEachFanout( pNode, pFanout, i )
01191 Vec_PtrPush( vNodes, pFanout );
01192 }
01193
01205 Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk )
01206 {
01207 Vec_Ptr_t * vLatches;
01208 Abc_Obj_t * pObj;
01209 int i;
01210 vLatches = Vec_PtrAlloc( 10 );
01211 Abc_NtkForEachObj( pNtk, pObj, i )
01212 Vec_PtrPush( vLatches, pObj );
01213 return vLatches;
01214 }
01215
01227 int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
01228 {
01229 int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
01230 if ( Diff < 0 )
01231 return -1;
01232 if ( Diff > 0 )
01233 return 1;
01234 return 0;
01235 }
01236
01248 int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
01249 {
01250 int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
01251 if ( Diff > 0 )
01252 return -1;
01253 if ( Diff < 0 )
01254 return 1;
01255 return 0;
01256 }
01257
01269 Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk )
01270 {
01271 Vec_Int_t * vFanNums;
01272 Abc_Obj_t * pObj;
01273 int i;
01274 vFanNums = Vec_IntAlloc( 0 );
01275 Vec_IntFill( vFanNums, Abc_NtkObjNumMax(pNtk), -1 );
01276 Abc_NtkForEachObj( pNtk, pObj, i )
01277 if ( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) )
01278 Vec_IntWriteEntry( vFanNums, i, Abc_ObjFanoutNum(pObj) );
01279 return vFanNums;
01280 }
01281
01293 Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk )
01294 {
01295 Vec_Ptr_t * vNodes;
01296 Abc_Obj_t * pNode;
01297 int i;
01298 vNodes = Vec_PtrAlloc( 100 );
01299 Abc_NtkForEachObj( pNtk, pNode, i )
01300 Vec_PtrPush( vNodes, pNode );
01301 return vNodes;
01302 }
01303
01315 Vec_Int_t * Abc_NtkGetCiIds( Abc_Ntk_t * pNtk )
01316 {
01317 Vec_Int_t * vCiIds;
01318 Abc_Obj_t * pObj;
01319 int i;
01320 vCiIds = Vec_IntAlloc( Abc_NtkCiNum(pNtk) );
01321 Abc_NtkForEachCi( pNtk, pObj, i )
01322 Vec_IntPush( vCiIds, pObj->Id );
01323 return vCiIds;
01324 }
01325
01337 void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
01338 {
01339 Vec_Ptr_t * vNodes;
01340 Vec_Ptr_t * vObjsNew;
01341 Abc_Obj_t * pNode, * pTemp, * pConst1;
01342 int i, k;
01343 assert( Abc_NtkIsStrash(pNtk) );
01344
01345
01346 vObjsNew = Vec_PtrAlloc( pNtk->nObjs );
01347
01348 pConst1 = Abc_AigConst1(pNtk);
01349 assert( pConst1->Id == 0 );
01350 Vec_PtrPush( vObjsNew, pConst1 );
01351
01352 Abc_NtkForEachPi( pNtk, pNode, i )
01353 {
01354 pNode->Id = Vec_PtrSize( vObjsNew );
01355 Vec_PtrPush( vObjsNew, pNode );
01356 }
01357
01358 Abc_NtkForEachPo( pNtk, pNode, i )
01359 {
01360 pNode->Id = Vec_PtrSize( vObjsNew );
01361 Vec_PtrPush( vObjsNew, pNode );
01362 }
01363
01364 Abc_NtkForEachAssert( pNtk, pNode, i )
01365 {
01366 pNode->Id = Vec_PtrSize( vObjsNew );
01367 Vec_PtrPush( vObjsNew, pNode );
01368 }
01369
01370 Abc_NtkForEachBox( pNtk, pNode, i )
01371 {
01372 pNode->Id = Vec_PtrSize( vObjsNew );
01373 Vec_PtrPush( vObjsNew, pNode );
01374 Abc_ObjForEachFanin( pNode, pTemp, k )
01375 {
01376 pTemp->Id = Vec_PtrSize( vObjsNew );
01377 Vec_PtrPush( vObjsNew, pTemp );
01378 }
01379 Abc_ObjForEachFanout( pNode, pTemp, k )
01380 {
01381 pTemp->Id = Vec_PtrSize( vObjsNew );
01382 Vec_PtrPush( vObjsNew, pTemp );
01383 }
01384 }
01385
01386 vNodes = Abc_AigDfs( pNtk, 1, 0 );
01387 Vec_PtrForEachEntry( vNodes, pNode, i )
01388 {
01389 if ( pNode == pConst1 )
01390 continue;
01391 pNode->Id = Vec_PtrSize( vObjsNew );
01392 Vec_PtrPush( vObjsNew, pNode );
01393 }
01394 Vec_PtrFree( vNodes );
01395 assert( Vec_PtrSize(vObjsNew) == pNtk->nObjs );
01396
01397
01398 Abc_NtkForEachObj( pNtk, pNode, i )
01399 {
01400 Abc_ObjForEachFanin( pNode, pTemp, k )
01401 pNode->vFanins.pArray[k] = pTemp->Id;
01402 Abc_ObjForEachFanout( pNode, pTemp, k )
01403 pNode->vFanouts.pArray[k] = pTemp->Id;
01404 }
01405
01406
01407 Vec_PtrFree( pNtk->vObjs );
01408 pNtk->vObjs = vObjsNew;
01409
01410
01411 Abc_AigRehash( pNtk->pManFunc );
01412
01413
01414 }
01415
01427 void Abc_NtkDetectMatching( Abc_Ntk_t * pNtk )
01428 {
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459 }
01460
01461
01473 int Abc_ObjPointerCompare( void ** pp1, void ** pp2 )
01474 {
01475 if ( *pp1 < *pp2 )
01476 return -1;
01477 if ( *pp1 > *pp2 )
01478 return 1;
01479 return 0;
01480 }
01481
01496 void Abc_NtkTransferCopy( Abc_Ntk_t * pNtk )
01497 {
01498 Abc_Obj_t * pObj;
01499 int i;
01500 Abc_NtkForEachObj( pNtk, pObj, i )
01501 if ( !Abc_ObjIsNet(pObj) )
01502 pObj->pCopy = pObj->pCopy? Abc_ObjCopyCond(pObj->pCopy) : NULL;
01503 }
01504
01505
01517 static inline int Abc_ObjCrossCutInc( Abc_Obj_t * pObj )
01518 {
01519
01520 int Value = (int)pObj->pCopy;
01521 pObj->pCopy = (void *)(Value + 1);
01522 return (int)pObj->pCopy == Abc_ObjFanoutNum(pObj);
01523 }
01524
01536 int Abc_NtkCrossCut_rec( Abc_Obj_t * pObj, int * pnCutSize, int * pnCutSizeMax )
01537 {
01538 Abc_Obj_t * pFanin;
01539 int i, nDecrem = 0;
01540 int fReverse = 0;
01541 if ( Abc_ObjIsCi(pObj) )
01542 return 0;
01543
01544 if ( Abc_NodeIsTravIdCurrent( pObj ) )
01545 return Abc_ObjCrossCutInc( pObj );
01546 Abc_NodeSetTravIdCurrent( pObj );
01547
01548 if ( !Abc_ObjIsCi(pObj) )
01549 {
01550 if ( fReverse )
01551 {
01552 Abc_ObjForEachFanin( pObj, pFanin, i )
01553 {
01554 pFanin = Abc_ObjFanin( pObj, Abc_ObjFaninNum(pObj) - 1 - i );
01555 nDecrem += Abc_NtkCrossCut_rec( pFanin, pnCutSize, pnCutSizeMax );
01556 }
01557 }
01558 else
01559 {
01560 Abc_ObjForEachFanin( pObj, pFanin, i )
01561 nDecrem += Abc_NtkCrossCut_rec( pFanin, pnCutSize, pnCutSizeMax );
01562 }
01563 }
01564
01565 (*pnCutSize)++;
01566 if ( *pnCutSizeMax < *pnCutSize )
01567 *pnCutSizeMax = *pnCutSize;
01568 (*pnCutSize) -= nDecrem;
01569 return Abc_ObjCrossCutInc( pObj );
01570 }
01571
01583 int Abc_NtkCrossCut( Abc_Ntk_t * pNtk )
01584 {
01585 Abc_Obj_t * pObj;
01586 int nCutSize = 0, nCutSizeMax = 0;
01587 int i;
01588 Abc_NtkCleanCopy( pNtk );
01589 Abc_NtkIncrementTravId( pNtk );
01590 Abc_NtkForEachCo( pNtk, pObj, i )
01591 {
01592 Abc_NtkCrossCut_rec( pObj, &nCutSize, &nCutSizeMax );
01593 nCutSize--;
01594 }
01595 assert( nCutSize == 0 );
01596 printf( "Max cross cut size = %6d. Ratio = %6.2f %%\n", nCutSizeMax, 100.0 * nCutSizeMax/Abc_NtkObjNum(pNtk) );
01597 return nCutSizeMax;
01598 }
01599
01600
01612 void Abc_NtkPrint256()
01613 {
01614 FILE * pFile;
01615 unsigned i;
01616 pFile = fopen( "4varfs.txt", "w" );
01617 for ( i = 1; i < (1<<16)-1; i++ )
01618 {
01619 fprintf( pFile, "read_truth " );
01620 Extra_PrintBinary( pFile, &i, 16 );
01621 fprintf( pFile, "; clp; st; w 1.blif; map; cec 1.blif\n" );
01622 }
01623 fclose( pFile );
01624 }
01625
01626
01627 static int * pSupps;
01628
01640 int Abc_NtkCompareConesCompare( int * pNum1, int * pNum2 )
01641 {
01642 if ( pSupps[*pNum1] > pSupps[*pNum2] )
01643 return -1;
01644 if ( pSupps[*pNum1] < pSupps[*pNum2] )
01645 return 1;
01646 return 0;
01647 }
01648
01660 void Abc_NtkCompareCones( Abc_Ntk_t * pNtk )
01661 {
01662 Vec_Ptr_t * vSupp, * vNodes, * vReverse;
01663 Abc_Obj_t * pObj, * pTemp;
01664 int Iter, i, k, Counter, CounterCos, CounterCosNew;
01665 int * pPerms;
01666
01667
01668 pPerms = ALLOC( int, Abc_NtkCoNum(pNtk) );
01669 pSupps = ALLOC( int, Abc_NtkCoNum(pNtk) );
01670 Abc_NtkForEachCo( pNtk, pObj, i )
01671 {
01672 pPerms[i] = i;
01673 vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
01674 pSupps[i] = Vec_PtrSize(vSupp);
01675 Vec_PtrFree( vSupp );
01676 }
01677 qsort( (void *)pPerms, Abc_NtkCoNum(pNtk), sizeof(int), (int (*)(const void *, const void *)) Abc_NtkCompareConesCompare );
01678
01679
01680 Iter = 0;
01681 Abc_NtkForEachCo( pNtk, pObj, i )
01682 {
01683 pObj = Abc_NtkCo( pNtk, pPerms[i] );
01684 if ( pObj->fMarkA )
01685 continue;
01686 Iter++;
01687
01688 vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
01689 vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
01690 vReverse = Abc_NtkDfsReverseNodesContained( pNtk, (Abc_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp) );
01691
01692 Counter = 0;
01693 for ( k = 1; k < Vec_PtrSize(vReverse) - 1; k++ )
01694 for ( pTemp = Vec_PtrEntry(vReverse, k); pTemp; pTemp = pTemp->pCopy )
01695 Counter++;
01696 CounterCos = CounterCosNew = 0;
01697 for ( pTemp = Vec_PtrEntryLast(vReverse); pTemp; pTemp = pTemp->pCopy )
01698 {
01699 assert( Abc_ObjIsCo(pTemp) );
01700 CounterCos++;
01701 if ( pTemp->fMarkA == 0 )
01702 CounterCosNew++;
01703 pTemp->fMarkA = 1;
01704 }
01705
01706 printf( "%4d CO %5d : Supp = %5d. Lev = %3d. Cone = %5d. Rev = %5d. COs = %3d (%3d).\n",
01707 Iter, pPerms[i], Vec_PtrSize(vSupp), Abc_ObjLevel(Abc_ObjFanin0(pObj)), Vec_PtrSize(vNodes), Counter, CounterCos, CounterCosNew );
01708
01709
01710 Vec_PtrFree( vSupp );
01711 Vec_PtrFree( vNodes );
01712 Vec_PtrFree( vReverse );
01713
01714 if ( Vec_PtrSize(vSupp) < 10 )
01715 break;
01716 }
01717 Abc_NtkForEachCo( pNtk, pObj, i )
01718 pObj->fMarkA = 0;
01719
01720 free( pPerms );
01721 free( pSupps );
01722 }
01723
01735 void Abc_NtkCompareSupports( Abc_Ntk_t * pNtk )
01736 {
01737 Vec_Ptr_t * vSupp;
01738 Abc_Obj_t * pObj, * pTemp;
01739 int i, nNodesOld;
01740 assert( Abc_NtkIsStrash(pNtk) );
01741 Abc_AigForEachAnd( pNtk, pObj, i )
01742 {
01743 if ( !Abc_AigNodeIsChoice(pObj) )
01744 continue;
01745
01746 vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
01747 nNodesOld = Vec_PtrSize(vSupp);
01748 Vec_PtrFree( vSupp );
01749
01750 for ( pTemp = pObj->pData; pTemp; pTemp = pTemp->pData )
01751 {
01752 vSupp = Abc_NtkNodeSupport( pNtk, &pTemp, 1 );
01753 if ( nNodesOld != Vec_PtrSize(vSupp) )
01754 printf( "Choice orig = %3d Choice new = %3d\n", nNodesOld, Vec_PtrSize(vSupp) );
01755 Vec_PtrFree( vSupp );
01756 }
01757 }
01758 }
01759
01763
01764