mirror of https://github.com/YosysHQ/abc.git
Preprocessing SOPs given to 'fx' to be D1C-free and SCC-free. Handling the case of non-prime SOPs.
This commit is contained in:
parent
cac32a32c7
commit
f2abd6b8a9
|
|
@ -503,11 +503,13 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At
|
||||||
#define Abc_ObjForEachFanout( pObj, pFanout, i ) \
|
#define Abc_ObjForEachFanout( pObj, pFanout, i ) \
|
||||||
for ( i = 0; (i < Abc_ObjFanoutNum(pObj)) && (((pFanout) = Abc_ObjFanout(pObj, i)), 1); i++ )
|
for ( i = 0; (i < Abc_ObjFanoutNum(pObj)) && (((pFanout) = Abc_ObjFanout(pObj, i)), 1); i++ )
|
||||||
// cubes and literals
|
// cubes and literals
|
||||||
#define Abc_SopForEachCube( pSop, nFanins, pCube ) \
|
|
||||||
for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 )
|
|
||||||
#define Abc_CubeForEachVar( pCube, Value, i ) \
|
#define Abc_CubeForEachVar( pCube, Value, i ) \
|
||||||
for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ )
|
for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ )
|
||||||
|
#define Abc_SopForEachCube( pSop, nFanins, pCube ) \
|
||||||
|
for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 )
|
||||||
|
#define Abc_SopForEachCubePair( pSop, nFanins, pCube, pCube2 ) \
|
||||||
|
Abc_SopForEachCube( pSop, nFanins, pCube ) \
|
||||||
|
Abc_SopForEachCube( pCube + (nFanins) + 3, nFanins, pCube2 )
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DECLARATIONS ///
|
/// FUNCTION DECLARATIONS ///
|
||||||
|
|
|
||||||
|
|
@ -231,77 +231,6 @@ void Abc_NtkOrderFaninsByLitCountAndCubeCount( Abc_Ntk_t * pNtk )
|
||||||
Vec_StrFree( vStore );
|
Vec_StrFree( vStore );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
|
||||||
|
|
||||||
Synopsis [Checks if the network is SCC-free.]
|
|
||||||
|
|
||||||
Description []
|
|
||||||
|
|
||||||
SideEffects []
|
|
||||||
|
|
||||||
SeeAlso []
|
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
static inline int Abc_CubeContain( char * pCube1, char * pCube2, int nVars )
|
|
||||||
{
|
|
||||||
int v, fCont12 = 1, fCont21 = 1;
|
|
||||||
for ( v = 0; v < nVars; v++ )
|
|
||||||
{
|
|
||||||
if ( pCube1[v] == pCube2[v] )
|
|
||||||
continue;
|
|
||||||
if ( pCube1[v] == '-' )
|
|
||||||
fCont21 = 0;
|
|
||||||
else if ( pCube2[v] == '-' )
|
|
||||||
fCont12 = 0;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
if ( !fCont21 && !fCont21 )
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
assert( fCont21 || fCont12 );
|
|
||||||
return (fCont21 << 1) | fCont12;
|
|
||||||
}
|
|
||||||
int Abc_NodeMakeSCCFree( Abc_Obj_t * pNode, Vec_Ptr_t * vCubes )
|
|
||||||
{
|
|
||||||
char * pSop = (char *)pNode->pData;
|
|
||||||
char * pCube, * pCube2;
|
|
||||||
int i, k, Status, nCount = 0;
|
|
||||||
int nVars = Abc_ObjFaninNum(pNode);
|
|
||||||
Vec_PtrClear( vCubes );
|
|
||||||
Abc_SopForEachCube( pSop, nVars, pCube )
|
|
||||||
Vec_PtrPush( vCubes, pCube );
|
|
||||||
Vec_PtrForEachEntry( char *, vCubes, pCube, i )
|
|
||||||
if ( pCube != NULL )
|
|
||||||
Vec_PtrForEachEntryStart( char *, vCubes, pCube2, k, i+1 )
|
|
||||||
if ( pCube2 != NULL )
|
|
||||||
{
|
|
||||||
Status = Abc_CubeContain( pCube, pCube2, nVars );
|
|
||||||
nCount += (int)(Status > 0);
|
|
||||||
if ( Status & 1 )
|
|
||||||
Vec_PtrWriteEntry( vCubes, k, NULL );
|
|
||||||
else if ( Status & 2 )
|
|
||||||
Vec_PtrWriteEntry( vCubes, i, NULL );
|
|
||||||
}
|
|
||||||
if ( nCount == 0 )
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
void Abc_NtkMakeSCCFree( Abc_Ntk_t * pNtk )
|
|
||||||
{
|
|
||||||
Vec_Ptr_t * vCubes;
|
|
||||||
Abc_Obj_t * pNode;
|
|
||||||
int i;
|
|
||||||
assert( Abc_NtkHasSop(pNtk) );
|
|
||||||
vCubes = Vec_PtrAlloc( 1000 );
|
|
||||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
|
||||||
if ( Abc_NodeMakeSCCFree( pNode, vCubes ) )
|
|
||||||
{
|
|
||||||
printf( "Node %d is not SCC-free.\n", i );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Vec_PtrFree( vCubes );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Split large nodes by dividing their SOPs in half.]
|
Synopsis [Split large nodes by dividing their SOPs in half.]
|
||||||
|
|
@ -424,6 +353,123 @@ void Abc_NtkSortSops( Abc_Ntk_t * pNtk )
|
||||||
Abc_NtkSortCubes( pNtk );
|
Abc_NtkSortCubes( pNtk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Makes cover legitimate for "fast_extract".]
|
||||||
|
|
||||||
|
Description [Iteratively removes distance-1 and contained cubes.]
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline int Abc_CubeContain( char * pCube1, char * pCube2, int nVars )
|
||||||
|
{
|
||||||
|
int v, fCont12 = 1, fCont21 = 1;
|
||||||
|
for ( v = 0; v < nVars; v++ )
|
||||||
|
{
|
||||||
|
if ( pCube1[v] == pCube2[v] )
|
||||||
|
continue;
|
||||||
|
if ( pCube1[v] == '-' )
|
||||||
|
fCont21 = 0;
|
||||||
|
else if ( pCube2[v] == '-' )
|
||||||
|
fCont12 = 0;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
if ( !fCont21 && !fCont21 )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
assert( fCont21 || fCont12 );
|
||||||
|
return (fCont21 << 1) | fCont12;
|
||||||
|
}
|
||||||
|
int Abc_NodeMakeSCCFree( Abc_Obj_t * pNode )
|
||||||
|
{
|
||||||
|
char * pSop = (char *)pNode->pData;
|
||||||
|
char * pCube, * pCube2, * pSopNew;
|
||||||
|
int nVars = Abc_ObjFaninNum(pNode);
|
||||||
|
int Status, nCount = 0;
|
||||||
|
Abc_SopForEachCubePair( pSop, nVars, pCube, pCube2 )
|
||||||
|
{
|
||||||
|
if ( pCube[0] == 'z' || pCube2[0] == 'z' )
|
||||||
|
continue;
|
||||||
|
Status = Abc_CubeContain( pCube, pCube2, nVars );
|
||||||
|
nCount += (int)(Status > 0);
|
||||||
|
if ( Status & 1 )
|
||||||
|
pCube2[0] = 'z';
|
||||||
|
else if ( Status & 2 )
|
||||||
|
pCube[0] = 'z';
|
||||||
|
}
|
||||||
|
if ( nCount == 0 )
|
||||||
|
return 0;
|
||||||
|
// create new cover
|
||||||
|
pSopNew = (char *)pNode->pData;
|
||||||
|
Abc_SopForEachCube( pSop, nVars, pCube )
|
||||||
|
{
|
||||||
|
if ( pCube[0] == 'z' )
|
||||||
|
continue;
|
||||||
|
memcpy( pSopNew, pCube, nVars + 3 );
|
||||||
|
pSopNew += nVars + 3;
|
||||||
|
}
|
||||||
|
*pSopNew = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
void Abc_NodeMakeDist1Free( Abc_Obj_t * pNode )
|
||||||
|
{
|
||||||
|
char * pSop = (char *)pNode->pData;
|
||||||
|
char * pCube, * pCube2;
|
||||||
|
int i, nVars = Abc_ObjFaninNum(pNode);
|
||||||
|
Abc_SopForEachCube( pSop, nVars, pCube )
|
||||||
|
Abc_SopForEachCube( pCube + nVars + 3, nVars, pCube2 )
|
||||||
|
{
|
||||||
|
int Counter = 0, iDiff = -1;
|
||||||
|
for ( i = 0; i < nVars; i++ )
|
||||||
|
if ( pCube[i] != pCube2[i] )
|
||||||
|
Counter++, iDiff = i;
|
||||||
|
if ( Counter == 1 && ((pCube[iDiff] == '0' && pCube2[iDiff] == '1') || (pCube[iDiff] == '1' && pCube2[iDiff] == '0')) )
|
||||||
|
pCube[iDiff] = pCube2[iDiff] = '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Abc_NodeCheckDist1Free( Abc_Obj_t * pNode )
|
||||||
|
{
|
||||||
|
char * pSop = (char *)pNode->pData;
|
||||||
|
char * pCube, * pCube2;
|
||||||
|
int i, nVars = Abc_ObjFaninNum(pNode);
|
||||||
|
Abc_SopForEachCube( pSop, nVars, pCube )
|
||||||
|
Abc_SopForEachCube( pSop, nVars, pCube2 )
|
||||||
|
{
|
||||||
|
int Counter = 0;
|
||||||
|
if ( pCube == pCube2 )
|
||||||
|
continue;
|
||||||
|
for ( i = 0; i < nVars; i++ )
|
||||||
|
if ( pCube[i] != pCube2[i] )
|
||||||
|
Counter++;
|
||||||
|
assert( Counter > 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int Abc_NodeMakeLegit( Abc_Obj_t * pNode )
|
||||||
|
{
|
||||||
|
int i, fChanges = 1;
|
||||||
|
for ( i = 0; fChanges; i++ )
|
||||||
|
{
|
||||||
|
Abc_NodeMakeDist1Free( pNode );
|
||||||
|
fChanges = Abc_NodeMakeSCCFree( pNode );
|
||||||
|
}
|
||||||
|
// Abc_NodeCheckDist1Free( pNode );
|
||||||
|
return i > 1;
|
||||||
|
}
|
||||||
|
int Abc_NtkMakeLegit( Abc_Ntk_t * pNtk )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode;
|
||||||
|
int i, Counter = 0;
|
||||||
|
assert( Abc_NtkHasSop(pNtk) );
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
Counter += Abc_NodeMakeLegit( pNode );
|
||||||
|
if ( Counter )
|
||||||
|
Abc_Print( 1, "%d nodes were made dist1-cube-free and/or single-cube-containment-free.\n", Counter );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -9625,8 +9625,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
*/
|
*/
|
||||||
if ( pNtk )
|
if ( pNtk )
|
||||||
{
|
{
|
||||||
extern void Abc_NtkTestTim( Abc_Ntk_t * pNtk, int fVerbose );
|
extern void Abc_NtkMakeLegit( Abc_Ntk_t * pNtk );
|
||||||
Abc_NtkTestTim( pNtk, fVerbose );
|
Abc_NtkMakeLegit( pNtk );
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
usage:
|
usage:
|
||||||
|
|
|
||||||
|
|
@ -134,12 +134,14 @@ static inline int Fx_ManGetFirstVarCube( Fx_Man_t * p, Vec_Int_t * vCube ) { ret
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
Vec_Wec_t * Abc_NtkFxRetrieve( Abc_Ntk_t * pNtk )
|
Vec_Wec_t * Abc_NtkFxRetrieve( Abc_Ntk_t * pNtk )
|
||||||
{
|
{
|
||||||
|
extern int Abc_NtkMakeLegit( Abc_Ntk_t * pNtk );
|
||||||
Vec_Wec_t * vCubes;
|
Vec_Wec_t * vCubes;
|
||||||
Vec_Int_t * vCube;
|
Vec_Int_t * vCube;
|
||||||
Abc_Obj_t * pNode;
|
Abc_Obj_t * pNode;
|
||||||
char * pCube, * pSop;
|
char * pCube, * pSop;
|
||||||
int nVars, i, v, Lit;
|
int nVars, i, v, Lit;
|
||||||
assert( Abc_NtkIsSopLogic(pNtk) );
|
assert( Abc_NtkIsSopLogic(pNtk) );
|
||||||
|
Abc_NtkMakeLegit( pNtk );
|
||||||
vCubes = Vec_WecAlloc( 1000 );
|
vCubes = Vec_WecAlloc( 1000 );
|
||||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
{
|
{
|
||||||
|
|
@ -597,7 +599,7 @@ int Fx_ManDivFindCubeFree( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vCu
|
||||||
pBeg1++, pBeg2++, Counter++;
|
pBeg1++, pBeg2++, Counter++;
|
||||||
else if ( *pBeg1 < *pBeg2 )
|
else if ( *pBeg1 < *pBeg2 )
|
||||||
Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg1++, fAttr0) );
|
Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg1++, fAttr0) );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( Vec_IntSize(vCubeFree) == 0 )
|
if ( Vec_IntSize(vCubeFree) == 0 )
|
||||||
fAttr0 = 1, fAttr1 = 0;
|
fAttr0 = 1, fAttr1 = 0;
|
||||||
|
|
@ -608,7 +610,12 @@ int Fx_ManDivFindCubeFree( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vCu
|
||||||
Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg1++, fAttr0) );
|
Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg1++, fAttr0) );
|
||||||
while ( pBeg2 < pEnd2 )
|
while ( pBeg2 < pEnd2 )
|
||||||
Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg2++, fAttr1) );
|
Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg2++, fAttr1) );
|
||||||
assert( Vec_IntSize(vCubeFree) > 1 ); // the cover is not SCC-free
|
if ( Vec_IntSize(vCubeFree) == 0 )
|
||||||
|
printf( "The SOP has duplicated cubes.\n" );
|
||||||
|
else if ( Vec_IntSize(vCubeFree) == 1 )
|
||||||
|
printf( "The SOP has contained cubes.\n" );
|
||||||
|
else if ( Vec_IntSize(vCubeFree) == 2 && Abc_Lit2Var(Abc_Lit2Var(Vec_IntEntry(vCubeFree, 0))) == Abc_Lit2Var(Abc_Lit2Var(Vec_IntEntry(vCubeFree, 1))) )
|
||||||
|
printf( "The SOP has distance-1 cubes or it is not a prime cover. Please make sure the result verifies.\n" );
|
||||||
assert( !Abc_LitIsCompl(Vec_IntEntry(vCubeFree, 0)) );
|
assert( !Abc_LitIsCompl(Vec_IntEntry(vCubeFree, 0)) );
|
||||||
return Counter;
|
return Counter;
|
||||||
}
|
}
|
||||||
|
|
@ -807,7 +814,7 @@ void Fx_ManCubeDoubleCubeDivisors( Fx_Man_t * p, int iFirst, Vec_Int_t * vPivot,
|
||||||
else if ( !fRemove )
|
else if ( !fRemove )
|
||||||
Vec_QuePush( p->vPrio, iDiv );
|
Vec_QuePush( p->vPrio, iDiv );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Fx_ManCreateDivisors( Fx_Man_t * p )
|
void Fx_ManCreateDivisors( Fx_Man_t * p )
|
||||||
{
|
{
|
||||||
|
|
@ -936,6 +943,11 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
|
||||||
Fx_ManDivFindPivots( vDiv, &Lit0, &Lit1 );
|
Fx_ManDivFindPivots( vDiv, &Lit0, &Lit1 );
|
||||||
assert( Lit0 >= 0 && Lit1 >= 0 );
|
assert( Lit0 >= 0 && Lit1 >= 0 );
|
||||||
|
|
||||||
|
// if the input cover is not prime, it may happen that we are extracting divisor (x + !x)
|
||||||
|
// although it is not strictly correct, it seems to be fine to just skip such divisors
|
||||||
|
if ( Abc_Lit2Var(Lit0) == Abc_Lit2Var(Lit1) )
|
||||||
|
return;
|
||||||
|
|
||||||
// collect single-cube-divisor cubes
|
// collect single-cube-divisor cubes
|
||||||
Vec_IntClear( p->vCubesS );
|
Vec_IntClear( p->vCubesS );
|
||||||
if ( Vec_IntSize(vDiv) == 2 )
|
if ( Vec_IntSize(vDiv) == 2 )
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue