| /**CFile**************************************************************** |
| |
| FileName [luckyFast6.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Semi-canonical form computation package.] |
| |
| Synopsis [Truth table minimization procedures for 6 vars.] |
| |
| Author [Jake] |
| |
| Date [Started - September 2012] |
| |
| ***********************************************************************/ |
| |
| #include "luckyInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| void resetPCanonPermArray_6Vars(char* x) |
| { |
| x[0]='a'; |
| x[1]='b'; |
| x[2]='c'; |
| x[3]='d'; |
| x[4]='e'; |
| x[5]='f'; |
| } |
| void resetPCanonPermArray(char* x, int nVars) |
| { |
| int i; |
| for(i=0;i<nVars;i++) |
| x[i] = 'a'+i; |
| } |
| |
| |
| |
| word Abc_allFlip(word x, unsigned* pCanonPhase) |
| { |
| if( (x>>63) ) |
| { |
| (* pCanonPhase) ^=(1<<6); |
| return ~x; |
| } |
| else |
| return x; |
| |
| } |
| |
| unsigned adjustInfoAfterSwap(char* pCanonPerm, unsigned uCanonPhase, int iVar, unsigned info) |
| { |
| if(info<4) |
| return (uCanonPhase ^= (info << iVar)); |
| else |
| { |
| char temp; |
| uCanonPhase ^= ((info-4) << iVar); |
| temp=pCanonPerm[iVar]; |
| pCanonPerm[iVar]=pCanonPerm[iVar+1]; |
| pCanonPerm[iVar+1]=temp; |
| if ( ((uCanonPhase & (1 << iVar)) > 0) != ((uCanonPhase & (1 << (iVar+1))) > 0) ) |
| { |
| uCanonPhase ^= (1 << iVar); |
| uCanonPhase ^= (1 << (iVar+1)); |
| } |
| return uCanonPhase; |
| } |
| |
| |
| } |
| |
| word Extra_Truth6SwapAdjacent( word t, int iVar ) |
| { |
| // variable swapping code |
| static word PMasks[5][3] = { |
| { ABC_CONST(0x9999999999999999), ABC_CONST(0x2222222222222222), ABC_CONST(0x4444444444444444) }, |
| { ABC_CONST(0xC3C3C3C3C3C3C3C3), ABC_CONST(0x0C0C0C0C0C0C0C0C), ABC_CONST(0x3030303030303030) }, |
| { ABC_CONST(0xF00FF00FF00FF00F), ABC_CONST(0x00F000F000F000F0), ABC_CONST(0x0F000F000F000F00) }, |
| { ABC_CONST(0xFF0000FFFF0000FF), ABC_CONST(0x0000FF000000FF00), ABC_CONST(0x00FF000000FF0000) }, |
| { ABC_CONST(0xFFFF00000000FFFF), ABC_CONST(0x00000000FFFF0000), ABC_CONST(0x0000FFFF00000000) } |
| }; |
| assert( iVar < 5 ); |
| return (t & PMasks[iVar][0]) | ((t & PMasks[iVar][1]) << (1 << iVar)) | ((t & PMasks[iVar][2]) >> (1 << iVar)); |
| } |
| word Extra_Truth6ChangePhase( word t, int iVar) |
| { |
| // elementary truth tables |
| static word Truth6[6] = { |
| ABC_CONST(0xAAAAAAAAAAAAAAAA), |
| ABC_CONST(0xCCCCCCCCCCCCCCCC), |
| ABC_CONST(0xF0F0F0F0F0F0F0F0), |
| ABC_CONST(0xFF00FF00FF00FF00), |
| ABC_CONST(0xFFFF0000FFFF0000), |
| ABC_CONST(0xFFFFFFFF00000000) |
| }; |
| assert( iVar < 6 ); |
| return ((t & ~Truth6[iVar]) << (1 << iVar)) | ((t & Truth6[iVar]) >> (1 << iVar)); |
| } |
| |
| word Extra_Truth6MinimumRoundOne( word t, int iVar, char* pCanonPerm, unsigned* pCanonPhase ) |
| { |
| word tCur, tMin = t; // ab |
| unsigned info =0; |
| assert( iVar >= 0 && iVar < 5 ); |
| |
| tCur = Extra_Truth6ChangePhase( t, iVar ); // !a b |
| if(tCur<tMin) |
| { |
| info = 1; |
| tMin = tCur; |
| } |
| tCur = Extra_Truth6ChangePhase( t, iVar+1 ); // a !b |
| if(tCur<tMin) |
| { |
| info = 2; |
| tMin = tCur; |
| } |
| tCur = Extra_Truth6ChangePhase( tCur, iVar ); // !a !b |
| if(tCur<tMin) |
| { |
| info = 3; |
| tMin = tCur; |
| } |
| |
| t = Extra_Truth6SwapAdjacent( t, iVar ); // b a |
| if(t<tMin) |
| { |
| info = 4; |
| tMin = t; |
| } |
| |
| tCur = Extra_Truth6ChangePhase( t, iVar ); // !b a |
| if(tCur<tMin) |
| { |
| info = 6; |
| tMin = tCur; |
| } |
| tCur = Extra_Truth6ChangePhase( t, iVar+1 ); // b !a |
| if(tCur<tMin) |
| { |
| info = 5; |
| tMin = tCur; |
| } |
| tCur = Extra_Truth6ChangePhase( tCur, iVar ); // !b !a |
| if(tCur<tMin) |
| { |
| (* pCanonPhase) = adjustInfoAfterSwap(pCanonPerm, * pCanonPhase, iVar, 7); |
| return tCur; |
| } |
| else |
| { |
| (* pCanonPhase) = adjustInfoAfterSwap(pCanonPerm, * pCanonPhase, iVar, info); |
| return tMin; |
| } |
| } |
| |
| word Extra_Truth6MinimumRoundOne_noEBFC( word t, int iVar, char* pCanonPerm, unsigned* pCanonPhase) |
| { |
| word tMin; |
| assert( iVar >= 0 && iVar < 5 ); |
| |
| tMin = Extra_Truth6SwapAdjacent( t, iVar ); // b a |
| if(t<tMin) |
| return t; |
| else |
| { |
| (* pCanonPhase) = adjustInfoAfterSwap(pCanonPerm, * pCanonPhase, iVar, 4); |
| return tMin; |
| } |
| } |
| |
| |
| // this function finds minimal for all TIED(and tied only) iVars |
| //it finds tied vars based on rearranged Store info - group of tied vars has the same bit count in Store |
| word Extra_Truth6MinimumRoundMany( word t, int* pStore, char* pCanonPerm, unsigned* pCanonPhase ) |
| { |
| int i, bitInfoTemp; |
| word tMin0, tMin=t; |
| do |
| { |
| bitInfoTemp = pStore[0]; |
| tMin0 = tMin; |
| for ( i = 0; i < 5; i++ ) |
| { |
| if(bitInfoTemp == pStore[i+1]) |
| tMin = Extra_Truth6MinimumRoundOne( tMin, i, pCanonPerm, pCanonPhase ); |
| else |
| bitInfoTemp = pStore[i+1]; |
| } |
| }while ( tMin0 != tMin ); |
| return tMin; |
| } |
| |
| word Extra_Truth6MinimumRoundMany_noEBFC( word t, int* pStore, char* pCanonPerm, unsigned* pCanonPhase ) |
| { |
| int i, bitInfoTemp; |
| word tMin0, tMin=t; |
| do |
| { |
| bitInfoTemp = pStore[0]; |
| tMin0 = tMin; |
| for ( i = 0; i < 5; i++ ) |
| { |
| if(bitInfoTemp == pStore[i+1]) |
| tMin = Extra_Truth6MinimumRoundOne_noEBFC( tMin, i, pCanonPerm, pCanonPhase ); |
| else |
| bitInfoTemp = pStore[i+1]; |
| } |
| }while ( tMin0 != tMin ); |
| return tMin; |
| } |
| word Extra_Truth6MinimumRoundMany1( word t, int* pStore, char* pCanonPerm, unsigned* pCanonPhase ) |
| { |
| word tMin0, tMin=t; |
| char pCanonPerm1[16]; |
| unsigned uCanonPhase1; |
| switch ((* pCanonPhase) >> 7) |
| { |
| case 0 : |
| { |
| |
| return Extra_Truth6MinimumRoundMany_noEBFC( t, pStore, pCanonPerm, pCanonPhase); |
| } |
| case 1 : |
| { |
| return Extra_Truth6MinimumRoundMany( t, pStore, pCanonPerm, pCanonPhase); |
| } |
| case 2 : |
| { |
| uCanonPhase1 = *pCanonPhase; |
| uCanonPhase1 ^= (1 << 6); |
| memcpy(pCanonPerm1,pCanonPerm,sizeof(char)*16); |
| tMin0 = Extra_Truth6MinimumRoundMany_noEBFC( t, pStore, pCanonPerm, pCanonPhase); |
| tMin = Extra_Truth6MinimumRoundMany_noEBFC( ~t, pStore, pCanonPerm1, &uCanonPhase1); |
| if(tMin0 <=tMin) |
| return tMin0; |
| else |
| { |
| *pCanonPhase = uCanonPhase1; |
| memcpy(pCanonPerm,pCanonPerm1,sizeof(char)*16); |
| return tMin; |
| } |
| } |
| case 3 : |
| { |
| uCanonPhase1 = *pCanonPhase; |
| uCanonPhase1 ^= (1 << 6); |
| memcpy(pCanonPerm1,pCanonPerm,sizeof(char)*16); |
| tMin0 = Extra_Truth6MinimumRoundMany( t, pStore, pCanonPerm, pCanonPhase); |
| tMin = Extra_Truth6MinimumRoundMany( ~t, pStore, pCanonPerm1, &uCanonPhase1); |
| if(tMin0 <=tMin) |
| return tMin0; |
| else |
| { |
| *pCanonPhase = uCanonPhase1; |
| memcpy(pCanonPerm,pCanonPerm1,sizeof(char)*16); |
| return tMin; |
| } |
| } |
| } |
| return Extra_Truth6MinimumRoundMany( t, pStore, pCanonPerm, pCanonPhase); |
| } |
| |
| word luckyCanonicizer_final_fast_6Vars(word InOut, int* pStore, char* pCanonPerm, unsigned* pCanonPhase) |
| { |
| (* pCanonPhase) = Kit_TruthSemiCanonicize_Yasha1( &InOut, 6, pCanonPerm, pStore); |
| return Extra_Truth6MinimumRoundMany1(InOut, pStore, pCanonPerm, pCanonPhase); |
| } |
| word luckyCanonicizer_final_fast_6Vars1(word InOut, int* pStore, char* pCanonPerm, unsigned* pCanonPhase ) |
| { |
| (* pCanonPhase) = Kit_TruthSemiCanonicize_Yasha1( &InOut, 6, pCanonPerm, pStore); |
| InOut = Extra_Truth6MinimumRoundMany1(InOut, pStore, pCanonPerm, pCanonPhase); |
| Kit_TruthChangePhase_64bit( &InOut, 6, 5 ); |
| Kit_TruthChangePhase_64bit( &InOut, 6, 4 ); |
| Kit_TruthChangePhase_64bit( &InOut, 6, 3 ); |
| Kit_TruthChangePhase_64bit( &InOut, 6, 2 ); |
| Kit_TruthChangePhase_64bit( &InOut, 6, 1 ); |
| Kit_TruthChangePhase_64bit( &InOut, 6, 0 ); |
| (*pCanonPhase) ^= 0x3F; |
| return Extra_Truth6MinimumRoundMany1(InOut, pStore, pCanonPerm, pCanonPhase); |
| } |
| |
| |
| ABC_NAMESPACE_IMPL_END |