From 28f4ad82812bc83587d021437d159f96d5b3c61c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 12 Nov 2025 10:04:10 -0800 Subject: [PATCH] New command &symfun. --- src/aig/gia/giaLutCas.c | 73 ++++++++++++++++++++++--- src/base/abci/abc.c | 111 +++++++++++++++++++++++++++++++++++++- src/misc/util/utilTruth.h | 40 +++++++++++++- 3 files changed, 214 insertions(+), 10 deletions(-) diff --git a/src/aig/gia/giaLutCas.c b/src/aig/gia/giaLutCas.c index 7465ad18c..c8f2026db 100644 --- a/src/aig/gia/giaLutCas.c +++ b/src/aig/gia/giaLutCas.c @@ -34,6 +34,65 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManGenSymFun_rec( Gia_Man_t * p, word Str, int nChars, Vec_Ptr_t * vStrs, Vec_Wec_t * vLits, Vec_Int_t * vIns ) +{ + if ( Str == 0 ) return 0; + if ( Str == Abc_Tt6Mask(nChars) ) return 1; + assert( nChars > 1 ); + Vec_Wrd_t * vStore = (Vec_Wrd_t *)Vec_PtrEntry(vStrs, nChars-1); + Vec_Int_t * vValue = Vec_WecEntry(vLits, nChars-1); + int Index; + if ( (Index = Vec_WrdFind(vStore, Str)) >= 0 ) + return Vec_IntEntry(vValue, Index); + word Str0 = Str & ~Abc_Tt6MaskI(nChars-1); + word Str1 = Str >> 1; + int Lit0 = Gia_ManGenSymFun_rec( p, Str0, nChars-1, vStrs, vLits, vIns ); + int Lit1 = Gia_ManGenSymFun_rec( p, Str1, nChars-1, vStrs, vLits, vIns ); + int Lit = Gia_ManAppendMux2( p, Vec_IntEntry(vIns, nChars-2), Lit1, Lit0 ); + Vec_WrdPush( vStore, Str ); + Vec_WrdPush( vStore, ~Str & Abc_Tt6Mask(nChars) ); + Vec_IntPush( vValue, Lit ); + Vec_IntPush( vValue, Abc_LitNot(Lit) ); + return Lit; +} +Gia_Man_t * Gia_ManGenSymFun( Vec_Wrd_t * vFuns, int nChars, int fVerbose ) +{ + assert( nChars <= 64 ); + word Str; int i; + Vec_Ptr_t * vStrs = Vec_PtrAlloc(nChars); + for ( i = 0; i < nChars; i++ ) + Vec_PtrPush( vStrs, Vec_WrdAlloc(0) ); + Vec_Wec_t * vLits = Vec_WecStart(nChars); + Vec_Int_t * vOuts = Vec_IntAlloc(Vec_WrdSize(vFuns)); + Gia_Man_t * pNew = Gia_ManStart( 10000 ); + pNew->pName = Abc_UtilStrsav( "sym" ); + Vec_Int_t * vIns = Vec_IntAlloc(nChars-1); + for ( i = 0; i < nChars-1; i++ ) + Vec_IntPush(vIns, Gia_ManAppendCi(pNew)); + Vec_WrdForEachEntry( vFuns, Str, i ) + Vec_IntPush( vOuts, Gia_ManGenSymFun_rec(pNew, Str, nChars, vStrs, vLits, vIns ) ); + Vec_WrdForEachEntry( vFuns, Str, i ) + Gia_ManAppendCo(pNew, Vec_IntEntry(vOuts,i) ); + for ( i = 0; i < nChars; i++ ) + Vec_WrdFree( (Vec_Wrd_t *)Vec_PtrEntry(vStrs, i) ); + Vec_PtrFree(vStrs); + Vec_WecFree(vLits); + Vec_IntFree(vOuts); + Vec_IntFree(vIns); + return pNew; +} + /**Function************************************************************* Synopsis [] @@ -101,15 +160,15 @@ char * Gia_LutCasPerm( int nVars, int nLuts, int LutSize ) Gia_LutCasSort( pRes + i * LutSize, 1, LutSize-1 ); return pRes; } -int Gia_ManLutCasGen_rec( Gia_Man_t * pNew, Vec_Int_t * vCtrls, int iCtrl, Vec_Int_t * vDatas, int Shift ) +int Gia_ManGenLutCas_rec( Gia_Man_t * pNew, Vec_Int_t * vCtrls, int iCtrl, Vec_Int_t * vDatas, int Shift ) { if ( iCtrl-- == 0 ) return Vec_IntEntry( vDatas, Shift ); - int iLit0 = Gia_ManLutCasGen_rec( pNew, vCtrls, iCtrl, vDatas, Shift ); - int iLit1 = Gia_ManLutCasGen_rec( pNew, vCtrls, iCtrl, vDatas, Shift + (1<= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by a file name.\n" ); + goto usage; + } + nMaj = atoi(argv[globalUtilOptind++]); + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by a file name.\n" ); + goto usage; + } + nHot = atoi(argv[globalUtilOptind++]); + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by a file name.\n" ); + goto usage; + } + nXor = atoi(argv[globalUtilOptind++]); + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( nMaj ) { + nChars = nMaj+1; + vFuns = Vec_WrdAlloc(1); + Vec_WrdPush( vFuns, Abc_Tt6Mask(nMaj/2+1) << (nMaj/2+1) ); + } + else if ( nHot ) { + nChars = nHot+1; + vFuns = Vec_WrdAlloc(1); + Vec_WrdPush( vFuns, 2 ); + } + else if ( nXor ) { + nChars = nXor+1; + vFuns = Vec_WrdAlloc(1); + Vec_WrdPush( vFuns, ABC_CONST(0xAAAAAAAAAAAAAAAA) & Abc_Tt6Mask(nXor+1) ); + } + else { + if ( argc == globalUtilOptind ) { + printf( "One or more characteristic strings should be given on the command line.\n" ); + return 0; + } + nChars = (int)strlen(argv[globalUtilOptind]); + for ( c = globalUtilOptind+1; c < argc; c++ ) + if ( nChars != (int)strlen(argv[c]) ) { + printf( "Char strings have different lengths. Quitting.\n" ); + return 0; + } + vFuns = Vec_WrdAlloc( argc ); + for ( c = globalUtilOptind; c < argc; c++ ) + Vec_WrdPush( vFuns, Abc_TtReadBin64(argv[c]) ); + } + if ( nChars > 64 ) { + printf( "Currently can handle functions up to 63 inputs. Quitting.\n" ); + return 0; + } + pNew = Gia_ManGenSymFun( vFuns, nChars, fVerbose ); + Abc_FrameUpdateGia( pAbc, pNew ); + Vec_WrdFree( vFuns ); + return 0; + +usage: + Abc_Print( -2, "usage: &symfun [-MHX num] [-vh] ... \n" ); + Abc_Print( -2, "\t derives AIG of a multi-output symmetric function\n" ); + Abc_Print( -2, "\t-M : generate the majority gate with the given input count [default = unused]\n" ); + Abc_Print( -2, "\t-H : generate the 1-hot condition with the given input count [default = unused]\n" ); + Abc_Print( -2, "\t-X : generate the xor-gate with the given input count [default = unused]\n" ); + Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : prints the command usage\n"); + Abc_Print( -2, "\t ... : char strings in binary notation LSB first\n"); + return 1; +} + /**Function************************************************************* Synopsis [] @@ -51726,7 +51833,7 @@ usage: ***********************************************************************/ int Abc_CommandAbc9GenLutCas( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Gia_Man_t * Gia_ManLutCasGen( Gia_Man_t * p, char * pPermStr, int nVars, int nLuts, int LutSize, int Seed, int fVerbose ); + extern Gia_Man_t * Gia_ManGenLutCas( Gia_Man_t * p, char * pPermStr, int nVars, int nLuts, int LutSize, int Seed, int fVerbose ); int nVars = 0; int nLuts = 2; int LutSize = 6; @@ -51840,7 +51947,7 @@ int Abc_CommandAbc9GenLutCas( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Function with %d variables is too large for a cascade composed of %d connected %d-LUTs.\n", nVars, nLuts, LutSize ); return 1; } - pTemp = Gia_ManLutCasGen( pAbc->pGia, pPermStr, nVars, nLuts, LutSize, Seed, fVerbose ); + pTemp = Gia_ManGenLutCas( pAbc->pGia, pPermStr, nVars, nLuts, LutSize, Seed, fVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index c9d453d06..d94e9bfe2 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -230,7 +230,8 @@ static inline int Abc_TtHexDigitNum( int nVars ) { return nVars <= 2 ? 1 : 1 << SeeAlso [] ***********************************************************************/ -static inline word Abc_Tt6Mask( int nBits ) { assert( nBits >= 0 && nBits <= 64 ); return (~(word)0) >> (64-nBits); } +static inline word Abc_Tt6MaskI( int iBit ) { assert( iBit >= 0 && iBit <= 64 ); return ((word)1) << iBit; } +static inline word Abc_Tt6Mask( int nBits ) { assert( nBits >= 0 && nBits <= 64 ); return (~(word)0) >> (64-nBits); } static inline void Abc_TtMask( word * pTruth, int nWords, int nBits ) { int w; @@ -1579,6 +1580,43 @@ static inline int Abc_TtReadHexNumber( word * pTruth, char * pString ) } +/**Function************************************************************* + + Synopsis [Reads the integer number as a binary string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_TtReadBin( word * pWords, int nWords, char * pString ) +{ + int i, Len = (int)strlen(pString), nWords2 = (Len+63)/64; + assert( nWords2 <= nWords ); + memset( pWords, 0, sizeof(word)*nWords ); + for ( i = 0; i < Len; i++ ) + if ( pString[i] == '1' ) + Abc_TtSetBit(pWords, i); + else if ( pString[i] != '0' ) + return 0; + return 1; +} +static inline word Abc_TtReadBin64( char * pString ) +{ + word Word = 0; + int Len = (int)strlen(pString); + assert( Len <= 64 ); + int Res = Abc_TtReadBin( &Word, 1, pString ); + if ( Res == 0 ) { + printf( "Reading binary string \"%s\" has failed.\n", pString ); + Word = ~(word)0; + } + return Word; +} + + /**Function************************************************************* Synopsis []