mirror of https://github.com/YosysHQ/abc.git
267 lines
7.9 KiB
C
267 lines
7.9 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [ Fxch.c ]
|
|
|
|
PackageName [ Fast eXtract with Cube Hashing (FXCH) ]
|
|
|
|
Synopsis [ The entrance into the fast extract module. ]
|
|
|
|
Author [ Bruno Schmitt - boschmitt at inf.ufrgs.br ]
|
|
|
|
Affiliation [ UFRGS ]
|
|
|
|
Date [ Ver. 1.0. Started - March 6, 2016. ]
|
|
|
|
Revision []
|
|
|
|
***********************************************************************/
|
|
#include "Fxch.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxch_CubesGruping(Fxch_Man_t* pFxchMan)
|
|
{
|
|
Vec_Int_t* vCube;
|
|
int iCube, nOutputs, SizeOutputID;
|
|
Hsh_VecMan_t* pCubeHash;
|
|
|
|
/* Identify the number of Outputs and create the translation table */
|
|
pFxchMan->vTranslation = Vec_IntAlloc( 32 );
|
|
Vec_WecForEachLevel( pFxchMan->vCubes, vCube, iCube )
|
|
{
|
|
int Id = Vec_IntEntry( vCube, 0 );
|
|
int iTranslation = Vec_IntFind( pFxchMan->vTranslation, Id );
|
|
|
|
if ( iTranslation == -1 )
|
|
Vec_IntPush( pFxchMan->vTranslation, Id );
|
|
}
|
|
nOutputs = Vec_IntSize( pFxchMan->vTranslation );
|
|
|
|
/* Size of the OutputID in number o ints */
|
|
SizeOutputID = ( nOutputs >> 5 ) + ( ( nOutputs & 31 ) > 0 );
|
|
|
|
/* Initialize needed structures */
|
|
pFxchMan->vOutputID = Vec_IntAlloc( 4096 );
|
|
pFxchMan->pTempOutputID = ABC_CALLOC( int, SizeOutputID );
|
|
pFxchMan->nSizeOutputID = SizeOutputID;
|
|
|
|
pCubeHash = Hsh_VecManStart( 1024 );
|
|
|
|
/* Identify equal cubes */
|
|
Vec_WecForEachLevel( pFxchMan->vCubes, vCube, iCube )
|
|
{
|
|
int Id = Vec_IntEntry( vCube, 0 );
|
|
int iTranslation = Vec_IntFind( pFxchMan->vTranslation, Id );
|
|
int i, iCubeNoID, Temp, * pEntry;
|
|
Vec_IntWriteEntry( vCube, 0, 0 ); // Clear ID, Outputs will be identified by it later
|
|
|
|
iCubeNoID = Hsh_VecManAdd( pCubeHash, vCube );
|
|
Temp = ( 1 << ( iTranslation & 31 ) );
|
|
if ( iCubeNoID == Vec_IntSize( pFxchMan->vOutputID ) / SizeOutputID )
|
|
{
|
|
for ( i = 0; i < SizeOutputID; i++ )
|
|
pFxchMan->pTempOutputID[i] = 0;
|
|
|
|
pFxchMan->pTempOutputID[ iTranslation >> 5 ] = Temp;
|
|
Vec_IntPushArray( pFxchMan->vOutputID, pFxchMan->pTempOutputID, SizeOutputID );
|
|
}
|
|
else
|
|
{
|
|
Vec_IntClear( vCube );
|
|
pEntry = Vec_IntEntryP( pFxchMan->vOutputID, ( iCubeNoID * SizeOutputID ) + ( iTranslation >> 5 ) );
|
|
*pEntry |= Temp;
|
|
}
|
|
}
|
|
|
|
Hsh_VecManStop( pCubeHash );
|
|
Vec_WecRemoveEmpty( pFxchMan->vCubes );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxch_CubesUnGruping(Fxch_Man_t* pFxchMan)
|
|
{
|
|
int iCube;
|
|
int i, j;
|
|
Vec_Int_t* vCube;
|
|
Vec_Int_t* vNewCube;
|
|
|
|
assert( Vec_WecSize( pFxchMan->vCubes ) == ( Vec_IntSize( pFxchMan->vOutputID ) / pFxchMan->nSizeOutputID ) );
|
|
Vec_WecForEachLevel( pFxchMan->vCubes, vCube, iCube )
|
|
{
|
|
int * pOutputID, nOnes;
|
|
if ( Vec_IntSize( vCube ) == 0 || Vec_IntEntry( vCube, 0 ) != 0 )
|
|
continue;
|
|
|
|
pOutputID = Vec_IntEntryP( pFxchMan->vOutputID, iCube * pFxchMan->nSizeOutputID );
|
|
nOnes = 0;
|
|
|
|
for ( i = 0; i < pFxchMan->nSizeOutputID; i++ )
|
|
nOnes += Fxch_CountOnes( (unsigned int) pOutputID[i] );
|
|
|
|
for ( i = 0; i < pFxchMan->nSizeOutputID && nOnes; i++ )
|
|
for ( j = 0; j < 32 && nOnes; j++ )
|
|
if ( pOutputID[i] & ( 1 << j ) )
|
|
{
|
|
if ( nOnes == 1 )
|
|
Vec_IntWriteEntry( vCube, 0, Vec_IntEntry( pFxchMan->vTranslation, ( i << 5 ) | j ) );
|
|
else
|
|
{
|
|
vNewCube = Vec_WecPushLevel( pFxchMan->vCubes );
|
|
Vec_IntAppend( vNewCube, vCube );
|
|
Vec_IntWriteEntry( vNewCube, 0, Vec_IntEntry( pFxchMan->vTranslation, (i << 5 ) | j ) );
|
|
}
|
|
nOnes -= 1;
|
|
}
|
|
}
|
|
|
|
Vec_IntFree( pFxchMan->vTranslation );
|
|
Vec_IntFree( pFxchMan->vOutputID );
|
|
ABC_FREE( pFxchMan->pTempOutputID );
|
|
return;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [ Performs fast extract with cube hashing on a set
|
|
of covers. ]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Fxch_FastExtract( Vec_Wec_t* vCubes,
|
|
int ObjIdMax,
|
|
int nMaxDivExt,
|
|
int fVerbose,
|
|
int fVeryVerbose )
|
|
{
|
|
abctime TempTime;
|
|
Fxch_Man_t* pFxchMan = Fxch_ManAlloc( vCubes );
|
|
int i;
|
|
|
|
TempTime = Abc_Clock();
|
|
Fxch_CubesGruping( pFxchMan );
|
|
Fxch_ManMapLiteralsIntoCubes( pFxchMan, ObjIdMax );
|
|
Fxch_ManGenerateLitHashKeys( pFxchMan );
|
|
Fxch_ManComputeLevel( pFxchMan );
|
|
Fxch_ManSCHashTablesInit( pFxchMan );
|
|
Fxch_ManDivCreate( pFxchMan );
|
|
pFxchMan->timeInit = Abc_Clock() - TempTime;
|
|
|
|
if ( fVeryVerbose )
|
|
Fxch_ManPrintDivs( pFxchMan );
|
|
|
|
if ( fVerbose )
|
|
Fxch_ManPrintStats( pFxchMan );
|
|
|
|
TempTime = Abc_Clock();
|
|
|
|
for ( i = 0; (!nMaxDivExt || i < nMaxDivExt) && Vec_QueTopPriority( pFxchMan->vDivPrio ) > 0.0; i++ )
|
|
{
|
|
int iDiv = Vec_QuePop( pFxchMan->vDivPrio );
|
|
|
|
if ( fVeryVerbose )
|
|
Fxch_DivPrint( pFxchMan, iDiv );
|
|
|
|
Fxch_ManUpdate( pFxchMan, iDiv );
|
|
}
|
|
|
|
pFxchMan->timeExt = Abc_Clock() - TempTime;
|
|
|
|
if ( fVerbose )
|
|
{
|
|
Fxch_ManPrintStats( pFxchMan );
|
|
Abc_PrintTime( 1, "\n[FXCH] Elapsed Time", pFxchMan->timeInit + pFxchMan->timeExt );
|
|
Abc_PrintTime( 1, "[FXCH] +-> Init", pFxchMan->timeInit );
|
|
Abc_PrintTime( 1, "[FXCH] +-> Extr", pFxchMan->timeExt );
|
|
}
|
|
|
|
Fxch_CubesUnGruping( pFxchMan );
|
|
Fxch_ManSCHashTablesFree( pFxchMan );
|
|
Fxch_ManFree( pFxchMan );
|
|
|
|
Vec_WecRemoveEmpty( vCubes );
|
|
Vec_WecSortByFirstInt( vCubes, 0 );
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [ Retrives the necessary information for the fast extract
|
|
with cube hashing. ]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkFxchPerform( Abc_Ntk_t* pNtk,
|
|
int nMaxDivExt,
|
|
int fVerbose,
|
|
int fVeryVerbose )
|
|
{
|
|
Vec_Wec_t* vCubes;
|
|
|
|
assert( Abc_NtkIsSopLogic( pNtk ) );
|
|
|
|
if ( !Abc_NtkFxCheck( pNtk ) )
|
|
{
|
|
printf( "Abc_NtkFxchPerform(): Nodes have duplicated fanins. FXCH is not performed.\n" );
|
|
return 0;
|
|
}
|
|
|
|
vCubes = Abc_NtkFxRetrieve( pNtk );
|
|
if ( Fxch_FastExtract( vCubes, Abc_NtkObjNumMax( pNtk ), nMaxDivExt, fVerbose, fVeryVerbose ) > 0 )
|
|
{
|
|
Abc_NtkFxInsert( pNtk, vCubes );
|
|
Vec_WecFree( vCubes );
|
|
|
|
if ( !Abc_NtkCheck( pNtk ) )
|
|
printf( "Abc_NtkFxchPerform(): The network check has failed.\n" );
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
printf( "Warning: The network has not been changed by \"fxch\".\n" );
|
|
|
|
Vec_WecFree( vCubes );
|
|
|
|
return 0;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
ABC_NAMESPACE_IMPL_END
|