diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index c9af8a32e..425dfd3f7 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -5407,6 +5407,48 @@ Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicates with the care set.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupWithCare( Gia_Man_t * p, Gia_Man_t * pCare ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i, iCare = -1; + assert( Gia_ManCiNum(pCare) == Gia_ManCiNum(p) ); + assert( Gia_ManCoNum(pCare) == 1 ); + assert( Gia_ManRegNum(p) == 0 ); + assert( Gia_ManRegNum(pCare) == 0 ); + pNew = Gia_ManStart( 2*Gia_ManObjNum(p) + Gia_ManObjNum(pCare) ); + pNew->pName = Abc_UtilStrsavTwo( pNew->pName, "_care" ); + Gia_ManConst0(pCare)->Value = 0; + Gia_ManForEachCi( pCare, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( pCare, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( pCare, pObj, i ) + iCare = Gia_ObjFanin0Copy(pObj); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManCi(pCare, i)->Value; + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + pObj->Value = Gia_ManAppendAnd( pNew, iCare, pObj->Value ); + } + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index b73732c62..f45e64b50 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -586,6 +586,7 @@ static int Abc_CommandAbc9Gla2Fla ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Gen ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9ProdAdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1345,6 +1346,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&gen", Abc_CommandAbc9Gen, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cfs", Abc_CommandAbc9Cfs, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&prodadd", Abc_CommandAbc9ProdAdd, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 ); { @@ -36297,6 +36299,7 @@ usage: int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Gia_Man_t * Gia_ManPairWiseMiter( Gia_Man_t * p ); + extern Gia_Man_t * Gia_ManDupWithCare( Gia_Man_t * p, Gia_Man_t * pCare ); FILE * pFile; Gia_Man_t * pAux; Gia_Man_t * pSecond; @@ -36312,9 +36315,10 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv ) int fTransX = 0; int fConvert = 0; int fTransZ = 0; + int fWithCare= 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Idsptxyzvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Idsptxyzcvh" ) ) != EOF ) { switch ( c ) { @@ -36350,6 +36354,9 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'z': fTransZ ^= 1; break; + case 'c': + fWithCare ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -36437,13 +36444,16 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // compute the miter - pAux = Gia_ManMiter( pAbc->pGia, pSecond, nInsDup, fDualOut, fSeq, 0, fVerbose ); + if ( fWithCare ) + pAux = Gia_ManDupWithCare( pAbc->pGia, pSecond ); + else + pAux = Gia_ManMiter( pAbc->pGia, pSecond, nInsDup, fDualOut, fSeq, 0, fVerbose ); Gia_ManStop( pSecond ); Abc_FrameUpdateGia( pAbc, pAux ); return 0; usage: - Abc_Print( -2, "usage: &miter [-I num] [-dsptxyzvh] \n" ); + Abc_Print( -2, "usage: &miter [-I num] [-dsptxyzcvh] \n" ); Abc_Print( -2, "\t creates miter of two designs (current AIG vs. )\n" ); Abc_Print( -2, "\t-I num : the number of last PIs to replicate [default = %d]\n", nInsDup ); Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", fDualOut? "yes": "no" ); @@ -36452,7 +36462,8 @@ usage: Abc_Print( -2, "\t-t : toggle XORing POs of dual-output miter [default = %s]\n", fTrans? "yes": "no" ); Abc_Print( -2, "\t-x : toggle XORing POs of two-word miter [default = %s]\n", fTransX? "yes": "no" ); Abc_Print( -2, "\t-y : toggle convering two-word miter into dual-output miter [default = %s]\n", fConvert? "yes": "no" ); - Abc_Print( -2, "\t-z : toggle odering sides of the dual-output miter [default = %s]\n", fTransZ? "yes": "no" ); + Abc_Print( -2, "\t-z : toggle ordering sides of the dual-output miter [default = %s]\n", fTransZ? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle duplicating AIG with the care set [default = %s]\n", fWithCare? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t : AIGER file with the design to miter\n"); @@ -50379,6 +50390,96 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9ProdAdd( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManProdAdderGen( int nArgA, int nArgB, int Seed, int fSigned, int fCla ); + Gia_Man_t * pTemp = NULL; + int nArgA = 4; + int nArgB = 4; + int Seed = 0; + int fSigned = 0; + int fCla = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "ABSscvh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + nArgA = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nArgA < 0 ) + goto usage; + break; + case 'B': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-B\" should be followed by an integer.\n" ); + goto usage; + } + nArgB = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nArgB < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + Seed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Seed < 0 ) + goto usage; + break; + case 's': + fSigned ^= 1; + break; + case 'c': + fCla ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + Gia_ManProdAdderGen( nArgA, nArgB, Seed, fSigned, fCla ); + return 0; + +usage: + Abc_Print( -2, "usage: &prodadd [-ABSscvh]\n" ); + Abc_Print( -2, "\t generates partial products and adder trees\n" ); + Abc_Print( -2, "\t-A num : the bit-width of the first arg [default = %d]\n", nArgA ); + Abc_Print( -2, "\t-B num : the bit-width of the second arg [default = %d]\n", nArgB ); + Abc_Print( -2, "\t-S num : random seed used the node ordering [default = %d]\n", Seed ); + Abc_Print( -2, "\t-s : toggle using signed operation [default = %s]\n", fSigned? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle using CLA in the adder tree [default = %s]\n", fCla? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* diff --git a/src/base/wlc/wlc.c b/src/base/wlc/wlc.c index 3ba9be96d..79c816ac8 100644 --- a/src/base/wlc/wlc.c +++ b/src/base/wlc/wlc.c @@ -780,6 +780,89 @@ void Wlc_AdderTreeGen( int n ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManProdAdderGen( int nArgA, int nArgB, int Seed, int fSigned, int fCla ) +{ + extern void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes, int fSigned, int fCla ); + int i, k, x, fCompl, iLit; char pNameP[32], pNameT[32]; + Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB ); + Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB ); + Vec_Int_t * vRes = Vec_IntAlloc( nArgA + nArgB ); + Vec_Int_t * vArgA = Vec_IntAlloc( nArgA ); + Vec_Int_t * vArgB = Vec_IntAlloc( nArgB ), * vLevel; + Gia_Man_t * pProd = Gia_ManStart( 1000 ); + Gia_Man_t * pTree = Gia_ManStart( 1000 ), * pTemp; + Gia_ManHashAlloc( pTree ); + pProd->pName = Abc_UtilStrsav( "prod" ); + pTree->pName = Abc_UtilStrsav( "tree" ); + for ( x = 0; x < nArgA; x++ ) + Vec_IntPush( vArgA, Gia_ManAppendCi(pProd) ); + for ( x = 0; x < nArgB; x++ ) + Vec_IntPush( vArgB, Gia_ManAppendCi(pProd) ); + for ( x = 0; x < nArgA + nArgB; x++ ) + { + for ( i = 0; i < nArgA; i++ ) + for ( k = 0; k < nArgB; k++ ) + { + if ( i + k != x ) + continue; + fCompl = fSigned && ((i == nArgA-1) ^ (k == nArgB-1)); + iLit = Abc_LitNotCond(Gia_ManAppendAnd(pProd, Vec_IntEntry(vArgA, i), Vec_IntEntry(vArgB, k)), fCompl); + Gia_ManAppendCo( pProd, iLit ); + Vec_WecPush( vProds, i+k, Gia_ManAppendCi(pTree) ); + Vec_WecPush( vLevels, i+k, 0 ); + } + } + if ( fSigned ) + { + Vec_WecPush( vProds, nArgA, 1 ); + Vec_WecPush( vLevels, nArgA, 0 ); + + Vec_WecPush( vProds, nArgA+nArgB-1, 1 ); + Vec_WecPush( vLevels, nArgA+nArgB-1, 0 ); + } + if ( Seed ) + { + Abc_Random( 1 ); + for ( x = 0; x < Seed; x++ ) + Abc_Random( 0 ); + Vec_WecForEachLevel( vProds, vLevel, x ) + if ( Vec_IntSize(vLevel) > 1 ) + Vec_IntRandomizeOrder( vLevel ); + } + Wlc_BlastReduceMatrix( pTree, vProds, vLevels, vRes, fSigned, fCla ); + Vec_IntShrink( vRes, nArgA + nArgB ); + assert( Vec_IntSize(vRes) == nArgA + nArgB ); + Vec_IntForEachEntry( vRes, iLit, x ) + Gia_ManAppendCo( pTree, iLit ); + pTree = Gia_ManCleanup( pTemp = pTree ); + Gia_ManStop( pTemp ); + + sprintf( pNameP, "prod%d%d.aig", nArgA, nArgB ); + sprintf( pNameT, "tree%d%d.aig", nArgA, nArgB ); + Gia_AigerWrite( pProd, pNameP, 0, 0, 0 ); + Gia_AigerWrite( pTree, pNameT, 0, 0, 0 ); + Gia_ManStop( pProd ); + Gia_ManStop( pTree ); + printf( "Dumped files \"%s\" and \"%s\".\n", pNameP, pNameT ); + + Vec_WecFree( vProds ); + Vec_WecFree( vLevels ); + Vec_IntFree( vArgA ); + Vec_IntFree( vArgB ); + Vec_IntFree( vRes ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// ////////////////////////////////////////////////////////////////////////