diff options
Diffstat (limited to 'src/base/abci')
-rw-r--r-- | src/base/abci/abc.c | 54 | ||||
-rw-r--r-- | src/base/abci/abcFraig.c | 6 | ||||
-rw-r--r-- | src/base/abci/abcHaig.c | 39 | ||||
-rw-r--r-- | src/base/abci/abcMiter.c | 53 | ||||
-rw-r--r-- | src/base/abci/abcPart.c | 703 | ||||
-rw-r--r-- | src/base/abci/abcStrash.c | 22 | ||||
-rw-r--r-- | src/base/abci/module.make | 1 |
7 files changed, 833 insertions, 45 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a91d6325..39d7cb2b 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -2914,7 +2914,7 @@ int Abc_CommandLutpack( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->nGrowthLevel = 1; pPars->fSatur = 1; pPars->fZeroCost = 0; - pPars->fVerbose = 1; + pPars->fVerbose = 0; pPars->fVeryVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "NQSLszvwh" ) ) != EOF ) @@ -3834,6 +3834,7 @@ usage: ***********************************************************************/ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) { + char Buffer[32]; FILE * pOut, * pErr; Abc_Ntk_t * pNtk, * pNtk1, * pNtk2, * pNtkRes; int fDelete1, fDelete2; @@ -3842,6 +3843,7 @@ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fCheck; int fComb; + int nPartSize; pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -3850,11 +3852,23 @@ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults fComb = 1; fCheck = 1; + nPartSize = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Pch" ) ) != EOF ) { switch ( c ) { + case 'P': + if ( globalUtilOptind >= argc ) + { + fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + nPartSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nPartSize < 0 ) + goto usage; + break; case 'c': fComb ^= 1; break; @@ -3869,7 +3883,7 @@ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; // compute the miter - pNtkRes = Abc_NtkMiter( pNtk1, pNtk2, fComb, 0 ); + pNtkRes = Abc_NtkMiter( pNtk1, pNtk2, fComb, nPartSize ); if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); @@ -3884,14 +3898,19 @@ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: miter [-ch] <file1> <file2>\n" ); - fprintf( pErr, "\t computes the miter of the two circuits\n" ); - fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); - fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); - fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); - fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); + if ( nPartSize == 0 ) + strcpy( Buffer, "unused" ); + else + sprintf( Buffer, "%d", nPartSize ); + fprintf( pErr, "usage: miter [-P num] [-ch] <file1> <file2>\n" ); + fprintf( pErr, "\t computes the miter of the two circuits\n" ); + fprintf( pErr, "\t-P num : output partition size [default = %s]\n", Buffer ); + fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); + fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); + fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); + fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); return 1; } @@ -5915,6 +5934,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) // extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ); // extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ); // extern int Pr_ManProofTest( char * pFileName ); + extern void Abc_NtkCompareSupports( Abc_Ntk_t * pNtk ); + extern void Abc_NtkCompareCones( Abc_Ntk_t * pNtk ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -6010,6 +6031,17 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) */ // Abc_NtkMaxFlowTest( pNtk ); // Pr_ManProofTest( "trace.cnf" ); + +// Abc_NtkCompareSupports( pNtk ); +// Abc_NtkCompareCones( pNtk ); + + { + extern Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int fVerbose ); + Vec_Vec_t * vParts; + vParts = Abc_NtkPartitionSmart( pNtk, 1 ); + Vec_VecFree( vParts ); + } + return 0; usage: diff --git a/src/base/abci/abcFraig.c b/src/base/abci/abcFraig.c index 96c468fe..30e49af2 100644 --- a/src/base/abci/abcFraig.c +++ b/src/base/abci/abcFraig.c @@ -704,6 +704,8 @@ int Abc_NtkFraigStore( Abc_Ntk_t * pNtk ) ***********************************************************************/ Abc_Ntk_t * Abc_NtkFraigRestore() { + extern Abc_Ntk_t * Abc_NtkFraigPartitioned( Abc_Ntk_t * pNtk, void * pParams ); + Fraig_Params_t Params; Abc_Ntk_t * pStore, * pFraig; int nWords1, nWords2, nWordsMin; @@ -743,7 +745,9 @@ Abc_Ntk_t * Abc_NtkFraigRestore() // Fraig_ManReportChoices( p ); // transform it into FRAIG - pFraig = Abc_NtkFraig( pStore, &Params, 1, 0 ); +// pFraig = Abc_NtkFraig( pStore, &Params, 1, 0 ); + pFraig = Abc_NtkFraigPartitioned( pStore, &Params ); + PRT( "Total fraiging time", clock() - clk ); if ( pFraig == NULL ) return NULL; diff --git a/src/base/abci/abcHaig.c b/src/base/abci/abcHaig.c index a0ed5906..d3513bbe 100644 --- a/src/base/abci/abcHaig.c +++ b/src/base/abci/abcHaig.c @@ -364,7 +364,7 @@ Hop_Man_t * Abc_NtkHaigReconstruct( Hop_Man_t * p ) if ( pObj->pData ) // member of the class Hop_Regular(pObj->pNext)->pData = Hop_Regular(((Hop_Obj_t *)pObj->pData)->pNext); } - printf( " Counter = %d.\n", Counter ); +// printf( " Counter = %d.\n", Counter ); // transfer the POs Hop_ManForEachPo( p, pObj, i ) Hop_ObjCreatePo( pNew, Hop_ObjChild0Hop(pObj) ); @@ -681,15 +681,7 @@ Abc_Ntk_t * Abc_NtkHaigUse( Abc_Ntk_t * pNtk ) pMan = Abc_NtkHaigReconstruct( pManTemp = pMan ); Hop_ManStop( pManTemp ); } -/* - pMan = Abc_NtkHaigReconstruct( pManTemp = pMan ); - Hop_ManStop( pManTemp ); - Abc_NtkHaigResetReprs( pMan ); - pMan = Abc_NtkHaigReconstruct( pManTemp = pMan ); - Hop_ManStop( pManTemp ); - Abc_NtkHaigResetReprs( pMan ); -*/ // traverse in the topological order and create new AIG pNtkAig = Abc_NtkHaigRecreateAig( pNtk, pMan ); Hop_ManStop( pMan ); @@ -698,6 +690,35 @@ Abc_Ntk_t * Abc_NtkHaigUse( Abc_Ntk_t * pNtk ) return pNtkAig; } +/**Function************************************************************* + + Synopsis [Transform HOP manager into the one without loops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkHopRemoveLoops( Abc_Ntk_t * pNtk, Hop_Man_t * pMan ) +{ + Abc_Ntk_t * pNtkAig; + Hop_Man_t * pManTemp; + + // iteratively reconstruct the HOP manager to create choice nodes + while ( Abc_NtkHaigResetReprs( pMan ) ) + { + pMan = Abc_NtkHaigReconstruct( pManTemp = pMan ); + Hop_ManStop( pManTemp ); + } + + // traverse in the topological order and create new AIG + pNtkAig = Abc_NtkHaigRecreateAig( pNtk, pMan ); + Hop_ManStop( pMan ); + return pNtkAig; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c index 823d81cc..445c73c1 100644 --- a/src/base/abci/abcMiter.c +++ b/src/base/abci/abcMiter.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// static Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, int nPartSize ); -static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ); +static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb, int nPartSize ); static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ); static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb, int nPartSize ); static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame ); @@ -94,7 +94,7 @@ Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, in pNtkMiter->pName = Extra_UtilStrsav(Buffer); // perform strashing - Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb ); + Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize ); Abc_NtkMiterAddOne( pNtk1, pNtkMiter ); Abc_NtkMiterAddOne( pNtk2, pNtkMiter ); Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize ); @@ -120,7 +120,7 @@ Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, in SeeAlso [] ***********************************************************************/ -void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ) +void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb, int nPartSize ) { Abc_Obj_t * pObj, * pObjNew; int i; @@ -143,10 +143,13 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk // add name Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL ); } - // create the only PO - pObjNew = Abc_NtkCreatePo( pNtkMiter ); - // add the PO name - Abc_ObjAssignName( pObjNew, "miter", NULL ); + if ( nPartSize <= 0 ) + { + // create the only PO + pObjNew = Abc_NtkCreatePo( pNtkMiter ); + // add the PO name + Abc_ObjAssignName( pObjNew, "miter", NULL ); + } } else { @@ -161,10 +164,13 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk // add name Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL ); } - // create the only PO - pObjNew = Abc_NtkCreatePo( pNtkMiter ); - // add the PO name - Abc_ObjAssignName( pObjNew, "miter", NULL ); + if ( nPartSize <= 0 ) + { + // create the only PO + pObjNew = Abc_NtkCreatePo( pNtkMiter ); + // add the PO name + Abc_ObjAssignName( pObjNew, "miter", NULL ); + } // create the latches Abc_NtkForEachLatch( pNtk1, pObj, i ) { @@ -276,7 +282,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt Abc_ObjAddFanin( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjChild0Copy(Abc_ObjFanin0(pNode)) ); } // add the miter - if ( nPartSize == 0 ) + if ( nPartSize <= 0 ) { pMiter = Abc_AigMiter( pNtkMiter->pManFunc, vPairs ); Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter ); @@ -284,7 +290,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt } else { - char Buffer[10]; + char Buffer[1024]; Vec_Ptr_t * vPairsPart; int nParts, i, k, iCur; assert( Vec_PtrSize(vPairs) == 2 * Abc_NtkCoNum(pNtk1) ); @@ -303,15 +309,14 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt Vec_PtrPush( vPairsPart, Vec_PtrEntry(vPairs, 2*iCur+1) ); } pMiter = Abc_AigMiter( pNtkMiter->pManFunc, vPairsPart ); - if ( i == 0 ) - Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter ); + pNode = Abc_NtkCreatePo( pNtkMiter ); + Abc_ObjAddFanin( pNode, pMiter ); + // assign the name to the node + if ( nPartSize == 1 ) + sprintf( Buffer, "%s", Abc_ObjName(Abc_NtkPo(pNtk1,i)) ); else - { sprintf( Buffer, "%d", i ); - pNode = Abc_NtkCreatePo( pNtkMiter ); - Abc_ObjAssignName( pNode, "miter", Buffer ); - Abc_ObjAddFanin( pNode, pMiter ); - } + Abc_ObjAssignName( pNode, "miter_", Buffer ); } Vec_PtrFree( vPairsPart ); Vec_PtrFree( vPairs ); @@ -355,7 +360,7 @@ Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fOr, int pNtkMiter->pName = Extra_UtilStrsav(Buffer); // perform strashing - Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, 1 ); + Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, 1, -1 ); Abc_NtkMiterAddOne( pNtk1, pNtkMiter ); Abc_NtkMiterAddOne( pNtk2, pNtkMiter ); // Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, 1 ); @@ -414,7 +419,7 @@ Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues ) pRoot = Abc_NtkCo( pNtk, 0 ); // perform strashing - Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); + Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1, -1 ); // set the first cofactor Vec_IntForEachEntry( vPiValues, Value, i ) { @@ -482,7 +487,7 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In pRoot = Abc_NtkCo( pNtk, Out ); // perform strashing - Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); + Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1, -1 ); // set the first cofactor Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) ); if ( In2 >= 0 ) @@ -547,7 +552,7 @@ Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist ) pRoot = Abc_NtkCo( pNtk, 0 ); // perform strashing - Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); + Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1, -1 ); // set the first cofactor Abc_NtkCi(pNtk, In)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) ); // add the first cofactor diff --git a/src/base/abci/abcPart.c b/src/base/abci/abcPart.c new file mode 100644 index 00000000..14e33c36 --- /dev/null +++ b/src/base/abci/abcPart.c @@ -0,0 +1,703 @@ +/**CFile**************************************************************** + + FileName [abcPart.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Output partitioning package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcPart.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Prepare supports.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkPartitionCollectSupps( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vSupp, * vSupports; + Vec_Int_t * vSuppI; + Abc_Obj_t * pObj, * pTemp; + int i, k; + vSupports = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); + vSuppI = (Vec_Int_t *)vSupp; + Vec_PtrForEachEntry( vSupp, pTemp, k ) + Vec_IntWriteEntry( vSuppI, k, pTemp->Id ); + Vec_IntSort( vSuppI, 0 ); + // append the number of this output + Vec_IntPush( vSuppI, i ); + // save the support in the vector + Vec_PtrPush( vSupports, vSuppI ); + } + // sort supports by size + Vec_VecSort( (Vec_Vec_t *)vSupports, 1 ); + return vSupports; +} + +/**Function************************************************************* + + Synopsis [Find the best partition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Int_t * vOne ) +{ + Vec_Int_t * vPartSupp; + double Attract, Repulse, Cost, CostBest; + int i, nCommon, iBest; + iBest = -1; + CostBest = 0.0; + Vec_PtrForEachEntry( vPartSuppsAll, vPartSupp, i ) + { + nCommon = Vec_IntTwoCountCommon( vPartSupp, vOne ); + if ( nCommon == Vec_IntSize(vOne) ) + return i; + Attract = 1.0 * nCommon / Vec_IntSize(vOne); + if ( Vec_IntSize(vPartSupp) < 100 ) + Repulse = 1.0; + else + Repulse = log10( Vec_IntSize(vPartSupp) / 10.0 ); + Cost = pow( Attract, pow(Repulse, 5.0) ); + if ( CostBest < Cost ) + { + CostBest = Cost; + iBest = i; + } + } + if ( CostBest < 0.6 ) + return -1; + return iBest; +} + +/**Function************************************************************* + + Synopsis [Perform the smart partitioning.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPartitionPrint( Abc_Ntk_t * pNtk, Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll ) +{ + Vec_Int_t * vOne; + int i, nOutputs, Counter; + + Counter = 0; + Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + { + nOutputs = Vec_IntSize(Vec_PtrEntry(vPartsAll, i)); + printf( "%d=(%d,%d) ", i, Vec_IntSize(vOne), nOutputs ); + Counter += nOutputs; + if ( i == Vec_PtrSize(vPartsAll) - 1 ) + break; + } + assert( Counter == Abc_NtkCoNum(pNtk) ); + printf( "\nTotal = %d. Outputs = %d.\n", Counter, Abc_NtkCoNum(pNtk) ); +} + +/**Function************************************************************* + + Synopsis [Perform the smart partitioning.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll ) +{ + Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp; + int i, iPart; + + // pack smaller partitions into larger blocks + iPart = 0; + vPart = vPartSupp = NULL; + Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + { + if ( Vec_IntSize(vOne) < 200 ) + { + if ( vPartSupp == NULL ) + { + assert( vPart == NULL ); + vPartSupp = Vec_IntDup(vOne); + vPart = Vec_PtrEntry(vPartsAll, i); + } + else + { + vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne ); + Vec_IntFree( vTemp ); + vPart = Vec_IntTwoMerge( vTemp = vPart, Vec_PtrEntry(vPartsAll, i) ); + Vec_IntFree( vTemp ); + Vec_IntFree( Vec_PtrEntry(vPartsAll, i) ); + } + if ( Vec_IntSize(vPartSupp) < 200 ) + continue; + } + else + vPart = Vec_PtrEntry(vPartsAll, i); + // add the partition + Vec_PtrWriteEntry( vPartsAll, iPart, vPart ); + vPart = NULL; + if ( vPartSupp ) + { + Vec_IntFree( Vec_PtrEntry(vPartSuppsAll, iPart) ); + Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); + vPartSupp = NULL; + } + iPart++; + } + // add the last one + if ( vPart ) + { + Vec_PtrWriteEntry( vPartsAll, iPart, vPart ); + vPart = NULL; + + assert( vPartSupp != NULL ); + Vec_IntFree( Vec_PtrEntry(vPartSuppsAll, iPart) ); + Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); + vPartSupp = NULL; + iPart++; + } + Vec_PtrShrink( vPartsAll, iPart ); + Vec_PtrShrink( vPartsAll, iPart ); +} + +/**Function************************************************************* + + Synopsis [Perform the smart partitioning.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int fVerbose ) +{ + Vec_Ptr_t * vSupps, * vPartsAll, * vPartsAll2, * vPartSuppsAll, * vPartPtr; + Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp; + int i, iPart, iOut, clk; + + // compute the supports for all outputs +clk = clock(); + vSupps = Abc_NtkPartitionCollectSupps( pNtk ); +if ( fVerbose ) +{ +PRT( "Supps", clock() - clk ); +} + + // create partitions +clk = clock(); + vPartsAll = Vec_PtrAlloc( 256 ); + vPartSuppsAll = Vec_PtrAlloc( 256 ); + Vec_PtrForEachEntry( vSupps, vOne, i ) + { + // get the output number + iOut = Vec_IntPop(vOne); + // find closely matching part + iPart = Abc_NtkPartitionSmartFindPart( vPartSuppsAll, vOne ); + if ( iPart == -1 ) + { + // create new partition + vPart = Vec_IntAlloc( 32 ); + Vec_IntPush( vPart, iOut ); + // create new partition support + vPartSupp = Vec_IntDup( vOne ); + // add this partition and its support + Vec_PtrPush( vPartsAll, vPart ); + Vec_PtrPush( vPartSuppsAll, vPartSupp ); + } + else + { + // add output to this partition + vPart = Vec_PtrEntry( vPartsAll, iPart ); + Vec_IntPush( vPart, iOut ); + // merge supports + vPartSupp = Vec_PtrEntry( vPartSuppsAll, iPart ); + vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne ); + Vec_IntFree( vTemp ); + // reinsert new support + Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); + } + } +if ( fVerbose ) +{ +PRT( "Parts", clock() - clk ); +} + +clk = clock(); + // remember number of supports + Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_IntPush( vOne, i ); + // sort the supports in the decreasing order + Vec_VecSort( (Vec_Vec_t *)vPartSuppsAll, 1 ); + // reproduce partitions + vPartsAll2 = Vec_PtrAlloc( 256 ); + Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrPush( vPartsAll2, Vec_PtrEntry(vPartsAll, Vec_IntPop(vOne)) ); + Vec_PtrFree( vPartsAll ); + vPartsAll = vPartsAll2; + + // compact small partitions +// Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll ); + Abc_NtkPartitionCompact( vPartsAll, vPartSuppsAll ); + if ( fVerbose ) + Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll ); +if ( fVerbose ) +{ +PRT( "Comps", clock() - clk ); +} + + // cleanup + Vec_VecFree( (Vec_Vec_t *)vSupps ); + Vec_VecFree( (Vec_Vec_t *)vPartSuppsAll ); + + // converts from intergers to nodes + Vec_PtrForEachEntry( vPartsAll, vPart, iPart ) + { + vPartPtr = Vec_PtrAlloc( Vec_IntSize(vPart) ); + Vec_IntForEachEntry( vPart, iOut, i ) + Vec_PtrPush( vPartPtr, Abc_NtkCo(pNtk, iOut) ); + Vec_IntFree( vPart ); + Vec_PtrWriteEntry( vPartsAll, iPart, vPartPtr ); + } + return (Vec_Vec_t *)vPartsAll; +} + +/**Function************************************************************* + + Synopsis [Perform the naive partitioning.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Abc_NtkPartitionNaive( Abc_Ntk_t * pNtk, int nPartSize ) +{ + Vec_Vec_t * vParts; + Abc_Obj_t * pObj; + int nParts, i; + nParts = (Abc_NtkCoNum(pNtk) / nPartSize) + ((Abc_NtkCoNum(pNtk) % nPartSize) > 0); + vParts = Vec_VecStart( nParts ); + Abc_NtkForEachCo( pNtk, pObj, i ) + Vec_VecPush( vParts, i / nPartSize, pObj ); + return vParts; +} + +/**Function************************************************************* + + Synopsis [Returns representative of the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkPartStitchFindRepr_rec( Vec_Ptr_t * vEquiv, Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pRepr; + pRepr = Vec_PtrEntry( vEquiv, pObj->Id ); + if ( pRepr == NULL || pRepr == pObj ) + return pObj; + return Abc_NtkPartStitchFindRepr_rec( vEquiv, pRepr ); +} + +/**Function************************************************************* + + Synopsis [Returns the representative of the fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Abc_Obj_t * Abc_NtkPartStitchCopy0( Vec_Ptr_t * vEquiv, Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFan = Abc_ObjFanin0( pObj ); + Abc_Obj_t * pRepr = Abc_NtkPartStitchFindRepr_rec( vEquiv, pFan ); + return Abc_ObjNotCond( pRepr->pCopy, pRepr->fPhase ^ pFan->fPhase ^ Abc_ObjFaninC1(pObj) ); +} +static inline Abc_Obj_t * Abc_NtkPartStitchCopy1( Vec_Ptr_t * vEquiv, Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFan = Abc_ObjFanin1( pObj ); + Abc_Obj_t * pRepr = Abc_NtkPartStitchFindRepr_rec( vEquiv, pFan ); + return Abc_ObjNotCond( pRepr->pCopy, pRepr->fPhase ^ pFan->fPhase ^ Abc_ObjFaninC1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Stitches together several networks with choice nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkPartStitchChoices_old( Abc_Ntk_t * pNtk, Vec_Ptr_t * vParts ) +{ + Vec_Ptr_t * vNodes, * vEquiv; + Abc_Ntk_t * pNtkNew, * pNtkNew2, * pNtkTemp; + Abc_Obj_t * pObj, * pFanin, * pRepr0, * pRepr1, * pRepr; + int i, k, iNodeId; + + // start a new network similar to the original one + assert( Abc_NtkIsStrash(pNtk) ); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); + // duplicate the name and the spec + pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); + pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); + + // annotate parts to point to the new network + vEquiv = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) + 1 ); + Vec_PtrForEachEntry( vParts, pNtkTemp, i ) + { + assert( Abc_NtkIsStrash(pNtkTemp) ); + Abc_NtkCleanCopy( pNtkTemp ); + + // map the CI nodes + Abc_AigConst1(pNtkTemp)->pCopy = Abc_AigConst1(pNtkNew); + Abc_NtkForEachCi( pNtkTemp, pObj, k ) + { + iNodeId = Nm_ManFindIdByNameTwoTypes( pNtkNew->pManName, Abc_ObjName(pObj), ABC_OBJ_PI, ABC_OBJ_BO ); + if ( iNodeId == -1 ) + { + printf( "Cannot find CI node %s in the original network.\n", Abc_ObjName(pObj) ); + return NULL; + } + pObj->pCopy = Abc_NtkObj( pNtkNew, iNodeId ); + } + + // add the internal nodes while saving representatives + vNodes = Abc_AigDfs( pNtkTemp, 1, 0 ); + Vec_PtrForEachEntry( vNodes, pObj, k ) + { + pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + assert( !Abc_ObjIsComplement(pObj->pCopy) ); + if ( !Abc_AigNodeIsChoice(pObj) ) + continue; + // find the earliest representative of the choice node + pRepr0 = NULL; + for ( pFanin = pObj; pFanin; pFanin = pFanin->pData ) + { + pRepr1 = Abc_NtkPartStitchFindRepr_rec( vEquiv, pFanin->pCopy ); + if ( pRepr0 == NULL || pRepr0->Id > pRepr1->Id ) + pRepr0 = pRepr1; + } + // set this representative for the representives of all choices + for ( pFanin = pObj; pFanin; pFanin = pFanin->pData ) + { + pRepr1 = Abc_NtkPartStitchFindRepr_rec( vEquiv, pFanin->pCopy ); + Vec_PtrWriteEntry( vEquiv, pRepr1->Id, pRepr0 ); + } + } + Vec_PtrFree( vNodes ); + + // map the CO nodes + Abc_NtkForEachCo( pNtkTemp, pObj, k ) + { + iNodeId = Nm_ManFindIdByNameTwoTypes( pNtkNew->pManName, Abc_ObjName(pObj), ABC_OBJ_PO, ABC_OBJ_BI ); + if ( iNodeId == -1 ) + { + printf( "Cannot find CO node %s in the original network.\n", Abc_ObjName(pObj) ); + return NULL; + } + pObj->pCopy = Abc_NtkObj( pNtkNew, iNodeId ); + Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); + } + } + + // reconstruct the AIG + pNtkNew2 = Abc_NtkStartFrom( pNtkNew, ABC_NTK_STRASH, ABC_FUNC_AIG ); + // duplicate the name and the spec + pNtkNew2->pName = Extra_UtilStrsav(pNtkNew->pName); + pNtkNew2->pSpec = Extra_UtilStrsav(pNtkNew->pSpec); + // duplicate internal nodes + Abc_AigForEachAnd( pNtkNew, pObj, i ) + { + pRepr0 = Abc_NtkPartStitchCopy0( vEquiv, pObj ); + pRepr1 = Abc_NtkPartStitchCopy1( vEquiv, pObj ); + pObj->pCopy = Abc_AigAnd( pNtkNew2->pManFunc, pRepr0, pRepr1 ); + assert( !Abc_ObjIsComplement(pObj->pCopy) ); + // add the choice if applicable + pRepr = Abc_NtkPartStitchFindRepr_rec( vEquiv, pObj ); + if ( pObj != pRepr ) + { + assert( pObj->Id > pRepr->Id ); + if ( pObj->pCopy != pRepr->pCopy ) + { + assert( pObj->pCopy->Id > pRepr->pCopy->Id ); + pObj->pCopy->pData = pRepr->pCopy->pData; + pRepr->pCopy->pData = pObj->pCopy; + } + } + } + // connect the COs + Abc_NtkForEachCo( pNtkNew, pObj, k ) + Abc_ObjAddFanin( pObj->pCopy, Abc_NtkPartStitchCopy0(vEquiv,pObj) ); + + // replace the network + Abc_NtkDelete( pNtkNew ); + pNtkNew = pNtkNew2; + + // check correctness of the new network + Vec_PtrFree( vEquiv ); + if ( !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkPartStitchChoices: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Hop_Obj_t * Hop_ObjChild0Next( Abc_Obj_t * pObj ) { return Hop_NotCond( (Hop_Obj_t *)Abc_ObjFanin0(pObj)->pNext, Abc_ObjFaninC0(pObj) ); } +static inline Hop_Obj_t * Hop_ObjChild1Next( Abc_Obj_t * pObj ) { return Hop_NotCond( (Hop_Obj_t *)Abc_ObjFanin1(pObj)->pNext, Abc_ObjFaninC1(pObj) ); } + + +/**Function************************************************************* + + Synopsis [Stitches together several networks with choice nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hop_Man_t * Abc_NtkPartStartHop( Abc_Ntk_t * pNtk ) +{ + Hop_Man_t * pMan; + Abc_Obj_t * pObj; + int i; + // start the HOP package + pMan = Hop_ManStart(); + pMan->vObjs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) + 1 ); + Vec_PtrPush( pMan->vObjs, Hop_ManConst1(pMan) ); + // map constant node and PIs + Abc_AigConst1(pNtk)->pNext = (Abc_Obj_t *)Hop_ManConst1(pMan); + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->pNext = (Abc_Obj_t *)Hop_ObjCreatePi(pMan); + // map the internal nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + { + pObj->pNext = (Abc_Obj_t *)Hop_And( pMan, Hop_ObjChild0Next(pObj), Hop_ObjChild1Next(pObj) ); + assert( !Abc_ObjIsComplement(pObj->pNext) ); + } + // set the choice nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + { + if ( pObj->pCopy ) + ((Hop_Obj_t *)pObj->pNext)->pData = pObj->pCopy->pNext; + } + // transfer the POs + Abc_NtkForEachCo( pNtk, pObj, i ) + Hop_ObjCreatePo( pMan, Hop_ObjChild0Next(pObj) ); + // check the new manager + if ( !Hop_ManCheck(pMan) ) + printf( "Abc_NtkPartStartHop: HOP manager check has failed.\n" ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Stitches together several networks with choice nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkPartStitchChoices( Abc_Ntk_t * pNtk, Vec_Ptr_t * vParts ) +{ + extern Abc_Ntk_t * Abc_NtkHopRemoveLoops( Abc_Ntk_t * pNtk, Hop_Man_t * pMan ); + + Hop_Man_t * pMan; + Vec_Ptr_t * vNodes; + Abc_Ntk_t * pNtkNew, * pNtkTemp; + Abc_Obj_t * pObj, * pFanin; + int i, k, iNodeId; + + // start a new network similar to the original one + assert( Abc_NtkIsStrash(pNtk) ); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); + + // annotate parts to point to the new network + Vec_PtrForEachEntry( vParts, pNtkTemp, i ) + { + assert( Abc_NtkIsStrash(pNtkTemp) ); + Abc_NtkCleanCopy( pNtkTemp ); + + // map the CI nodes + Abc_AigConst1(pNtkTemp)->pCopy = Abc_AigConst1(pNtkNew); + Abc_NtkForEachCi( pNtkTemp, pObj, k ) + { + iNodeId = Nm_ManFindIdByNameTwoTypes( pNtkNew->pManName, Abc_ObjName(pObj), ABC_OBJ_PI, ABC_OBJ_BO ); + if ( iNodeId == -1 ) + { + printf( "Cannot find CI node %s in the original network.\n", Abc_ObjName(pObj) ); + return NULL; + } + pObj->pCopy = Abc_NtkObj( pNtkNew, iNodeId ); + } + + // add the internal nodes while saving representatives + vNodes = Abc_AigDfs( pNtkTemp, 1, 0 ); + Vec_PtrForEachEntry( vNodes, pObj, k ) + { + pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + assert( !Abc_ObjIsComplement(pObj->pCopy) ); + if ( Abc_AigNodeIsChoice(pObj) ) + for ( pFanin = pObj->pData; pFanin; pFanin = pFanin->pData ) + pFanin->pCopy->pCopy = pObj->pCopy; + } + Vec_PtrFree( vNodes ); + + // map the CO nodes + Abc_NtkForEachCo( pNtkTemp, pObj, k ) + { + iNodeId = Nm_ManFindIdByNameTwoTypes( pNtkNew->pManName, Abc_ObjName(pObj), ABC_OBJ_PO, ABC_OBJ_BI ); + if ( iNodeId == -1 ) + { + printf( "Cannot find CO node %s in the original network.\n", Abc_ObjName(pObj) ); + return NULL; + } + pObj->pCopy = Abc_NtkObj( pNtkNew, iNodeId ); + Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); + } + } + + // transform into the HOP manager + pMan = Abc_NtkPartStartHop( pNtkNew ); + pNtkNew = Abc_NtkHopRemoveLoops( pNtkTemp = pNtkNew, pMan ); + Abc_NtkDelete( pNtkTemp ); + + // check correctness of the new network + if ( !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkPartStitchChoices: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Stitches together several networks with choice nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFraigPartitioned( Abc_Ntk_t * pNtk, void * pParams ) +{ + extern int Cmd_CommandExecute( void * pAbc, char * sCommand ); + extern void * Abc_FrameGetGlobalFrame(); + + Vec_Vec_t * vParts; + Vec_Ptr_t * vFraigs, * vOne; + Abc_Ntk_t * pNtkAig, * pNtkFraig; + int i; + + // perform partitioning + assert( Abc_NtkIsStrash(pNtk) ); +// vParts = Abc_NtkPartitionNaive( pNtk, 20 ); + vParts = Abc_NtkPartitionSmart( pNtk, 0 ); + + Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" ); + + // fraig each partition + vFraigs = Vec_PtrAlloc( Vec_VecSize(vParts) ); + Vec_VecForEachLevel( vParts, vOne, i ) + { + pNtkAig = Abc_NtkCreateConeArray( pNtk, vOne, 0 ); + pNtkFraig = Abc_NtkFraig( pNtkAig, pParams, 0, 0 ); + Vec_PtrPush( vFraigs, pNtkFraig ); + Abc_NtkDelete( pNtkAig ); + + printf( "Finished part %d (out of %d)\r", i+1, Vec_VecSize(vParts) ); + } + Vec_VecFree( vParts ); + + Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "set progressbar" ); + + // derive the final network + pNtkFraig = Abc_NtkPartStitchChoices( pNtk, vFraigs ); + Vec_PtrForEachEntry( vFraigs, pNtkAig, i ) + Abc_NtkDelete( pNtkAig ); + Vec_PtrFree( vFraigs ); + + return pNtkFraig; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c index 4f48f3bf..b1a0dc5b 100644 --- a/src/base/abci/abcStrash.c +++ b/src/base/abci/abcStrash.c @@ -168,6 +168,7 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ) // perform strashing nNewCis = 0; Abc_NtkCleanCopy( pNtk2 ); + Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1); Abc_NtkForEachCi( pNtk2, pObj, i ) { pName = Abc_ObjName(pObj); @@ -196,6 +197,27 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ) Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj->pCopy), NULL ); } } + else + { + Abc_Obj_t * pObjOld, * pDriverOld, * pDriverNew; + int fCompl, iNodeId; + // OR the choices + Abc_NtkForEachCo( pNtk2, pObj, i ) + { + iNodeId = Nm_ManFindIdByNameTwoTypes( pNtk1->pManName, Abc_ObjName(pObj), ABC_OBJ_PO, ABC_OBJ_BI ); + assert( iNodeId >= 0 ); + pObjOld = Abc_NtkObj( pNtk1, iNodeId ); + // derive the new driver + pDriverOld = Abc_ObjChild0( pObjOld ); + pDriverNew = Abc_ObjChild0Copy( pObj ); + pDriverNew = Abc_AigOr( pNtk1->pManFunc, pDriverOld, pDriverNew ); + if ( Abc_ObjRegular(pDriverOld) == Abc_ObjRegular(pDriverNew) ) + continue; + // replace the old driver by the new driver + fCompl = Abc_ObjRegular(pDriverOld)->fPhase ^ Abc_ObjRegular(pDriverNew)->fPhase; + Abc_ObjPatchFanin( pObjOld, Abc_ObjRegular(pDriverOld), Abc_ObjNotCond(Abc_ObjRegular(pDriverNew), fCompl) ); + } + } // make sure that everything is okay if ( !Abc_NtkCheck( pNtk1 ) ) { diff --git a/src/base/abci/module.make b/src/base/abci/module.make index e8eb6c7f..5d5bccb8 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -29,6 +29,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcNtbdd.c \ src/base/abci/abcOdc.c \ src/base/abci/abcOrder.c \ + src/base/abci/abcPart.c \ src/base/abci/abcPlace.c \ src/base/abci/abcPrint.c \ src/base/abci/abcProve.c \ |