/**CFile**************************************************************** FileName [exorBits.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Exclusive sum-of-product minimization.] Synopsis [Bit-level procedures.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: exorBits.c,v 1.0 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ //////////////////////////////////////////////////////////////////////// /// /// /// Implementation of EXORCISM - 4 /// /// An Exclusive Sum-of-Product Minimizer /// /// /// /// Alan Mishchenko /// /// /// //////////////////////////////////////////////////////////////////////// /// /// /// EXOR-Oriented Bit String Manipulation /// /// /// /// Ver. 1.0. Started - July 18, 2000. Last update - July 20, 2000 /// /// Ver. 1.4. Started - Aug 10, 2000. Last update - Aug 10, 2000 /// /// /// //////////////////////////////////////////////////////////////////////// /// This software was tested with the BDD package "CUDD", v.2.3.0 /// /// by Fabio Somenzi /// /// http://vlsi.colorado.edu/~fabio/ /// //////////////////////////////////////////////////////////////////////// #include "exor.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// EXTERNAL VARIABLES /// //////////////////////////////////////////////////////////////////////// // information about the cube cover // the number of cubes is constantly updated when the cube cover is processed // in this module, only the number of variables (nVarsIn) and integers (nWordsIn) // is used, which do not change extern cinfo g_CoverInfo; //////////////////////////////////////////////////////////////////////// /// FUNCTIONS OF THIS MODULE /// //////////////////////////////////////////////////////////////////////// int GetDistance( Cube * pC1, Cube * pC2 ); // return the distance between two cubes int GetDistancePlus( Cube * pC1, Cube * pC2 ); int FindDiffVars( int * pDiffVars, Cube * pC1, Cube * pC2 ); // determine different variables in cubes from pCubes[] and writes them into pDiffVars // returns the number of different variables void InsertVars( Cube * pC, int * pVars, int nVarsIn, int * pVarValues ); //inline int VarWord( int element ); //inline int VarBit( int element ); varvalue GetVar( Cube * pC, int Var ); void ExorVar( Cube * pC, int Var, varvalue Val ); //////////////////////////////////////////////////////////////////////// /// STATIC VARIABLES /// //////////////////////////////////////////////////////////////////////// // the bit count for the first 256 integer numbers static unsigned char BitCount8[256] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 }; static int SparseNumbers[163] = { 0,1,4,5,16,17,20,21,64,65,68,69,80,81,84,85,256,257,260, 261,272,273,276,277,320,321,324,325,336,337,340,1024,1025, 1028,1029,1040,1041,1044,1045,1088,1089,1092,1093,1104,1105, 1108,1280,1281,1284,1285,1296,1297,1300,1344,1345,1348,1360, 4096,4097,4100,4101,4112,4113,4116,4117,4160,4161,4164,4165, 4176,4177,4180,4352,4353,4356,4357,4368,4369,4372,4416,4417, 4420,4432,5120,5121,5124,5125,5136,5137,5140,5184,5185,5188, 5200,5376,5377,5380,5392,5440,16384,16385,16388,16389,16400, 16401,16404,16405,16448,16449,16452,16453,16464,16465,16468, 16640,16641,16644,16645,16656,16657,16660,16704,16705,16708, 16720,17408,17409,17412,17413,17424,17425,17428,17472,17473, 17476,17488,17664,17665,17668,17680,17728,20480,20481,20484, 20485,20496,20497,20500,20544,20545,20548,20560,20736,20737, 20740,20752,20800,21504,21505,21508,21520,21568,21760 }; static unsigned char GroupLiterals[163][4] = { {0}, {0}, {1}, {0,1}, {2}, {0,2}, {1,2}, {0,1,2}, {3}, {0,3}, {1,3}, {0,1,3}, {2,3}, {0,2,3}, {1,2,3}, {0,1,2,3}, {4}, {0,4}, {1,4}, {0,1,4}, {2,4}, {0,2,4}, {1,2,4}, {0,1,2,4}, {3,4}, {0,3,4}, {1,3,4}, {0,1,3,4}, {2,3,4}, {0,2,3,4}, {1,2,3,4}, {5}, {0,5}, {1,5}, {0,1,5}, {2,5}, {0,2,5}, {1,2,5}, {0,1,2,5}, {3,5}, {0,3,5}, {1,3,5}, {0,1,3,5}, {2,3,5}, {0,2,3,5}, {1,2,3,5}, {4,5}, {0,4,5}, {1,4,5}, {0,1,4,5}, {2,4,5}, {0,2,4,5}, {1,2,4,5}, {3,4,5}, {0,3,4,5}, {1,3,4,5}, {2,3,4,5}, {6}, {0,6}, {1,6}, {0,1,6}, {2,6}, {0,2,6}, {1,2,6}, {0,1,2,6}, {3,6}, {0,3,6}, {1,3,6}, {0,1,3,6}, {2,3,6}, {0,2,3,6}, {1,2,3,6}, {4,6}, {0,4,6}, {1,4,6}, {0,1,4,6}, {2,4,6}, {0,2,4,6}, {1,2,4,6}, {3,4,6}, {0,3,4,6}, {1,3,4,6}, {2,3,4,6}, {5,6}, {0,5,6}, {1,5,6}, {0,1,5,6}, {2,5,6}, {0,2,5,6}, {1,2,5,6}, {3,5,6}, {0,3,5,6}, {1,3,5,6}, {2,3,5,6}, {4,5,6}, {0,4,5,6}, {1,4,5,6}, {2,4,5,6}, {3,4,5,6}, {7}, {0,7}, {1,7}, {0,1,7}, {2,7}, {0,2,7}, {1,2,7}, {0,1,2,7}, {3,7}, {0,3,7}, {1,3,7}, {0,1,3,7}, {2,3,7}, {0,2,3,7}, {1,2,3,7}, {4,7}, {0,4,7}, {1,4,7}, {0,1,4,7}, {2,4,7}, {0,2,4,7}, {1,2,4,7}, {3,4,7}, {0,3,4,7}, {1,3,4,7}, {2,3,4,7}, {5,7}, {0,5,7}, {1,5,7}, {0,1,5,7}, {2,5,7}, {0,2,5,7}, {1,2,5,7}, {3,5,7}, {0,3,5,7}, {1,3,5,7}, {2,3,5,7}, {4,5,7}, {0,4,5,7}, {1,4,5,7}, {2,4,5,7}, {3,4,5,7}, {6,7}, {0,6,7}, {1,6,7}, {0,1,6,7}, {2,6,7}, {0,2,6,7}, {1,2,6,7}, {3,6,7}, {0,3,6,7}, {1,3,6,7}, {2,3,6,7}, {4,6,7}, {0,4,6,7}, {1,4,6,7}, {2,4,6,7}, {3,4,6,7}, {5,6,7}, {0,5,6,7}, {1,5,6,7}, {2,5,6,7}, {3,5,6,7}, {4,5,6,7} }; // the bit count to 16-bit numbers #define FULL16BITS 0x10000 #define MARKNUMBER 200 static unsigned char BitGroupNumbers[FULL16BITS]; unsigned char BitCount[FULL16BITS]; //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// void PrepareBitSetModule() // this function should be called before anything is done with the cube cover { // prepare bit count int i, k; int nLimit; nLimit = FULL16BITS; for ( i = 0; i < nLimit; i++ ) { BitCount[i] = BitCount8[ i & 0xff ] + BitCount8[ i>>8 ]; BitGroupNumbers[i] = MARKNUMBER; } // prepare bit groups for ( k = 0; k < 163; k++ ) BitGroupNumbers[ SparseNumbers[k] ] = k; /* // verify bit groups int n = 4368; char Buff[100]; cout << "The number is " << n << endl; cout << "The binary is " << itoa(n,Buff,2) << endl; cout << "BitGroupNumbers[n] is " << (int)BitGroupNumbers[n] << endl; cout << "The group literals are "; for ( int g = 0; g < 4; g++ ) cout << " " << (int)GroupLiterals[BitGroupNumbers[n]][g]; */ } //////////////////////////////////////////////////////////////////////// /// INLINE FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /* int VarWord( int element ) { return ( element >> LOGBPI ); } int VarBit( int element ) { return ( element & BPIMASK ); } */ varvalue GetVar( Cube * pC, int Var ) // returns VAR_NEG if var is neg, VAR_POS if var is pos, VAR_ABS if var is absent { int Bit = (Var<<1); int Value = ((pC->pCubeDataIn[VarWord(Bit)] >> VarBit(Bit)) & 3); assert( Value == VAR_NEG || Value == VAR_POS || Value == VAR_ABS ); return (varvalue)Value; } void ExorVar( Cube * pC, int Var, varvalue Val ) // EXORs the value Val with the value of variable Var in the given cube // ((cube[VAR_WORD((v)<<1)]) ^ ( (pol)<pCubeDataIn[VarWord(Bit)] ^= ( Val << VarBit(Bit) ); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// static int DiffVarCounter, cVars; static drow Temp1, Temp2, Temp; static drow LastNonZeroWord; static int LastNonZeroWordNum; int GetDistance( Cube * pC1, Cube * pC2 ) // finds and returns the distance between two cubes pC1 and pC2 { int i; DiffVarCounter = 0; for ( i = 0; i < g_CoverInfo.nWordsIn; i++ ) { Temp1 = pC1->pCubeDataIn[i] ^ pC2->pCubeDataIn[i]; Temp2 = (Temp1|(Temp1>>1)) & DIFFERENT; // count how many bits are one in this var difference DiffVarCounter += BIT_COUNT(Temp2); if ( DiffVarCounter > 4 ) return 5; } // check whether the output parts are different for ( i = 0; i < g_CoverInfo.nWordsOut; i++ ) if ( pC1->pCubeDataOut[i] ^ pC2->pCubeDataOut[i] ) { DiffVarCounter++; break; } return DiffVarCounter; } // place to put the number of the different variable and its value in the second cube extern int s_DiffVarNum; extern int s_DiffVarValueP_old; extern int s_DiffVarValueP_new; extern int s_DiffVarValueQ; int GetDistancePlus( Cube * pC1, Cube * pC2 ) // finds and returns the distance between two cubes pC1 and pC2 // if the distance is 1, returns the number of diff variable in VarNum { int i; DiffVarCounter = 0; LastNonZeroWordNum = -1; for ( i = 0; i < g_CoverInfo.nWordsIn; i++ ) { Temp1 = pC1->pCubeDataIn[i] ^ pC2->pCubeDataIn[i]; Temp2 = (Temp1|(Temp1>>1)) & DIFFERENT; // save the value of var difference, in case // the distance is one and we need to return the var number if ( Temp2 ) { LastNonZeroWordNum = i; LastNonZeroWord = Temp2; } // count how many bits are one in this var difference DiffVarCounter += BIT_COUNT(Temp2); if ( DiffVarCounter > 4 ) return 5; } // check whether the output parts are different for ( i = 0; i < g_CoverInfo.nWordsOut; i++ ) if ( pC1->pCubeDataOut[i] ^ pC2->pCubeDataOut[i] ) { DiffVarCounter++; break; } if ( DiffVarCounter == 1 ) { if ( LastNonZeroWordNum == -1 ) // the output is the only different variable s_DiffVarNum = -1; else { Temp = (LastNonZeroWord>>2); for ( i = 0; Temp; Temp>>=2, i++ ); s_DiffVarNum = LastNonZeroWordNum*BPI/2 + i; // save the old var value s_DiffVarValueP_old = GetVar( pC1, s_DiffVarNum ); s_DiffVarValueQ = GetVar( pC2, s_DiffVarNum ); // EXOR this value with the corresponding value in p cube ExorVar( pC1, s_DiffVarNum, (varvalue)s_DiffVarValueQ ); s_DiffVarValueP_new = GetVar( pC1, s_DiffVarNum ); } } return DiffVarCounter; } int FindDiffVars( int * pDiffVars, Cube * pC1, Cube * pC2 ) // determine different variables in two cubes and // writes them into pDiffVars[] // -1 is written into pDiffVars[0] if the cubes have different outputs // returns the number of different variables (including the output) { int i, v; DiffVarCounter = 0; // check whether the output parts of the cubes are different for ( i = 0; i < g_CoverInfo.nWordsOut; i++ ) if ( pC1->pCubeDataOut[i] != pC2->pCubeDataOut[i] ) { // they are different pDiffVars[0] = -1; DiffVarCounter = 1; break; } for ( i = 0; i < g_CoverInfo.nWordsIn; i++ ) { Temp1 = pC1->pCubeDataIn[i] ^ pC2->pCubeDataIn[i]; Temp2 = (Temp1|(Temp1>>1)) & DIFFERENT; // check the first part of this word Temp = Temp2 & 0xffff; cVars = BitCount[ Temp ]; if ( cVars ) { if ( cVars < 5 ) for ( v = 0; v < cVars; v++ ) { assert( BitGroupNumbers[Temp] != MARKNUMBER ); pDiffVars[ DiffVarCounter++ ] = i*16 + GroupLiterals[ BitGroupNumbers[Temp] ][v]; } else return 5; } if ( DiffVarCounter > 4 ) return 5; // check the second part of this word Temp = Temp2 >> 16; cVars = BitCount[ Temp ]; if ( cVars ) { if ( cVars < 5 ) for ( v = 0; v < cVars; v++ ) { assert( BitGroupNumbers[Temp] != MARKNUMBER ); pDiffVars[ DiffVarCounter++ ] = i*16 + 8 + GroupLiterals[ BitGroupNumbers[Temp] ][v]; } else return 5; } if ( DiffVarCounter > 4 ) return 5; } return DiffVarCounter; } void InsertVars( Cube * pC, int * pVars, int nVarsIn, int * pVarValues ) // corrects the given number of variables (nVarsIn) in pC->pCubeDataIn[] // variable numbers are given in pVarNumbers[], their values are in pVarValues[] // arrays pVarNumbers[] and pVarValues[] are provided by the user { int GlobalBit; int LocalWord; int LocalBit; int i; assert( nVarsIn > 0 && nVarsIn <= g_CoverInfo.nVarsIn ); for ( i = 0; i < nVarsIn; i++ ) { assert( pVars[i] >= 0 && pVars[i] < g_CoverInfo.nVarsIn ); assert( pVarValues[i] == VAR_NEG || pVarValues[i] == VAR_POS || pVarValues[i] == VAR_ABS ); GlobalBit = (pVars[i]<<1); LocalWord = VarWord(GlobalBit); LocalBit = VarBit(GlobalBit); // correct this variables pC->pCubeDataIn[LocalWord] = ((pC->pCubeDataIn[LocalWord]&(~(3<pCubeDataIn[] // variable numbers are given in pVarNumbers[], their values are in pVarValues[] // arrays pVarNumbers[] and pVarValues[] are provided by the user { int GlobalBit; int LocalWord; int LocalBit; int i; assert( nVarsIn > 0 && nVarsIn <= g_CoverInfo.nVarsIn ); for ( i = 0; i < nVarsIn; i++ ) { assert( pVars[i] >= 0 && pVars[i] < g_CoverInfo.nVarsIn ); assert( pVarValues[i] == VAR_NEG || pVarValues[i] == VAR_POS || pVarValues[i] == VAR_ABS ); GlobalBit = (pVars[i]<<1); LocalWord = VarWord(GlobalBit); LocalBit = VarBit(GlobalBit); // correct this variables pC->pCubeDataIn[LocalWord] |= ( pVarValues[i] << LocalBit ); } // insert the output bit pC->pCubeDataOut[VarWord(Output)] |= ( 1 << VarBit(Output) ); } /////////////////////////////////////////////////////////////////// //////////// End of File ///////////////// /////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END