mirror of https://github.com/YosysHQ/abc.git
2029 lines
68 KiB
C
2029 lines
68 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [dauDsd.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [DAG-aware unmapping.]
|
|
|
|
Synopsis [Disjoint-support decomposition.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: dauDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "dauInt.h"
|
|
#include "misc/util/utilTruth.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/*
|
|
This code performs truth-table-based decomposition for 6-variable functions.
|
|
Representation of operations:
|
|
! = not;
|
|
(ab) = a and b;
|
|
[ab] = a xor b;
|
|
<abc> = ITE( a, b, c )
|
|
FUNCTION{abc} = FUNCTION( a, b, c )
|
|
*/
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Elementary truth tables.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline word ** Dau_DsdTtElems()
|
|
{
|
|
static word TtElems[DAU_MAX_VAR+1][DAU_MAX_WORD], * pTtElems[DAU_MAX_VAR+1] = {NULL};
|
|
if ( pTtElems[0] == NULL )
|
|
{
|
|
int v;
|
|
for ( v = 0; v <= DAU_MAX_VAR; v++ )
|
|
pTtElems[v] = TtElems[v];
|
|
Abc_TtElemInit( pTtElems, DAU_MAX_VAR );
|
|
}
|
|
return pTtElems;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [DSD formula manipulation.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int * Dau_DsdComputeMatches( char * p )
|
|
{
|
|
static int pMatches[DAU_MAX_STR];
|
|
int pNested[DAU_MAX_VAR];
|
|
int v, nNested = 0;
|
|
for ( v = 0; p[v]; v++ )
|
|
{
|
|
pMatches[v] = 0;
|
|
if ( p[v] == '(' || p[v] == '[' || p[v] == '<' || p[v] == '{' )
|
|
pNested[nNested++] = v;
|
|
else if ( p[v] == ')' || p[v] == ']' || p[v] == '>' || p[v] == '}' )
|
|
pMatches[pNested[--nNested]] = v;
|
|
assert( nNested < DAU_MAX_VAR );
|
|
}
|
|
assert( nNested == 0 );
|
|
return pMatches;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generate random permutation.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Dau_DsdFindVarNum( char * pDsd )
|
|
{
|
|
int vMax = 0;
|
|
pDsd--;
|
|
while ( *++pDsd )
|
|
if ( *pDsd >= 'a' && *pDsd <= 'z' )
|
|
vMax = Abc_MaxInt( vMax, *pDsd - 'a' );
|
|
return vMax + 1;
|
|
}
|
|
void Dau_DsdGenRandPerm( int * pPerm, int nVars )
|
|
{
|
|
int v, vNew;
|
|
for ( v = 0; v < nVars; v++ )
|
|
pPerm[v] = v;
|
|
for ( v = 0; v < nVars; v++ )
|
|
{
|
|
vNew = rand() % nVars;
|
|
ABC_SWAP( int, pPerm[v], pPerm[vNew] );
|
|
}
|
|
}
|
|
void Dau_DsdPermute( char * pDsd )
|
|
{
|
|
int pPerm[16];
|
|
int nVars = Dau_DsdFindVarNum( pDsd );
|
|
Dau_DsdGenRandPerm( pPerm, nVars );
|
|
pDsd--;
|
|
while ( *++pDsd )
|
|
if ( *pDsd >= 'a' && *pDsd < 'a' + nVars )
|
|
*pDsd = 'a' + pPerm[*pDsd - 'a'];
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Normalize the ordering of components.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Dau_DsdNormalizeCopy( char * pDest, char * pSour, int * pMarks, int i )
|
|
{
|
|
int s;
|
|
for ( s = pMarks[i]; s < pMarks[i+1]; s++ )
|
|
*pDest++ = pSour[s];
|
|
return pDest;
|
|
}
|
|
int Dau_DsdNormalizeCompare( char * pStr, int * pMarks, int i, int j )
|
|
{
|
|
char * pStr1 = pStr + pMarks[i];
|
|
char * pStr2 = pStr + pMarks[j];
|
|
char * pLimit1 = pStr + pMarks[i+1];
|
|
char * pLimit2 = pStr + pMarks[j+1];
|
|
for ( ; pStr1 < pLimit1 && pStr2 < pLimit2; pStr1++, pStr2++ )
|
|
{
|
|
if ( !(*pStr1 >= 'a' && *pStr1 <= 'z') )
|
|
{
|
|
pStr2--;
|
|
continue;
|
|
}
|
|
if ( !(*pStr2 >= 'a' && *pStr2 <= 'z') )
|
|
{
|
|
pStr1--;
|
|
continue;
|
|
}
|
|
if ( *pStr1 < *pStr2 )
|
|
return -1;
|
|
if ( *pStr1 > *pStr2 )
|
|
return 1;
|
|
}
|
|
assert( pStr1 < pLimit1 || pStr2 < pLimit2 );
|
|
if ( pStr1 == pLimit1 )
|
|
return -1;
|
|
if ( pStr2 == pLimit2 )
|
|
return 1;
|
|
assert( 0 );
|
|
return 0;
|
|
}
|
|
int * Dau_DsdNormalizePerm( char * pStr, int * pMarks, int nMarks )
|
|
{
|
|
static int pPerm[DAU_MAX_VAR];
|
|
int i, k;
|
|
for ( i = 0; i < nMarks; i++ )
|
|
pPerm[i] = i;
|
|
for ( i = 0; i < nMarks; i++ )
|
|
{
|
|
int iBest = i;
|
|
for ( k = i + 1; k < nMarks; k++ )
|
|
if ( Dau_DsdNormalizeCompare( pStr, pMarks, pPerm[iBest], pPerm[k] ) == 1 )
|
|
iBest = k;
|
|
ABC_SWAP( int, pPerm[i], pPerm[iBest] );
|
|
}
|
|
return pPerm;
|
|
}
|
|
void Dau_DsdNormalize_rec( char * pStr, char ** p, int * pMatches )
|
|
{
|
|
static char pBuffer[DAU_MAX_STR];
|
|
if ( **p == '!' )
|
|
(*p)++;
|
|
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
|
|
(*p)++;
|
|
if ( **p == '<' )
|
|
{
|
|
char * q = pStr + pMatches[*p - pStr];
|
|
if ( *(q+1) == '{' )
|
|
*p = q+1;
|
|
}
|
|
if ( **p >= 'a' && **p <= 'z' ) // var
|
|
return;
|
|
if ( **p == '(' || **p == '[' ) // and/or/xor
|
|
{
|
|
char * pStore, * pOld = *p + 1;
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
int i, * pPerm, nMarks = 0, pMarks[DAU_MAX_VAR+1];
|
|
assert( *q == **p + 1 + (**p != '(') );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
{
|
|
pMarks[nMarks++] = *p - pStr;
|
|
Dau_DsdNormalize_rec( pStr, p, pMatches );
|
|
}
|
|
pMarks[nMarks] = *p - pStr;
|
|
assert( *p == q );
|
|
// add to buffer in good order
|
|
pPerm = Dau_DsdNormalizePerm( pStr, pMarks, nMarks );
|
|
// copy to the buffer
|
|
pStore = pBuffer;
|
|
for ( i = 0; i < nMarks; i++ )
|
|
pStore = Dau_DsdNormalizeCopy( pStore, pStr, pMarks, pPerm[i] );
|
|
assert( pStore - pBuffer == *p - pOld );
|
|
memcpy( pOld, pBuffer, pStore - pBuffer );
|
|
return;
|
|
}
|
|
if ( **p == '<' || **p == '{' ) // mux
|
|
{
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
assert( *q == **p + 1 + (**p != '(') );
|
|
if ( (**p == '<') && (*(q+1) == '{') )
|
|
{
|
|
*p = q+1;
|
|
Dau_DsdNormalize_rec( pStr, p, pMatches );
|
|
return;
|
|
}
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
Dau_DsdNormalize_rec( pStr, p, pMatches );
|
|
assert( *p == q );
|
|
return;
|
|
}
|
|
assert( 0 );
|
|
}
|
|
void Dau_DsdNormalize( char * pDsd )
|
|
{
|
|
if ( pDsd[1] != 0 )
|
|
Dau_DsdNormalize_rec( pDsd, &pDsd, Dau_DsdComputeMatches(pDsd) );
|
|
}
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Dau_DsdCountAnds_rec( char * pStr, char ** p, int * pMatches )
|
|
{
|
|
if ( **p == '!' )
|
|
(*p)++;
|
|
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
|
|
(*p)++;
|
|
if ( **p == '<' )
|
|
{
|
|
char * q = pStr + pMatches[*p - pStr];
|
|
if ( *(q+1) == '{' )
|
|
*p = q+1;
|
|
}
|
|
if ( **p >= 'a' && **p <= 'z' ) // var
|
|
return 0;
|
|
if ( **p == '(' || **p == '[' ) // and/or/xor
|
|
{
|
|
int Counter = 0, AddOn = (**p == '(')? 1 : 3;
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
assert( *q == **p + 1 + (**p != '(') );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
Counter += AddOn + Dau_DsdCountAnds_rec( pStr, p, pMatches );
|
|
assert( *p == q );
|
|
return Counter - AddOn;
|
|
}
|
|
if ( **p == '<' || **p == '{' ) // mux
|
|
{
|
|
int Counter = 3;
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
assert( *q == **p + 1 + (**p != '(') );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
Counter += Dau_DsdCountAnds_rec( pStr, p, pMatches );
|
|
assert( *p == q );
|
|
return Counter;
|
|
}
|
|
assert( 0 );
|
|
return 0;
|
|
}
|
|
int Dau_DsdCountAnds( char * pDsd )
|
|
{
|
|
if ( pDsd[1] == 0 )
|
|
return 0;
|
|
return Dau_DsdCountAnds_rec( pDsd, &pDsd, Dau_DsdComputeMatches(pDsd) );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes truth table for the DSD formula.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
word Dau_Dsd6TruthCompose_rec( word Func, word * pFanins, int nVars )
|
|
{
|
|
word t0, t1;
|
|
if ( Func == 0 )
|
|
return 0;
|
|
if ( Func == ~(word)0 )
|
|
return ~(word)0;
|
|
assert( nVars > 0 );
|
|
if ( --nVars == 0 )
|
|
{
|
|
assert( Func == s_Truths6[0] || Func == s_Truths6Neg[0] );
|
|
return (Func == s_Truths6[0]) ? pFanins[0] : ~pFanins[0];
|
|
}
|
|
if ( !Abc_Tt6HasVar(Func, nVars) )
|
|
return Dau_Dsd6TruthCompose_rec( Func, pFanins, nVars );
|
|
t0 = Dau_Dsd6TruthCompose_rec( Abc_Tt6Cofactor0(Func, nVars), pFanins, nVars );
|
|
t1 = Dau_Dsd6TruthCompose_rec( Abc_Tt6Cofactor1(Func, nVars), pFanins, nVars );
|
|
return (~pFanins[nVars] & t0) | (pFanins[nVars] & t1);
|
|
}
|
|
word Dau_Dsd6ToTruth_rec( char * pStr, char ** p, int * pMatches, word * pTruths )
|
|
{
|
|
int fCompl = 0;
|
|
if ( **p == '!' )
|
|
(*p)++, fCompl = 1;
|
|
if ( **p >= 'a' && **p <= 'f' ) // var
|
|
{
|
|
assert( **p - 'a' >= 0 && **p - 'a' < 6 );
|
|
return fCompl ? ~pTruths[**p - 'a'] : pTruths[**p - 'a'];
|
|
}
|
|
if ( **p == '(' ) // and/or
|
|
{
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
word Res = ~(word)0;
|
|
assert( **p == '(' && *q == ')' );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
Res &= Dau_Dsd6ToTruth_rec( pStr, p, pMatches, pTruths );
|
|
assert( *p == q );
|
|
return fCompl ? ~Res : Res;
|
|
}
|
|
if ( **p == '[' ) // xor
|
|
{
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
word Res = 0;
|
|
assert( **p == '[' && *q == ']' );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
Res ^= Dau_Dsd6ToTruth_rec( pStr, p, pMatches, pTruths );
|
|
assert( *p == q );
|
|
return fCompl ? ~Res : Res;
|
|
}
|
|
if ( **p == '<' ) // mux
|
|
{
|
|
int nVars = 0;
|
|
word Temp[3], * pTemp = Temp, Res;
|
|
word Fanins[6], * pTruths2;
|
|
char * pOld = *p;
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
// read fanins
|
|
if ( *(q+1) == '{' )
|
|
{
|
|
char * q2;
|
|
*p = q+1;
|
|
q2 = pStr + pMatches[ *p - pStr ];
|
|
assert( **p == '{' && *q2 == '}' );
|
|
for ( nVars = 0, (*p)++; *p < q2; (*p)++, nVars++ )
|
|
Fanins[nVars] = Dau_Dsd6ToTruth_rec( pStr, p, pMatches, pTruths );
|
|
assert( *p == q2 );
|
|
pTruths2 = Fanins;
|
|
}
|
|
else
|
|
pTruths2 = pTruths;
|
|
// read MUX
|
|
*p = pOld;
|
|
q = pStr + pMatches[ *p - pStr ];
|
|
assert( **p == '<' && *q == '>' );
|
|
// verify internal variables
|
|
if ( nVars )
|
|
for ( ; pOld < q; pOld++ )
|
|
if ( *pOld >= 'a' && *pOld <= 'z' )
|
|
assert( *pOld - 'a' < nVars );
|
|
// derive MAX components
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
*pTemp++ = Dau_Dsd6ToTruth_rec( pStr, p, pMatches, pTruths2 );
|
|
assert( pTemp == Temp + 3 );
|
|
assert( *p == q );
|
|
if ( *(q+1) == '{' ) // and/or
|
|
{
|
|
char * q = pStr + pMatches[ ++(*p) - pStr ];
|
|
assert( **p == '{' && *q == '}' );
|
|
*p = q;
|
|
}
|
|
Res = (Temp[0] & Temp[1]) | (~Temp[0] & Temp[2]);
|
|
return fCompl ? ~Res : Res;
|
|
}
|
|
if ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
|
|
{
|
|
word Func, Fanins[6], Res;
|
|
char * q;
|
|
int i, nVars = Abc_TtReadHex( &Func, *p );
|
|
*p += Abc_TtHexDigitNum( nVars );
|
|
q = pStr + pMatches[ *p - pStr ];
|
|
assert( **p == '{' && *q == '}' );
|
|
for ( i = 0, (*p)++; *p < q; (*p)++, i++ )
|
|
Fanins[i] = Dau_Dsd6ToTruth_rec( pStr, p, pMatches, pTruths );
|
|
assert( i == nVars );
|
|
assert( *p == q );
|
|
Res = Dau_Dsd6TruthCompose_rec( Func, Fanins, nVars );
|
|
return fCompl ? ~Res : Res;
|
|
}
|
|
assert( 0 );
|
|
return 0;
|
|
}
|
|
word Dau_Dsd6ToTruth( char * p )
|
|
{
|
|
word Res;
|
|
if ( *p == '0' && *(p+1) == 0 )
|
|
Res = 0;
|
|
else if ( *p == '1' && *(p+1) == 0 )
|
|
Res = ~(word)0;
|
|
else
|
|
Res = Dau_Dsd6ToTruth_rec( p, &p, Dau_DsdComputeMatches(p), s_Truths6 );
|
|
assert( *++p == 0 );
|
|
return Res;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes truth table for the DSD formula.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Dau_DsdTruth6Compose_rec( word Func, word pFanins[DAU_MAX_VAR][DAU_MAX_WORD], word * pRes, int nVars, int nWordsR )
|
|
{
|
|
if ( Func == 0 )
|
|
{
|
|
Abc_TtConst0( pRes, nWordsR );
|
|
return;
|
|
}
|
|
if ( Func == ~(word)0 )
|
|
{
|
|
Abc_TtConst1( pRes, nWordsR );
|
|
return;
|
|
}
|
|
assert( nVars > 0 );
|
|
if ( --nVars == 0 )
|
|
{
|
|
assert( Func == s_Truths6[0] || Func == s_Truths6Neg[0] );
|
|
Abc_TtCopy( pRes, pFanins[0], nWordsR, Func == s_Truths6Neg[0] );
|
|
return;
|
|
}
|
|
if ( !Abc_Tt6HasVar(Func, nVars) )
|
|
{
|
|
Dau_DsdTruth6Compose_rec( Func, pFanins, pRes, nVars, nWordsR );
|
|
return;
|
|
}
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
Dau_DsdTruth6Compose_rec( Abc_Tt6Cofactor0(Func, nVars), pFanins, pTtTemp[0], nVars, nWordsR );
|
|
Dau_DsdTruth6Compose_rec( Abc_Tt6Cofactor1(Func, nVars), pFanins, pTtTemp[1], nVars, nWordsR );
|
|
Abc_TtMux( pRes, pFanins[nVars], pTtTemp[1], pTtTemp[0], nWordsR );
|
|
return;
|
|
}
|
|
}
|
|
void Dau_DsdTruthCompose_rec( word * pFunc, word pFanins[DAU_MAX_VAR][DAU_MAX_WORD], word * pRes, int nVars, int nWordsR )
|
|
{
|
|
int nWordsF;
|
|
if ( nVars <= 6 )
|
|
{
|
|
Dau_DsdTruth6Compose_rec( pFunc[0], pFanins, pRes, nVars, nWordsR );
|
|
return;
|
|
}
|
|
nWordsF = Abc_TtWordNum( nVars );
|
|
assert( nWordsF > 1 );
|
|
if ( Abc_TtIsConst0(pFunc, nWordsF) )
|
|
{
|
|
Abc_TtConst0( pRes, nWordsR );
|
|
return;
|
|
}
|
|
if ( Abc_TtIsConst1(pFunc, nWordsF) )
|
|
{
|
|
Abc_TtConst1( pRes, nWordsR );
|
|
return;
|
|
}
|
|
if ( !Abc_TtHasVar( pFunc, nVars, nVars-1 ) )
|
|
{
|
|
Dau_DsdTruthCompose_rec( pFunc, pFanins, pRes, nVars-1, nWordsR );
|
|
return;
|
|
}
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
nVars--;
|
|
Dau_DsdTruthCompose_rec( pFunc, pFanins, pTtTemp[0], nVars, nWordsR );
|
|
Dau_DsdTruthCompose_rec( pFunc + nWordsF/2, pFanins, pTtTemp[1], nVars, nWordsR );
|
|
Abc_TtMux( pRes, pFanins[nVars], pTtTemp[1], pTtTemp[0], nWordsR );
|
|
return;
|
|
}
|
|
}
|
|
void Dau_DsdToTruth_rec( char * pStr, char ** p, int * pMatches, word ** pTtElems, word * pRes, int nVars )
|
|
{
|
|
int nWords = Abc_TtWordNum( nVars );
|
|
int fCompl = 0;
|
|
if ( **p == '!' )
|
|
(*p)++, fCompl = 1;
|
|
if ( **p >= 'a' && **p <= 'z' ) // var
|
|
{
|
|
assert( **p - 'a' >= 0 && **p - 'a' < nVars );
|
|
Abc_TtCopy( pRes, pTtElems[**p - 'a'], nWords, fCompl );
|
|
return;
|
|
}
|
|
if ( **p == '(' ) // and/or
|
|
{
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
word pTtTemp[DAU_MAX_WORD];
|
|
assert( **p == '(' && *q == ')' );
|
|
Abc_TtConst1( pRes, nWords );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
{
|
|
Dau_DsdToTruth_rec( pStr, p, pMatches, pTtElems, pTtTemp, nVars );
|
|
Abc_TtAnd( pRes, pRes, pTtTemp, nWords, 0 );
|
|
}
|
|
assert( *p == q );
|
|
if ( fCompl ) Abc_TtNot( pRes, nWords );
|
|
return;
|
|
}
|
|
if ( **p == '[' ) // xor
|
|
{
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
word pTtTemp[DAU_MAX_WORD];
|
|
assert( **p == '[' && *q == ']' );
|
|
Abc_TtConst0( pRes, nWords );
|
|
for ( (*p)++; *p < q; (*p)++ )
|
|
{
|
|
Dau_DsdToTruth_rec( pStr, p, pMatches, pTtElems, pTtTemp, nVars );
|
|
Abc_TtXor( pRes, pRes, pTtTemp, nWords, 0 );
|
|
}
|
|
assert( *p == q );
|
|
if ( fCompl ) Abc_TtNot( pRes, nWords );
|
|
return;
|
|
}
|
|
if ( **p == '<' ) // mux
|
|
{
|
|
char * q = pStr + pMatches[ *p - pStr ];
|
|
word pTtTemp[3][DAU_MAX_WORD];
|
|
int i;
|
|
assert( **p == '<' && *q == '>' );
|
|
for ( i = 0, (*p)++; *p < q; (*p)++, i++ )
|
|
Dau_DsdToTruth_rec( pStr, p, pMatches, pTtElems, pTtTemp[i], nVars );
|
|
assert( i == 3 );
|
|
Abc_TtMux( pRes, pTtTemp[0], pTtTemp[1], pTtTemp[2], nWords );
|
|
assert( *p == q );
|
|
if ( fCompl ) Abc_TtNot( pRes, nWords );
|
|
return;
|
|
}
|
|
if ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
|
|
{
|
|
word pFanins[DAU_MAX_VAR][DAU_MAX_WORD], pFunc[DAU_MAX_WORD];
|
|
char * q;
|
|
int i, nVarsF = Abc_TtReadHex( pFunc, *p );
|
|
*p += Abc_TtHexDigitNum( nVarsF );
|
|
q = pStr + pMatches[ *p - pStr ];
|
|
assert( **p == '{' && *q == '}' );
|
|
for ( i = 0, (*p)++; *p < q; (*p)++, i++ )
|
|
Dau_DsdToTruth_rec( pStr, p, pMatches, pTtElems, pFanins[i], nVars );
|
|
assert( i == nVarsF );
|
|
assert( *p == q );
|
|
Dau_DsdTruthCompose_rec( pFunc, pFanins, pRes, nVarsF, nWords );
|
|
if ( fCompl ) Abc_TtNot( pRes, nWords );
|
|
return;
|
|
}
|
|
assert( 0 );
|
|
}
|
|
word * Dau_DsdToTruth( char * p, int nVars )
|
|
{
|
|
int nWords = Abc_TtWordNum( nVars );
|
|
word ** pTtElems = Dau_DsdTtElems();
|
|
word * pRes = pTtElems[DAU_MAX_VAR];
|
|
assert( nVars <= DAU_MAX_VAR );
|
|
if ( Dau_DsdIsConst0(p) )
|
|
Abc_TtConst0( pRes, nWords );
|
|
else if ( Dau_DsdIsConst1(p) )
|
|
Abc_TtConst1( pRes, nWords );
|
|
else
|
|
Dau_DsdToTruth_rec( p, &p, Dau_DsdComputeMatches(p), pTtElems, pRes, nVars );
|
|
assert( *++p == 0 );
|
|
return pRes;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Dau_DsdTest2()
|
|
{
|
|
// char * p = Abc_UtilStrsav( "!(ab!(de[cf]))" );
|
|
// char * p = Abc_UtilStrsav( "!(a![d<ecf>]b)" );
|
|
// word t = Dau_Dsd6ToTruth( p );
|
|
}
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Performs DSD.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Dau_DsdPerformReplace( char * pBuffer, int PosStart, int Pos, int Symb, char * pNext )
|
|
{
|
|
static char pTemp[DAU_MAX_STR];
|
|
char * pCur = pTemp;
|
|
int i, k, RetValue;
|
|
for ( i = PosStart; i < Pos; i++ )
|
|
if ( pBuffer[i] != Symb )
|
|
*pCur++ = pBuffer[i];
|
|
else
|
|
for ( k = 0; pNext[k]; k++ )
|
|
*pCur++ = pNext[k];
|
|
RetValue = PosStart + (pCur - pTemp);
|
|
for ( i = PosStart; i < RetValue; i++ )
|
|
pBuffer[i] = pTemp[i-PosStart];
|
|
return RetValue;
|
|
}
|
|
int Dau_DsdPerform_rec( word t, char * pBuffer, int Pos, int * pVars, int nVars )
|
|
{
|
|
char pNest[10];
|
|
word Cof0[6], Cof1[6], Cof[4];
|
|
int pVarsNew[6], nVarsNew, PosStart;
|
|
int v, u, vBest, CountBest;
|
|
assert( Pos < DAU_MAX_STR );
|
|
// perform support minimization
|
|
nVarsNew = 0;
|
|
for ( v = 0; v < nVars; v++ )
|
|
if ( Abc_Tt6HasVar( t, pVars[v] ) )
|
|
pVarsNew[ nVarsNew++ ] = pVars[v];
|
|
assert( nVarsNew > 0 );
|
|
// special case when function is a var
|
|
if ( nVarsNew == 1 )
|
|
{
|
|
if ( t == s_Truths6[ pVarsNew[0] ] )
|
|
{
|
|
pBuffer[Pos++] = 'a' + pVarsNew[0];
|
|
return Pos;
|
|
}
|
|
if ( t == ~s_Truths6[ pVarsNew[0] ] )
|
|
{
|
|
pBuffer[Pos++] = '!';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[0];
|
|
return Pos;
|
|
}
|
|
assert( 0 );
|
|
return Pos;
|
|
}
|
|
// decompose on the output side
|
|
for ( v = 0; v < nVarsNew; v++ )
|
|
{
|
|
Cof0[v] = Abc_Tt6Cofactor0( t, pVarsNew[v] );
|
|
Cof1[v] = Abc_Tt6Cofactor1( t, pVarsNew[v] );
|
|
assert( Cof0[v] != Cof1[v] );
|
|
if ( Cof0[v] == 0 ) // ax
|
|
{
|
|
pBuffer[Pos++] = '(';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[v];
|
|
Pos = Dau_DsdPerform_rec( Cof1[v], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
pBuffer[Pos++] = ')';
|
|
return Pos;
|
|
}
|
|
if ( Cof0[v] == ~(word)0 ) // !(ax)
|
|
{
|
|
pBuffer[Pos++] = '!';
|
|
pBuffer[Pos++] = '(';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[v];
|
|
Pos = Dau_DsdPerform_rec( ~Cof1[v], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
pBuffer[Pos++] = ')';
|
|
return Pos;
|
|
}
|
|
if ( Cof1[v] == 0 ) // !ax
|
|
{
|
|
pBuffer[Pos++] = '(';
|
|
pBuffer[Pos++] = '!';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[v];
|
|
Pos = Dau_DsdPerform_rec( Cof0[v], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
pBuffer[Pos++] = ')';
|
|
return Pos;
|
|
}
|
|
if ( Cof1[v] == ~(word)0 ) // !(!ax)
|
|
{
|
|
pBuffer[Pos++] = '!';
|
|
pBuffer[Pos++] = '(';
|
|
pBuffer[Pos++] = '!';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[v];
|
|
Pos = Dau_DsdPerform_rec( ~Cof0[v], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
pBuffer[Pos++] = ')';
|
|
return Pos;
|
|
}
|
|
if ( Cof0[v] == ~Cof1[v] ) // a^x
|
|
{
|
|
pBuffer[Pos++] = '[';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[v];
|
|
Pos = Dau_DsdPerform_rec( Cof0[v], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
pBuffer[Pos++] = ']';
|
|
return Pos;
|
|
}
|
|
}
|
|
// decompose on the input side
|
|
for ( v = 0; v < nVarsNew; v++ )
|
|
for ( u = v+1; u < nVarsNew; u++ )
|
|
{
|
|
Cof[0] = Abc_Tt6Cofactor0( Cof0[v], pVarsNew[u] );
|
|
Cof[1] = Abc_Tt6Cofactor1( Cof0[v], pVarsNew[u] );
|
|
Cof[2] = Abc_Tt6Cofactor0( Cof1[v], pVarsNew[u] );
|
|
Cof[3] = Abc_Tt6Cofactor1( Cof1[v], pVarsNew[u] );
|
|
if ( Cof[0] == Cof[1] && Cof[0] == Cof[2] ) // vu
|
|
{
|
|
PosStart = Pos;
|
|
sprintf( pNest, "(%c%c)", 'a' + pVarsNew[v], 'a' + pVarsNew[u] );
|
|
Pos = Dau_DsdPerform_rec( (s_Truths6[pVarsNew[u]] & Cof[3]) | (~s_Truths6[pVarsNew[u]] & Cof[0]), pBuffer, Pos, pVarsNew, nVarsNew );
|
|
Pos = Dau_DsdPerformReplace( pBuffer, PosStart, Pos, 'a' + pVarsNew[u], pNest );
|
|
return Pos;
|
|
}
|
|
if ( Cof[0] == Cof[1] && Cof[0] == Cof[3] ) // v!u
|
|
{
|
|
PosStart = Pos;
|
|
sprintf( pNest, "(%c!%c)", 'a' + pVarsNew[v], 'a' + pVarsNew[u] );
|
|
Pos = Dau_DsdPerform_rec( (s_Truths6[pVarsNew[u]] & Cof[2]) | (~s_Truths6[pVarsNew[u]] & Cof[0]), pBuffer, Pos, pVarsNew, nVarsNew );
|
|
Pos = Dau_DsdPerformReplace( pBuffer, PosStart, Pos, 'a' + pVarsNew[u], pNest );
|
|
return Pos;
|
|
}
|
|
if ( Cof[0] == Cof[2] && Cof[0] == Cof[3] ) // !vu
|
|
{
|
|
PosStart = Pos;
|
|
sprintf( pNest, "(!%c%c)", 'a' + pVarsNew[v], 'a' + pVarsNew[u] );
|
|
Pos = Dau_DsdPerform_rec( (s_Truths6[pVarsNew[u]] & Cof[1]) | (~s_Truths6[pVarsNew[u]] & Cof[0]), pBuffer, Pos, pVarsNew, nVarsNew );
|
|
Pos = Dau_DsdPerformReplace( pBuffer, PosStart, Pos, 'a' + pVarsNew[u], pNest );
|
|
return Pos;
|
|
}
|
|
if ( Cof[1] == Cof[2] && Cof[1] == Cof[3] ) // !v!u
|
|
{
|
|
PosStart = Pos;
|
|
sprintf( pNest, "(!%c!%c)", 'a' + pVarsNew[v], 'a' + pVarsNew[u] );
|
|
Pos = Dau_DsdPerform_rec( (s_Truths6[pVarsNew[u]] & Cof[0]) | (~s_Truths6[pVarsNew[u]] & Cof[1]), pBuffer, Pos, pVarsNew, nVarsNew );
|
|
Pos = Dau_DsdPerformReplace( pBuffer, PosStart, Pos, 'a' + pVarsNew[u], pNest );
|
|
return Pos;
|
|
}
|
|
if ( Cof[0] == Cof[3] && Cof[1] == Cof[2] ) // v+u
|
|
{
|
|
PosStart = Pos;
|
|
sprintf( pNest, "[%c%c]", 'a' + pVarsNew[v], 'a' + pVarsNew[u] );
|
|
Pos = Dau_DsdPerform_rec( (s_Truths6[pVarsNew[u]] & Cof[1]) | (~s_Truths6[pVarsNew[u]] & Cof[0]), pBuffer, Pos, pVarsNew, nVarsNew );
|
|
Pos = Dau_DsdPerformReplace( pBuffer, PosStart, Pos, 'a' + pVarsNew[u], pNest );
|
|
return Pos;
|
|
}
|
|
}
|
|
// find best variable for MUX decomposition
|
|
vBest = -1;
|
|
CountBest = 10;
|
|
for ( v = 0; v < nVarsNew; v++ )
|
|
{
|
|
int CountCur = 0;
|
|
for ( u = 0; u < nVarsNew; u++ )
|
|
if ( u != v && Abc_Tt6HasVar(Cof0[v], pVarsNew[u]) && Abc_Tt6HasVar(Cof1[v], pVarsNew[u]) )
|
|
CountCur++;
|
|
if ( CountBest > CountCur )
|
|
{
|
|
CountBest = CountCur;
|
|
vBest = v;
|
|
}
|
|
if ( CountCur == 0 )
|
|
break;
|
|
}
|
|
// perform MUX decomposition
|
|
pBuffer[Pos++] = '<';
|
|
pBuffer[Pos++] = 'a' + pVarsNew[vBest];
|
|
Pos = Dau_DsdPerform_rec( Cof1[vBest], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
Pos = Dau_DsdPerform_rec( Cof0[vBest], pBuffer, Pos, pVarsNew, nVarsNew );
|
|
pBuffer[Pos++] = '>';
|
|
return Pos;
|
|
}
|
|
char * Dau_DsdPerform( word t )
|
|
{
|
|
static char pBuffer[DAU_MAX_STR];
|
|
int pVarsNew[6] = {0, 1, 2, 3, 4, 5};
|
|
int Pos = 0;
|
|
if ( t == 0 )
|
|
pBuffer[Pos++] = '0';
|
|
else if ( t == ~(word)0 )
|
|
pBuffer[Pos++] = '1';
|
|
else
|
|
Pos = Dau_DsdPerform_rec( t, pBuffer, Pos, pVarsNew, 6 );
|
|
pBuffer[Pos++] = 0;
|
|
// printf( "%d ", strlen(pBuffer) );
|
|
// printf( "%s ->", pBuffer );
|
|
Dau_DsdRemoveBraces( pBuffer, Dau_DsdComputeMatches(pBuffer) );
|
|
// printf( " %s\n", pBuffer );
|
|
return pBuffer;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Dau_DsdTest3()
|
|
{
|
|
// word t = s_Truths6[0] & s_Truths6[1] & s_Truths6[2];
|
|
// word t = ~s_Truths6[0] | (s_Truths6[1] ^ ~s_Truths6[2]);
|
|
// word t = (s_Truths6[1] & s_Truths6[2]) | (s_Truths6[0] & s_Truths6[3]);
|
|
// word t = (~s_Truths6[1] & ~s_Truths6[2]) | (s_Truths6[0] ^ s_Truths6[3]);
|
|
// word t = ((~s_Truths6[1] & ~s_Truths6[2]) | (s_Truths6[0] ^ s_Truths6[3])) ^ s_Truths6[5];
|
|
// word t = ((s_Truths6[1] & ~s_Truths6[2]) ^ (s_Truths6[0] & s_Truths6[3])) & s_Truths6[5];
|
|
// word t = (~(~s_Truths6[0] & ~s_Truths6[4]) & s_Truths6[2]) | (~s_Truths6[1] & ~s_Truths6[0] & ~s_Truths6[4]);
|
|
// word t = 0x0000000000005F3F;
|
|
// word t = 0xF3F5030503050305;
|
|
// word t = (s_Truths6[0] & s_Truths6[1] & (s_Truths6[2] ^ s_Truths6[4])) | (~s_Truths6[0] & ~s_Truths6[1] & ~(s_Truths6[2] ^ s_Truths6[4]));
|
|
// word t = 0x05050500f5f5f5f3;
|
|
word t = ABC_CONST(0x9ef7a8d9c7193a0f);
|
|
char * p = Dau_DsdPerform( t );
|
|
word t2 = Dau_Dsd6ToTruth( p );
|
|
if ( t != t2 )
|
|
printf( "Verification failed.\n" );
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Find the best cofactoring variable.]
|
|
|
|
Description [Return -2 if non-DSD; -1 if full DSD; otherwise,
|
|
returns cofactoring variables i (i >= 0).]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Dau_DsdCheck1Step( word * pTruth, int nVarsInit )
|
|
{
|
|
word pCofTemp[DAU_MAX_WORD];
|
|
int nWords = Abc_TtWordNum(nVarsInit);
|
|
int nSizeNonDec, nSizeNonDec0, nSizeNonDec1;
|
|
int v, vBest = -2, nSumCofsBest = ABC_INFINITY, nSumCofs;
|
|
nSizeNonDec = Dau_DsdDecompose( pTruth, nVarsInit, 0, 0, NULL );
|
|
if ( nSizeNonDec == 0 )
|
|
return -1;
|
|
assert( nSizeNonDec > 0 );
|
|
for ( v = 0; v < nVarsInit; v++ )
|
|
{
|
|
// try first cofactor
|
|
Abc_TtCofactor0p( pCofTemp, pTruth, nWords, v );
|
|
nSumCofs = Abc_TtSupportSize( pCofTemp, nVarsInit );
|
|
nSizeNonDec0 = Dau_DsdDecompose( pCofTemp, nVarsInit, 0, 0, NULL );
|
|
// try second cofactor
|
|
Abc_TtCofactor1p( pCofTemp, pTruth, nWords, v );
|
|
nSumCofs += Abc_TtSupportSize( pCofTemp, nVarsInit );
|
|
nSizeNonDec1 = Dau_DsdDecompose( pCofTemp, nVarsInit, 0, 0, NULL );
|
|
// compare cofactors
|
|
if ( nSizeNonDec0 || nSizeNonDec1 )
|
|
continue;
|
|
if ( nSumCofsBest > nSumCofs )
|
|
{
|
|
vBest = v;
|
|
nSumCofsBest = nSumCofs;
|
|
}
|
|
}
|
|
return vBest;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Data-structure to store DSD information.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
typedef struct Dau_Dsd_t_ Dau_Dsd_t;
|
|
struct Dau_Dsd_t_
|
|
{
|
|
int nVarsInit; // the initial number of variables
|
|
int nVarsUsed; // the current number of variables
|
|
int nPos; // writing position
|
|
int nSizeNonDec; // size of the largest non-decomposable block
|
|
int nConsts; // the number of constant decompositions
|
|
int uConstMask; // constant decomposition mask
|
|
int fSplitPrime; // represent prime function as 1-step DSD
|
|
int fWriteTruth; // writing truth table as a hex string
|
|
char pVarDefs[32][8]; // variable definitions
|
|
char Cache[32][32]; // variable cache
|
|
char pOutput[DAU_MAX_STR]; // output stream
|
|
};
|
|
|
|
static abctime s_Times[3] = {0};
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Manipulation of DSD data-structure.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Dau_DsdInitialize( Dau_Dsd_t * p, int nVarsInit )
|
|
{
|
|
int i, v, u;
|
|
assert( nVarsInit >= 0 && nVarsInit <= 16 );
|
|
p->nVarsInit = nVarsInit;
|
|
p->nVarsUsed = nVarsInit;
|
|
p->nPos = 0;
|
|
p->nSizeNonDec = 0;
|
|
p->nConsts = 0;
|
|
p->uConstMask = 0;
|
|
for ( i = 0; i < nVarsInit; i++ )
|
|
p->pVarDefs[i][0] = 'a' + i, p->pVarDefs[i][1] = 0;
|
|
for ( v = 0; v < nVarsInit; v++ )
|
|
for ( u = 0; u < nVarsInit; u++ )
|
|
p->Cache[v][u] = 0;
|
|
|
|
}
|
|
static inline void Dau_DsdWriteString( Dau_Dsd_t * p, char * pStr )
|
|
{
|
|
while ( *pStr )
|
|
p->pOutput[ p->nPos++ ] = *pStr++;
|
|
}
|
|
static inline void Dau_DsdWriteVar( Dau_Dsd_t * p, int iVar, int fInv )
|
|
{
|
|
char * pStr;
|
|
if ( fInv )
|
|
p->pOutput[ p->nPos++ ] = '!';
|
|
for ( pStr = p->pVarDefs[iVar]; *pStr; pStr++ )
|
|
if ( *pStr >= 'a' + p->nVarsInit && *pStr < 'a' + p->nVarsUsed )
|
|
Dau_DsdWriteVar( p, *pStr - 'a', 0 );
|
|
else
|
|
p->pOutput[ p->nPos++ ] = *pStr;
|
|
}
|
|
static inline void Dau_DsdTranslate( Dau_Dsd_t * p, int * pVars, int nVars, char * pStr )
|
|
{
|
|
for ( ; *pStr; pStr++ )
|
|
if ( *pStr >= 'a' && *pStr < 'a' + nVars )
|
|
Dau_DsdWriteVar( p, pVars[*pStr - 'a'], 0 );
|
|
else
|
|
p->pOutput[ p->nPos++ ] = *pStr;
|
|
}
|
|
static inline int Dau_DsdWritePrime( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
int v, RetValue = 2;
|
|
assert( nVars > 2 );
|
|
if ( p->fSplitPrime )
|
|
{
|
|
word pCofTemp[DAU_MAX_WORD];
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
int vBest = Dau_DsdCheck1Step( pTruth, nVars );
|
|
assert( vBest != -1 );
|
|
if ( vBest == -2 ) // non-dec
|
|
p->nPos += Abc_TtWriteHexRev( p->pOutput + p->nPos, pTruth, nVars );
|
|
else
|
|
{
|
|
char pRes[DAU_MAX_STR];
|
|
int nNonDecSize;
|
|
// compose the result
|
|
Dau_DsdWriteString( p, "<" );
|
|
Dau_DsdWriteVar( p, vBest, 0 );
|
|
// split decomposition
|
|
Abc_TtCofactor1p( pCofTemp, pTruth, nWords, vBest );
|
|
nNonDecSize = Dau_DsdDecompose( pCofTemp, nVars, 0, p->fWriteTruth, pRes );
|
|
assert( nNonDecSize == 0 );
|
|
Dau_DsdWriteString( p, pRes );
|
|
// split decomposition
|
|
Abc_TtCofactor0p( pCofTemp, pTruth, nWords, vBest );
|
|
nNonDecSize = Dau_DsdDecompose( pCofTemp, nVars, 0, p->fWriteTruth, pRes );
|
|
assert( nNonDecSize == 0 );
|
|
Dau_DsdWriteString( p, pRes );
|
|
Dau_DsdWriteString( p, ">" );
|
|
RetValue = 1;
|
|
}
|
|
}
|
|
else if ( p->fWriteTruth )
|
|
p->nPos += Abc_TtWriteHexRev( p->pOutput + p->nPos, pTruth, nVars );
|
|
Dau_DsdWriteString( p, "{" );
|
|
for ( v = 0; v < nVars; v++ )
|
|
Dau_DsdWriteVar( p, pVars[v], 0 );
|
|
Dau_DsdWriteString( p, "}" );
|
|
p->nSizeNonDec = nVars;
|
|
return RetValue;
|
|
}
|
|
static inline void Dau_DsdFinalize( Dau_Dsd_t * p )
|
|
{
|
|
int i;
|
|
for ( i = 0; i < p->nConsts; i++ )
|
|
p->pOutput[ p->nPos++ ] = ((p->uConstMask >> (p->nConsts-1-i)) & 1) ? ']' : ')';
|
|
p->pOutput[ p->nPos++ ] = 0;
|
|
}
|
|
static inline int Dau_DsdAddVarDef( Dau_Dsd_t * p, char * pStr )
|
|
{
|
|
int u;
|
|
assert( strlen(pStr) < 8 );
|
|
assert( p->nVarsUsed < 32 );
|
|
for ( u = 0; u < p->nVarsUsed; u++ )
|
|
p->Cache[p->nVarsUsed][u] = 0;
|
|
for ( u = 0; u < p->nVarsUsed; u++ )
|
|
p->Cache[u][p->nVarsUsed] = 0;
|
|
sprintf( p->pVarDefs[p->nVarsUsed++], "%s", pStr );
|
|
return p->nVarsUsed - 1;
|
|
}
|
|
static inline int Dau_DsdFindVarDef( int * pVars, int nVars, int VarDef )
|
|
{
|
|
int v;
|
|
for ( v = 0; v < nVars; v++ )
|
|
if ( pVars[v] == VarDef )
|
|
break;
|
|
assert( v < nVars );
|
|
return v;
|
|
}
|
|
static inline void Dau_DsdInsertVarCache( Dau_Dsd_t * p, int v, int u, int Status )
|
|
{
|
|
assert( v != u );
|
|
assert( Status > 0 && Status < 4 );
|
|
assert( p->Cache[v][u] == 0 );
|
|
p->Cache[v][u] = Status;
|
|
}
|
|
static inline int Dau_DsdLookupVarCache( Dau_Dsd_t * p, int v, int u )
|
|
{
|
|
return p->Cache[v][u];
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Procedures specialized for 6-variable functions.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Dau_Dsd6DecomposeSingleVarOne( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v )
|
|
{
|
|
// consider negative cofactors
|
|
if ( pTruth[0] & 1 )
|
|
{
|
|
if ( Abc_Tt6Cof0IsConst1( pTruth[0], v ) ) // !(ax)
|
|
{
|
|
Dau_DsdWriteString( p, "!(" );
|
|
pTruth[0] = ~Abc_Tt6Cofactor1( pTruth[0], v );
|
|
goto finish;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( Abc_Tt6Cof0IsConst0( pTruth[0], v ) ) // ax
|
|
{
|
|
Dau_DsdWriteString( p, "(" );
|
|
pTruth[0] = Abc_Tt6Cofactor1( pTruth[0], v );
|
|
goto finish;
|
|
}
|
|
}
|
|
// consider positive cofactors
|
|
if ( pTruth[0] >> 63 )
|
|
{
|
|
if ( Abc_Tt6Cof1IsConst1( pTruth[0], v ) ) // !(!ax)
|
|
{
|
|
Dau_DsdWriteString( p, "!(!" );
|
|
pTruth[0] = ~Abc_Tt6Cofactor0( pTruth[0], v );
|
|
goto finish;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( Abc_Tt6Cof1IsConst0( pTruth[0], v ) ) // !ax
|
|
{
|
|
Dau_DsdWriteString( p, "(!" );
|
|
pTruth[0] = Abc_Tt6Cofactor0( pTruth[0], v );
|
|
goto finish;
|
|
}
|
|
}
|
|
// consider equal cofactors
|
|
if ( Abc_Tt6CofsOpposite( pTruth[0], v ) ) // [ax]
|
|
{
|
|
Dau_DsdWriteString( p, "[" );
|
|
pTruth[0] = Abc_Tt6Cofactor0( pTruth[0], v );
|
|
p->uConstMask |= (1 << p->nConsts);
|
|
goto finish;
|
|
}
|
|
return 0;
|
|
|
|
finish:
|
|
p->nConsts++;
|
|
Dau_DsdWriteVar( p, pVars[v], 0 );
|
|
pVars[v] = pVars[nVars-1];
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
return 1;
|
|
}
|
|
int Dau_Dsd6DecomposeSingleVar( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
assert( nVars > 1 );
|
|
while ( 1 )
|
|
{
|
|
int v;
|
|
for ( v = nVars - 1; v >= 0 && nVars > 1; v-- )
|
|
if ( Dau_Dsd6DecomposeSingleVarOne( p, pTruth, pVars, nVars, v ) )
|
|
{
|
|
nVars--;
|
|
break;
|
|
}
|
|
if ( v == -1 || nVars == 1 )
|
|
break;
|
|
}
|
|
if ( nVars == 1 )
|
|
Dau_DsdWriteVar( p, pVars[--nVars], (int)(pTruth[0] & 1) );
|
|
s_Times[0] += Abc_Clock() - clk;
|
|
return nVars;
|
|
}
|
|
static inline int Dau_Dsd6FindSupportOne( Dau_Dsd_t * p, word tCof0, word tCof1, int * pVars, int nVars, int v, int u )
|
|
{
|
|
int Status = p ? Dau_DsdLookupVarCache( p, pVars[v], pVars[u] ) : 0;
|
|
if ( Status == 0 )
|
|
{
|
|
Status = (Abc_Tt6HasVar(tCof1, u) << 1) | Abc_Tt6HasVar(tCof0, u);
|
|
if ( p )
|
|
Dau_DsdInsertVarCache( p, pVars[v], pVars[u], Status );
|
|
}
|
|
return Status;
|
|
}
|
|
static inline unsigned Dau_Dsd6FindSupports( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v )
|
|
{
|
|
int u;
|
|
unsigned uSupports = 0;
|
|
word tCof0 = Abc_Tt6Cofactor0( pTruth[0], v );
|
|
word tCof1 = Abc_Tt6Cofactor1( pTruth[0], v );
|
|
//Kit_DsdPrintFromTruth( (unsigned *)&tCof0, 6 );printf( "\n" );
|
|
//Kit_DsdPrintFromTruth( (unsigned *)&tCof1, 6 );printf( "\n" );
|
|
for ( u = 0; u < nVars; u++ )
|
|
if ( u != v )
|
|
uSupports |= (Dau_Dsd6FindSupportOne( p, tCof0, tCof1, pVars, nVars, v, u ) << (2 * u));
|
|
return uSupports;
|
|
}
|
|
static inline void Dau_DsdPrintSupports( unsigned uSupp, int nVars )
|
|
{
|
|
int v, Value;
|
|
printf( "Cofactor supports: " );
|
|
for ( v = nVars - 1; v >= 0; v-- )
|
|
{
|
|
Value = ((uSupp >> (2*v)) & 3);
|
|
if ( Value == 1 )
|
|
printf( "01" );
|
|
else if ( Value == 2 )
|
|
printf( "10" );
|
|
else if ( Value == 3 )
|
|
printf( "11" );
|
|
else
|
|
printf( "00" );
|
|
if ( v )
|
|
printf( "-" );
|
|
}
|
|
printf( "\n" );
|
|
}
|
|
// checks decomposability with respect to the pair (v, u)
|
|
static inline int Dau_Dsd6DecomposeDoubleVarsOne( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, int u )
|
|
{
|
|
char pBuffer[10] = { 0 };
|
|
word tCof0 = Abc_Tt6Cofactor0( pTruth[0], v );
|
|
word tCof1 = Abc_Tt6Cofactor1( pTruth[0], v );
|
|
int Status = Dau_Dsd6FindSupportOne( p, tCof0, tCof1, pVars, nVars, v, u );
|
|
assert( v > u );
|
|
//printf( "Checking %s and %s.\n", p->pVarDefs[pVars[v]], p->pVarDefs[pVars[u]] );
|
|
|
|
// Kit_DsdPrintFromTruth( (unsigned *)pTruth, 6 );printf( "\n" );
|
|
if ( Status == 3 )
|
|
{
|
|
// both F(v=0) and F(v=1) depend on u
|
|
if ( Abc_Tt6Cof0EqualCof1(tCof0, tCof1, u) && Abc_Tt6Cof0EqualCof1(tCof1, tCof0, u) ) // v+u
|
|
{
|
|
pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor1(tCof0, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
sprintf( pBuffer, "[%c%c]", 'a' + pVars[v], 'a' + pVars[u] );
|
|
goto finish;
|
|
}
|
|
}
|
|
else if ( Status == 2 )
|
|
{
|
|
// F(v=0) does not depend on u; F(v=1) depends on u
|
|
if ( Abc_Tt6Cof0EqualCof0(tCof0, tCof1, u) ) // vu
|
|
{
|
|
sprintf( pBuffer, "(%c%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor1(tCof1, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
goto finish;
|
|
}
|
|
if ( Abc_Tt6Cof0EqualCof1(tCof0, tCof1, u) ) // v!u
|
|
{
|
|
sprintf( pBuffer, "(%c!%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor0(tCof1, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
goto finish;
|
|
}
|
|
}
|
|
else if ( Status == 1 )
|
|
{
|
|
// F(v=0) depends on u; F(v=1) does not depend on u
|
|
if ( Abc_Tt6Cof0EqualCof1(tCof0, tCof1, u) ) // !vu
|
|
{
|
|
sprintf( pBuffer, "(!%c%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor1(tCof0, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
goto finish;
|
|
}
|
|
if ( Abc_Tt6Cof1EqualCof1(tCof0, tCof1, u) ) // !v!u
|
|
{
|
|
sprintf( pBuffer, "(!%c!%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor1(tCof1, u));
|
|
goto finish;
|
|
}
|
|
}
|
|
return nVars;
|
|
finish:
|
|
// finalize decomposition
|
|
assert( pBuffer[0] );
|
|
pVars[u] = Dau_DsdAddVarDef( p, pBuffer );
|
|
pVars[v] = pVars[nVars-1];
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
if ( Dau_Dsd6DecomposeSingleVarOne( p, pTruth, pVars, --nVars, u ) )
|
|
nVars = Dau_Dsd6DecomposeSingleVar( p, pTruth, pVars, --nVars );
|
|
return nVars;
|
|
}
|
|
int Dau_Dsd6DecomposeDoubleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
while ( 1 )
|
|
{
|
|
int v, u, nVarsOld;
|
|
for ( v = nVars - 1; v > 0; v-- )
|
|
{
|
|
for ( u = v - 1; u >= 0; u-- )
|
|
{
|
|
if ( Dau_DsdLookupVarCache( p, pVars[v], pVars[u] ) )
|
|
continue;
|
|
nVarsOld = nVars;
|
|
nVars = Dau_Dsd6DecomposeDoubleVarsOne( p, pTruth, pVars, nVars, v, u );
|
|
if ( nVars == 0 )
|
|
{
|
|
s_Times[1] += Abc_Clock() - clk;
|
|
return 0;
|
|
}
|
|
if ( nVarsOld > nVars )
|
|
break;
|
|
}
|
|
if ( u >= 0 ) // found
|
|
break;
|
|
}
|
|
if ( v == 0 ) // not found
|
|
break;
|
|
}
|
|
s_Times[1] += Abc_Clock() - clk;
|
|
return nVars;
|
|
}
|
|
|
|
// look for MUX-decomposable variable on top or at the bottom
|
|
static inline int Dau_Dsd6DecomposeTripleVarsOuter( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v )
|
|
{
|
|
extern int Dau_DsdDecomposeInt( Dau_Dsd_t * p, word * pTruth, int nVarsInit );
|
|
Dau_Dsd_t P1, * p1 = &P1;
|
|
word tCof0, tCof1;
|
|
p1->fSplitPrime = 0;
|
|
p1->fWriteTruth = p->fWriteTruth;
|
|
// move this variable to the top
|
|
ABC_SWAP( int, pVars[v], pVars[nVars-1] );
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
// cofactor w.r.t the last variable
|
|
tCof0 = Abc_Tt6Cofactor0( pTruth[0], nVars - 1 );
|
|
tCof1 = Abc_Tt6Cofactor1( pTruth[0], nVars - 1 );
|
|
// compose the result
|
|
Dau_DsdWriteString( p, "<" );
|
|
Dau_DsdWriteVar( p, pVars[nVars - 1], 0 );
|
|
// split decomposition
|
|
Dau_DsdDecomposeInt( p1, &tCof1, nVars - 1 );
|
|
Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput );
|
|
p->nSizeNonDec = p1->nSizeNonDec;
|
|
if ( p1->nSizeNonDec )
|
|
*pTruth = tCof1;
|
|
// split decomposition
|
|
Dau_DsdDecomposeInt( p1, &tCof0, nVars - 1 );
|
|
Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput );
|
|
Dau_DsdWriteString( p, ">" );
|
|
p->nSizeNonDec = Abc_MaxInt( p->nSizeNonDec, p1->nSizeNonDec );
|
|
if ( p1->nSizeNonDec )
|
|
*pTruth = tCof0;
|
|
return 0;
|
|
}
|
|
static inline int Dau_Dsd6DecomposeTripleVarsInner( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, unsigned uSupports )
|
|
{
|
|
int iVar0 = Abc_TtSuppFindFirst( uSupports & (~uSupports >> 1) & 0x55555555 ) >> 1;
|
|
int iVar1 = Abc_TtSuppFindFirst( ~uSupports & ( uSupports >> 1) & 0x55555555 ) >> 1;
|
|
word tCof0 = Abc_Tt6Cofactor0( pTruth[0], v );
|
|
word tCof1 = Abc_Tt6Cofactor1( pTruth[0], v );
|
|
word C00 = Abc_Tt6Cofactor0( tCof0, iVar0 );
|
|
word C01 = Abc_Tt6Cofactor1( tCof0, iVar0 );
|
|
word C10 = Abc_Tt6Cofactor0( tCof1, iVar1 );
|
|
word C11 = Abc_Tt6Cofactor1( tCof1, iVar1 );
|
|
int fEqual0 = (C00 == C10) && (C01 == C11);
|
|
int fEqual1 = (C00 == C11) && (C01 == C10);
|
|
if ( fEqual0 || fEqual1 )
|
|
{
|
|
char pBuffer[10];
|
|
int VarId = pVars[iVar0];
|
|
pTruth[0] = (s_Truths6[v] & C11) | (~s_Truths6[v] & C10);
|
|
sprintf( pBuffer, "<%c%c%s%c>", 'a' + pVars[v], 'a' + pVars[iVar1], fEqual1 ? "!":"", 'a' + pVars[iVar0] );
|
|
pVars[v] = Dau_DsdAddVarDef( p, pBuffer );
|
|
// remove iVar1
|
|
ABC_SWAP( int, pVars[iVar1], pVars[nVars-1] );
|
|
Abc_TtSwapVars( pTruth, nVars, iVar1, nVars-1 ); nVars--;
|
|
// remove iVar0
|
|
iVar0 = Dau_DsdFindVarDef( pVars, nVars, VarId );
|
|
ABC_SWAP( int, pVars[iVar0], pVars[nVars-1] );
|
|
Abc_TtSwapVars( pTruth, nVars, iVar0, nVars-1 ); nVars--;
|
|
// find the new var
|
|
v = Dau_DsdFindVarDef( pVars, nVars, p->nVarsUsed-1 );
|
|
// remove single variables if possible
|
|
if ( Dau_Dsd6DecomposeSingleVarOne( p, pTruth, pVars, nVars, v ) )
|
|
nVars = Dau_Dsd6DecomposeSingleVar( p, pTruth, pVars, --nVars );
|
|
return nVars;
|
|
}
|
|
return nVars;
|
|
}
|
|
int Dau_Dsd6DecomposeTripleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
while ( 1 )
|
|
{
|
|
int v;
|
|
// Kit_DsdPrintFromTruth( (unsigned *)pTruth, 6 ); printf( "\n" );
|
|
for ( v = nVars - 1; v >= 0; v-- )
|
|
{
|
|
unsigned uSupports = Dau_Dsd6FindSupports( p, pTruth, pVars, nVars, v );
|
|
// Dau_DsdPrintSupports( uSupports, nVars );
|
|
if ( (uSupports & (uSupports >> 1) & 0x55555555) == 0 ) // non-overlapping supports
|
|
return Dau_Dsd6DecomposeTripleVarsOuter( p, pTruth, pVars, nVars, v );
|
|
if ( Abc_TtSuppOnlyOne( uSupports & (~uSupports >> 1) & 0x55555555) &&
|
|
Abc_TtSuppOnlyOne(~uSupports & ( uSupports >> 1) & 0x55555555) ) // one unique variable in each cofactor
|
|
{
|
|
int nVarsNew = Dau_Dsd6DecomposeTripleVarsInner( p, pTruth, pVars, nVars, v, uSupports );
|
|
if ( nVarsNew == nVars )
|
|
continue;
|
|
if ( nVarsNew == 0 )
|
|
{
|
|
s_Times[2] += Abc_Clock() - clk;
|
|
return 0;
|
|
}
|
|
nVars = Dau_Dsd6DecomposeDoubleVars( p, pTruth, pVars, nVarsNew );
|
|
if ( nVars == 0 )
|
|
{
|
|
s_Times[2] += Abc_Clock() - clk;
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if ( v == -1 )
|
|
{
|
|
s_Times[2] += Abc_Clock() - clk;
|
|
return nVars;
|
|
}
|
|
}
|
|
assert( 0 );
|
|
return -1;
|
|
}
|
|
int Dau_Dsd6DecomposeInternal( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
// decompose single variales on the output side
|
|
nVars = Dau_Dsd6DecomposeSingleVar( p, pTruth, pVars, nVars );
|
|
if ( nVars == 0 )
|
|
return 0;
|
|
// decompose double variables on the input side
|
|
nVars = Dau_Dsd6DecomposeDoubleVars( p, pTruth, pVars, nVars );
|
|
if ( nVars == 0 )
|
|
return 0;
|
|
// decompose MUX on the output/input side
|
|
nVars = Dau_Dsd6DecomposeTripleVars( p, pTruth, pVars, nVars );
|
|
if ( nVars == 0 )
|
|
return 0;
|
|
// write non-decomposable function
|
|
return Dau_DsdWritePrime( p, pTruth, pVars, nVars );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Procedures specialized for 6-variable functions.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Dau_DsdDecomposeSingleVarOne( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v )
|
|
{
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
// consider negative cofactors
|
|
if ( pTruth[0] & 1 )
|
|
{
|
|
if ( Abc_TtCof0IsConst1( pTruth, nWords, v ) ) // !(ax)
|
|
{
|
|
Dau_DsdWriteString( p, "!(" );
|
|
Abc_TtCofactor1( pTruth, nWords, v );
|
|
Abc_TtNot( pTruth, nWords );
|
|
goto finish;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( Abc_TtCof0IsConst0( pTruth, nWords, v ) ) // ax
|
|
{
|
|
Dau_DsdWriteString( p, "(" );
|
|
Abc_TtCofactor1( pTruth, nWords, v );
|
|
goto finish;
|
|
}
|
|
}
|
|
// consider positive cofactors
|
|
if ( pTruth[nWords-1] >> 63 )
|
|
{
|
|
if ( Abc_TtCof1IsConst1( pTruth, nWords, v ) ) // !(!ax)
|
|
{
|
|
Dau_DsdWriteString( p, "!(!" );
|
|
Abc_TtCofactor0( pTruth, nWords, v );
|
|
Abc_TtNot( pTruth, nWords );
|
|
goto finish;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( Abc_TtCof1IsConst0( pTruth, nWords, v ) ) // !ax
|
|
{
|
|
Dau_DsdWriteString( p, "(!" );
|
|
Abc_TtCofactor0( pTruth, nWords, v );
|
|
goto finish;
|
|
}
|
|
}
|
|
// consider equal cofactors
|
|
if ( Abc_TtCofsOpposite( pTruth, nWords, v ) ) // [ax]
|
|
{
|
|
Dau_DsdWriteString( p, "[" );
|
|
Abc_TtCofactor0( pTruth, nWords, v );
|
|
p->uConstMask |= (1 << p->nConsts);
|
|
goto finish;
|
|
}
|
|
return 0;
|
|
|
|
finish:
|
|
p->nConsts++;
|
|
Dau_DsdWriteVar( p, pVars[v], 0 );
|
|
pVars[v] = pVars[nVars-1];
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
return 1;
|
|
}
|
|
int Dau_DsdDecomposeSingleVar( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
assert( nVars > 1 );
|
|
while ( 1 )
|
|
{
|
|
int v;
|
|
for ( v = nVars - 1; v >= 0 && nVars > 1; v-- )
|
|
if ( Dau_DsdDecomposeSingleVarOne( p, pTruth, pVars, nVars, v ) )
|
|
{
|
|
nVars--;
|
|
break;
|
|
}
|
|
if ( v == -1 || nVars == 1 )
|
|
break;
|
|
}
|
|
if ( nVars == 1 )
|
|
Dau_DsdWriteVar( p, pVars[--nVars], (int)(pTruth[0] & 1) );
|
|
s_Times[0] += Abc_Clock() - clk;
|
|
return nVars;
|
|
}
|
|
|
|
static inline int Dau_DsdFindSupportOne( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, int u )
|
|
{
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
int Status = p ? Dau_DsdLookupVarCache( p, pVars[v], pVars[u] ) : 0;
|
|
if ( Status == 0 )
|
|
{
|
|
// Status = (Abc_Tt6HasVar(tCof1, u) << 1) | Abc_Tt6HasVar(tCof0, u);
|
|
if ( v < u )
|
|
Status = (!Abc_TtCheckEqualCofs(pTruth, nWords, v, u, 1, 3) << 1) | !Abc_TtCheckEqualCofs(pTruth, nWords, v, u, 0, 2);
|
|
else // if ( v > u )
|
|
Status = (!Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 2, 3) << 1) | !Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 0, 1);
|
|
assert( Status != 0 );
|
|
if ( p )
|
|
Dau_DsdInsertVarCache( p, pVars[v], pVars[u], Status );
|
|
}
|
|
return Status;
|
|
}
|
|
static inline unsigned Dau_DsdFindSupports( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v )
|
|
{
|
|
int u;
|
|
unsigned uSupports = 0;
|
|
//Kit_DsdPrintFromTruth( (unsigned *)&tCof0, 6 );printf( "\n" );
|
|
//Kit_DsdPrintFromTruth( (unsigned *)&tCof1, 6 );printf( "\n" );
|
|
for ( u = 0; u < nVars; u++ )
|
|
if ( u != v )
|
|
uSupports |= (Dau_DsdFindSupportOne( p, pTruth, pVars, nVars, v, u ) << (2 * u));
|
|
return uSupports;
|
|
}
|
|
|
|
// checks decomposability with respect to the pair (v, u)
|
|
static inline int Dau_DsdDecomposeDoubleVarsOne( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, int u )
|
|
{
|
|
char pBuffer[10] = { 0 };
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
int Status = Dau_DsdFindSupportOne( p, pTruth, pVars, nVars, v, u );
|
|
assert( v > u );
|
|
//printf( "Checking %s and %s.\n", p->pVarDefs[pVars[v]], p->pVarDefs[pVars[u]] );
|
|
if ( Status == 3 )
|
|
{
|
|
// both F(v=0) and F(v=1) depend on u
|
|
// if ( Abc_Tt6Cof0EqualCof1(tCof0, tCof1, u) && Abc_Tt6Cof0EqualCof1(tCof1, tCof0, u) ) // v+u
|
|
if ( Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 0, 3) && Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 1, 2) ) // 00=11 01=10 v+u
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
sprintf( pBuffer, "[%c%c]", 'a' + pVars[v], 'a' + pVars[u] );
|
|
// pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor1(tCof0, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
Abc_TtCofactor0p( pTtTemp[0], pTruth, nWords, v );
|
|
Abc_TtCofactor0( pTtTemp[0], nWords, u );
|
|
Abc_TtCofactor0p( pTtTemp[1], pTruth, nWords, v );
|
|
Abc_TtCofactor1( pTtTemp[1], nWords, u );
|
|
Abc_TtMux( pTruth, Dau_DsdTtElems()[u], pTtTemp[1], pTtTemp[0], nWords );
|
|
goto finish;
|
|
}
|
|
}
|
|
else if ( Status == 2 )
|
|
{
|
|
// F(v=0) does not depend on u; F(v=1) depends on u
|
|
// if ( Abc_Tt6Cof0EqualCof0(tCof0, tCof1, u) ) // vu
|
|
if ( Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 0, 2) ) // 00=10 vu
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
sprintf( pBuffer, "(%c%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
// pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor1(tCof1, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
Abc_TtCofactor0p( pTtTemp[0], pTruth, nWords, v );
|
|
Abc_TtCofactor0( pTtTemp[0], nWords, u );
|
|
Abc_TtCofactor1p( pTtTemp[1], pTruth, nWords, v );
|
|
Abc_TtCofactor1( pTtTemp[1], nWords, u );
|
|
Abc_TtMux( pTruth, Dau_DsdTtElems()[u], pTtTemp[1], pTtTemp[0], nWords );
|
|
goto finish;
|
|
}
|
|
// if ( Abc_Tt6Cof0EqualCof1(tCof0, tCof1, u) ) // v!u
|
|
if ( Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 0, 3) ) // 00=11 v!u
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
sprintf( pBuffer, "(%c!%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
// pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor0(tCof1, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
Abc_TtCofactor0p( pTtTemp[0], pTruth, nWords, v );
|
|
Abc_TtCofactor0( pTtTemp[0], nWords, u );
|
|
Abc_TtCofactor1p( pTtTemp[1], pTruth, nWords, v );
|
|
Abc_TtCofactor0( pTtTemp[1], nWords, u );
|
|
Abc_TtMux( pTruth, Dau_DsdTtElems()[u], pTtTemp[1], pTtTemp[0], nWords );
|
|
goto finish;
|
|
}
|
|
}
|
|
else if ( Status == 1 )
|
|
{
|
|
// F(v=0) depends on u; F(v=1) does not depend on u
|
|
// if ( Abc_Tt6Cof0EqualCof1(tCof0, tCof1, u) ) // !vu
|
|
if ( Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 0, 3) ) // 00=11 !vu
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
sprintf( pBuffer, "(!%c%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
// pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor1(tCof0, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u));
|
|
Abc_TtCofactor0p( pTtTemp[0], pTruth, nWords, v );
|
|
Abc_TtCofactor0( pTtTemp[0], nWords, u );
|
|
Abc_TtCofactor0p( pTtTemp[1], pTruth, nWords, v );
|
|
Abc_TtCofactor1( pTtTemp[1], nWords, u );
|
|
Abc_TtMux( pTruth, Dau_DsdTtElems()[u], pTtTemp[1], pTtTemp[0], nWords );
|
|
goto finish;
|
|
}
|
|
// if ( Abc_Tt6Cof1EqualCof1(tCof0, tCof1, u) ) // !v!u
|
|
if ( Abc_TtCheckEqualCofs(pTruth, nWords, u, v, 1, 3) ) // 01=11 !v!u
|
|
{
|
|
word pTtTemp[2][DAU_MAX_WORD];
|
|
sprintf( pBuffer, "(!%c!%c)", 'a' + pVars[v], 'a' + pVars[u] );
|
|
// pTruth[0] = (s_Truths6[u] & Abc_Tt6Cofactor0(tCof0, u)) | (~s_Truths6[u] & Abc_Tt6Cofactor1(tCof1, u));
|
|
Abc_TtCofactor1p( pTtTemp[0], pTruth, nWords, v );
|
|
Abc_TtCofactor1( pTtTemp[0], nWords, u );
|
|
Abc_TtCofactor0p( pTtTemp[1], pTruth, nWords, v );
|
|
Abc_TtCofactor0( pTtTemp[1], nWords, u );
|
|
Abc_TtMux( pTruth, Dau_DsdTtElems()[u], pTtTemp[1], pTtTemp[0], nWords );
|
|
goto finish;
|
|
}
|
|
}
|
|
return nVars;
|
|
finish:
|
|
// finalize decomposition
|
|
assert( pBuffer[0] );
|
|
pVars[u] = Dau_DsdAddVarDef( p, pBuffer );
|
|
pVars[v] = pVars[nVars-1];
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
if ( Dau_DsdDecomposeSingleVarOne( p, pTruth, pVars, --nVars, u ) )
|
|
nVars = Dau_DsdDecomposeSingleVar( p, pTruth, pVars, --nVars );
|
|
return nVars;
|
|
}
|
|
int Dau_DsdDecomposeDoubleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
while ( 1 )
|
|
{
|
|
int v, u, nVarsOld;
|
|
for ( v = nVars - 1; v > 0; v-- )
|
|
{
|
|
for ( u = v - 1; u >= 0; u-- )
|
|
{
|
|
if ( Dau_DsdLookupVarCache( p, pVars[v], pVars[u] ) )
|
|
continue;
|
|
nVarsOld = nVars;
|
|
nVars = Dau_DsdDecomposeDoubleVarsOne( p, pTruth, pVars, nVars, v, u );
|
|
if ( nVars == 0 )
|
|
{
|
|
s_Times[1] += Abc_Clock() - clk;
|
|
return 0;
|
|
}
|
|
if ( nVarsOld > nVars )
|
|
break;
|
|
}
|
|
if ( u >= 0 ) // found
|
|
break;
|
|
}
|
|
if ( v == 0 ) // not found
|
|
break;
|
|
}
|
|
s_Times[1] += Abc_Clock() - clk;
|
|
return nVars;
|
|
}
|
|
|
|
// look for MUX-decomposable variable on top or at the bottom
|
|
static inline int Dau_DsdDecomposeTripleVarsOuter( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v )
|
|
{
|
|
extern int Dau_DsdDecomposeInt( Dau_Dsd_t * p, word * pTruth, int nVarsInit );
|
|
Dau_Dsd_t P1, * p1 = &P1;
|
|
word pTtCof[2][DAU_MAX_WORD];
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
p1->fSplitPrime = 0;
|
|
p1->fWriteTruth = p->fWriteTruth;
|
|
// move this variable to the top
|
|
ABC_SWAP( int, pVars[v], pVars[nVars-1] );
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
// cofactor w.r.t the last variable
|
|
// tCof0 = Abc_Tt6Cofactor0( pTruth[0], nVars - 1 );
|
|
// tCof1 = Abc_Tt6Cofactor1( pTruth[0], nVars - 1 );
|
|
Abc_TtCofactor0p( pTtCof[0], pTruth, nWords, nVars - 1 );
|
|
Abc_TtCofactor1p( pTtCof[1], pTruth, nWords, nVars - 1 );
|
|
// compose the result
|
|
Dau_DsdWriteString( p, "<" );
|
|
Dau_DsdWriteVar( p, pVars[nVars - 1], 0 );
|
|
// split decomposition
|
|
Dau_DsdDecomposeInt( p1, pTtCof[1], nVars - 1 );
|
|
Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput );
|
|
p->nSizeNonDec = p1->nSizeNonDec;
|
|
if ( p1->nSizeNonDec )
|
|
Abc_TtCopy( pTruth, pTtCof[1], Abc_TtWordNum(p1->nSizeNonDec), 0 );
|
|
// split decomposition
|
|
Dau_DsdDecomposeInt( p1, pTtCof[0], nVars - 1 );
|
|
Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput );
|
|
Dau_DsdWriteString( p, ">" );
|
|
p->nSizeNonDec = Abc_MaxInt( p->nSizeNonDec, p1->nSizeNonDec );
|
|
if ( p1->nSizeNonDec )
|
|
Abc_TtCopy( pTruth, pTtCof[0], Abc_TtWordNum(p1->nSizeNonDec), 0 );
|
|
return 0;
|
|
}
|
|
static inline int Dau_DsdDecomposeTripleVarsInner( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, unsigned uSupports )
|
|
{
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
int iVar0 = Abc_TtSuppFindFirst( uSupports & (~uSupports >> 1) & 0x55555555 ) >> 1;
|
|
int iVar1 = Abc_TtSuppFindFirst( ~uSupports & ( uSupports >> 1) & 0x55555555 ) >> 1;
|
|
int fEqual0, fEqual1;
|
|
// word tCof0 = Abc_Tt6Cofactor0( pTruth[0], v );
|
|
// word tCof1 = Abc_Tt6Cofactor1( pTruth[0], v );
|
|
// word C00 = Abc_Tt6Cofactor0( tCof0, iVar0 );
|
|
// word C01 = Abc_Tt6Cofactor1( tCof0, iVar0 );
|
|
// word C10 = Abc_Tt6Cofactor0( tCof1, iVar1 );
|
|
// word C11 = Abc_Tt6Cofactor1( tCof1, iVar1 );
|
|
// int fEqual0 = (C00 == C10) && (C01 == C11);
|
|
// int fEqual1 = (C00 == C11) && (C01 == C10);
|
|
word pTtCof[2][DAU_MAX_WORD];
|
|
word pTtFour[2][2][DAU_MAX_WORD];
|
|
Abc_TtCofactor0p( pTtCof[0], pTruth, nWords, v );
|
|
Abc_TtCofactor1p( pTtCof[1], pTruth, nWords, v );
|
|
Abc_TtCofactor0p( pTtFour[0][0], pTtCof[0], nWords, iVar0 );
|
|
Abc_TtCofactor1p( pTtFour[0][1], pTtCof[0], nWords, iVar0 );
|
|
Abc_TtCofactor0p( pTtFour[1][0], pTtCof[1], nWords, iVar1 );
|
|
Abc_TtCofactor1p( pTtFour[1][1], pTtCof[1], nWords, iVar1 );
|
|
fEqual0 = Abc_TtEqual(pTtFour[0][0], pTtFour[1][0], nWords) && Abc_TtEqual(pTtFour[0][1], pTtFour[1][1], nWords);
|
|
fEqual1 = Abc_TtEqual(pTtFour[0][0], pTtFour[1][1], nWords) && Abc_TtEqual(pTtFour[0][1], pTtFour[1][0], nWords);
|
|
if ( fEqual0 || fEqual1 )
|
|
{
|
|
char pBuffer[10];
|
|
int VarId = pVars[iVar0];
|
|
// pTruth[0] = (s_Truths6[v] & C11) | (~s_Truths6[v] & C10);
|
|
Abc_TtMux( pTruth, Dau_DsdTtElems()[v], pTtFour[1][1], pTtFour[1][0], nWords );
|
|
sprintf( pBuffer, "<%c%c%s%c>", 'a' + pVars[v], 'a' + pVars[iVar1], fEqual1 ? "!":"", 'a' + pVars[iVar0] );
|
|
pVars[v] = Dau_DsdAddVarDef( p, pBuffer );
|
|
// remove iVar1
|
|
ABC_SWAP( int, pVars[iVar1], pVars[nVars-1] );
|
|
Abc_TtSwapVars( pTruth, nVars, iVar1, nVars-1 ); nVars--;
|
|
// remove iVar0
|
|
iVar0 = Dau_DsdFindVarDef( pVars, nVars, VarId );
|
|
ABC_SWAP( int, pVars[iVar0], pVars[nVars-1] );
|
|
Abc_TtSwapVars( pTruth, nVars, iVar0, nVars-1 ); nVars--;
|
|
// find the new var
|
|
v = Dau_DsdFindVarDef( pVars, nVars, p->nVarsUsed-1 );
|
|
// remove single variables if possible
|
|
if ( Dau_DsdDecomposeSingleVarOne( p, pTruth, pVars, nVars, v ) )
|
|
nVars = Dau_DsdDecomposeSingleVar( p, pTruth, pVars, --nVars );
|
|
return nVars;
|
|
}
|
|
return nVars;
|
|
}
|
|
int Dau_DsdDecomposeTripleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
while ( 1 )
|
|
{
|
|
int v;
|
|
// Kit_DsdPrintFromTruth( (unsigned *)pTruth, 6 ); printf( "\n" );
|
|
for ( v = nVars - 1; v >= 0; v-- )
|
|
{
|
|
unsigned uSupports = Dau_DsdFindSupports( p, pTruth, pVars, nVars, v );
|
|
// Dau_DsdPrintSupports( uSupports, nVars );
|
|
if ( (uSupports & (uSupports >> 1) & 0x55555555) == 0 ) // non-overlapping supports
|
|
return Dau_DsdDecomposeTripleVarsOuter( p, pTruth, pVars, nVars, v );
|
|
if ( Abc_TtSuppOnlyOne( uSupports & (~uSupports >> 1) & 0x55555555) &&
|
|
Abc_TtSuppOnlyOne(~uSupports & ( uSupports >> 1) & 0x55555555) ) // one unique variable in each cofactor
|
|
{
|
|
int nVarsNew = Dau_DsdDecomposeTripleVarsInner( p, pTruth, pVars, nVars, v, uSupports );
|
|
if ( nVarsNew == nVars )
|
|
continue;
|
|
if ( nVarsNew == 0 )
|
|
{
|
|
s_Times[2] += Abc_Clock() - clk;
|
|
return 0;
|
|
}
|
|
nVars = Dau_DsdDecomposeDoubleVars( p, pTruth, pVars, nVarsNew );
|
|
if ( nVars == 0 )
|
|
{
|
|
s_Times[2] += Abc_Clock() - clk;
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if ( v == -1 )
|
|
{
|
|
s_Times[2] += Abc_Clock() - clk;
|
|
return nVars;
|
|
}
|
|
}
|
|
assert( 0 );
|
|
return -1;
|
|
}
|
|
int Dau_DsdDecomposeInternal( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars )
|
|
{
|
|
// decompose single variales on the output side
|
|
nVars = Dau_DsdDecomposeSingleVar( p, pTruth, pVars, nVars );
|
|
if ( nVars == 0 )
|
|
return 0;
|
|
// decompose double variables on the input side
|
|
nVars = Dau_DsdDecomposeDoubleVars( p, pTruth, pVars, nVars );
|
|
if ( nVars == 0 )
|
|
return 0;
|
|
// decompose MUX on the output/input side
|
|
nVars = Dau_DsdDecomposeTripleVars( p, pTruth, pVars, nVars );
|
|
if ( nVars == 0 )
|
|
return 0;
|
|
// write non-decomposable function
|
|
return Dau_DsdWritePrime( p, pTruth, pVars, nVars );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Fast DSD for truth tables.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Dau_DsdMinBase( word * pTruth, int nVars, int * pVarsNew )
|
|
{
|
|
int v;
|
|
for ( v = 0; v < nVars; v++ )
|
|
pVarsNew[v] = v;
|
|
for ( v = nVars - 1; v >= 0; v-- )
|
|
{
|
|
if ( Abc_TtHasVar( pTruth, nVars, v ) )
|
|
continue;
|
|
Abc_TtSwapVars( pTruth, nVars, v, nVars-1 );
|
|
pVarsNew[v] = pVarsNew[--nVars];
|
|
}
|
|
return nVars;
|
|
}
|
|
int Dau_DsdDecomposeInt( Dau_Dsd_t * p, word * pTruth, int nVarsInit )
|
|
{
|
|
int Status = 0, nVars, pVars[16];
|
|
Dau_DsdInitialize( p, nVarsInit );
|
|
nVars = Dau_DsdMinBase( pTruth, nVarsInit, pVars );
|
|
assert( nVars > 0 && nVars <= nVarsInit );
|
|
if ( nVars == 1 )
|
|
Dau_DsdWriteVar( p, pVars[0], (int)(pTruth[0] & 1) );
|
|
else if ( nVars <= 6 )
|
|
Status = Dau_Dsd6DecomposeInternal( p, pTruth, pVars, nVars );
|
|
else
|
|
Status = Dau_DsdDecomposeInternal( p, pTruth, pVars, nVars );
|
|
Dau_DsdFinalize( p );
|
|
return Status;
|
|
}
|
|
int Dau_DsdDecompose( word * pTruth, int nVarsInit, int fSplitPrime, int fWriteTruth, char * pRes )
|
|
{
|
|
Dau_Dsd_t P, * p = &P;
|
|
p->fSplitPrime = fSplitPrime;
|
|
p->fWriteTruth = fWriteTruth;
|
|
p->nSizeNonDec = 0;
|
|
if ( (pTruth[0] & 1) == 0 && Abc_TtIsConst0(pTruth, Abc_TtWordNum(nVarsInit)) )
|
|
{ if ( pRes ) pRes[0] = '0', pRes[1] = 0; }
|
|
else if ( (pTruth[0] & 1) && Abc_TtIsConst1(pTruth, Abc_TtWordNum(nVarsInit)) )
|
|
{ if ( pRes ) pRes[0] = '1', pRes[1] = 0; }
|
|
else
|
|
{
|
|
int Status = Dau_DsdDecomposeInt( p, pTruth, nVarsInit );
|
|
Dau_DsdRemoveBraces( p->pOutput, Dau_DsdComputeMatches(p->pOutput) );
|
|
if ( pRes )
|
|
strcpy( pRes, p->pOutput );
|
|
assert( fSplitPrime || Status != 1 );
|
|
if ( fSplitPrime && Status == 2 )
|
|
return -1;
|
|
}
|
|
// assert( p->nSizeNonDec == 0 );
|
|
return p->nSizeNonDec;
|
|
}
|
|
void Dau_DsdPrintFromTruth( FILE * pFile, word * pTruth, int nVarsInit )
|
|
{
|
|
char pRes[DAU_MAX_STR];
|
|
Dau_DsdDecompose( pTruth, nVarsInit, 0, 1, pRes );
|
|
fprintf( pFile, "%s\n", pRes );
|
|
}
|
|
|
|
void Dau_DsdTest44()
|
|
{
|
|
char pRes[DAU_MAX_STR];
|
|
// char * pStr = "(!(!a<bcd>)!(!fe))";
|
|
// char * pStr = "([acb]<!edf>)";
|
|
// char * pStr = "!(f!(b!c!(d[ea])))";
|
|
// char * pStr = "[!(a[be])!(c!df)]";
|
|
// char * pStr = "<(e<bca>)fd>";
|
|
// char * pStr = "[d8001{abef}c]";
|
|
char * pStr = "[dc<a(cbd)(!c!b!d)>{abef}]";
|
|
// char * pStr3;
|
|
word t = Dau_Dsd6ToTruth( pStr );
|
|
// return;
|
|
int nNonDec = Dau_DsdDecompose( &t, 6, 1, 1, pRes );
|
|
// Dau_DsdNormalize( pStr2 );
|
|
// Dau_DsdExtract( pStr, 2, 0 );
|
|
t = 0;
|
|
nNonDec = 0;
|
|
}
|
|
|
|
|
|
|
|
void Dau_DsdTest888()
|
|
{
|
|
char pDsd[DAU_MAX_STR];
|
|
int nVars = 9;
|
|
// char * pStr = "[(abc)(def)(ghi)]";
|
|
// char * pStr = "[a!b!(c!d[e(fg)hi])]";
|
|
// char * pStr = "[(abc)(def)]";
|
|
// char * pStr = "[(abc)(def)]";
|
|
// char * pStr = "[abcdefg]";
|
|
// char * pStr = "[<abc>(de[ghi])]";
|
|
char * pStr = "(<abc>(<def><ghi>))";
|
|
word * pTruth = Dau_DsdToTruth( pStr, 9 );
|
|
int i, Status;
|
|
// Kit_DsdPrintFromTruth( (unsigned *)pTruth, 9 ); printf( "\n" );
|
|
/*
|
|
for ( i = 0; i < 6; i++ )
|
|
{
|
|
unsigned uSupp = Dau_Dsd6FindSupports( NULL, pTruth, NULL, 6, i );
|
|
Dau_DsdPrintSupports( uSupp, 6 );
|
|
}
|
|
*/
|
|
/*
|
|
printf( "\n" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
{
|
|
unsigned uSupp = Dau_DsdFindSupports( NULL, pTruth, NULL, nVars, i );
|
|
Dau_DsdPrintSupports( uSupp, nVars );
|
|
}
|
|
*/
|
|
Status = Dau_DsdDecompose( pTruth, nVars, 0, 0, pDsd );
|
|
i = 0;
|
|
}
|
|
|
|
void Dau_DsdTest555()
|
|
{
|
|
int nVars = 10;
|
|
int nWords = Abc_TtWordNum(nVars);
|
|
char * pFileName = "_npn/npn/dsd10.txt";
|
|
FILE * pFile = fopen( pFileName, "rb" );
|
|
word Tru[2][DAU_MAX_WORD], * pTruth;
|
|
char pBuffer[DAU_MAX_STR];
|
|
char pRes[DAU_MAX_STR];
|
|
int nSizeNonDec;
|
|
int i, Counter = 0;
|
|
abctime clk = Abc_Clock(), clkDec = 0, clk2;
|
|
// return;
|
|
|
|
while ( fgets( pBuffer, DAU_MAX_STR, pFile ) != NULL )
|
|
{
|
|
char * pStr2 = pBuffer + strlen(pBuffer)-1;
|
|
if ( *pStr2 == '\n' )
|
|
*pStr2-- = 0;
|
|
if ( *pStr2 == '\r' )
|
|
*pStr2-- = 0;
|
|
if ( pBuffer[0] == 'V' || pBuffer[0] == 0 )
|
|
continue;
|
|
Counter++;
|
|
|
|
for ( i = 0; i < 1; i++ )
|
|
{
|
|
// Dau_DsdPermute( pBuffer );
|
|
pTruth = Dau_DsdToTruth( pBuffer[0] == '*' ? pBuffer + 1 : pBuffer, nVars );
|
|
Abc_TtCopy( Tru[0], pTruth, nWords, 0 );
|
|
Abc_TtCopy( Tru[1], pTruth, nWords, 0 );
|
|
clk2 = Abc_Clock();
|
|
nSizeNonDec = Dau_DsdDecompose( Tru[1], nVars, 0, 1, pRes );
|
|
clkDec += Abc_Clock() - clk2;
|
|
Dau_DsdNormalize( pRes );
|
|
// pStr2 = Dau_DsdPerform( t ); nSizeNonDec = 0;
|
|
assert( nSizeNonDec == 0 );
|
|
pTruth = Dau_DsdToTruth( pRes, nVars );
|
|
if ( !Abc_TtEqual( pTruth, Tru[0], nWords ) )
|
|
{
|
|
// Kit_DsdPrintFromTruth( (unsigned *)&t, 6 );
|
|
// printf( " " );
|
|
// Kit_DsdPrintFromTruth( (unsigned *)&t2, 6 );
|
|
printf( "%s -> %s \n", pBuffer, pRes );
|
|
printf( "Verification failed.\n" );
|
|
}
|
|
}
|
|
}
|
|
printf( "Finished trying %d decompositions. ", Counter );
|
|
Abc_PrintTime( 1, "Time", clkDec );
|
|
Abc_PrintTime( 1, "Total", Abc_Clock() - clk );
|
|
|
|
Abc_PrintTime( 1, "Time1", s_Times[0] );
|
|
Abc_PrintTime( 1, "Time2", s_Times[1] );
|
|
Abc_PrintTime( 1, "Time3", s_Times[2] );
|
|
|
|
fclose( pFile );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|