blob: 75135537d790f2a05af1318ad58314bc78e67d72 [file] [log] [blame]
/**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