mirror of https://github.com/YosysHQ/abc.git
New SAT-based optimization package.
This commit is contained in:
parent
b3514ee7e0
commit
3b5527b620
|
|
@ -42,6 +42,8 @@ struct Sbd_Man_t_
|
|||
Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability)
|
||||
Vec_Int_t * vCover; // temporary
|
||||
Vec_Int_t * vLits; // temporary
|
||||
int nConsts; // constants
|
||||
int nChanges; // changes
|
||||
// target node
|
||||
int Pivot; // target node
|
||||
Vec_Int_t * vTfo; // TFO (excludes node, includes roots) - precomputed
|
||||
|
|
@ -82,7 +84,7 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars )
|
|||
{
|
||||
memset( pPars, 0, sizeof(Sbd_Par_t) );
|
||||
pPars->nLutSize = 4; // target LUT size
|
||||
pPars->nTfoLevels = 3; // the number of TFO levels (windowing)
|
||||
pPars->nTfoLevels = 2; // the number of TFO levels (windowing)
|
||||
pPars->nTfoFanMax = 4; // the max number of fanouts (windowing)
|
||||
pPars->nWinSizeMax = 0; // maximum window size (windowing)
|
||||
pPars->nBTLimit = 0; // maximum number of SAT conflicts
|
||||
|
|
@ -145,7 +147,7 @@ Vec_Wec_t * Sbd_ManWindowRoots( Gia_Man_t * p, int nTfoLevels, int nTfoFanMax )
|
|||
Vec_BitFree( vPoDrivers );
|
||||
|
||||
// print the results
|
||||
if ( 1 )
|
||||
if ( 0 )
|
||||
Vec_WecForEachLevel( vTfos, vNodes, i )
|
||||
{
|
||||
if ( !Gia_ObjIsAnd(Gia_ManObj(p, i)) )
|
||||
|
|
@ -244,12 +246,88 @@ void Sbd_ManStop( Sbd_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int Node )
|
||||
void Sbd_ManPropagateControlOne( Sbd_Man_t * p, int Node )
|
||||
{
|
||||
Gia_Obj_t * pNode = Gia_ManObj(p->pGia, Node); int w;
|
||||
int iObj0 = Gia_ObjFaninId0(pNode, Node);
|
||||
int iObj1 = Gia_ObjFaninId1(pNode, Node);
|
||||
|
||||
word * pSims = Sbd_ObjSim0(p, Node);
|
||||
word * pSims0 = Sbd_ObjSim0(p, iObj0);
|
||||
word * pSims1 = Sbd_ObjSim0(p, iObj1);
|
||||
|
||||
word * pCtrl = Sbd_ObjSim2(p, Node);
|
||||
word * pCtrl0 = Sbd_ObjSim2(p, iObj0);
|
||||
word * pCtrl1 = Sbd_ObjSim2(p, iObj1);
|
||||
|
||||
word * pDtrl = Sbd_ObjSim3(p, Node);
|
||||
word * pDtrl0 = Sbd_ObjSim3(p, iObj0);
|
||||
word * pDtrl1 = Sbd_ObjSim3(p, iObj1);
|
||||
|
||||
// Gia_ObjPrint( p->pGia, pNode );
|
||||
// printf( "Node %2d : %d %d\n\n", Node, (int)(pSims[0] & 1), (int)(pCtrl[0] & 1) );
|
||||
|
||||
for ( w = 0; w < p->pPars->nWords; w++ )
|
||||
{
|
||||
word Sim0 = Gia_ObjFaninC0(pNode) ? ~pSims0[w] : pSims0[w];
|
||||
word Sim1 = Gia_ObjFaninC1(pNode) ? ~pSims1[w] : pSims1[w];
|
||||
|
||||
pCtrl0[w] |= pCtrl[w] & (pSims[w] | Sim1 | (~Sim0 & ~Sim1));
|
||||
pCtrl1[w] |= pCtrl[w] & (pSims[w] | Sim0);
|
||||
|
||||
pDtrl0[w] |= pDtrl[w] & (pSims[w] | Sim1);
|
||||
pDtrl1[w] |= pDtrl[w] & (pSims[w] | Sim0 | (~Sim0 & ~Sim1));
|
||||
}
|
||||
}
|
||||
void Sbd_ManPropagateControl( Sbd_Man_t * p, int Pivot )
|
||||
{
|
||||
int i, Node;
|
||||
Abc_TtCopy( Sbd_ObjSim3(p, Pivot), Sbd_ObjSim2(p, Pivot), p->pPars->nWords, 0 );
|
||||
// clean controlability
|
||||
for ( i = 0; i < Vec_IntEntry(p->vObj2Var, Pivot) && ((Node = Vec_IntEntry(p->vWinObjs, i)), 1); i++ )
|
||||
{
|
||||
Abc_TtClear( Sbd_ObjSim2(p, Node), p->pPars->nWords );
|
||||
Abc_TtClear( Sbd_ObjSim3(p, Node), p->pPars->nWords );
|
||||
//printf( "Clearing node %d.\n", Node );
|
||||
}
|
||||
// propagate controlability to fanins for the TFI nodes starting from the pivot
|
||||
for ( i = Vec_IntEntry(p->vObj2Var, Pivot); i >= 0 && ((Node = Vec_IntEntry(p->vWinObjs, i)), 1); i-- )
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p->pGia, Node)) )
|
||||
Sbd_ManPropagateControlOne( p, Node );
|
||||
}
|
||||
void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot )
|
||||
{
|
||||
int i, k, Node;
|
||||
Vec_Int_t * vLevel;
|
||||
// collect divisors by logic level
|
||||
int LevelMax = Vec_IntEntry(p->vLutLevs, Pivot);
|
||||
Vec_WecClear( p->vDivLevels );
|
||||
Vec_WecInit( p->vDivLevels, LevelMax + 1 );
|
||||
Vec_IntForEachEntry( p->vWinObjs, Node, i )
|
||||
Vec_WecPush( p->vDivLevels, Vec_IntEntry(p->vLutLevs, Node), Node );
|
||||
// sort primary inputs
|
||||
Vec_IntSort( Vec_WecEntry(p->vDivLevels, 0), 0 );
|
||||
// reload divisors
|
||||
Vec_IntClear( p->vWinObjs );
|
||||
Vec_WecForEachLevel( p->vDivLevels, vLevel, i )
|
||||
{
|
||||
Vec_IntForEachEntry( vLevel, Node, k )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vObj2Var, Node, Vec_IntSize(p->vWinObjs) );
|
||||
Vec_IntPush( p->vWinObjs, Node );
|
||||
}
|
||||
// detect useful divisors
|
||||
if ( i == LevelMax - 2 )
|
||||
Vec_IntFill( p->vDivValues, Vec_IntSize(p->vWinObjs), 0 );
|
||||
}
|
||||
}
|
||||
void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int NodeInit )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int Node = NodeInit;
|
||||
if ( Vec_IntEntry(p->vMirrors, Node) >= 0 )
|
||||
Node = Abc_Lit2Var( Vec_IntEntry(p->vMirrors, Node) );
|
||||
if ( Gia_ObjIsTravIdCurrentId(p->pGia, Node) || Node == 0 )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p->pGia, Node) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrentId(p->pGia, Node);
|
||||
pObj = Gia_ManObj( p->pGia, Node );
|
||||
|
|
@ -295,66 +373,10 @@ void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int Node )
|
|||
Gia_ObjFanin1(pObj)->fMark0 ? Sbd_ObjSim1(p, Gia_ObjFaninId1(pObj, Node)) : Sbd_ObjSim0(p, Gia_ObjFaninId1(pObj, Node)), Gia_ObjFaninC1(pObj),
|
||||
p->pPars->nWords );
|
||||
}
|
||||
if ( Node != NodeInit )
|
||||
Abc_TtCopy( Sbd_ObjSim0(p, NodeInit), Sbd_ObjSim0(p, Node), p->pPars->nWords, Abc_LitIsCompl(Vec_IntEntry(p->vMirrors, NodeInit)) );
|
||||
}
|
||||
void Sbd_ManPropagateControl( Sbd_Man_t * p, int Node )
|
||||
{
|
||||
Gia_Obj_t * pNode = Gia_ManObj(p->pGia, Node);
|
||||
int iObj0 = Gia_ObjFaninId0(pNode, Node);
|
||||
int iObj1 = Gia_ObjFaninId1(pNode, Node);
|
||||
|
||||
word * pSims = Sbd_ObjSim0(p, Node);
|
||||
word * pSims0 = Sbd_ObjSim0(p, iObj0);
|
||||
word * pSims1 = Sbd_ObjSim0(p, iObj1);
|
||||
|
||||
word * pCtrl = Sbd_ObjSim2(p, Node);
|
||||
word * pCtrl0 = Sbd_ObjSim2(p, iObj0);
|
||||
word * pCtrl1 = Sbd_ObjSim2(p, iObj1);
|
||||
|
||||
word * pDtrl = Sbd_ObjSim3(p, Node);
|
||||
word * pDtrl0 = Sbd_ObjSim3(p, iObj0);
|
||||
word * pDtrl1 = Sbd_ObjSim3(p, iObj1);
|
||||
|
||||
// printf( "Node %2d : %d %d\n", Node, (int)(pSims[0] & 1), (int)(pCtrl[0] & 1) );
|
||||
int w;
|
||||
for ( w = 0; w < p->pPars->nWords; w++ )
|
||||
{
|
||||
word Sim0 = Gia_ObjFaninC0(pNode) ? ~pSims0[w] : pSims0[w];
|
||||
word Sim1 = Gia_ObjFaninC1(pNode) ? ~pSims1[w] : pSims1[w];
|
||||
|
||||
pCtrl0[w] = pCtrl[w] & (pSims[w] | Sim1 | (~Sim0 & ~Sim1));
|
||||
pCtrl1[w] = pCtrl[w] & (pSims[w] | Sim0);
|
||||
|
||||
pDtrl0[w] = pDtrl[w] & (pSims[w] | Sim1);
|
||||
pDtrl1[w] = pDtrl[w] & (pSims[w] | Sim0 | (~Sim0 & ~Sim1));
|
||||
}
|
||||
}
|
||||
void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot )
|
||||
{
|
||||
int i, k, Node;
|
||||
Vec_Int_t * vLevel;
|
||||
// collect divisors by logic level
|
||||
int LevelMax = Vec_IntEntry(p->vLutLevs, Pivot);
|
||||
Vec_WecClear( p->vDivLevels );
|
||||
Vec_WecInit( p->vDivLevels, LevelMax + 1 );
|
||||
Vec_IntForEachEntry( p->vWinObjs, Node, i )
|
||||
Vec_WecPush( p->vDivLevels, Vec_IntEntry(p->vLutLevs, Node), Node );
|
||||
// sort primary inputs
|
||||
Vec_IntSort( Vec_WecEntry(p->vDivLevels, 0), 0 );
|
||||
// reload divisors
|
||||
Vec_IntClear( p->vWinObjs );
|
||||
Vec_WecForEachLevel( p->vDivLevels, vLevel, i )
|
||||
{
|
||||
Vec_IntForEachEntry( vLevel, Node, k )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vObj2Var, Node, Vec_IntSize(p->vWinObjs) );
|
||||
Vec_IntPush( p->vWinObjs, Node );
|
||||
}
|
||||
// detect useful divisors
|
||||
if ( i == LevelMax - 2 )
|
||||
Vec_IntFill( p->vDivValues, Vec_IntSize(p->vWinObjs), 0 );
|
||||
}
|
||||
}
|
||||
void Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
|
||||
int Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
|
||||
{
|
||||
int i, Node;
|
||||
// assign pivot and TFO (assume siminfo is assigned at the PIs)
|
||||
|
|
@ -362,7 +384,10 @@ void Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
|
|||
p->vTfo = Vec_WecEntry( p->vTfos, Pivot );
|
||||
// simulate TFI cone
|
||||
Vec_IntClear( p->vWinObjs );
|
||||
Vec_IntWriteEntry( p->vObj2Var, 0, Vec_IntSize(p->vWinObjs) );
|
||||
Vec_IntPush( p->vWinObjs, 0 );
|
||||
Gia_ManIncrementTravId( p->pGia );
|
||||
Gia_ObjSetTravIdCurrentId(p->pGia, 0);
|
||||
Sbd_ManWindowSim_rec( p, Pivot );
|
||||
Sbd_ManUpdateOrder( p, Pivot );
|
||||
// simulate node
|
||||
|
|
@ -394,11 +419,143 @@ void Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
|
|||
Vec_IntForEachEntry( p->vTfo, Node, i )
|
||||
if ( Abc_LitIsCompl(Node) ) // root
|
||||
Abc_TtOrXor( Sbd_ObjSim2(p, Pivot), Sbd_ObjSim0(p, Abc_Lit2Var(Node)), Sbd_ObjSim1(p, Abc_Lit2Var(Node)), p->pPars->nWords );
|
||||
Abc_TtCopy( Sbd_ObjSim3(p, Pivot), Sbd_ObjSim2(p, Pivot), p->pPars->nWords, 0 );
|
||||
// propagate controlability to fanins for the TFI nodes starting from the pivot
|
||||
for ( i = Vec_IntEntry(p->vObj2Var, Pivot); i >= 0 && ((Node = Vec_IntEntry(p->vWinObjs, i)), 1); i-- )
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p->pGia, Node)) )
|
||||
Sbd_ManPropagateControl( p, Node );
|
||||
Sbd_ManPropagateControl( p, Pivot );
|
||||
// return 1 if window is too large
|
||||
if ( p->pPars->fVerbose && Vec_IntSize(p->vDivValues) >= 64 )
|
||||
printf( "Window is too large.\n" );
|
||||
return (int)(Vec_IntSize(p->vDivValues) >= 64);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot )
|
||||
{
|
||||
extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot );
|
||||
int nMintCount = 16;
|
||||
Vec_Ptr_t * vSims;
|
||||
word * pSims = Sbd_ObjSim0( p, Pivot );
|
||||
word * pCtrl = Sbd_ObjSim2( p, Pivot );
|
||||
int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot);
|
||||
int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0};
|
||||
extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds );
|
||||
extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots );
|
||||
p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots );
|
||||
//return -1;
|
||||
//Sbd_ManPrintObj( p, Pivot );
|
||||
|
||||
// count the number of on-set and off-set care-set minterms
|
||||
Vec_IntClear( p->vLits );
|
||||
for ( i = 0; i < 64; i++ )
|
||||
if ( Abc_TtGetBit(pCtrl, i) )
|
||||
nCares[Abc_TtGetBit(pSims, i)]++;
|
||||
else
|
||||
Vec_IntPush( p->vLits, i );
|
||||
fFindOnset = (int)(nCares[0] < nCares[1]);
|
||||
if ( nCares[0] >= nMintCount && nCares[1] >= nMintCount )
|
||||
return -1;
|
||||
// find how many do we need
|
||||
nCares[0] = nCares[0] < nMintCount ? nMintCount - nCares[0] : 0;
|
||||
nCares[1] = nCares[1] < nMintCount ? nMintCount - nCares[1] : 0;
|
||||
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Computing %d offset and %d onset minterms for node %d.\n", nCares[0], nCares[1], Pivot );
|
||||
|
||||
if ( Vec_IntSize(p->vLits) >= nCares[0] + nCares[1] )
|
||||
Vec_IntShrink( p->vLits, nCares[0] + nCares[1] );
|
||||
else
|
||||
{
|
||||
// collect places to insert new minterms
|
||||
for ( i = 0; i < 64 && Vec_IntSize(p->vLits) < nCares[0] + nCares[1]; i++ )
|
||||
if ( fFindOnset == Abc_TtGetBit(pSims, i) )
|
||||
Vec_IntPush( p->vLits, i );
|
||||
}
|
||||
// collect simulation pointers
|
||||
vSims = Vec_PtrAlloc( PivotVar + 1 );
|
||||
Vec_IntForEachEntry( p->vWinObjs, iObj, i )
|
||||
{
|
||||
Vec_PtrPush( vSims, Sbd_ObjSim0(p, iObj) );
|
||||
if ( iObj == Pivot )
|
||||
break;
|
||||
}
|
||||
assert( i == PivotVar );
|
||||
// compute patterns
|
||||
RetValue = Sbd_ManCollectConstants( p->pSat, nCares, PivotVar, (word **)Vec_PtrArray(vSims), p->vLits );
|
||||
// print computed miterms
|
||||
if ( 0 && RetValue < 0 )
|
||||
{
|
||||
Vec_Int_t * vPis = Vec_WecEntry(p->vDivLevels, 0);
|
||||
int i, k, Ind;
|
||||
printf( "Additional minterms:\n" );
|
||||
Vec_IntForEachEntry( p->vLits, Ind, k )
|
||||
{
|
||||
for ( i = 0; i < Vec_IntSize(vPis); i++ )
|
||||
printf( "%d", Abc_TtGetBit( (word *)Vec_PtrEntry(vSims, Vec_IntEntry(p->vWinObjs, i)), Ind ) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
Vec_PtrFree( vSims );
|
||||
if ( RetValue >= 0 )
|
||||
{
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot );
|
||||
p->nConsts++;
|
||||
return RetValue;
|
||||
}
|
||||
// set controlability of these minterms
|
||||
Vec_IntForEachEntry( p->vLits, Ind, i )
|
||||
Abc_TtSetBit( pCtrl, Ind );
|
||||
// propagate controlability to fanins for the TFI nodes starting from the pivot
|
||||
Sbd_ManPropagateControl( p, Pivot );
|
||||
// double check that we now have enough minterms
|
||||
for ( i = 0; i < 64; i++ )
|
||||
if ( Abc_TtGetBit(pCtrl, i) )
|
||||
nCares[Abc_TtGetBit(pSims, i)]++;
|
||||
assert( nCares[0] >= nMintCount && nCares[1] >= nMintCount );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transposing 64-bit matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Sbd_TransposeMatrix64( word A[64] )
|
||||
{
|
||||
int j, k;
|
||||
word t, m = 0x00000000FFFFFFFF;
|
||||
for ( j = 32; j != 0; j = j >> 1, m = m ^ (m << j) )
|
||||
{
|
||||
for ( k = 0; k < 64; k = (k + j + 1) & ~j )
|
||||
{
|
||||
t = (A[k] ^ (A[k+j] >> j)) & m;
|
||||
A[k] = A[k] ^ t;
|
||||
A[k+j] = A[k+j] ^ (t << j);
|
||||
}
|
||||
}
|
||||
}
|
||||
static inline void Sbd_PrintMatrix64( word A[64] )
|
||||
{
|
||||
int j, k;
|
||||
for ( j = 0; j < 64; j++, printf("\n") )
|
||||
for ( k = 0; k < 64; k++ )
|
||||
printf( "%d", (int)((A[j] >> k) & 1) );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -418,7 +575,7 @@ void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot )
|
|||
int i, k, k0, k1, Id, Bit0, Bit1;
|
||||
|
||||
Vec_IntForEachEntryStop( p->vWinObjs, Id, i, nDivs )
|
||||
printf( "%d : ", Id ), Extra_PrintBinary( stdout, (unsigned *)Sbd_ObjSim0(p, Id), 64 ), printf( "\n" );
|
||||
printf( "%3d : ", Id ), Extra_PrintBinary( stdout, (unsigned *)Sbd_ObjSim0(p, Id), 64 ), printf( "\n" );
|
||||
|
||||
assert( p->Pivot == Pivot );
|
||||
Vec_IntClear( p->vCounts[0] );
|
||||
|
|
@ -561,52 +718,182 @@ void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot )
|
|||
if ( Abc_TtGetBit(pCtrl, Bit0) && Abc_TtGetBit(pCtrl, Bit1) && Abc_TtGetBit(pSims, Bit0) != Abc_TtGetBit(pSims, Bit1) )
|
||||
Abc_TtXorBit( &Row, i );
|
||||
}
|
||||
if ( !Vec_WrdPushUnique( p->vMatrix, Row ) )
|
||||
Extra_PrintBinary( stdout, (unsigned *)&Row, nDivs ), printf( "\n" );
|
||||
if ( Vec_WrdPushUnique( p->vMatrix, Row ) )
|
||||
continue;
|
||||
for ( i = 0; i < nDivs; i++ )
|
||||
printf( "%d", (int)((Row >> i) & 1) );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth )
|
||||
{
|
||||
extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots );
|
||||
int fVerbose = 0;
|
||||
extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp );
|
||||
|
||||
word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, Cube0, Cube1, Target;
|
||||
int c0, c1, c2, c3, i, k, n, Index, nCubes[2] = {0}, nRows = 0, fFound = 0;
|
||||
|
||||
int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot);
|
||||
int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots);
|
||||
int RetValue = 0;
|
||||
|
||||
// Sbd_ManPrintObj( p, Pivot );
|
||||
Vec_IntPrint( p->vObj2Var );
|
||||
if ( fVerbose )
|
||||
Sbd_ManPrintObj( p, Pivot );
|
||||
|
||||
// collect bit-matrices
|
||||
for ( i = 0; i < Vec_IntSize(p->vDivValues); i++ )
|
||||
{
|
||||
MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, i) );
|
||||
MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, i) );
|
||||
MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, i) );
|
||||
}
|
||||
MatrS[63-i] = *Sbd_ObjSim0( p, Pivot );
|
||||
MatrC[0][63-i] = *Sbd_ObjSim2( p, Pivot );
|
||||
MatrC[1][63-i] = *Sbd_ObjSim3( p, Pivot );
|
||||
|
||||
//Sbd_PrintMatrix64( MatrS );
|
||||
Sbd_TransposeMatrix64( MatrS );
|
||||
Sbd_TransposeMatrix64( MatrC[0] );
|
||||
Sbd_TransposeMatrix64( MatrC[1] );
|
||||
//Sbd_PrintMatrix64( MatrS );
|
||||
|
||||
// collect cubes
|
||||
for ( i = 0; i < 64; i++ )
|
||||
{
|
||||
assert( Abc_TtGetBit(&MatrC[0][i], Vec_IntSize(p->vDivValues)) == Abc_TtGetBit(&MatrC[1][i], Vec_IntSize(p->vDivValues)) );
|
||||
if ( !Abc_TtGetBit(&MatrC[0][i], Vec_IntSize(p->vDivValues)) )
|
||||
continue;
|
||||
Index = Abc_TtGetBit(&MatrS[i], Vec_IntSize(p->vDivValues)); // Index==0 offset; Index==1 onset
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
if ( n && MatrC[0][i] == MatrC[1][i] )
|
||||
continue;
|
||||
assert( MatrC[n][i] );
|
||||
Cube0 = ~MatrS[i] & MatrC[n][i];
|
||||
Cube1 = MatrS[i] & MatrC[n][i];
|
||||
assert( Cube0 || Cube1 );
|
||||
for ( k = 0; k < nCubes[Index]; k++ )
|
||||
if ( Cubes[Index][0][k] == Cube0 && Cubes[Index][1][k] == Cube1 )
|
||||
break;
|
||||
if ( k == nCubes[Index] && k < 64 )
|
||||
{
|
||||
Cubes[Index][0][nCubes[Index]] = Cube0;
|
||||
Cubes[Index][1][nCubes[Index]] = Cube1;
|
||||
nCubes[Index]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Generated matrix with %d x %d entries.\n", nCubes[0], nCubes[1] );
|
||||
|
||||
if ( fVerbose )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
printf( "%s:\n", n ? "Onset" : "Offset" );
|
||||
for ( i = 0; i < nCubes[n]; i++, printf( "\n" ) )
|
||||
for ( k = 0; k < 64; k++ )
|
||||
if ( Abc_TtGetBit(&Cubes[n][0][i], k) )
|
||||
printf( "0" );
|
||||
else if ( Abc_TtGetBit(&Cubes[n][1][i], k) )
|
||||
printf( "1" );
|
||||
else
|
||||
printf( "." );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
// collect cover
|
||||
for ( i = 0; i < nCubes[0]; i++ )
|
||||
for ( k = 0; k < nCubes[1]; k++ )
|
||||
{
|
||||
Cube = (Cubes[0][1][i] & Cubes[1][0][k]) | (Cubes[0][0][i] & Cubes[1][1][k]);
|
||||
assert( Cube );
|
||||
for ( n = 0; n < nRows; n++ )
|
||||
if ( Cover[63-n] == Cube )
|
||||
break;
|
||||
if ( n == nRows && n < 64 )
|
||||
Cover[63-nRows++] = Cube;
|
||||
}
|
||||
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Generated cover with %d entries.\n", nRows );
|
||||
|
||||
|
||||
//Sbd_PrintMatrix64( Cover );
|
||||
Sbd_TransposeMatrix64( Cover );
|
||||
//Sbd_PrintMatrix64( Cover );
|
||||
|
||||
// swap
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
Cube = Cover[i];
|
||||
Cover[i] = Cover[63-i];
|
||||
Cover[63-i] = Cube;
|
||||
}
|
||||
|
||||
if ( fVerbose )
|
||||
{
|
||||
for ( i = 0; i <= nRows; i++, printf( "\n") )
|
||||
for ( k = 0; k < 64; k++ )
|
||||
printf( "%d", (int)((Cover[i] >> k) & 1) );
|
||||
}
|
||||
|
||||
Target = Cover[Vec_IntSize(p->vDivValues)];
|
||||
for ( c0 = 0; c0 < Vec_IntSize(p->vDivValues); c0++ )
|
||||
for ( c1 = c0+1; c1 < Vec_IntSize(p->vDivValues); c1++ )
|
||||
for ( c2 = c1+1; c2 < Vec_IntSize(p->vDivValues); c2++ )
|
||||
for ( c3 = c2+1; c3 < Vec_IntSize(p->vDivValues); c3++ )
|
||||
{
|
||||
if ( (Cover[c0] | Cover[c1] | Cover[c2] | Cover[c3]) == Target )
|
||||
goto finish;
|
||||
}
|
||||
finish:
|
||||
if ( c0 == Vec_IntSize(p->vDivValues) )
|
||||
{
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Cannot find a feasible cover.\n" );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
Vec_IntClear( p->vDivVars );
|
||||
Vec_IntPush( p->vDivVars, 0 );
|
||||
Vec_IntPush( p->vDivVars, 1 );
|
||||
Vec_IntPush( p->vDivVars, 2 );
|
||||
Vec_IntPush( p->vDivVars, 4 );
|
||||
Vec_IntPush( p->vDivVars, c0 );
|
||||
Vec_IntPush( p->vDivVars, c1 );
|
||||
Vec_IntPush( p->vDivVars, c2 );
|
||||
Vec_IntPush( p->vDivVars, c3 );
|
||||
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Feasible cover: " );
|
||||
if ( p->pPars->fVerbose )
|
||||
Vec_IntPrint( p->vDivVars );
|
||||
|
||||
p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots );
|
||||
*pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar, p->vDivVars, p->vDivValues, p->vLits );
|
||||
if ( *pTruth == SBD_SAT_UNDEC )
|
||||
printf( "Node %d: Undecided.\n", Pivot );
|
||||
else if ( *pTruth == SBD_SAT_SAT )
|
||||
{
|
||||
int i;
|
||||
printf( "Node %d: SAT.\n", Pivot );
|
||||
for ( i = 0; i < Vec_IntSize(p->vDivValues); i++ )
|
||||
printf( "%d", Vec_IntEntry(p->vDivValues, i) & 1 );
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < Vec_IntSize(p->vDivValues); i++ )
|
||||
printf( "%d", Vec_IntEntry(p->vDivValues, i) >> 1 );
|
||||
printf( "\n" );
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
int i;
|
||||
printf( "Node %d: SAT.\n", Pivot );
|
||||
for ( i = 0; i < Vec_IntSize(p->vDivValues); i++ )
|
||||
printf( "%d", Vec_IntEntry(p->vDivValues, i) & 1 );
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < Vec_IntSize(p->vDivValues); i++ )
|
||||
printf( "%d", Vec_IntEntry(p->vDivValues, i) >> 1 );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Node %d: UNSAT.\n", Pivot );
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Node %d: UNSAT.\n", Pivot );
|
||||
if ( p->pPars->fVerbose )
|
||||
Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivVars) ), printf( "\n" );
|
||||
RetValue = 1;
|
||||
}
|
||||
|
||||
Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivVars) ), printf( "\n" );
|
||||
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
|
|
@ -669,7 +956,7 @@ int Sbd_ManComputeCut( Sbd_Man_t * p, int Node )
|
|||
assert( Vec_IntEntry(p->vLutLevs, Node) == 0 );
|
||||
Vec_IntWriteEntry( p->vLutLevs, Node, LevMax );
|
||||
memcpy( Sbd_ObjCut(p, Node), pCut, sizeof(int) * (pCut[0] + 1) );
|
||||
printf( "Setting node %d with delay %d (result = %d).\n", Node, LevMax, Result );
|
||||
//printf( "Setting node %d with delay %d (result = %d).\n", Node, LevMax, Result );
|
||||
return Result;
|
||||
}
|
||||
int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth )
|
||||
|
|
@ -697,11 +984,15 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth )
|
|||
// remember this function
|
||||
assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 );
|
||||
Vec_IntWriteEntry( p->vMirrors, Pivot, iLit );
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Replacing node %d by literal %d.\n", Pivot, iLit );
|
||||
// extend data-structure for new nodes
|
||||
assert( Vec_IntSize(p->vLutLevs) == iObjLast );
|
||||
for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ )
|
||||
{
|
||||
Vec_IntPush( p->vLutLevs, 0 );
|
||||
Vec_IntPush( p->vObj2Var, 0 );
|
||||
Vec_IntPush( p->vMirrors, -1 );
|
||||
Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 );
|
||||
Sbd_ManComputeCut( p, i );
|
||||
for ( k = 0; k < 4; k++ )
|
||||
|
|
@ -710,6 +1001,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth )
|
|||
}
|
||||
// make sure delay reduction is achieved
|
||||
assert( Vec_IntEntry(p->vLutLevs, Abc_Lit2Var(iLit)) < iCurLev );
|
||||
p->nChanges++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -728,18 +1020,19 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v
|
|||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int Obj = Node;
|
||||
if ( Node < Vec_IntSize(vMirrors) && Vec_IntEntry(vMirrors, Node) >= 0 )
|
||||
if ( Vec_IntEntry(vMirrors, Node) >= 0 )
|
||||
Obj = Abc_Lit2Var( Vec_IntEntry(vMirrors, Node) );
|
||||
pObj = Gia_ManObj( p, Obj );
|
||||
if ( ~pObj->Value )
|
||||
return;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Sbd_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors );
|
||||
Sbd_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors );
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
pObj->Value = Gia_ManHashXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
else
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
if ( !~pObj->Value )
|
||||
{
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Sbd_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors );
|
||||
Sbd_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors );
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
pObj->Value = Gia_ManHashXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
else
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
// set the original node as well
|
||||
if ( Obj != Node )
|
||||
Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) );
|
||||
|
|
@ -766,7 +1059,6 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs delay optimization for the given LUT size.]
|
||||
|
|
@ -782,18 +1074,28 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars )
|
|||
{
|
||||
Gia_Man_t * pNew;
|
||||
Sbd_Man_t * p = Sbd_ManStart( pGia, pPars );
|
||||
int Pivot; word Truth = 0;
|
||||
int nNodesOld = Gia_ManObjNum(pGia);
|
||||
int RetValue, Pivot; word Truth = 0;
|
||||
assert( pPars->nLutSize <= 6 );
|
||||
Gia_ManForEachAndId( pGia, Pivot )
|
||||
{
|
||||
if ( Pivot >= nNodesOld )
|
||||
break;
|
||||
if ( Sbd_ManComputeCut( p, Pivot ) )
|
||||
continue;
|
||||
printf( "Looking at node %d\n", Pivot );
|
||||
Sbd_ManWindow( p, Pivot );
|
||||
if ( Sbd_ManExplore( p, Pivot, &Truth ) )
|
||||
//if ( Pivot != 313 )
|
||||
// continue;
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "\nLooking at node %d\n", Pivot );
|
||||
if ( Sbd_ManWindow( p, Pivot ) )
|
||||
continue;
|
||||
RetValue = Sbd_ManCheckConst( p, Pivot );
|
||||
if ( RetValue >= 0 )
|
||||
Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue );
|
||||
else if ( Sbd_ManExplore( p, Pivot, &Truth ) )
|
||||
Sbd_ManImplement( p, Pivot, Truth );
|
||||
break;
|
||||
}
|
||||
printf( "Found %d constants and %d replacements.\n", p->nConsts, p->nChanges );
|
||||
pNew = Sbd_ManDerive( pGia, p->vMirrors );
|
||||
Sbd_ManStop( p );
|
||||
return pNew;
|
||||
|
|
|
|||
|
|
@ -46,46 +46,62 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
|
||||
sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iObj, Fan0, Fan1, Node, fCompl0, fCompl1, RetValue;
|
||||
int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue;
|
||||
int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo);
|
||||
int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
|
||||
//Vec_IntPrint( vWinObjs );
|
||||
//Vec_IntPrint( vTfo );
|
||||
//Vec_IntPrint( vRoots );
|
||||
// create SAT solver
|
||||
if ( pSat == NULL )
|
||||
pSat = sat_solver_new();
|
||||
else
|
||||
sat_solver_restart( pSat );
|
||||
sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 );
|
||||
// create constant 0 clause
|
||||
sat_solver_addclause( pSat, &iLit, &iLit + 1 );
|
||||
// add clauses for all nodes
|
||||
Vec_IntForEachEntry( vWinObjs, iObj, i )
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObj, i, 1 )
|
||||
{
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
continue;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( Vec_IntEntry( vMirrors, iObj ) < 0 );
|
||||
Node = Vec_IntEntry( vObj2Var, iObj );
|
||||
Fan0 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Fan1 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId1(pObj, iObj) );
|
||||
fCompl0 = Gia_ObjFaninC0(pObj);
|
||||
fCompl1 = Gia_ObjFaninC1(pObj);
|
||||
Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) );
|
||||
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
|
||||
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
|
||||
Fan0 = Vec_IntEntry( vObj2Var, Fan0 );
|
||||
Fan1 = Vec_IntEntry( vObj2Var, Fan1 );
|
||||
fCompl0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
|
||||
fCompl1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
|
||||
else
|
||||
sat_solver_add_and( pSat, Node, Fan0, Fan1, fCompl0, fCompl1, 0 );
|
||||
}
|
||||
// add second clauses for the TFO
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObj, i, Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo) )
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObj, i, TfoStart )
|
||||
{
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( Vec_IntEntry( vMirrors, iObj ) < 0 );
|
||||
Node = Vec_IntEntry( vObj2Var, iObj ) + Vec_IntSize(vTfo);
|
||||
Fan0 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Fan1 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId1(pObj, iObj) );
|
||||
Fan0 = Fan0 <= PivotVar ? Fan0 : Fan0 + Vec_IntSize(vTfo);
|
||||
Fan1 = Fan1 <= PivotVar ? Fan1 : Fan1 + Vec_IntSize(vTfo);
|
||||
fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar);
|
||||
fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar);
|
||||
Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) );
|
||||
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
|
||||
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
|
||||
Fan0 = Vec_IntEntry( vObj2Var, Fan0 );
|
||||
Fan1 = Vec_IntEntry( vObj2Var, Fan1 );
|
||||
Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo);
|
||||
Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo);
|
||||
fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
|
||||
fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
|
||||
else
|
||||
|
|
@ -98,8 +114,9 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, int Pivot, Vec_
|
|||
Vec_Int_t * vFaninVars = Vec_IntAlloc( Vec_IntSize(vRoots) );
|
||||
Vec_IntForEachEntry( vRoots, iObj, i )
|
||||
{
|
||||
Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars, 0) );
|
||||
assert( Vec_IntEntry( vMirrors, iObj ) < 0 );
|
||||
Node = Vec_IntEntry( vObj2Var, iObj );
|
||||
Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars, 0) );
|
||||
sat_solver_add_xor( pSat, Node, Node + Vec_IntSize(vTfo), nVars++, 0 );
|
||||
}
|
||||
// make OR clause for the last nRoots variables
|
||||
|
|
@ -190,6 +207,50 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
|
|||
return SBD_SAT_SAT;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns a bunch of positive/negative random care minterms.]
|
||||
|
||||
Description [Returns 0/1 if the functions is const 0/1.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static void sat_solver_random_polarity(sat_solver* s)
|
||||
{
|
||||
int i, k;
|
||||
for ( i = 0; i < s->size; i += 64 )
|
||||
{
|
||||
word Polar = Gia_ManRandomW(0);
|
||||
for ( k = 0; k < 64 && (i << 6) + k < s->size; k++ )
|
||||
s->polarity[(i << 6) + k] = Abc_TtGetBit(&Polar, k);
|
||||
}
|
||||
}
|
||||
int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds )
|
||||
{
|
||||
int nBTLimit = 0;
|
||||
int i, Ind;
|
||||
assert( Vec_IntSize(vInds) == nCareMints[0] + nCareMints[1] );
|
||||
Vec_IntForEachEntry( vInds, Ind, i )
|
||||
{
|
||||
int fOffSet = (int)(i < nCareMints[0]);
|
||||
int status, k, iLit = Abc_Var2Lit( PivotVar, fOffSet );
|
||||
sat_solver_random_polarity( pSat );
|
||||
status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 );
|
||||
if ( status == l_Undef )
|
||||
return -2;
|
||||
if ( status == l_False )
|
||||
return fOffSet;
|
||||
for ( k = 0; k <= PivotVar; k++ )
|
||||
if ( Abc_TtGetBit(pVarSims[k], Ind) != sat_solver_var_value(pSat, k) )
|
||||
Abc_TtXorBit(pVarSims[k], Ind);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue