diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 69a6e7235..d3a3cb0b5 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -3274,6 +3274,73 @@ void Gia_ManTestProblem() } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_GenDecoder( Gia_Man_t * p, int * pLits, int nLits ) +{ + if ( nLits == 1 ) + { + Vec_Int_t * vRes = Vec_IntAlloc( 2 ); + Vec_IntPush( vRes, Abc_LitNot(pLits[0]) ); + Vec_IntPush( vRes, pLits[0] ); + return vRes; + } + assert( nLits > 1 ); + int nPart1 = nLits / 2; + int nPart2 = nLits - nPart1; + Vec_Int_t * vRes1 = Gia_GenDecoder( p, pLits, nPart1 ); + Vec_Int_t * vRes2 = Gia_GenDecoder( p, pLits+nPart1, nPart2 ); + Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRes1) * Vec_IntSize(vRes2) ); + int i, k, Lit1, Lit2; + Vec_IntForEachEntry( vRes2, Lit2, k ) + Vec_IntForEachEntry( vRes1, Lit1, i ) + Vec_IntPush( vRes, Gia_ManHashAnd(p, Lit1, Lit2) ); + Vec_IntFree( vRes1 ); + Vec_IntFree( vRes2 ); + return vRes; +} +Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums ) +{ + Vec_Int_t * vIns = Vec_IntAlloc( nIns ); + Vec_Int_t * vData = Vec_IntAlloc( 1 << nIns ); + Gia_Man_t * p = Gia_ManStart( 4*(1 << nIns) + nIns ), * pTemp; + int i, iStart = 0, nSize = 1 << nIns; + p->pName = Abc_UtilStrsav( "mux" ); + for ( i = 0; i < nIns; i++ ) + Vec_IntPush( vIns, Gia_ManAppendCi(p) ); + for ( i = 0; i < nSize; i++ ) + Vec_IntPush( vData, Gia_ManAppendCi(p) ); + Gia_ManHashAlloc( p ); + for ( i = (int)strlen(pNums)-1; i >= 0; i-- ) + { + int k, b, nBits = (int)(pNums[i] - '0'); + Vec_Int_t * vDec = Gia_GenDecoder( p, Vec_IntEntryP(vIns, iStart), nBits ); + for ( k = 0; k < nSize; k++ ) + Vec_IntWriteEntry( vData, k, Gia_ManHashAnd(p, Vec_IntEntry(vData, k), Vec_IntEntry(vDec, k%Vec_IntSize(vDec))) ); + for ( b = 0; b < nBits; b++, nSize /= 2 ) + for ( k = 0; k < nSize/2; k++ ) + Vec_IntWriteEntry( vData, k, Gia_ManHashOr(p, Vec_IntEntry(vData, 2*k), Vec_IntEntry(vData, 2*k+1)) ); + Vec_IntFree( vDec ); + iStart += nBits; + } + assert( nSize == 1 ); + Gia_ManAppendCo( p, Vec_IntEntry(vData, 0) ); + Vec_IntFree( vIns ); + Vec_IntFree( vData ); + p = Gia_ManCleanup( pTemp = p ); + Gia_ManStop( pTemp ); + return p; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 36d9b46d3..d7141ce41 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -609,6 +609,7 @@ static int Abc_CommandAbc9StrEco ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9GenCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Odc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GenRel ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9GenMux ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Window ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1401,6 +1402,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&gencex", Abc_CommandAbc9GenCex, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&odc", Abc_CommandAbc9Odc, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&genrel", Abc_CommandAbc9GenRel, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&genmux", Abc_CommandAbc9GenMux, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&window", Abc_CommandAbc9Window, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 ); @@ -53217,6 +53219,119 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9GenMux( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums ); + Gia_Man_t * pTemp = NULL; + int c, nIns = 0, fVerbose = 0; + char * pNums = NULL; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + nIns = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nIns < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc == globalUtilOptind && nIns > 0 ) + { + if ( nIns == 2 ) + pNums = "11"; + else if ( nIns == 3 ) + pNums = "111"; + else if ( nIns == 4 ) + pNums = "112"; + else if ( nIns == 5 ) + pNums = "113"; + else if ( nIns == 6 ) + pNums = "1122"; + else if ( nIns == 7 ) + pNums = "1123"; + else if ( nIns == 8 ) + pNums = "1124"; + else if ( nIns == 9 ) + pNums = "1134"; + else if ( nIns == 10 ) + pNums = "1135"; + else if ( nIns == 11 ) + pNums = "1145"; + else if ( nIns == 12 ) + pNums = "1146"; + else if ( nIns == 13 ) + pNums = "1147"; + else if ( nIns == 14 ) + pNums = "1148"; + else if ( nIns == 15 ) + pNums = "1158"; + else if ( nIns == 16 ) + pNums = "1159"; + else + { + Abc_Print( -1, "Abc_CommandAbc9GenMux(): The number of controls should not be in the range: 2 <= n <= 16.\n" ); + return 0; + } + } + else if ( argc == globalUtilOptind+1 ) + { + int nIns2 = 0; + pNums = argv[globalUtilOptind]; + for ( c = 0; pNums[c]; c++ ) + nIns2 += (int)(pNums[c] - '0'); + if ( nIns > 0 && nIns2 > 0 && nIns != nIns2 ) + { + Abc_Print( -1, "Abc_CommandAbc9GenMux(): The number of inputs does not match.\n" ); + return 0; + } + nIns = nIns2; + } + else + { + Abc_Print( -1, "Abc_CommandAbc9GenMux(): The number of controls or the control input groups should be given on the command line.\n" ); + return 0; + } + pTemp = Gia_ManGenMux( nIns, pNums ); + Abc_FrameUpdateGia( pAbc, pTemp ); + Abc_Print( 1, "Generated a %d:1 MUX with the following groups: %s\n", 1<] [-vh] \n" ); + Abc_Print( -2, "\t generates the multiplexer\n" ); + Abc_Print( -2, "\t-K num : the number of control inputs [default = undefined]\n" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose ? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\tstring : the sizes of control input groups\n"); + return 1; +} + /**Function*************************************************************