mirror of https://github.com/YosysHQ/abc.git
Merge remote-tracking branch 'upstream' into yosys-experimental
This commit is contained in:
commit
476b31cac5
|
|
@ -33,6 +33,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||||
|
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||||
|
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,14 @@ ReleaseExt/
|
||||||
|
|
||||||
_/
|
_/
|
||||||
_TEST/
|
_TEST/
|
||||||
|
tools/
|
||||||
|
temp/
|
||||||
lib/abc*
|
lib/abc*
|
||||||
lib/m114*
|
lib/m114*
|
||||||
lib/bip*
|
lib/bip*
|
||||||
docs/
|
docs/
|
||||||
.cache/
|
.cache/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
src/ext*
|
src/ext*
|
||||||
src/xxx/
|
src/xxx/
|
||||||
|
|
|
||||||
|
|
@ -443,6 +443,10 @@ SOURCE=.\src\base\abci\abcResub.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\base\abci\abcRmInverters.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\src\base\abci\abcRewrite.c
|
SOURCE=.\src\base\abci\abcRewrite.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
|
||||||
|
|
@ -685,16 +685,16 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
||||||
if ( fVerbose ) printf( "Finished reading extension \"o\".\n" );
|
if ( fVerbose ) printf( "Finished reading extension \"o\".\n" );
|
||||||
}
|
}
|
||||||
// read equivalence classes
|
// read equivalence classes
|
||||||
else if ( *pCur == 'e' )
|
//else if ( *pCur == 'e' )
|
||||||
{
|
//{
|
||||||
extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
|
// extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
|
||||||
pCur++;
|
// pCur++;
|
||||||
pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
|
// pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
|
||||||
pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
|
// pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
|
||||||
pNew->pNexts = Gia_ManDeriveNexts( pNew );
|
// pNew->pNexts = Gia_ManDeriveNexts( pNew );
|
||||||
assert( pCur == pCurTemp );
|
// assert( pCur == pCurTemp );
|
||||||
if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
|
// if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
|
||||||
}
|
//}
|
||||||
// read flop classes
|
// read flop classes
|
||||||
else if ( *pCur == 'f' )
|
else if ( *pCur == 'f' )
|
||||||
{
|
{
|
||||||
|
|
@ -1582,15 +1582,15 @@ void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// write equivalences
|
// write equivalences
|
||||||
if ( p->pReprs && p->pNexts )
|
//if ( p->pReprs && p->pNexts )
|
||||||
{
|
//{
|
||||||
extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
|
// extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
|
||||||
fprintf( pFile, "e" );
|
// fprintf( pFile, "e" );
|
||||||
vStrExt = Gia_WriteEquivClasses( p );
|
// vStrExt = Gia_WriteEquivClasses( p );
|
||||||
Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
|
// Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
|
||||||
fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
|
// fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
|
||||||
Vec_StrFree( vStrExt );
|
// Vec_StrFree( vStrExt );
|
||||||
}
|
//}
|
||||||
// write flop classes
|
// write flop classes
|
||||||
if ( p->vFlopClasses )
|
if ( p->vFlopClasses )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,229 @@ Gia_Man_t * Gia_ManRandSyn( Gia_Man_t * p, unsigned random_seed )
|
||||||
return pRes;
|
return pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static void Gia_ManDeepSynParetoUpdate( Vec_Ptr_t * vPareto, Gia_Man_t * pCand, int nLevels, int nAnds )
|
||||||
|
{
|
||||||
|
Gia_Man_t * pBest = (Gia_Man_t *)Vec_PtrGetEntry( vPareto, nLevels );
|
||||||
|
if ( pBest == NULL || Gia_ManAndNum(pBest) > nAnds )
|
||||||
|
{
|
||||||
|
if ( pBest )
|
||||||
|
Gia_ManStop( pBest );
|
||||||
|
Vec_PtrSetEntry( vPareto, nLevels, Gia_ManDup(pCand) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Gia_ManDeepSynParetoPrint( Vec_Ptr_t * vPareto )
|
||||||
|
{
|
||||||
|
Gia_Man_t * pTemp;
|
||||||
|
int i, fFirst = 1;
|
||||||
|
printf( "Pareto points:" );
|
||||||
|
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
|
||||||
|
{
|
||||||
|
if ( pTemp == NULL )
|
||||||
|
continue;
|
||||||
|
printf( "%s%d:%d", fFirst ? " " : " ", i, Gia_ManAndNum(pTemp) );
|
||||||
|
fFirst = 0;
|
||||||
|
}
|
||||||
|
if ( fFirst )
|
||||||
|
printf( " none" );
|
||||||
|
printf( "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Gia_ManDeepSynParetoSave( Vec_Ptr_t * vPareto, char * pBase )
|
||||||
|
{
|
||||||
|
Gia_Man_t * pTemp;
|
||||||
|
char FileName[1000];
|
||||||
|
int i;
|
||||||
|
if ( pBase == NULL )
|
||||||
|
pBase = Extra_UtilStrsav( "gia" );
|
||||||
|
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
|
||||||
|
{
|
||||||
|
if ( pTemp == NULL )
|
||||||
|
continue;
|
||||||
|
sprintf( FileName, "%s_%d_%d.aig", pBase, i, Gia_ManAndNum(pTemp) );
|
||||||
|
Gia_AigerWrite( pTemp, FileName, 0, 0, 0 );
|
||||||
|
}
|
||||||
|
ABC_FREE( pBase );
|
||||||
|
}
|
||||||
|
|
||||||
|
Gia_Man_t * Gia_ManDeepSynOne2( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose, Vec_Ptr_t * vGias, Vec_Ptr_t * vPareto )
|
||||||
|
{
|
||||||
|
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
|
||||||
|
abctime clkStart = Abc_Clock();
|
||||||
|
int s, i, k, IterMax = 100000, nLevelsMin = -1, nAndsMin = -1;
|
||||||
|
int nNoImprCount = 0;
|
||||||
|
Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||||
|
Gia_Man_t * pNew = Gia_ManDup( pTemp );
|
||||||
|
(void)fUseTwo;
|
||||||
|
Abc_Random(1);
|
||||||
|
for ( s = 0; s < 10+Seed; s++ )
|
||||||
|
Abc_Random(0);
|
||||||
|
nLevelsMin = Gia_ManLevelNum(pNew);
|
||||||
|
nAndsMin = Gia_ManAndNum(pNew);
|
||||||
|
for ( i = 0; i < IterMax; )
|
||||||
|
{
|
||||||
|
unsigned Rand = Abc_Random(0);
|
||||||
|
int fDch = Rand & 1;
|
||||||
|
int fResyn = (Rand >> 1) % 3;
|
||||||
|
int fChange = 0;
|
||||||
|
char Command[2000];
|
||||||
|
char pResyn[200];
|
||||||
|
if ( fResyn == 0 )
|
||||||
|
sprintf( pResyn, "&resyn3" );
|
||||||
|
else if ( fResyn == 1 )
|
||||||
|
sprintf( pResyn, "&resyn3rs" );
|
||||||
|
else
|
||||||
|
sprintf( pResyn, "&resyn3; &resyn3rs" );
|
||||||
|
sprintf( Command, "&dch%s; &if -y -K 6; %s", fDch ? " -f" : "", pResyn );
|
||||||
|
if ( Abc_FrameIsBatchMode() )
|
||||||
|
{
|
||||||
|
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||||
|
{
|
||||||
|
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Abc_FrameSetBatchMode( 1 );
|
||||||
|
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||||
|
{
|
||||||
|
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Abc_FrameSetBatchMode( 0 );
|
||||||
|
}
|
||||||
|
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||||
|
{
|
||||||
|
int nLevelTemp = Gia_ManLevelNum(pTemp);
|
||||||
|
int nAndsTemp = Gia_ManAndNum(pTemp);
|
||||||
|
if ( vPareto )
|
||||||
|
Gia_ManDeepSynParetoUpdate( vPareto, pTemp, nLevelTemp, nAndsTemp );
|
||||||
|
if ( nLevelsMin > nLevelTemp || (nLevelsMin == nLevelTemp && nAndsMin > nAndsTemp) )
|
||||||
|
{
|
||||||
|
Gia_ManStop( pNew );
|
||||||
|
pNew = Gia_ManDup( pTemp );
|
||||||
|
nLevelsMin = nLevelTemp;
|
||||||
|
nAndsMin = nAndsTemp;
|
||||||
|
fChange = 1;
|
||||||
|
if ( vGias )
|
||||||
|
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
|
||||||
|
nNoImprCount = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nNoImprCount++;
|
||||||
|
}
|
||||||
|
if ( fChange && fVerbose )
|
||||||
|
{
|
||||||
|
printf( "Iter %6d : ", i );
|
||||||
|
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||||
|
printf( "Lev = %3d ", nLevelsMin );
|
||||||
|
printf( "And = %6d ", nAndsMin );
|
||||||
|
printf( "<== best : " );
|
||||||
|
printf( "%s", Command );
|
||||||
|
printf( "\n" );
|
||||||
|
}
|
||||||
|
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||||
|
{
|
||||||
|
if ( !Abc_FrameIsBatchMode() )
|
||||||
|
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if ( nNoImprCount > nNoImpr )
|
||||||
|
{
|
||||||
|
int nOuter = 1 + (Abc_Random(0) % 3);
|
||||||
|
int nKmax = nAnds ? nAnds : 6;
|
||||||
|
int nKmin = 3;
|
||||||
|
int nLuts[3];
|
||||||
|
if ( nKmax < nKmin )
|
||||||
|
nKmin = nKmax;
|
||||||
|
for ( k = 0; k < nOuter; k++ )
|
||||||
|
nLuts[k] = nKmin + (Abc_Random(0) % (nKmax - nKmin + 1));
|
||||||
|
if ( fVerbose )
|
||||||
|
{
|
||||||
|
printf( "Completed %d iterations without improvement. Trying %d outer iterations with ", nNoImpr, nOuter );
|
||||||
|
for ( k = 0; k < nOuter; k++ )
|
||||||
|
printf( "%sK=%d", k ? ", " : "", nLuts[k] );
|
||||||
|
printf( ". Time = %.2f sec\n", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||||
|
}
|
||||||
|
nNoImprCount = 0;
|
||||||
|
for ( k = 0; k < nOuter && i < IterMax; k++ )
|
||||||
|
{
|
||||||
|
int nLut = nLuts[k];
|
||||||
|
int fOuterChange = 0;
|
||||||
|
sprintf( Command, "&dch; &if -K %d -m; &mfs; &st", nLut );
|
||||||
|
if ( Abc_FrameIsBatchMode() )
|
||||||
|
{
|
||||||
|
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||||
|
{
|
||||||
|
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Abc_FrameSetBatchMode( 1 );
|
||||||
|
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||||
|
{
|
||||||
|
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Abc_FrameSetBatchMode( 0 );
|
||||||
|
}
|
||||||
|
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||||
|
{
|
||||||
|
int nLevelTemp = Gia_ManLevelNum(pTemp);
|
||||||
|
int nAndsTemp = Gia_ManAndNum(pTemp);
|
||||||
|
if ( vPareto )
|
||||||
|
Gia_ManDeepSynParetoUpdate( vPareto, pTemp, nLevelTemp, nAndsTemp );
|
||||||
|
if ( nLevelsMin > nLevelTemp || (nLevelsMin == nLevelTemp && nAndsMin > nAndsTemp) )
|
||||||
|
{
|
||||||
|
Gia_ManStop( pNew );
|
||||||
|
pNew = Gia_ManDup( pTemp );
|
||||||
|
nLevelsMin = nLevelTemp;
|
||||||
|
nAndsMin = nAndsTemp;
|
||||||
|
fOuterChange = 1;
|
||||||
|
if ( vGias )
|
||||||
|
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( fOuterChange && fVerbose )
|
||||||
|
{
|
||||||
|
printf( "Iter %6d : ", i );
|
||||||
|
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||||
|
printf( "Lev = %3d ", nLevelsMin );
|
||||||
|
printf( "And = %6d ", nAndsMin );
|
||||||
|
printf( "<== best : " );
|
||||||
|
printf( "%s", Command );
|
||||||
|
printf( "\n" );
|
||||||
|
}
|
||||||
|
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||||
|
{
|
||||||
|
if ( !Abc_FrameIsBatchMode() )
|
||||||
|
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( i == IterMax )
|
||||||
|
printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
@ -251,7 +474,84 @@ Gia_Man_t * Gia_ManRandSyn( Gia_Man_t * p, unsigned random_seed )
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
Gia_Man_t * Gia_ManDeepSyn2( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fChoices, int fVerbose )
|
Gia_Man_t * Gia_ManDeepSyn2( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fChoices, int fVerbose )
|
||||||
{
|
{
|
||||||
return Gia_ManDeepSyn( pGia, nIters, nNoImpr, TimeOut, nAnds, Seed, fUseTwo, fChoices, fVerbose );
|
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc(100) : NULL;
|
||||||
|
Vec_Ptr_t * vPareto = fUseTwo ? Vec_PtrStart(100) : NULL;
|
||||||
|
char * pParetoBase = NULL;
|
||||||
|
Gia_Man_t * pInit;
|
||||||
|
Gia_Man_t * pBest;
|
||||||
|
Gia_Man_t * pThis;
|
||||||
|
int i, nBestLev, nBestAnd;
|
||||||
|
if ( !Abc_NtkRecIsRunning3() )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Gia_ManDeepSyn2(): LMS library is not loaded.\n" );
|
||||||
|
Abc_Print( -1, "Download \"rec6Lib_final_filtered3_recanon.aig\" and run \"rec_start3 _/rec6Lib_final_filtered3_recanon.aig\".\n" );
|
||||||
|
if ( vGias )
|
||||||
|
Vec_PtrFree( vGias );
|
||||||
|
if ( vPareto )
|
||||||
|
Vec_PtrFree( vPareto );
|
||||||
|
return Gia_ManDup( pGia );
|
||||||
|
}
|
||||||
|
if ( vPareto )
|
||||||
|
{
|
||||||
|
if ( pGia->pSpec && pGia->pSpec[0] )
|
||||||
|
pParetoBase = Extra_FileNameGeneric( pGia->pSpec );
|
||||||
|
else if ( pGia->pName && pGia->pName[0] )
|
||||||
|
pParetoBase = Extra_FileNameGeneric( pGia->pName );
|
||||||
|
else
|
||||||
|
pParetoBase = Extra_UtilStrsav( "gia" );
|
||||||
|
}
|
||||||
|
pInit = Gia_ManDup(pGia);
|
||||||
|
pBest = Gia_ManDup(pGia);
|
||||||
|
nBestLev = Gia_ManLevelNum(pBest);
|
||||||
|
nBestAnd = Gia_ManAndNum(pBest);
|
||||||
|
if ( vPareto )
|
||||||
|
Gia_ManDeepSynParetoUpdate( vPareto, pGia, nBestLev, nBestAnd );
|
||||||
|
if ( vGias )
|
||||||
|
Vec_PtrPush( vGias, Gia_ManDup(pGia) );
|
||||||
|
for ( i = 0; i < nIters; i++ )
|
||||||
|
{
|
||||||
|
if ( fVerbose )
|
||||||
|
printf( "ITER %d (out of %d) running for %d seconds\n", i + 1, nIters, TimeOut );
|
||||||
|
int nThisLev, nThisAnd;
|
||||||
|
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
|
||||||
|
pThis = Gia_ManDeepSynOne2( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose, vGias, vPareto );
|
||||||
|
nThisLev = Gia_ManLevelNum(pThis);
|
||||||
|
nThisAnd = Gia_ManAndNum(pThis);
|
||||||
|
if ( nBestLev > nThisLev || (nBestLev == nThisLev && nBestAnd > nThisAnd) )
|
||||||
|
{
|
||||||
|
Gia_ManStop( pBest );
|
||||||
|
pBest = pThis;
|
||||||
|
nBestLev = nThisLev;
|
||||||
|
nBestAnd = nThisAnd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Gia_ManStop( pThis );
|
||||||
|
if ( vPareto )
|
||||||
|
Gia_ManDeepSynParetoPrint( vPareto );
|
||||||
|
}
|
||||||
|
Gia_ManStop( pInit );
|
||||||
|
if ( vGias) {
|
||||||
|
if ( Vec_PtrSize(vGias) > 1 ) {
|
||||||
|
extern Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose );
|
||||||
|
Gia_ManStopP( &pBest );
|
||||||
|
pBest = Gia_ManCreateChoicesArray( vGias, fVerbose );
|
||||||
|
}
|
||||||
|
// cleanup
|
||||||
|
Gia_Man_t * pTemp;
|
||||||
|
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
|
||||||
|
Gia_ManStop( pTemp );
|
||||||
|
Vec_PtrFree( vGias );
|
||||||
|
}
|
||||||
|
if ( vPareto )
|
||||||
|
{
|
||||||
|
Gia_ManDeepSynParetoSave( vPareto, pParetoBase );
|
||||||
|
Gia_Man_t * pTemp;
|
||||||
|
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
|
||||||
|
if ( pTemp )
|
||||||
|
Gia_ManStop( pTemp );
|
||||||
|
Vec_PtrFree( vPareto );
|
||||||
|
}
|
||||||
|
return pBest;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -260,4 +560,3 @@ Gia_Man_t * Gia_ManDeepSyn2( Gia_Man_t * pGia, int nIters, int nNoImpr, int Time
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -640,6 +640,8 @@ static inline int Sbl_CutIsFeasible( word CutI1, word CutI2, word CutN1, word Cu
|
||||||
if ( LutSize <= 4 )
|
if ( LutSize <= 4 )
|
||||||
return Count <= 4;
|
return Count <= 4;
|
||||||
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
||||||
|
if ( LutSize <= 5 )
|
||||||
|
return Count <= 5;
|
||||||
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
||||||
return Count <= 6;
|
return Count <= 6;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p )
|
||||||
if ( p->pListFree == NULL )
|
if ( p->pListFree == NULL )
|
||||||
Hop_ManAddMemory( p );
|
Hop_ManAddMemory( p );
|
||||||
pTemp = p->pListFree;
|
pTemp = p->pListFree;
|
||||||
p->pListFree = *((Hop_Obj_t **)pTemp);
|
memcpy(&p->pListFree, pTemp, sizeof(Hop_Obj_t *));
|
||||||
memset( pTemp, 0, sizeof(Hop_Obj_t) );
|
memset( pTemp, 0, sizeof(Hop_Obj_t) );
|
||||||
if ( p->vObjs )
|
if ( p->vObjs )
|
||||||
{
|
{
|
||||||
|
|
@ -245,8 +245,8 @@ static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p )
|
||||||
}
|
}
|
||||||
static inline void Hop_ManRecycleMemory( Hop_Man_t * p, Hop_Obj_t * pEntry )
|
static inline void Hop_ManRecycleMemory( Hop_Man_t * p, Hop_Obj_t * pEntry )
|
||||||
{
|
{
|
||||||
pEntry->Type = AIG_NONE; // distinquishes dead node from live node
|
pEntry->Type = AIG_NONE; // distinguishes dead node from live node
|
||||||
*((Hop_Obj_t **)pEntry) = p->pListFree;
|
memcpy(pEntry, &p->pListFree, sizeof(Hop_Obj_t *));
|
||||||
p->pListFree = pEntry;
|
p->pListFree = pEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,13 +88,15 @@ void Hop_ManStopMemory( Hop_Man_t * p )
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
void Hop_ManAddMemory( Hop_Man_t * p )
|
void Hop_ManAddMemory( Hop_Man_t * p )
|
||||||
{
|
{
|
||||||
char * pMemory;
|
char * pMemory = 0;
|
||||||
|
Hop_Obj_t * pEntry, * pNext;
|
||||||
int i, nBytes;
|
int i, nBytes;
|
||||||
assert( sizeof(Hop_Obj_t) <= 64 );
|
assert( sizeof(Hop_Obj_t) <= 64 );
|
||||||
assert( p->pListFree == NULL );
|
assert( p->pListFree == NULL );
|
||||||
// assert( (Hop_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
|
// assert( (Hop_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
|
||||||
// allocate new memory page
|
// allocate new memory page
|
||||||
nBytes = sizeof(Hop_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
|
nBytes = sizeof(Hop_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
|
||||||
|
pMemory = pMemory + 64 - (((int)(ABC_PTRUINT_T)pMemory) & 63);
|
||||||
pMemory = ABC_ALLOC( char, nBytes );
|
pMemory = ABC_ALLOC( char, nBytes );
|
||||||
Vec_PtrPush( p->vChunks, pMemory );
|
Vec_PtrPush( p->vChunks, pMemory );
|
||||||
// align memory at the 32-byte boundary
|
// align memory at the 32-byte boundary
|
||||||
|
|
@ -102,13 +104,16 @@ void Hop_ManAddMemory( Hop_Man_t * p )
|
||||||
// remember the manager in the first entry
|
// remember the manager in the first entry
|
||||||
Vec_PtrPush( p->vPages, pMemory );
|
Vec_PtrPush( p->vPages, pMemory );
|
||||||
// break the memory down into nodes
|
// break the memory down into nodes
|
||||||
p->pListFree = (Hop_Obj_t *)pMemory;
|
pEntry = (Hop_Obj_t *)pMemory;
|
||||||
|
p->pListFree = pEntry;
|
||||||
for ( i = 1; i <= IVY_PAGE_MASK; i++ )
|
for ( i = 1; i <= IVY_PAGE_MASK; i++ )
|
||||||
{
|
{
|
||||||
*((char **)pMemory) = pMemory + sizeof(Hop_Obj_t);
|
pNext = pEntry + 1;
|
||||||
pMemory += sizeof(Hop_Obj_t);
|
memcpy( pEntry, &pNext, sizeof(Hop_Obj_t *) );
|
||||||
|
pEntry++;
|
||||||
}
|
}
|
||||||
*((char **)pMemory) = NULL;
|
pNext = NULL;
|
||||||
|
memcpy( pEntry, &pNext, sizeof(Hop_Obj_t *) );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ struct Abc_Obj_t_ // 48/72 bytes (32-bits/64-bits)
|
||||||
unsigned Level : 20; // the level of the node
|
unsigned Level : 20; // the level of the node
|
||||||
Vec_Int_t vFanins; // the array of fanins
|
Vec_Int_t vFanins; // the array of fanins
|
||||||
Vec_Int_t vFanouts; // the array of fanouts
|
Vec_Int_t vFanouts; // the array of fanouts
|
||||||
|
void * pDataComp;
|
||||||
union { void * pData; // the network specific data
|
union { void * pData; // the network specific data
|
||||||
int iData; }; // (SOP, BDD, gate, equiv class, etc)
|
int iData; }; // (SOP, BDD, gate, equiv class, etc)
|
||||||
union { void * pTemp; // temporary store for user's data
|
union { void * pTemp; // temporary store for user's data
|
||||||
|
|
@ -620,6 +621,7 @@ extern ABC_DLL float Abc_NtkDelayTraceLut( Abc_Ntk_t * pNtk, int fU
|
||||||
/*=== abcDfs.c ==========================================================*/
|
/*=== abcDfs.c ==========================================================*/
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk );
|
||||||
|
extern ABC_DLL void Abc_NtkDfsSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSup, int iVerbose);
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||||
|
|
@ -885,6 +887,8 @@ extern ABC_DLL int Abc_NodeRef_rec( Abc_Obj_t * pNode );
|
||||||
extern ABC_DLL int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nMinSaved, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose );
|
extern ABC_DLL int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nMinSaved, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose );
|
||||||
/*=== abcRewrite.c ==========================================================*/
|
/*=== abcRewrite.c ==========================================================*/
|
||||||
extern ABC_DLL int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable );
|
extern ABC_DLL int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable );
|
||||||
|
/*=== abcRmInverters.c ======================================================*/
|
||||||
|
extern ABC_DLL void Abc_NtkRmInverter(Abc_Ntk_t * pNtk, int iVerbose);
|
||||||
/*=== abcSat.c ==========================================================*/
|
/*=== abcSat.c ==========================================================*/
|
||||||
extern ABC_DLL int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects );
|
extern ABC_DLL int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects );
|
||||||
extern ABC_DLL void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes );
|
extern ABC_DLL void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes );
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "abc.h"
|
#include "abc.h"
|
||||||
|
#include "misc/vec/vecPtr.h"
|
||||||
#include "proof/cec/cec.h"
|
#include "proof/cec/cec.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_START
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
@ -137,6 +138,101 @@ Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk )
|
||||||
return vNodes;
|
return vNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Collect support nodes bounded internal nodes.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkDfsSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSup, int iVerbose)
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanin;
|
||||||
|
int i;
|
||||||
|
assert( !Abc_ObjIsNet(pNode) );
|
||||||
|
if ( Abc_NodeIsTravIdCurrent( pNode ) )
|
||||||
|
return;
|
||||||
|
Abc_NodeSetTravIdCurrent( pNode );
|
||||||
|
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsCo(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
|
||||||
|
return;
|
||||||
|
if( Vec_PtrFind(vSup, pNode) >= 0 )
|
||||||
|
{
|
||||||
|
if(iVerbose)
|
||||||
|
{
|
||||||
|
printf("Encountered vSup Node: %s\n", Abc_ObjName(pNode));
|
||||||
|
printf("Whose fanins are:\n");
|
||||||
|
printf(" Fanin0: %s", Abc_ObjName(Abc_ObjFanin0(pNode)));
|
||||||
|
printf(" %d on comp\n", pNode->fCompl0);
|
||||||
|
printf(" Fanin1: %s", Abc_ObjName(Abc_ObjFanin1(pNode)));
|
||||||
|
printf(" %d on comp\n", pNode->fCompl1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert( Abc_ObjIsNode( pNode ) );
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||||
|
{
|
||||||
|
if(iVerbose)
|
||||||
|
{
|
||||||
|
printf(" Node %s Fanin %d: ", Abc_ObjName(pNode), i);
|
||||||
|
printf("%s", Abc_ObjName(pFanin));
|
||||||
|
printf(" %d on comp\n", i == 0 ? pNode->fCompl0 : pNode->fCompl1);
|
||||||
|
}
|
||||||
|
Abc_NtkDfsSup_rec( Abc_ObjFanin0Ntk(pFanin), vNodes, vSup, iVerbose);
|
||||||
|
}
|
||||||
|
Vec_PtrPush( vNodes, pNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkDfsInvSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSup, int * countFlip)
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanin;
|
||||||
|
int i;
|
||||||
|
assert( !Abc_ObjIsNet(pNode) );
|
||||||
|
if ( Abc_NodeIsTravIdCurrent( pNode ) )
|
||||||
|
return;
|
||||||
|
Abc_NodeSetTravIdCurrent( pNode );
|
||||||
|
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsCo(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
|
||||||
|
return;
|
||||||
|
if( Vec_PtrFind(vSup, pNode) >= 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
|
||||||
|
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||||
|
{
|
||||||
|
if(Vec_PtrFind(vSup, pFanin) >= 0)
|
||||||
|
{
|
||||||
|
if(i == 0)
|
||||||
|
{
|
||||||
|
printf("Flipping edge on Node %s %d (Phase = %d)\n", Abc_ObjName(pNode), i, pFanin->fPhase );
|
||||||
|
pNode->fCompl0 ^= 1;
|
||||||
|
}
|
||||||
|
else if(i == 1)
|
||||||
|
{
|
||||||
|
printf("Flipping edge on Node %s %d (Phase = %d)\n", Abc_ObjName(pNode),i , pFanin->fPhase);
|
||||||
|
pNode->fCompl1 ^= 1;
|
||||||
|
}
|
||||||
|
*countFlip = *countFlip + 1;
|
||||||
|
}
|
||||||
|
Abc_NtkDfsInvSup_rec( Abc_ObjFanin0Ntk(pFanin), vSup, countFlip );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Returns the DFS ordered array of logic nodes.]
|
Synopsis [Returns the DFS ordered array of logic nodes.]
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,7 @@ static int Abc_CommandRunEco ( Abc_Frame_t * pAbc, int argc, cha
|
||||||
static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandRunScript ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRunScript ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandRunTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRunTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
static int Abc_CommandRmInverter ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
|
||||||
static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
|
@ -1009,6 +1010,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_unate", Abc_CommandResubUnate, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "resub_unate", Abc_CommandResubUnate, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_core", Abc_CommandResubCore, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "resub_core", Abc_CommandResubCore, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 );
|
||||||
|
Cmd_CommandAdd( pAbc, "Synthesis", "rd_inv", Abc_CommandRmInverter, 1 );
|
||||||
// Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
|
// Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "lutcasdec", Abc_CommandLutCasDec, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "lutcasdec", Abc_CommandLutCasDec, 1 );
|
||||||
|
|
@ -7996,7 +7998,58 @@ usage:
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
||||||
Description [Orchestration synthesis]
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_CommandRmInverter( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
|
{
|
||||||
|
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
int iVerbose = 0;
|
||||||
|
int c;
|
||||||
|
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||||
|
{
|
||||||
|
switch ( c )
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
|
iVerbose ^= 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
goto usage;
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( pNtk == NULL )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Empty network.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( !Abc_NtkHasAig(pNtk) || !Abc_NtkIsStrash(pNtk) )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "This command only works on AIG network.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Abc_NtkRmInverter(pNtk, iVerbose);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
Abc_Print( -2, "usage: rd_inv\n" );
|
||||||
|
Abc_Print( -2, "\t redistribute inverters on self-dual and self-anti-dual functions in network\n" );
|
||||||
|
Abc_Print( -2, "\t-v : verbose output\n");
|
||||||
|
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
SideEffects []
|
SideEffects []
|
||||||
|
|
||||||
|
|
@ -60995,7 +61048,7 @@ int Abc_CommandAbc9eSLIM( Abc_Frame_t * pAbc, int argc, char ** argv ) {
|
||||||
}
|
}
|
||||||
params.synthesis_approach = atoi(argv[globalUtilOptind]);
|
params.synthesis_approach = atoi(argv[globalUtilOptind]);
|
||||||
globalUtilOptind++;
|
globalUtilOptind++;
|
||||||
if ( params.synthesis_approach < 0 || params.synthesis_approach > 2)
|
if ( params.synthesis_approach < 0 || params.synthesis_approach > 3)
|
||||||
goto usage;
|
goto usage;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
|
|
@ -61211,7 +61264,7 @@ int Abc_CommandAbc9elSLIM( Abc_Frame_t * pAbc, int argc, char ** argv ) {
|
||||||
}
|
}
|
||||||
params.synthesis_approach = atoi(argv[globalUtilOptind]);
|
params.synthesis_approach = atoi(argv[globalUtilOptind]);
|
||||||
globalUtilOptind++;
|
globalUtilOptind++;
|
||||||
if ( params.synthesis_approach < 0 || params.synthesis_approach > 2)
|
if ( params.synthesis_approach < 0 || params.synthesis_approach > 3)
|
||||||
goto usage;
|
goto usage;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,853 @@
|
||||||
|
/**CFile****************************************************************
|
||||||
|
|
||||||
|
FileName [abcRmInverters.c]
|
||||||
|
|
||||||
|
SystemName [ABC: Logic synthesis and verification system.]
|
||||||
|
|
||||||
|
PackageName [Network and node package.]
|
||||||
|
|
||||||
|
Synopsis [Remove/Redistribute inverted edges on AIG nodes.]
|
||||||
|
|
||||||
|
Author [Jingren Wang]
|
||||||
|
|
||||||
|
Affiliation [HKUST(GZ)]
|
||||||
|
|
||||||
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||||
|
|
||||||
|
Revision [$Id: abcRmInverters.c,v 1.00 2005/06/20 00:00:00 jingren Exp $]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "aig/aig/aig.h"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "misc/util/abc_global.h"
|
||||||
|
#include "misc/vec/vecInt.h"
|
||||||
|
#include "misc/vec/vecPtr.h"
|
||||||
|
#include "opt/cut/cut.h"
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
#define RDINV_SIM_SIZE 100
|
||||||
|
|
||||||
|
static unsigned int uMask[] = { 0x1, 0x3, 0xF, 0xFF, 0xFFFF, 0xFFFFFFFF };
|
||||||
|
|
||||||
|
extern void Abc_NtkMarkCriticalNodes( Abc_Ntk_t * pNtk );
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Collect cut leaves into a Vec_Ptr.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline Vec_Ptr_t * Abc_RdInvCollectCutLeaves( Abc_Ntk_t * pNtk, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vLeaves = Vec_PtrAlloc( pCut->nLeaves );
|
||||||
|
for ( int li = 0; li < pCut->nLeaves; li++ )
|
||||||
|
Vec_PtrPush( vLeaves, Abc_NtkObj(pNtk, Cut_CutReadLeaves(pCut)[li]) );
|
||||||
|
return vLeaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Detect if function is self-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int AbcRmInvHasSelfDual( unsigned int uTruth, int fPhaseOri, unsigned int uTruthFlipped, int fPhaseFlipped, unsigned int uMsk )
|
||||||
|
{
|
||||||
|
return (uTruth == uTruthFlipped && (fPhaseOri ^ fPhaseFlipped) == 1) ||
|
||||||
|
(uTruth == (~uTruthFlipped & uMsk) && fPhaseOri == fPhaseFlipped);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Detect if function is self-anti-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int AbcRmInvHasSelfAntiDual( unsigned int uTruth, int fPhaseOri, unsigned int uTruthFlipped, int fPhaseFlipped, unsigned int uMsk )
|
||||||
|
{
|
||||||
|
return (uTruth == uTruthFlipped && fPhaseOri == fPhaseFlipped) ||
|
||||||
|
(uTruth == (~uTruthFlipped & uMsk) && (fPhaseOri ^ fPhaseFlipped) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Collect MFFC with support variables and internal nodes.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso [abcMffc.c]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NodeMffcConeSuppCollect( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int iVerbose )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int i;
|
||||||
|
Abc_NodeDeref_rec( pNode );
|
||||||
|
Abc_NodeMffcConeSupp( pNode, vCone, vSupp );
|
||||||
|
Abc_NodeRef_rec( pNode );
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf( "Node = %6s : Supp = %3d Cone = %3d (",
|
||||||
|
Abc_ObjName(pNode), Vec_PtrSize(vSupp), Vec_PtrSize(vCone) );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i )
|
||||||
|
printf( " %s", Abc_ObjName(pObj) );
|
||||||
|
printf( " )\n" );
|
||||||
|
printf("vSupp = (");
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, i )
|
||||||
|
printf( " %s", Abc_ObjName(pObj) );
|
||||||
|
printf( " )\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Get inverter count on support variables for self-anti-dual case.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterCountInvRatioSelfAntiDual( Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int * nLocalInv, int * nLocalInvOnCritical, int * nLocalNonInvOnCritical, int * nLocalSup )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj, * pFanin;
|
||||||
|
int i_cone, i_fanin;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i_cone )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pObj, pFanin, i_fanin )
|
||||||
|
{
|
||||||
|
if ( Vec_PtrFind(vSupp, pFanin) < 0 )
|
||||||
|
continue;
|
||||||
|
if ( (i_fanin == 0 && pObj->fCompl0) || (i_fanin == 1 && pObj->fCompl1) )
|
||||||
|
(*nLocalInv)++;
|
||||||
|
if ( (i_fanin == 0 && pObj->fCompl0 && pFanin->fMarkA) || (i_fanin == 1 && pObj->fCompl1 && pFanin->fMarkA) )
|
||||||
|
(*nLocalInvOnCritical)++;
|
||||||
|
if ( (i_fanin == 0 && !pObj->fCompl0 && pFanin->fMarkA) || (i_fanin == 1 && !pObj->fCompl1 && pFanin->fMarkA) )
|
||||||
|
(*nLocalNonInvOnCritical)++;
|
||||||
|
(*nLocalSup)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Get inverter count on support variables for self-dual case.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterCountInvRatioSelfDual( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int * nLocalInv, int * nLocalInvOnCritical, int * nLocalNonInvOnCritical, int * nLocalSup )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanout;
|
||||||
|
int i;
|
||||||
|
Abc_NtkRmInverterCountInvRatioSelfAntiDual( vCone, vSupp, nLocalInv, nLocalInvOnCritical, nLocalNonInvOnCritical, nLocalSup );
|
||||||
|
Abc_ObjForEachFanout( pNode, pFanout, i )
|
||||||
|
{
|
||||||
|
int fCompl = (Abc_ObjFanin0(pFanout) == pNode) ? pFanout->fCompl0 : pFanout->fCompl1;
|
||||||
|
*nLocalInv += fCompl;
|
||||||
|
int fIsCritical = (Abc_ObjFanin0(pFanout) == pNode)
|
||||||
|
? (Abc_ObjFanin0(pFanout)->fMarkA == 1)
|
||||||
|
: (Abc_ObjFanin1(pFanout)->fMarkA == 1);
|
||||||
|
if ( fCompl && fIsCritical )
|
||||||
|
(*nLocalInvOnCritical)++;
|
||||||
|
else if ( !fCompl && fIsCritical )
|
||||||
|
(*nLocalNonInvOnCritical)++;
|
||||||
|
(*nLocalSup)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Flip inverters on self-anti-dual function.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterFlipInvSelfAntiDual( Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj, * pFanin;
|
||||||
|
int i_cone, i_fanin;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i_cone )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pObj, pFanin, i_fanin )
|
||||||
|
{
|
||||||
|
if ( Vec_PtrFind(vSupp, pFanin) < 0 )
|
||||||
|
continue;
|
||||||
|
if ( i_fanin == 0 )
|
||||||
|
pObj->fCompl0 ^= 1;
|
||||||
|
else if ( i_fanin == 1 )
|
||||||
|
pObj->fCompl1 ^= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Flip inverters on self-dual function.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterFlipInvSelfDual( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanout;
|
||||||
|
int i;
|
||||||
|
Abc_NtkRmInverterFlipInvSelfAntiDual( vCone, vSupp );
|
||||||
|
Abc_ObjForEachFanout( pNode, pFanout, i )
|
||||||
|
{
|
||||||
|
Abc_ObjFanin0(pFanout) == pNode ? (pFanout->fCompl0 ^= 1) : (pFanout->fCompl1 ^= 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Simulate AIG nodes and compute truth tables.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_ManResubSimulateComp( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
unsigned * puData0, * puData1, * puData;
|
||||||
|
int i, k;
|
||||||
|
assert( Vec_PtrSize(vDivs) - nLeaves <= Vec_PtrSize(vSims) - nLeavesMax );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pObj, i )
|
||||||
|
{
|
||||||
|
if ( i < nLeaves )
|
||||||
|
{
|
||||||
|
pObj->pDataComp = Vec_PtrEntry( vSims, i );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pObj->pDataComp = Vec_PtrEntry( vSims, i - nLeaves + nLeavesMax );
|
||||||
|
puData = (unsigned *)pObj->pDataComp;
|
||||||
|
puData0 = (unsigned *)Abc_ObjFanin0(pObj)->pDataComp;
|
||||||
|
puData1 = (unsigned *)Abc_ObjFanin1(pObj)->pDataComp;
|
||||||
|
if ( Abc_ObjFaninC0(pObj) && Abc_ObjFaninC1(pObj) )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = ~puData0[k] & ~puData1[k];
|
||||||
|
else if ( Abc_ObjFaninC0(pObj) )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = ~puData0[k] & puData1[k];
|
||||||
|
else if ( Abc_ObjFaninC1(pObj) )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = puData0[k] & ~puData1[k];
|
||||||
|
else
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = puData0[k] & puData1[k];
|
||||||
|
}
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pObj, i )
|
||||||
|
{
|
||||||
|
puData = (unsigned *)pObj->pDataComp;
|
||||||
|
pObj->fPhase = (puData[0] & 1);
|
||||||
|
if ( pObj->fPhase )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = ~puData[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Clean pDataComp on cone nodes.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkCleanDataComp( Vec_Ptr_t * vCone )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int i;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i )
|
||||||
|
pObj->pDataComp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Simulate a cut to extract truth + phase for one polarity.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvSimCuts( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut, int nMaxLeaves, unsigned int * uNodeVal, int * fPhaseFlipped, unsigned int * pInfo, Vec_Ptr_t * vSims )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int nVar = pCut->nLeaves;
|
||||||
|
int nBits = (1 << nVar);
|
||||||
|
int nWords = (nBits <= 32) ? 1 : (nBits / 32);
|
||||||
|
|
||||||
|
Vec_Ptr_t * vCone = Vec_PtrAlloc( pCut->nLeaves + 16 );
|
||||||
|
Vec_Ptr_t * vSup = Vec_PtrAlloc( pCut->nLeaves );
|
||||||
|
for ( int li = 0; li < pCut->nLeaves; li++ )
|
||||||
|
{
|
||||||
|
pObj = Abc_NtkObj( pNtk, Cut_CutReadLeaves(pCut)[li] );
|
||||||
|
Vec_PtrPush( vSup, pObj );
|
||||||
|
Vec_PtrPush( vCone, pObj );
|
||||||
|
}
|
||||||
|
assert( Vec_PtrSize(vSup) == pCut->nLeaves );
|
||||||
|
|
||||||
|
Abc_NtkIncrementTravId( pNtk );
|
||||||
|
Abc_NtkDfsSup_rec( pNode, vCone, vSup, 0 );
|
||||||
|
assert( Vec_PtrSize(vCone) > pCut->nLeaves );
|
||||||
|
|
||||||
|
Vec_Int_t * vPh = Vec_IntAlloc( Vec_PtrSize(vCone) );
|
||||||
|
Abc_Obj_t * pEntry;
|
||||||
|
int iPh;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pEntry, iPh )
|
||||||
|
Vec_IntPush( vPh, pEntry->fPhase );
|
||||||
|
|
||||||
|
Abc_ManResubSimulateComp( vCone, nVar, vSims, nMaxLeaves, nWords );
|
||||||
|
unsigned int uNode = (*((unsigned int *)(pNode->pDataComp)));
|
||||||
|
*uNodeVal = uNode & uMask[nVar];
|
||||||
|
*fPhaseFlipped = pNode->fPhase;
|
||||||
|
|
||||||
|
Abc_NtkCleanDataComp( vCone );
|
||||||
|
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pEntry, iPh )
|
||||||
|
pEntry->fPhase = Vec_IntEntry( vPh, iPh );
|
||||||
|
|
||||||
|
Vec_IntFree( vPh );
|
||||||
|
Vec_PtrFree( vCone );
|
||||||
|
Vec_PtrFree( vSup );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Compute original and flipped truth/phase pair for a cut.]
|
||||||
|
|
||||||
|
Description [Allocates and frees simulation arrays internally.
|
||||||
|
Returns 1 on success, 0 if cut is too large.]
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static void Abc_RdInvComputeTruthPair( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut,
|
||||||
|
unsigned * uTruthOri, int * fPhaseOri,
|
||||||
|
unsigned * uTruthFlipped, int * fPhaseFlipped )
|
||||||
|
{
|
||||||
|
int nVar = pCut->nLeaves;
|
||||||
|
int nBits = (1 << nVar);
|
||||||
|
int nWords = (nBits <= 32) ? 1 : (nBits / 32);
|
||||||
|
int in, k;
|
||||||
|
|
||||||
|
Vec_Ptr_t * vSims = Vec_PtrAlloc( RDINV_SIM_SIZE );
|
||||||
|
unsigned int *pInfo = ABC_ALLOC( unsigned, nWords * (RDINV_SIM_SIZE + 1) );
|
||||||
|
for ( in = 0; in < RDINV_SIM_SIZE; in++ )
|
||||||
|
Vec_PtrPush( vSims, pInfo + in * nWords );
|
||||||
|
|
||||||
|
for ( k = 0; k < nVar; k++ )
|
||||||
|
{
|
||||||
|
unsigned * pData = (unsigned *)vSims->pArray[k];
|
||||||
|
Abc_InfoClear( pData, nWords );
|
||||||
|
for ( in = 0; in < nBits; in++ )
|
||||||
|
if ( in & (1 << k) )
|
||||||
|
pData[in >> 5] |= (1 << (in & 31));
|
||||||
|
}
|
||||||
|
AbcRmInvSimCuts( pNtk, pNode, pCut, 5, uTruthOri, fPhaseOri, pInfo, vSims );
|
||||||
|
Vec_PtrFree( vSims );
|
||||||
|
ABC_FREE( pInfo );
|
||||||
|
|
||||||
|
vSims = Vec_PtrAlloc( RDINV_SIM_SIZE );
|
||||||
|
pInfo = ABC_ALLOC( unsigned, nWords * (RDINV_SIM_SIZE + 1) );
|
||||||
|
for ( in = 0; in < RDINV_SIM_SIZE; in++ )
|
||||||
|
Vec_PtrPush( vSims, pInfo + in * nWords );
|
||||||
|
|
||||||
|
for ( k = 0; k < nVar; k++ )
|
||||||
|
{
|
||||||
|
unsigned * pData = (unsigned *)vSims->pArray[k];
|
||||||
|
Abc_InfoClear( pData, nWords );
|
||||||
|
for ( in = 0; in < nBits; in++ )
|
||||||
|
if ( !(in & (1 << k)) )
|
||||||
|
pData[in >> 5] |= (1 << (in & 31));
|
||||||
|
}
|
||||||
|
AbcRmInvSimCuts( pNtk, pNode, pCut, 5, uTruthFlipped, fPhaseFlipped, pInfo, vSims );
|
||||||
|
Vec_PtrFree( vSims );
|
||||||
|
ABC_FREE( pInfo );
|
||||||
|
|
||||||
|
assert( (*uTruthOri & uMask[nVar]) == *uTruthOri );
|
||||||
|
assert( (*uTruthFlipped & uMask[nVar]) == *uTruthFlipped );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Check if cut is self-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_NtkRmInvCutIsSelfDual( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
unsigned uTruthOri, uTruthFlipped;
|
||||||
|
int fPhaseOri, fPhaseFlipped;
|
||||||
|
Abc_RdInvComputeTruthPair( pNtk, pNode, pCut, &uTruthOri, &fPhaseOri, &uTruthFlipped, &fPhaseFlipped );
|
||||||
|
return AbcRmInvHasSelfDual( uTruthOri, fPhaseOri, uTruthFlipped, fPhaseFlipped, uMask[pCut->nLeaves] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Check if cut is self-anti-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_NtkRmInvCutIsSelfAntiDual( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
unsigned uTruthOri, uTruthFlipped;
|
||||||
|
int fPhaseOri, fPhaseFlipped;
|
||||||
|
Abc_RdInvComputeTruthPair( pNtk, pNode, pCut, &uTruthOri, &fPhaseOri, &uTruthFlipped, &fPhaseFlipped );
|
||||||
|
return AbcRmInvHasSelfAntiDual( uTruthOri, fPhaseOri, uTruthFlipped, fPhaseFlipped, uMask[pCut->nLeaves] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Get valid cuts of self-dual and self-anti-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvAvaCuts( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Man_t * pCutMan, Vec_Ptr_t * vASDCuts, Vec_Ptr_t * vASADCuts, int iVerbose )
|
||||||
|
{
|
||||||
|
int nCuts = 0;
|
||||||
|
Vec_Ptr_t * vCutsPreSD = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Ptr_t * vCutsPreSAD = Vec_PtrAlloc( 16 );
|
||||||
|
Cut_Cut_t * pCut;
|
||||||
|
pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pCutMan, pNode, 0, 1 );
|
||||||
|
if ( pCut == NULL )
|
||||||
|
{
|
||||||
|
printf("Warning: Abc_NodeGetCutsRecursive returned NULL for node %d\n", Abc_ObjId(pNode));
|
||||||
|
Vec_PtrFree( vCutsPreSD );
|
||||||
|
Vec_PtrFree( vCutsPreSAD );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
|
||||||
|
{
|
||||||
|
if ( Abc_NtkRmInvCutIsSelfDual(pNtk, pNode, pCut) )
|
||||||
|
Vec_PtrPush( vCutsPreSD, pCut );
|
||||||
|
if ( Abc_NtkRmInvCutIsSelfAntiDual(pNtk, pNode, pCut) )
|
||||||
|
Vec_PtrPush( vCutsPreSAD, pCut );
|
||||||
|
nCuts++;
|
||||||
|
}
|
||||||
|
Vec_PtrCopy( vASADCuts, vCutsPreSAD );
|
||||||
|
Vec_PtrCopy( vASDCuts, vCutsPreSD );
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf(" %d cuts have been found and processed.\n", nCuts);
|
||||||
|
printf(" Retrieved %d(%d) of cuts in self-anti-dual and %d(%d) of cuts in self-dual.\n",
|
||||||
|
Vec_PtrSize(vASADCuts), Vec_PtrSize(vCutsPreSAD),
|
||||||
|
Vec_PtrSize(vASDCuts), Vec_PtrSize(vCutsPreSD));
|
||||||
|
}
|
||||||
|
Vec_PtrFree( vCutsPreSD );
|
||||||
|
Vec_PtrFree( vCutsPreSAD );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Show cut structure for verbose output.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_RmInvShowCutStructure( Abc_Ntk_t * pNtk, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vCone = Vec_PtrAlloc( pCut->nLeaves + 16 );
|
||||||
|
Vec_Ptr_t * vSup = Abc_RdInvCollectCutLeaves( pNtk, pCut );
|
||||||
|
int li;
|
||||||
|
for ( li = 0; li < pCut->nLeaves; li++ )
|
||||||
|
Vec_PtrPush( vCone, Abc_NtkObj(pNtk, Cut_CutReadLeaves(pCut)[li]) );
|
||||||
|
Abc_NtkIncrementTravId( pNtk );
|
||||||
|
Abc_NtkDfsSup_rec( pRoot, vCone, vSup, 1 );
|
||||||
|
Vec_PtrFree( vSup );
|
||||||
|
Vec_PtrFree( vCone );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Retrieve max level slack.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvFetchMaxLSlack( Abc_Ntk_t * pNtk, int * iLSM )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
Abc_Obj_t * pNode;
|
||||||
|
Vec_Int_t * vLS = Vec_IntAlloc( Abc_NtkNodeNum(pNtk) );
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
int item = Abc_ObjRequiredLevel(pNode) - pNode->Level;
|
||||||
|
Vec_IntPush( vLS, item );
|
||||||
|
}
|
||||||
|
Vec_IntSort( vLS, 1 );
|
||||||
|
assert( Vec_IntEntry(vLS, 0) >= Vec_IntEntry(vLS, Vec_IntSize(vLS) - 1) );
|
||||||
|
*iLSM = Vec_IntEntry( vLS, 0 );
|
||||||
|
Vec_IntFree( vLS );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*********************************************************
|
||||||
|
|
||||||
|
Synopsis [Retrieve critical and near-critical edges count.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvCollectNCE( Abc_Ntk_t * pNtk, int iThreshold, int * iCount )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode, * pFanin, * pPo;
|
||||||
|
int i, j, k;
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjRequiredLevel(pNode) - pNode->Level <= iThreshold )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, j )
|
||||||
|
{
|
||||||
|
*iCount += (j == 0) ? pNode->fCompl0 : pNode->fCompl1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Abc_NtkForEachPo( pNtk, pPo, k )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNodeToPo = Abc_ObjFanin0(pPo);
|
||||||
|
if ( pPo->fCompl0 && Abc_ObjIsNode(pNodeToPo) && (Abc_ObjRequiredLevel(pNodeToPo) - pNodeToPo->Level <= iThreshold) )
|
||||||
|
(*iCount)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Use markB to record level slack, markA for critical flag.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkMarkCriticalNodesScale( Abc_Ntk_t * pNtk )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode;
|
||||||
|
int i, Counter = 0;
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjRequiredLevel(pNode) - pNode->Level <= 1 )
|
||||||
|
{
|
||||||
|
pNode->fMarkA = 1;
|
||||||
|
pNode->fMarkB = Abc_ObjRequiredLevel(pNode) - pNode->Level;
|
||||||
|
Counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf( "The number of nodes on the critical paths = %6d (%5.2f %%)\n", Counter, 100.0 * Counter / Abc_NtkNodeNum(pNtk) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Record sum of slack with inverted edges.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkCollectInvRelatedSlack( Abc_Ntk_t * pNtk, int * invSlack )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode, * pFanin;
|
||||||
|
int i, j;
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, j )
|
||||||
|
{
|
||||||
|
if ( j == 0 && pNode->fCompl0 == 1 )
|
||||||
|
(*invSlack) += pFanin->fMarkB;
|
||||||
|
if ( j == 1 && pNode->fCompl1 == 1 )
|
||||||
|
(*invSlack) += pFanin->fMarkB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Process cuts: evaluate gain condition and flip if beneficial.]
|
||||||
|
|
||||||
|
Description [Shared logic for self-anti-dual and self-dual cut processing.
|
||||||
|
fIsSelfDual=0 treats SAD; fIsSelfDual=1 treats SD.]
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static void Abc_RdInvProcessCuts( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode,
|
||||||
|
Vec_Ptr_t * vCone, Vec_Ptr_t * vCuts, int fIsSelfDual,
|
||||||
|
int * nCountCritical, int * nCountNonCritical, int * nCount, int iVerbose )
|
||||||
|
{
|
||||||
|
Cut_Cut_t * pCut;
|
||||||
|
int i;
|
||||||
|
Vec_PtrForEachEntry( Cut_Cut_t *, vCuts, pCut, i )
|
||||||
|
{
|
||||||
|
int nLocalInv = 0;
|
||||||
|
int nLocalSup = 0;
|
||||||
|
int nLocalInvOnCritical = 0;
|
||||||
|
int nLocalNonInvOnCritical = 0;
|
||||||
|
|
||||||
|
Vec_Ptr_t * vSupCuts = Abc_RdInvCollectCutLeaves( pNtk, pCut );
|
||||||
|
|
||||||
|
if ( fIsSelfDual )
|
||||||
|
Abc_NtkRmInverterCountInvRatioSelfDual( pNode, vCone, vSupCuts, &nLocalInv, &nLocalInvOnCritical, &nLocalNonInvOnCritical, &nLocalSup );
|
||||||
|
else
|
||||||
|
Abc_NtkRmInverterCountInvRatioSelfAntiDual( vCone, vSupCuts, &nLocalInv, &nLocalInvOnCritical, &nLocalNonInvOnCritical, &nLocalSup );
|
||||||
|
|
||||||
|
int fCheckCritical = (nLocalInvOnCritical > nLocalNonInvOnCritical);
|
||||||
|
int fCheckNonCritical = (nLocalInvOnCritical == 0 && nLocalNonInvOnCritical == 0 && nLocalSup > 0 && (float)nLocalInv / nLocalSup >= 0.5);
|
||||||
|
|
||||||
|
if ( fCheckCritical || fCheckNonCritical )
|
||||||
|
{
|
||||||
|
if ( fCheckCritical )
|
||||||
|
(*nCountCritical)++;
|
||||||
|
if ( fCheckNonCritical )
|
||||||
|
(*nCountNonCritical)++;
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
Abc_RmInvShowCutStructure( pNtk, pNode, pCut );
|
||||||
|
|
||||||
|
if ( fIsSelfDual )
|
||||||
|
Abc_NtkRmInverterFlipInvSelfDual( pNode, vCone, vSupCuts );
|
||||||
|
else
|
||||||
|
Abc_NtkRmInverterFlipInvSelfAntiDual( vCone, vSupCuts );
|
||||||
|
|
||||||
|
(*nCount)++;
|
||||||
|
}
|
||||||
|
Vec_PtrFree( vSupCuts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Gain-based inverter removal.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverter( Abc_Ntk_t * pNtk, int iVerbose )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Abc_Obj_t * pNode, * pObj;
|
||||||
|
|
||||||
|
if ( !Abc_NtkIsStrash(pNtk) )
|
||||||
|
{
|
||||||
|
printf("Error: Abc_NtkRmInverter requires a strashed AIG network.\n");
|
||||||
|
printf("Current network type: %d\n", pNtk->ntkType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf("Processing strashed AIG network with %d nodes, %d PIs, %d POs\n",
|
||||||
|
Abc_NtkNodeNum(pNtk), Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk));
|
||||||
|
printf("Network level: %d\n", Abc_NtkLevel(pNtk));
|
||||||
|
}
|
||||||
|
|
||||||
|
Abc_NtkStartReverseLevels( pNtk, 0 );
|
||||||
|
Abc_NtkMarkCriticalNodesScale( pNtk );
|
||||||
|
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_AigNodeIsChoice(pNode) )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pCurTempNode = (Abc_Obj_t *)pNode->pData;
|
||||||
|
while ( pCurTempNode != NULL )
|
||||||
|
{
|
||||||
|
pCurTempNode->fMarkA = 1;
|
||||||
|
pCurTempNode->fMarkB = pNode->fMarkB;
|
||||||
|
pCurTempNode = (Abc_Obj_t *)pCurTempNode->pData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iNCEBefore = 0;
|
||||||
|
int iNCEAfter = 0;
|
||||||
|
int invSlackBefore = 0;
|
||||||
|
int invSlackAfter = 0;
|
||||||
|
int iLSM = 0;
|
||||||
|
AbcRmInvFetchMaxLSlack( pNtk, &iLSM );
|
||||||
|
int iThreshold = iLSM;
|
||||||
|
AbcRmInvCollectNCE( pNtk, iThreshold, &iNCEBefore );
|
||||||
|
Abc_NtkCollectInvRelatedSlack( pNtk, &invSlackBefore );
|
||||||
|
|
||||||
|
int nCountCriticalSAD = 0;
|
||||||
|
int nCountNonCriticalSAD = 0;
|
||||||
|
int nCountSAD = 0;
|
||||||
|
int nCountCriticalSD = 0;
|
||||||
|
int nCountNonCriticalSD = 0;
|
||||||
|
int nCountSD = 0;
|
||||||
|
int nTotalNodes = Abc_NtkNodeNum(pNtk);
|
||||||
|
int nProcessed = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
Cut_Man_t * pCutMan;
|
||||||
|
Cut_Params_t Params, * pParams = &Params;
|
||||||
|
memset( pParams, 0, sizeof(Cut_Params_t) );
|
||||||
|
pParams->nVarsMax = 5;
|
||||||
|
pParams->nKeepMax = 250;
|
||||||
|
pParams->fTruth = 1;
|
||||||
|
pParams->fFilter = 1;
|
||||||
|
pParams->fSeq = 0;
|
||||||
|
pParams->fLocal = 0;
|
||||||
|
pParams->fGlobal = 0;
|
||||||
|
pParams->fTree = 1;
|
||||||
|
pParams->fDrop = 0;
|
||||||
|
pParams->fVerbose = 1;
|
||||||
|
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||||
|
pCutMan = Cut_ManStart( pParams );
|
||||||
|
|
||||||
|
int j_ci;
|
||||||
|
Abc_NtkForEachCi( pNtk, pObj, j_ci )
|
||||||
|
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||||
|
Cut_NodeSetTriv( pCutMan, pObj->Id );
|
||||||
|
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjFanoutNum(pNode) == 1 && pNode->pData != NULL )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vec_Ptr_t * vCone = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Ptr_t * vSupp = Vec_PtrAlloc( 16 );
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
printf("\n\n\n");
|
||||||
|
|
||||||
|
Abc_NodeMffcConeSuppCollect( pNode, vCone, vSupp, iVerbose );
|
||||||
|
|
||||||
|
int i_sup;
|
||||||
|
Vec_PtrForEachEntryReverse( Abc_Obj_t *, vSupp, pObj, i_sup )
|
||||||
|
Vec_PtrInsert( vCone, 0, pObj );
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
printf("Support var size %d, internal node size %d\n", Vec_PtrSize(vSupp), Vec_PtrSize(vCone));
|
||||||
|
|
||||||
|
Vec_Ptr_t * vASDCuts = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Ptr_t * vASADCuts = Vec_PtrAlloc( 16 );
|
||||||
|
|
||||||
|
AbcRmInvAvaCuts( pNtk, pNode, pCutMan, vASDCuts, vASADCuts, iVerbose );
|
||||||
|
|
||||||
|
int nSADBefore = nCountSAD;
|
||||||
|
Abc_RdInvProcessCuts( pNtk, pNode, vCone, vASADCuts, 0,
|
||||||
|
&nCountCriticalSAD, &nCountNonCriticalSAD, &nCountSAD, iVerbose );
|
||||||
|
|
||||||
|
int nSDBefore = nCountSD;
|
||||||
|
Abc_RdInvProcessCuts( pNtk, pNode, vCone, vASDCuts, 1,
|
||||||
|
&nCountCriticalSD, &nCountNonCriticalSD, &nCountSD, iVerbose );
|
||||||
|
|
||||||
|
if ( nCountSAD > nSADBefore || nCountSD > nSDBefore )
|
||||||
|
nProcessed++;
|
||||||
|
|
||||||
|
Vec_PtrFree( vASADCuts );
|
||||||
|
Vec_PtrFree( vASDCuts );
|
||||||
|
Vec_PtrFree( vCone );
|
||||||
|
Vec_PtrFree( vSupp );
|
||||||
|
}
|
||||||
|
Cut_ManStop( pCutMan );
|
||||||
|
}
|
||||||
|
|
||||||
|
AbcRmInvCollectNCE( pNtk, iThreshold, &iNCEAfter );
|
||||||
|
Abc_NtkCollectInvRelatedSlack( pNtk, &invSlackAfter );
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf("=====Statistics about invNum with Threshold %d=====\n", iThreshold);
|
||||||
|
printf("Before %d After %d Gain %d \n", iNCEBefore, iNCEAfter, iNCEBefore - iNCEAfter);
|
||||||
|
if ( iNCEAfter > 0 || iNCEBefore > 0 )
|
||||||
|
printf("=====Statistics about edges that ease on slack=====\n"
|
||||||
|
"Ease Gain %f \n", (float)invSlackAfter / (iNCEAfter ? iNCEAfter : 1) - (float)invSlackBefore / (iNCEBefore ? iNCEBefore : 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Abc_NtkStopReverseLevels( pNtk );
|
||||||
|
Abc_NtkCleanMarkAB( pNtk );
|
||||||
|
|
||||||
|
assert( nCountCriticalSAD + nCountNonCriticalSAD == nCountSAD );
|
||||||
|
assert( nCountCriticalSD + nCountNonCriticalSD == nCountSD );
|
||||||
|
|
||||||
|
printf("Total %d self-anti-dual functions", nCountSAD);
|
||||||
|
if ( nCountSAD > 0 )
|
||||||
|
printf(", Critical(%f), Non-critical(%f)", (float)nCountCriticalSAD / nCountSAD, (float)nCountNonCriticalSAD / nCountSAD);
|
||||||
|
printf(" / %d self-dual are modified", nCountSD);
|
||||||
|
if ( nCountSD > 0 )
|
||||||
|
printf(", Critical(%f), Non-critical(%f)", (float)nCountCriticalSD / nCountSD, (float)nCountNonCriticalSD / nCountSD);
|
||||||
|
printf(". Total process rate %f\n", nTotalNodes > 0 ? (float)nProcessed / nTotalNodes : 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
@ -49,6 +49,7 @@ SRC += src/base/abci/abc.c \
|
||||||
src/base/abci/abcProve.c \
|
src/base/abci/abcProve.c \
|
||||||
src/base/abci/abcQbf.c \
|
src/base/abci/abcQbf.c \
|
||||||
src/base/abci/abcQuant.c \
|
src/base/abci/abcQuant.c \
|
||||||
|
src/base/abci/abcRmInverters.c \
|
||||||
src/base/abci/abcRec3.c \
|
src/base/abci/abcRec3.c \
|
||||||
src/base/abci/abcReconv.c \
|
src/base/abci/abcReconv.c \
|
||||||
src/base/abci/abcReach.c \
|
src/base/abci/abcReach.c \
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ static int Scl_CommandLeak2Area ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Scl_CommandDumpGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Scl_CommandDumpGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
static int Scl_CommandPower ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Scl_CommandUnBuffer ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Scl_CommandUnBuffer ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
|
@ -110,6 +111,7 @@ void Scl_Init( Abc_Frame_t * pAbc )
|
||||||
Cmd_CommandAdd( pAbc, "SCL mapping", "dump_genlib", Scl_CommandDumpGen, 0 );
|
Cmd_CommandAdd( pAbc, "SCL mapping", "dump_genlib", Scl_CommandDumpGen, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "SCL mapping", "print_gs", Scl_CommandPrintGS, 0 );
|
Cmd_CommandAdd( pAbc, "SCL mapping", "print_gs", Scl_CommandPrintGS, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 );
|
Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 );
|
||||||
|
Cmd_CommandAdd( pAbc, "SCL mapping", "power", Scl_CommandPower, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 );
|
Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "SCL mapping", "unbuffer", Scl_CommandUnBuffer, 1 );
|
Cmd_CommandAdd( pAbc, "SCL mapping", "unbuffer", Scl_CommandUnBuffer, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 1 );
|
Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 1 );
|
||||||
|
|
@ -826,6 +828,108 @@ usage:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Scl_CommandPower( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int fUseWireLoads = 0;
|
||||||
|
int nTreeCRatio = 0;
|
||||||
|
int nFrames = 48;
|
||||||
|
int nPref = 16;
|
||||||
|
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
while ( ( c = Extra_UtilGetopt( argc, argv, "XFPch" ) ) != EOF )
|
||||||
|
{
|
||||||
|
switch ( c )
|
||||||
|
{
|
||||||
|
case 'X':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-X\" should be followed by a positive integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
nTreeCRatio = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( nTreeCRatio < 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-F\" should be followed by a positive integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
nFrames = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( nFrames <= 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-P\" should be followed by a non-negative integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
nPref = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( nPref < 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
fUseWireLoads ^= 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
goto usage;
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Abc_FrameReadNtk(pAbc) == NULL )
|
||||||
|
{
|
||||||
|
fprintf( pAbc->Err, "There is no current network.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) )
|
||||||
|
{
|
||||||
|
fprintf( pAbc->Err, "The current network is not mapped.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) )
|
||||||
|
{
|
||||||
|
fprintf( pAbc->Err, "The current network is not in a topo order (run \"topo\").\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( pAbc->pLibScl == NULL )
|
||||||
|
{
|
||||||
|
fprintf( pAbc->Err, "There is no Liberty library available.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Abc_SclPowerPerform( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nTreeCRatio, fUseWireLoads, nFrames, nPref );
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
fprintf( pAbc->Err, "usage: power [-X num] [-F num] [-P num] [-ch]\n" );
|
||||||
|
fprintf( pAbc->Err, "\t computes power using Liberty library\n" );
|
||||||
|
fprintf( pAbc->Err, "\t-X : min Cout/Cave ratio for tree estimations [default = %d]\n", nTreeCRatio );
|
||||||
|
fprintf( pAbc->Err, "\t-F : number of frames to simulate for switching [default = %d]\n", nFrames );
|
||||||
|
fprintf( pAbc->Err, "\t-P : number of prefix frames for switching [default = %d]\n", nPref );
|
||||||
|
fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" );
|
||||||
|
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
@ -2127,4 +2231,3 @@ usage:
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ ABC_NAMESPACE_HEADER_START
|
||||||
/// PARAMETERS ///
|
/// PARAMETERS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define ABC_SCL_CUR_VERSION 8
|
#define ABC_SCL_CUR_VERSION 10
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
@ -172,6 +172,8 @@ struct SC_Timing_
|
||||||
SC_Surface pCellFall;
|
SC_Surface pCellFall;
|
||||||
SC_Surface pRiseTrans; // -- Used to compute output slew
|
SC_Surface pRiseTrans; // -- Used to compute output slew
|
||||||
SC_Surface pFallTrans;
|
SC_Surface pFallTrans;
|
||||||
|
SC_Surface pRisePower; // -- Used to compute internal power
|
||||||
|
SC_Surface pFallPower;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SC_Timings_
|
struct SC_Timings_
|
||||||
|
|
@ -230,6 +232,7 @@ struct SC_Lib_
|
||||||
int unit_time; // -- Valid 9..12. Unit is '10^(-val)' seconds (e.g. 9=1ns, 10=100ps, 11=10ps, 12=1ps)
|
int unit_time; // -- Valid 9..12. Unit is '10^(-val)' seconds (e.g. 9=1ns, 10=100ps, 11=10ps, 12=1ps)
|
||||||
float unit_cap_fst; // -- First part is a multiplier, second either 12 or 15 for 'pf' or 'ff'.
|
float unit_cap_fst; // -- First part is a multiplier, second either 12 or 15 for 'pf' or 'ff'.
|
||||||
int unit_cap_snd;
|
int unit_cap_snd;
|
||||||
|
float nom_voltage; // -- nominal voltage, used for external switching power
|
||||||
Vec_Ptr_t vWireLoads; // NamedSet<SC_WireLoad>
|
Vec_Ptr_t vWireLoads; // NamedSet<SC_WireLoad>
|
||||||
Vec_Ptr_t vWireLoadSels; // NamedSet<SC_WireLoadSel>
|
Vec_Ptr_t vWireLoadSels; // NamedSet<SC_WireLoadSel>
|
||||||
Vec_Ptr_t vTempls; // NamedSet<SC_TableTempl>
|
Vec_Ptr_t vTempls; // NamedSet<SC_TableTempl>
|
||||||
|
|
@ -351,6 +354,7 @@ static inline SC_Lib * Abc_SclLibAlloc()
|
||||||
p->unit_time = 9;
|
p->unit_time = 9;
|
||||||
p->unit_cap_fst = 1;
|
p->unit_cap_fst = 1;
|
||||||
p->unit_cap_snd = 12;
|
p->unit_cap_snd = 12;
|
||||||
|
p->nom_voltage = 1;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,6 +411,8 @@ static inline void Abc_SclTimingFree( SC_Timing * p )
|
||||||
Abc_SclSurfaceFree( &p->pCellFall );
|
Abc_SclSurfaceFree( &p->pCellFall );
|
||||||
Abc_SclSurfaceFree( &p->pRiseTrans );
|
Abc_SclSurfaceFree( &p->pRiseTrans );
|
||||||
Abc_SclSurfaceFree( &p->pFallTrans );
|
Abc_SclSurfaceFree( &p->pFallTrans );
|
||||||
|
Abc_SclSurfaceFree( &p->pRisePower );
|
||||||
|
Abc_SclSurfaceFree( &p->pFallPower );
|
||||||
ABC_FREE( p->related_pin );
|
ABC_FREE( p->related_pin );
|
||||||
ABC_FREE( p->when_text );
|
ABC_FREE( p->when_text );
|
||||||
ABC_FREE( p );
|
ABC_FREE( p );
|
||||||
|
|
@ -492,11 +498,63 @@ static inline float Scl_LibLookup( SC_Surface * p, float slew, float load )
|
||||||
// handle constant table
|
// handle constant table
|
||||||
if ( Vec_FltSize(&p->vIndex0) == 1 && Vec_FltSize(&p->vIndex1) == 1 )
|
if ( Vec_FltSize(&p->vIndex0) == 1 && Vec_FltSize(&p->vIndex1) == 1 )
|
||||||
{
|
{
|
||||||
Vec_Flt_t * vTemp = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0);
|
Vec_Flt_t * vTemp;
|
||||||
assert( Vec_PtrSize(&p->vData) == 1 );
|
if ( Vec_PtrSize(&p->vData) != 1 )
|
||||||
|
return 0;
|
||||||
|
vTemp = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0);
|
||||||
assert( Vec_FltSize(vTemp) == 1 );
|
assert( Vec_FltSize(vTemp) == 1 );
|
||||||
|
if ( Vec_FltSize(vTemp) != 1 )
|
||||||
|
return 0;
|
||||||
return Vec_FltEntry(vTemp, 0);
|
return Vec_FltEntry(vTemp, 0);
|
||||||
}
|
}
|
||||||
|
if ( Vec_FltSize(&p->vIndex0) > 1 && Vec_FltSize(&p->vIndex1) == 1 )
|
||||||
|
{
|
||||||
|
pIndex0 = Vec_FltArray(&p->vIndex0);
|
||||||
|
for ( s = 1; s < Vec_FltSize(&p->vIndex0)-1; s++ )
|
||||||
|
if ( pIndex0[s] > slew )
|
||||||
|
break;
|
||||||
|
s--;
|
||||||
|
if ( pIndex0[s+1] == pIndex0[s] )
|
||||||
|
return 0;
|
||||||
|
sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]);
|
||||||
|
if ( Vec_PtrSize(&p->vData) == Vec_FltSize(&p->vIndex0) )
|
||||||
|
{
|
||||||
|
Vec_Flt_t * vDataS = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s);
|
||||||
|
Vec_Flt_t * vDataS1 = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1);
|
||||||
|
if ( Vec_FltSize(vDataS) < 1 || Vec_FltSize(vDataS1) < 1 )
|
||||||
|
return 0;
|
||||||
|
pDataS = Vec_FltArray( vDataS );
|
||||||
|
pDataS1 = Vec_FltArray( vDataS1 );
|
||||||
|
return pDataS[0] + sfrac * (pDataS1[0] - pDataS[0]);
|
||||||
|
}
|
||||||
|
if ( Vec_PtrSize(&p->vData) != 1 )
|
||||||
|
return 0;
|
||||||
|
if ( Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0)) != Vec_FltSize(&p->vIndex0) )
|
||||||
|
return 0;
|
||||||
|
pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0) );
|
||||||
|
return pDataS[s] + sfrac * (pDataS[s+1] - pDataS[s]);
|
||||||
|
}
|
||||||
|
if ( Vec_FltSize(&p->vIndex0) == 1 && Vec_FltSize(&p->vIndex1) > 1 )
|
||||||
|
{
|
||||||
|
pIndex1 = Vec_FltArray(&p->vIndex1);
|
||||||
|
for ( l = 1; l < Vec_FltSize(&p->vIndex1)-1; l++ )
|
||||||
|
if ( pIndex1[l] > load )
|
||||||
|
break;
|
||||||
|
l--;
|
||||||
|
if ( pIndex1[l+1] == pIndex1[l] )
|
||||||
|
return 0;
|
||||||
|
lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]);
|
||||||
|
if ( Vec_PtrSize(&p->vData) != 1 )
|
||||||
|
return 0;
|
||||||
|
if ( Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0)) != Vec_FltSize(&p->vIndex1) )
|
||||||
|
return 0;
|
||||||
|
pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0) );
|
||||||
|
return pDataS[l] + lfrac * (pDataS[l+1] - pDataS[l]);
|
||||||
|
}
|
||||||
|
if ( Vec_PtrSize(&p->vData) != Vec_FltSize(&p->vIndex0) )
|
||||||
|
return 0;
|
||||||
|
if ( Vec_FltSize(&p->vIndex0) < 2 || Vec_FltSize(&p->vIndex1) < 2 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Find closest sample points in surface:
|
// Find closest sample points in surface:
|
||||||
pIndex0 = Vec_FltArray(&p->vIndex0);
|
pIndex0 = Vec_FltArray(&p->vIndex0);
|
||||||
|
|
@ -512,9 +570,14 @@ static inline float Scl_LibLookup( SC_Surface * p, float slew, float load )
|
||||||
l--;
|
l--;
|
||||||
|
|
||||||
// Interpolate (or extrapolate) function value from sample points:
|
// Interpolate (or extrapolate) function value from sample points:
|
||||||
|
if ( pIndex0[s+1] == pIndex0[s] || pIndex1[l+1] == pIndex1[l] )
|
||||||
|
return 0;
|
||||||
sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]);
|
sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]);
|
||||||
lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]);
|
lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]);
|
||||||
|
|
||||||
|
if ( Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, s)) <= l+1 ||
|
||||||
|
Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1)) <= l+1 )
|
||||||
|
return 0;
|
||||||
pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s) );
|
pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s) );
|
||||||
pDataS1 = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1) );
|
pDataS1 = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1) );
|
||||||
|
|
||||||
|
|
@ -662,8 +725,11 @@ static inline SC_Timing * Scl_CellPinOutTime( SC_Cell * pCell, int iOut, int iPi
|
||||||
SC_Timings * pRTime;
|
SC_Timings * pRTime;
|
||||||
assert( iOut >= 0 && iOut < pCell->n_outputs );
|
assert( iOut >= 0 && iOut < pCell->n_outputs );
|
||||||
assert( iPin >= 0 && iPin < pCell->n_inputs );
|
assert( iPin >= 0 && iPin < pCell->n_inputs );
|
||||||
|
if ( pCell->n_inputs + iOut >= Vec_PtrSize(&pCell->vPins) )
|
||||||
|
return NULL;
|
||||||
pPin = SC_CellPin( pCell, pCell->n_inputs + iOut );
|
pPin = SC_CellPin( pCell, pCell->n_inputs + iOut );
|
||||||
assert( Vec_PtrSize(&pPin->vRTimings) == pCell->n_inputs );
|
if ( iPin >= Vec_PtrSize(&pPin->vRTimings) )
|
||||||
|
return NULL;
|
||||||
pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin );
|
pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin );
|
||||||
if ( Vec_PtrSize(&pRTime->vTimings) == 0 )
|
if ( Vec_PtrSize(&pRTime->vTimings) == 0 )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ static int Abc_SclReadLibraryGenlib( SC_Lib * p, Mio_Library_t * pLib )
|
||||||
p->unit_time = 12;
|
p->unit_time = 12;
|
||||||
p->unit_cap_fst = 1.0;
|
p->unit_cap_fst = 1.0;
|
||||||
p->unit_cap_snd = 15;
|
p->unit_cap_snd = 15;
|
||||||
|
p->nom_voltage = 1.0;
|
||||||
|
|
||||||
Mio_LibraryForEachGate( pLib, pGate )
|
Mio_LibraryForEachGate( pLib, pGate )
|
||||||
{
|
{
|
||||||
|
|
@ -251,6 +252,7 @@ static int Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p )
|
||||||
p->unit_time = Vec_StrGetI(vOut, pPos);
|
p->unit_time = Vec_StrGetI(vOut, pPos);
|
||||||
p->unit_cap_fst = Vec_StrGetF(vOut, pPos);
|
p->unit_cap_fst = Vec_StrGetF(vOut, pPos);
|
||||||
p->unit_cap_snd = Vec_StrGetI(vOut, pPos);
|
p->unit_cap_snd = Vec_StrGetI(vOut, pPos);
|
||||||
|
p->nom_voltage = Vec_StrGetF(vOut, pPos);
|
||||||
|
|
||||||
// Read 'wire_load' vector:
|
// Read 'wire_load' vector:
|
||||||
for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- )
|
for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- )
|
||||||
|
|
@ -392,6 +394,8 @@ static int Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p )
|
||||||
Abc_SclReadSurface( vOut, pPos, &pTime->pCellFall );
|
Abc_SclReadSurface( vOut, pPos, &pTime->pCellFall );
|
||||||
Abc_SclReadSurface( vOut, pPos, &pTime->pRiseTrans );
|
Abc_SclReadSurface( vOut, pPos, &pTime->pRiseTrans );
|
||||||
Abc_SclReadSurface( vOut, pPos, &pTime->pFallTrans );
|
Abc_SclReadSurface( vOut, pPos, &pTime->pFallTrans );
|
||||||
|
Abc_SclReadSurface( vOut, pPos, &pTime->pRisePower );
|
||||||
|
Abc_SclReadSurface( vOut, pPos, &pTime->pFallPower );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert( Vec_PtrSize(&pRTime->vTimings) == 0 );
|
assert( Vec_PtrSize(&pRTime->vTimings) == 0 );
|
||||||
|
|
@ -554,6 +558,8 @@ static void Abc_SclWriteLibraryCellsOnly( Vec_Str_t * vOut, SC_Lib * p, int fAdd
|
||||||
Abc_SclWriteSurface( vOut, &pTime->pCellFall );
|
Abc_SclWriteSurface( vOut, &pTime->pCellFall );
|
||||||
Abc_SclWriteSurface( vOut, &pTime->pRiseTrans );
|
Abc_SclWriteSurface( vOut, &pTime->pRiseTrans );
|
||||||
Abc_SclWriteSurface( vOut, &pTime->pFallTrans );
|
Abc_SclWriteSurface( vOut, &pTime->pFallTrans );
|
||||||
|
Abc_SclWriteSurface( vOut, &pTime->pRisePower );
|
||||||
|
Abc_SclWriteSurface( vOut, &pTime->pFallPower );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert( Vec_PtrSize(&pRTime->vTimings) == 0 );
|
assert( Vec_PtrSize(&pRTime->vTimings) == 0 );
|
||||||
|
|
@ -590,6 +596,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p, int nExtra, int f
|
||||||
Vec_StrPutI( vOut, p->unit_time );
|
Vec_StrPutI( vOut, p->unit_time );
|
||||||
Vec_StrPutF( vOut, p->unit_cap_fst );
|
Vec_StrPutF( vOut, p->unit_cap_fst );
|
||||||
Vec_StrPutI( vOut, p->unit_cap_snd );
|
Vec_StrPutI( vOut, p->unit_cap_snd );
|
||||||
|
Vec_StrPutF( vOut, p->nom_voltage );
|
||||||
|
|
||||||
// Write 'wire_load' vector:
|
// Write 'wire_load' vector:
|
||||||
Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoads) );
|
Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoads) );
|
||||||
|
|
@ -731,6 +738,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p )
|
||||||
else if ( p->unit_time == 12 )
|
else if ( p->unit_time == 12 )
|
||||||
fprintf( s, " time_unit : \"1ps\";\n" );
|
fprintf( s, " time_unit : \"1ps\";\n" );
|
||||||
else assert( 0 );
|
else assert( 0 );
|
||||||
|
fprintf( s, " nom_voltage : %f;\n", p->nom_voltage );
|
||||||
fprintf( s, " capacitive_load_unit(%.1f,%s);\n", p->unit_cap_fst, p->unit_cap_snd == 12 ? "pf" : "ff" );
|
fprintf( s, " capacitive_load_unit(%.1f,%s);\n", p->unit_cap_fst, p->unit_cap_snd == 12 ? "pf" : "ff" );
|
||||||
fprintf( s, "\n" );
|
fprintf( s, "\n" );
|
||||||
|
|
||||||
|
|
@ -831,6 +839,19 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p )
|
||||||
fprintf( s, " fall_transition() {\n" );
|
fprintf( s, " fall_transition() {\n" );
|
||||||
Abc_SclWriteSurfaceText( s, &pTime->pFallTrans );
|
Abc_SclWriteSurfaceText( s, &pTime->pFallTrans );
|
||||||
fprintf( s, " }\n" );
|
fprintf( s, " }\n" );
|
||||||
|
|
||||||
|
if ( Vec_FltSize(&pTime->pRisePower.vIndex0) )
|
||||||
|
{
|
||||||
|
fprintf( s, " rise_power() {\n" );
|
||||||
|
Abc_SclWriteSurfaceText( s, &pTime->pRisePower );
|
||||||
|
fprintf( s, " }\n" );
|
||||||
|
}
|
||||||
|
if ( Vec_FltSize(&pTime->pFallPower.vIndex0) )
|
||||||
|
{
|
||||||
|
fprintf( s, " fall_power() {\n" );
|
||||||
|
Abc_SclWriteSurfaceText( s, &pTime->pFallPower );
|
||||||
|
fprintf( s, " }\n" );
|
||||||
|
}
|
||||||
fprintf( s, " }\n" );
|
fprintf( s, " }\n" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -887,4 +908,3 @@ SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2, int fUsePrefix )
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -747,6 +747,14 @@ void Abc_SclLibNormalizeSurface( SC_Surface * p, float Time, float Load )
|
||||||
Vec_FltForEachEntry( vArray, Entry, i ) // delay/slew
|
Vec_FltForEachEntry( vArray, Entry, i ) // delay/slew
|
||||||
Vec_FltWriteEntry( vArray, i, Time * Entry );
|
Vec_FltWriteEntry( vArray, i, Time * Entry );
|
||||||
}
|
}
|
||||||
|
void Abc_SclLibNormalizeSurfaceIndex( SC_Surface * p, float Time, float Load )
|
||||||
|
{
|
||||||
|
int i; float Entry;
|
||||||
|
Vec_FltForEachEntry( &p->vIndex0, Entry, i ) // slew
|
||||||
|
Vec_FltWriteEntry( &p->vIndex0, i, Time * Entry );
|
||||||
|
Vec_FltForEachEntry( &p->vIndex1, Entry, i ) // load
|
||||||
|
Vec_FltWriteEntry( &p->vIndex1, i, Load * Entry );
|
||||||
|
}
|
||||||
void Abc_SclLibNormalize( SC_Lib * p )
|
void Abc_SclLibNormalize( SC_Lib * p )
|
||||||
{
|
{
|
||||||
SC_WireLoad * pWL;
|
SC_WireLoad * pWL;
|
||||||
|
|
@ -780,6 +788,8 @@ void Abc_SclLibNormalize( SC_Lib * p )
|
||||||
Abc_SclLibNormalizeSurface( &pTiming->pCellFall, Time, Load );
|
Abc_SclLibNormalizeSurface( &pTiming->pCellFall, Time, Load );
|
||||||
Abc_SclLibNormalizeSurface( &pTiming->pRiseTrans, Time, Load );
|
Abc_SclLibNormalizeSurface( &pTiming->pRiseTrans, Time, Load );
|
||||||
Abc_SclLibNormalizeSurface( &pTiming->pFallTrans, Time, Load );
|
Abc_SclLibNormalizeSurface( &pTiming->pFallTrans, Time, Load );
|
||||||
|
Abc_SclLibNormalizeSurfaceIndex( &pTiming->pRisePower, Time, Load );
|
||||||
|
Abc_SclLibNormalizeSurfaceIndex( &pTiming->pFallPower, Time, Load );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1134,4 +1144,3 @@ void Abc_SclInstallGenlib( void * pScl, float SlewInit, float Gain, int fUseAll,
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -935,6 +935,19 @@ int Scl_LibertyReadTimeUnit( Scl_Tree_t * p )
|
||||||
printf( "Liberty parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" );
|
printf( "Liberty parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" );
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
float Scl_LibertyReadNomVoltage( Scl_Tree_t * p )
|
||||||
|
{
|
||||||
|
Scl_Item_t * pItem;
|
||||||
|
Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "nom_voltage" )
|
||||||
|
return atof(Scl_LibertyReadString(p, pItem->Head));
|
||||||
|
Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "operating_conditions" )
|
||||||
|
{
|
||||||
|
Scl_Item_t * pChild;
|
||||||
|
Scl_ItemForEachChildName( p, pItem, pChild, "voltage" )
|
||||||
|
return atof(Scl_LibertyReadString(p, pChild->Head));
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
void Scl_LibertyReadLoadUnit( Scl_Tree_t * p, Vec_Str_t * vOut )
|
void Scl_LibertyReadLoadUnit( Scl_Tree_t * p, Vec_Str_t * vOut )
|
||||||
{
|
{
|
||||||
Scl_Item_t * pItem;
|
Scl_Item_t * pItem;
|
||||||
|
|
@ -1125,6 +1138,24 @@ void Scl_LibertyDumpTables( Vec_Str_t * vOut, Vec_Flt_t * vInd1, Vec_Flt_t * vIn
|
||||||
Vec_StrPut_( vOut );
|
Vec_StrPut_( vOut );
|
||||||
Vec_StrPut_( vOut );
|
Vec_StrPut_( vOut );
|
||||||
}
|
}
|
||||||
|
void Scl_LibertyDumpEmptyTable( Vec_Str_t * vOut )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Vec_StrPutI_( vOut, 0 );
|
||||||
|
Vec_StrPut_( vOut );
|
||||||
|
Vec_StrPutI_( vOut, 0 );
|
||||||
|
Vec_StrPut_( vOut );
|
||||||
|
Vec_StrPut_( vOut );
|
||||||
|
Vec_StrPut_( vOut );
|
||||||
|
for ( i = 0; i < 3; i++ )
|
||||||
|
Vec_StrPutF_( vOut, 0 );
|
||||||
|
for ( i = 0; i < 4; i++ )
|
||||||
|
Vec_StrPutF_( vOut, 0 );
|
||||||
|
for ( i = 0; i < 6; i++ )
|
||||||
|
Vec_StrPutF_( vOut, 0 );
|
||||||
|
Vec_StrPut_( vOut );
|
||||||
|
Vec_StrPut_( vOut );
|
||||||
|
}
|
||||||
int Scl_LibertyScanTable( Scl_Tree_t * p, Vec_Ptr_t * vOut, Scl_Item_t * pTiming, char * pName, Vec_Ptr_t * vTemples )
|
int Scl_LibertyScanTable( Scl_Tree_t * p, Vec_Ptr_t * vOut, Scl_Item_t * pTiming, char * pName, Vec_Ptr_t * vTemples )
|
||||||
{
|
{
|
||||||
Vec_Flt_t * vIndex1 = NULL;
|
Vec_Flt_t * vIndex1 = NULL;
|
||||||
|
|
@ -1206,6 +1237,19 @@ int Scl_LibertyScanTable( Scl_Tree_t * p, Vec_Ptr_t * vOut, Scl_Item_t * pTiming
|
||||||
// check the template style
|
// check the template style
|
||||||
vInd1 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 2 ); // slew
|
vInd1 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 2 ); // slew
|
||||||
vInd2 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 3 ); // load
|
vInd2 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 3 ); // load
|
||||||
|
if ( vInd2 == NULL )
|
||||||
|
{
|
||||||
|
assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
|
||||||
|
vInd1 = vIndex1 ? vIndex1 : vInd1;
|
||||||
|
vInd2 = Vec_FltAlloc( 1 );
|
||||||
|
Vec_FltPush( vInd2, 0 );
|
||||||
|
assert( Vec_FltSize(vInd1) == Vec_FltSize(vValues) );
|
||||||
|
// write entries
|
||||||
|
Vec_PtrPush( vOut, Vec_FltDup(vInd1) );
|
||||||
|
Vec_PtrPush( vOut, vInd2 );
|
||||||
|
Vec_PtrPush( vOut, Vec_FltDup(vValues) );
|
||||||
|
}
|
||||||
|
else
|
||||||
if ( Vec_PtrEntry(vTemples, iPlace + 1) == NULL ) // normal order (vIndex1 is slew; vIndex2 is load)
|
if ( Vec_PtrEntry(vTemples, iPlace + 1) == NULL ) // normal order (vIndex1 is slew; vIndex2 is load)
|
||||||
{
|
{
|
||||||
assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
|
assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
|
||||||
|
|
@ -1287,6 +1331,43 @@ int Scl_LibertyComputeWorstCase( Vec_Ptr_t * vTables, Vec_Flt_t ** pvInd0, Vec_F
|
||||||
*pvValues = vValues;
|
*pvValues = vValues;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Vec_Ptr_t * Scl_LibertyReadPinPowerAll( Scl_Tree_t * p, Scl_Item_t * pPinOut, char * pNameIn )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vPowers = Vec_PtrAlloc( 4 );
|
||||||
|
Scl_Item_t * pPower, * pPinIn;
|
||||||
|
Scl_ItemForEachChildName( p, pPinOut, pPower, "internal_power" )
|
||||||
|
Scl_ItemForEachChildName( p, pPower, pPinIn, "related_pin" )
|
||||||
|
if ( !strcmp(Scl_LibertyReadString(p, pPinIn->Head), pNameIn) )
|
||||||
|
Vec_PtrPush( vPowers, pPower );
|
||||||
|
return vPowers;
|
||||||
|
}
|
||||||
|
void Scl_LibertyWritePowerTable( Scl_Tree_t * p, Vec_Str_t * vOut, Vec_Ptr_t * vPowers, char * pName1, char * pName2, Vec_Ptr_t * vTemples )
|
||||||
|
{
|
||||||
|
Scl_Item_t * pPower;
|
||||||
|
Vec_Ptr_t * vTables = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Flt_t * vInd0, * vInd1, * vValues;
|
||||||
|
int i;
|
||||||
|
Vec_PtrForEachEntry( Scl_Item_t *, vPowers, pPower, i )
|
||||||
|
if ( !Scl_LibertyScanTable( p, vTables, pPower, pName1, vTemples ) && pName2 )
|
||||||
|
Scl_LibertyScanTable( p, vTables, pPower, pName2, vTemples );
|
||||||
|
if ( Vec_PtrSize(vTables) == 0 )
|
||||||
|
{
|
||||||
|
Vec_PtrFree( vTables );
|
||||||
|
Scl_LibertyDumpEmptyTable( vOut );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !Scl_LibertyComputeWorstCase( vTables, &vInd0, &vInd1, &vValues ) )
|
||||||
|
{
|
||||||
|
Vec_VecFree( (Vec_Vec_t *)vTables );
|
||||||
|
Scl_LibertyDumpEmptyTable( vOut );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vec_VecFree( (Vec_Vec_t *)vTables );
|
||||||
|
Scl_LibertyDumpTables( vOut, vInd0, vInd1, vValues );
|
||||||
|
Vec_FltFree( vInd0 );
|
||||||
|
Vec_FltFree( vInd1 );
|
||||||
|
Vec_FltFree( vValues );
|
||||||
|
}
|
||||||
|
|
||||||
int Scl_LibertyReadTable( Scl_Tree_t * p, Vec_Str_t * vOut, Scl_Item_t * pTiming, char * pName, Vec_Ptr_t * vTemples )
|
int Scl_LibertyReadTable( Scl_Tree_t * p, Vec_Str_t * vOut, Scl_Item_t * pTiming, char * pName, Vec_Ptr_t * vTemples )
|
||||||
{
|
{
|
||||||
|
|
@ -1460,10 +1541,12 @@ Vec_Ptr_t * Scl_LibertyReadTemplates( Scl_Tree_t * p )
|
||||||
Vec_Flt_t * vIndex1, * vIndex2;
|
Vec_Flt_t * vIndex1, * vIndex2;
|
||||||
Scl_Item_t * pTempl, * pItem;
|
Scl_Item_t * pTempl, * pItem;
|
||||||
char * pVar1, * pVar2;
|
char * pVar1, * pVar2;
|
||||||
int fFlag0, fFlag1;
|
int fFlag0, fFlag1, fVar1Slew, fVar2Slew;
|
||||||
vRes = Vec_PtrAlloc( 100 );
|
vRes = Vec_PtrAlloc( 100 );
|
||||||
Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pTempl, "lu_table_template" )
|
Scl_ItemForEachChild( p, Scl_LibertyRoot(p), pTempl )
|
||||||
{
|
{
|
||||||
|
if ( Scl_LibertyCompare(p, pTempl->Key, "lu_table_template") && Scl_LibertyCompare(p, pTempl->Key, "power_lut_template") )
|
||||||
|
continue;
|
||||||
pVar1 = pVar2 = NULL;
|
pVar1 = pVar2 = NULL;
|
||||||
vIndex1 = vIndex2 = NULL;
|
vIndex1 = vIndex2 = NULL;
|
||||||
Scl_ItemForEachChild( p, pTempl, pItem )
|
Scl_ItemForEachChild( p, pTempl, pItem )
|
||||||
|
|
@ -1477,7 +1560,7 @@ Vec_Ptr_t * Scl_LibertyReadTemplates( Scl_Tree_t * p )
|
||||||
else if ( !Scl_LibertyCompare(p, pItem->Key, "variable_2") )
|
else if ( !Scl_LibertyCompare(p, pItem->Key, "variable_2") )
|
||||||
assert(pVar2 == NULL), pVar2 = Abc_UtilStrsav( Scl_LibertyReadString(p, pItem->Head) );
|
assert(pVar2 == NULL), pVar2 = Abc_UtilStrsav( Scl_LibertyReadString(p, pItem->Head) );
|
||||||
}
|
}
|
||||||
if ( pVar1 == NULL || pVar2 == NULL )
|
if ( pVar1 == NULL )
|
||||||
{
|
{
|
||||||
ABC_FREE( pVar1 );
|
ABC_FREE( pVar1 );
|
||||||
ABC_FREE( pVar2 );
|
ABC_FREE( pVar2 );
|
||||||
|
|
@ -1485,9 +1568,11 @@ Vec_Ptr_t * Scl_LibertyReadTemplates( Scl_Tree_t * p )
|
||||||
Vec_FltFreeP( &vIndex2 );
|
Vec_FltFreeP( &vIndex2 );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assert( pVar1 != NULL && pVar2 != NULL );
|
assert( pVar1 != NULL );
|
||||||
fFlag0 = (!strcmp(pVar1, "input_net_transition") && !strcmp(pVar2, "total_output_net_capacitance"));
|
fVar1Slew = !strcmp(pVar1, "input_net_transition") || !strcmp(pVar1, "input_transition_time") || !strcmp(pVar1, "related_pin_transition");
|
||||||
fFlag1 = (!strcmp(pVar2, "input_net_transition") && !strcmp(pVar1, "total_output_net_capacitance"));
|
fVar2Slew = pVar2 && (!strcmp(pVar2, "input_net_transition") || !strcmp(pVar2, "input_transition_time") || !strcmp(pVar2, "related_pin_transition"));
|
||||||
|
fFlag0 = fVar1Slew && (pVar2 == NULL || !strcmp(pVar2, "total_output_net_capacitance"));
|
||||||
|
fFlag1 = fVar2Slew && !strcmp(pVar1, "total_output_net_capacitance");
|
||||||
ABC_FREE( pVar1 );
|
ABC_FREE( pVar1 );
|
||||||
ABC_FREE( pVar2 );
|
ABC_FREE( pVar2 );
|
||||||
if ( !fFlag0 && !fFlag1 )
|
if ( !fFlag0 && !fFlag1 )
|
||||||
|
|
@ -1534,6 +1619,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
|
||||||
Vec_StrPutF_( vOut, Scl_LibertyReadDefaultMaxTrans(p) );
|
Vec_StrPutF_( vOut, Scl_LibertyReadDefaultMaxTrans(p) );
|
||||||
Vec_StrPutI_( vOut, Scl_LibertyReadTimeUnit(p) );
|
Vec_StrPutI_( vOut, Scl_LibertyReadTimeUnit(p) );
|
||||||
Scl_LibertyReadLoadUnit( p, vOut );
|
Scl_LibertyReadLoadUnit( p, vOut );
|
||||||
|
Vec_StrPutF_( vOut, Scl_LibertyReadNomVoltage(p) );
|
||||||
Vec_StrPut_( vOut );
|
Vec_StrPut_( vOut );
|
||||||
Vec_StrPut_( vOut );
|
Vec_StrPut_( vOut );
|
||||||
|
|
||||||
|
|
@ -1668,6 +1754,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
|
||||||
{
|
{
|
||||||
Vec_PtrForEachEntry( char *, vNameIns, pName, i )
|
Vec_PtrForEachEntry( char *, vNameIns, pName, i )
|
||||||
{
|
{
|
||||||
|
Vec_Ptr_t * vPowers;
|
||||||
pTiming = Scl_LibertyReadPinTiming( p, pPin, pName );
|
pTiming = Scl_LibertyReadPinTiming( p, pPin, pName );
|
||||||
Vec_StrPutS_( vOut, pName );
|
Vec_StrPutS_( vOut, pName );
|
||||||
Vec_StrPutI_( vOut, (int)(pTiming != NULL) );
|
Vec_StrPutI_( vOut, (int)(pTiming != NULL) );
|
||||||
|
|
@ -1689,6 +1776,10 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
|
||||||
if ( !Scl_LibertyReadTable( p, vOut, pTiming, "fall_transition", vTemples ) )
|
if ( !Scl_LibertyReadTable( p, vOut, pTiming, "fall_transition", vTemples ) )
|
||||||
if ( !Scl_LibertyReadTable( p, vOut, pTiming, "rise_transition", vTemples ) )
|
if ( !Scl_LibertyReadTable( p, vOut, pTiming, "rise_transition", vTemples ) )
|
||||||
{ printf( "Table cannot be found\n" ); return NULL; }
|
{ printf( "Table cannot be found\n" ); return NULL; }
|
||||||
|
vPowers = Scl_LibertyReadPinPowerAll( p, pPin, pName );
|
||||||
|
Scl_LibertyWritePowerTable( p, vOut, vPowers, "rise_power", "power", vTemples );
|
||||||
|
Scl_LibertyWritePowerTable( p, vOut, vPowers, "fall_power", "power", vTemples );
|
||||||
|
Vec_PtrFree( vPowers );
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1697,7 +1788,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
|
||||||
Vec_PtrForEachEntry( char *, vNameIns, pName, i )
|
Vec_PtrForEachEntry( char *, vNameIns, pName, i )
|
||||||
{
|
{
|
||||||
Vec_Ptr_t * vTables[4];
|
Vec_Ptr_t * vTables[4];
|
||||||
Vec_Ptr_t * vTimings;
|
Vec_Ptr_t * vTimings, * vPowers;
|
||||||
vTimings = Scl_LibertyReadPinTimingAll( p, pPin, pName );
|
vTimings = Scl_LibertyReadPinTimingAll( p, pPin, pName );
|
||||||
Vec_StrPutS_( vOut, pName );
|
Vec_StrPutS_( vOut, pName );
|
||||||
Vec_StrPutI_( vOut, (int)(Vec_PtrSize(vTimings) != 0) );
|
Vec_StrPutI_( vOut, (int)(Vec_PtrSize(vTimings) != 0) );
|
||||||
|
|
@ -1741,6 +1832,10 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
|
||||||
Vec_FltFree( vInd1 );
|
Vec_FltFree( vInd1 );
|
||||||
Vec_FltFree( vValues );
|
Vec_FltFree( vValues );
|
||||||
}
|
}
|
||||||
|
vPowers = Scl_LibertyReadPinPowerAll( p, pPin, pName );
|
||||||
|
Scl_LibertyWritePowerTable( p, vOut, vPowers, "rise_power", "power", vTemples );
|
||||||
|
Scl_LibertyWritePowerTable( p, vOut, vPowers, "fall_power", "power", vTemples );
|
||||||
|
Vec_PtrFree( vPowers );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vec_StrPut_( vOut );
|
Vec_StrPut_( vOut );
|
||||||
|
|
@ -1834,4 +1929,3 @@ void Scl_LibertyTest()
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -759,6 +759,92 @@ void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int f
|
||||||
Abc_NtkDelete( pNtkNew );
|
Abc_NtkDelete( pNtkNew );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Printing out power information for the network.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline float Abc_SclPowerTableLookup( SC_Surface * p, float Slew, float Load )
|
||||||
|
{
|
||||||
|
Vec_Flt_t * vRow;
|
||||||
|
int i, nSize0 = Vec_FltSize(&p->vIndex0);
|
||||||
|
int nSize1 = Vec_FltSize(&p->vIndex1);
|
||||||
|
if ( nSize0 == 0 || nSize1 == 0 || Vec_PtrSize(&p->vData) != nSize0 )
|
||||||
|
return 0;
|
||||||
|
Vec_PtrForEachEntry( Vec_Flt_t *, &p->vData, vRow, i )
|
||||||
|
if ( Vec_FltSize(vRow) != nSize1 )
|
||||||
|
return 0;
|
||||||
|
return Scl_LibLookup( p, Slew, Load );
|
||||||
|
}
|
||||||
|
void Abc_SclPowerPerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int nFrames, int nPref )
|
||||||
|
{
|
||||||
|
SC_Man * p;
|
||||||
|
Vec_Flt_t * vSwitching;
|
||||||
|
Abc_Obj_t * pObj, * pFanin;
|
||||||
|
double StaticPower = 0, InternalPower = 0, ExternalPower = 0, DynamicPower = 0;
|
||||||
|
double TotalPower, TotalPowerAbs;
|
||||||
|
int i, k, nPowerArcs = 0;
|
||||||
|
p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 0, 0, nTreeCRatio );
|
||||||
|
vSwitching = Abc_SclComputeSwitching( pNtk, nFrames, nPref );
|
||||||
|
Abc_NtkForEachNodeNotBarBuf1( pNtk, pObj, i )
|
||||||
|
{
|
||||||
|
SC_Cell * pCell = Abc_SclObjCell( pObj );
|
||||||
|
int iOut = Abc_SclObjOutputIndex( pObj, pCell );
|
||||||
|
if ( !Abc_SclObjIsSecondTwin(pObj) )
|
||||||
|
StaticPower += pCell->leakage;
|
||||||
|
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||||
|
{
|
||||||
|
SC_Timing * pTime = Scl_CellPinOutTime( pCell, iOut, k );
|
||||||
|
SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
|
||||||
|
SC_Pair * pSlew = Abc_SclObjSlew( p, pFanin );
|
||||||
|
float Switch = Vec_FltEntry( vSwitching, Abc_ObjId(pFanin) );
|
||||||
|
float RisePower, FallPower;
|
||||||
|
if ( pTime == NULL )
|
||||||
|
{
|
||||||
|
assert( pCell->n_outputs > 1 );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
RisePower = Abc_SclPowerTableLookup( &pTime->pRisePower, pSlew->rise, pLoad->rise );
|
||||||
|
FallPower = Abc_SclPowerTableLookup( &pTime->pFallPower, pSlew->fall, pLoad->fall );
|
||||||
|
RisePower = Abc_MaxFloat( 0, RisePower );
|
||||||
|
FallPower = Abc_MaxFloat( 0, FallPower );
|
||||||
|
if ( RisePower == 0 && FallPower == 0 )
|
||||||
|
continue;
|
||||||
|
InternalPower += Switch * 0.5 * (RisePower + FallPower);
|
||||||
|
nPowerArcs++;
|
||||||
|
}
|
||||||
|
ExternalPower += Vec_FltEntry( vSwitching, Abc_ObjId(pObj) ) * 0.5 * Abc_SclObjLoadAve(p, pObj) * pLib->nom_voltage * pLib->nom_voltage;
|
||||||
|
}
|
||||||
|
DynamicPower = InternalPower + ExternalPower;
|
||||||
|
TotalPower = StaticPower + DynamicPower;
|
||||||
|
TotalPowerAbs = fabs(StaticPower) + fabs(DynamicPower);
|
||||||
|
Abc_Print( 1, "WireLoad = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
|
||||||
|
Abc_Print( 1, "Frames = %d Prefix = %d ", nFrames, nPref );
|
||||||
|
Abc_Print( 1, "Power = %.6g ", TotalPower );
|
||||||
|
Abc_Print( 1, "Static = %.6g (%5.1f %%) ", StaticPower, 100.0 * StaticPower / Abc_MaxDouble(1.0, TotalPowerAbs) );
|
||||||
|
Abc_Print( 1, "Dynamic = %.6g (%5.1f %%) ", DynamicPower, 100.0 * DynamicPower / Abc_MaxDouble(1.0, TotalPowerAbs) );
|
||||||
|
Abc_Print( 1, "Internal = %.6g ", InternalPower );
|
||||||
|
Abc_Print( 1, "External = %.6g ", ExternalPower );
|
||||||
|
Abc_Print( 1, "Arcs = %d\n", nPowerArcs );
|
||||||
|
Vec_FltFree( vSwitching );
|
||||||
|
Abc_SclManFree( p );
|
||||||
|
}
|
||||||
|
void Abc_SclPowerPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int nFrames, int nPref )
|
||||||
|
{
|
||||||
|
Abc_Ntk_t * pNtkNew = pNtk;
|
||||||
|
if ( pNtk->nBarBufs2 > 0 )
|
||||||
|
pNtkNew = Abc_NtkDupDfsNoBarBufs( pNtk );
|
||||||
|
Abc_SclPowerPerformInt( pLib, pNtkNew, nTreeCRatio, fUseWireLoads, nFrames, nPref );
|
||||||
|
if ( pNtk->nBarBufs2 > 0 )
|
||||||
|
Abc_NtkDelete( pNtkNew );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
@ -972,4 +1058,3 @@ void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose )
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -634,6 +634,7 @@ extern int Abc_SclTimeIncUpdate( SC_Man * p );
|
||||||
extern void Abc_SclTimeIncInsert( SC_Man * p, Abc_Obj_t * pObj );
|
extern void Abc_SclTimeIncInsert( SC_Man * p, Abc_Obj_t * pObj );
|
||||||
extern void Abc_SclTimeIncUpdateLevel( Abc_Obj_t * pObj );
|
extern void Abc_SclTimeIncUpdateLevel( Abc_Obj_t * pObj );
|
||||||
extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int fShowAll, int fPrintPath, int fDumpStats );
|
extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int fShowAll, int fPrintPath, int fDumpStats );
|
||||||
|
extern void Abc_SclPowerPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int nFrames, int nPref );
|
||||||
extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );
|
extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );
|
||||||
/*=== sclUpsize.c ===============================================================*/
|
/*=== sclUpsize.c ===============================================================*/
|
||||||
extern int Abc_SclCountNearCriticalNodes( SC_Man * p );
|
extern int Abc_SclCountNearCriticalNodes( SC_Man * p );
|
||||||
|
|
@ -645,6 +646,7 @@ extern void Abc_SclTransferGates( Abc_Ntk_t * pOld, Abc_Ntk_t * pNew );
|
||||||
extern void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p );
|
extern void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p );
|
||||||
extern void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose );
|
extern void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose );
|
||||||
extern int Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax );
|
extern int Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax );
|
||||||
|
extern Vec_Flt_t * Abc_SclComputeSwitching( Abc_Ntk_t * pNtk, int nFrames, int nPref );
|
||||||
extern Vec_Int_t * Abc_SclExtractBarBufs( Abc_Ntk_t * pNtk );
|
extern Vec_Int_t * Abc_SclExtractBarBufs( Abc_Ntk_t * pNtk );
|
||||||
extern void Abc_SclInsertBarBufs( Abc_Ntk_t * pNtk, Vec_Int_t * vBufs );
|
extern void Abc_SclInsertBarBufs( Abc_Ntk_t * pNtk, Vec_Int_t * vBufs );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "sclSize.h"
|
#include "sclSize.h"
|
||||||
#include "map/mio/mio.h"
|
#include "map/mio/mio.h"
|
||||||
#include "base/main/main.h"
|
#include "base/main/main.h"
|
||||||
|
#include "aig/aig/aig.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_START
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
|
@ -275,6 +276,81 @@ void Abc_SclReadTimingConstr( Abc_Frame_t * pAbc, char * pFileName, int fVerbose
|
||||||
fclose( pFile );
|
fclose( pFile );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Computes switching activity for each object.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
Vec_Flt_t * Abc_SclComputeSwitching( Abc_Ntk_t * pNtk, int nFrames, int nPref )
|
||||||
|
{
|
||||||
|
extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
|
||||||
|
extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||||
|
Vec_Int_t * vSwitching = NULL;
|
||||||
|
Vec_Flt_t * vResult;
|
||||||
|
float * pSwitching, * pResult;
|
||||||
|
Abc_Ntk_t * pNtkDup = NULL, * pNtkStr = NULL;
|
||||||
|
Aig_Man_t * pAig = NULL;
|
||||||
|
Aig_Obj_t * pObjAig;
|
||||||
|
Abc_Obj_t * pObj, * pObjDup, * pObjStr;
|
||||||
|
int i;
|
||||||
|
vResult = Vec_FltStart( Abc_NtkObjNumMax(pNtk) );
|
||||||
|
pResult = Vec_FltArray(vResult);
|
||||||
|
pNtkDup = Abc_NtkDup( pNtk );
|
||||||
|
if ( pNtkDup == NULL )
|
||||||
|
goto cleanup;
|
||||||
|
// strash the duplicated network
|
||||||
|
pNtkStr = Abc_NtkStrash( pNtkDup, 0, 1, 0 );
|
||||||
|
if ( pNtkStr == NULL )
|
||||||
|
goto cleanup;
|
||||||
|
Abc_NtkForEachObj( pNtkDup, pObj, i )
|
||||||
|
if ( (pObj->pTemp && Abc_ObjRegular((Abc_Obj_t *)pObj->pTemp)->Type == ABC_FUNC_NONE) || (!Abc_ObjIsCi(pObj) && !Abc_ObjIsNode(pObj)) )
|
||||||
|
pObj->pTemp = NULL;
|
||||||
|
// map network into an AIG
|
||||||
|
pAig = Abc_NtkToDar( pNtkStr, 0, (int)(Abc_NtkLatchNum(pNtkDup) > 0) );
|
||||||
|
if ( pAig == NULL )
|
||||||
|
goto cleanup;
|
||||||
|
vSwitching = Saig_ManComputeSwitchProbs( pAig, nFrames, nPref, 0 );
|
||||||
|
if ( vSwitching == NULL )
|
||||||
|
goto cleanup;
|
||||||
|
pSwitching = (float *)Vec_IntArray(vSwitching);
|
||||||
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||||
|
{
|
||||||
|
pObjDup = (Abc_Obj_t *)pObj->pCopy;
|
||||||
|
if ( pObjDup == NULL )
|
||||||
|
continue;
|
||||||
|
if ( pObjDup->pTemp == NULL )
|
||||||
|
continue;
|
||||||
|
pObjStr = Abc_ObjRegular((Abc_Obj_t *)pObjDup->pTemp);
|
||||||
|
if ( pObjStr == NULL )
|
||||||
|
continue;
|
||||||
|
if ( pObjStr->pTemp == NULL )
|
||||||
|
continue;
|
||||||
|
pObjAig = Aig_Regular((Aig_Obj_t *)pObjStr->pTemp);
|
||||||
|
if ( pObjAig == NULL )
|
||||||
|
continue;
|
||||||
|
pResult[pObj->Id] = pSwitching[pObjAig->Id];
|
||||||
|
}
|
||||||
|
cleanup:
|
||||||
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||||
|
pObj->pCopy = NULL;
|
||||||
|
pNtk->pCopy = NULL;
|
||||||
|
if ( vSwitching )
|
||||||
|
Vec_IntFree( vSwitching );
|
||||||
|
if ( pAig )
|
||||||
|
Aig_ManStop( pAig );
|
||||||
|
if ( pNtkStr )
|
||||||
|
Abc_NtkDelete( pNtkStr );
|
||||||
|
if ( pNtkDup )
|
||||||
|
Abc_NtkDelete( pNtkDup );
|
||||||
|
return vResult;
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
|
||||||
|
|
@ -1069,28 +1069,28 @@ static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
|
static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
|
||||||
{
|
{
|
||||||
int i;
|
int i, Size = p->nSize;
|
||||||
for ( i = 0; i < p->nSize; i++ )
|
for ( i = 0; i < Size; i++ )
|
||||||
if ( p->pArray[i] == Entry )
|
if ( p->pArray[i] == Entry )
|
||||||
break;
|
break;
|
||||||
if ( i == p->nSize )
|
if ( i == Size )
|
||||||
return 0;
|
return 0;
|
||||||
assert( i < p->nSize );
|
assert( i < Size );
|
||||||
for ( i++; i < p->nSize; i++ )
|
for ( i++; i < Size; i++ )
|
||||||
p->pArray[i-1] = p->pArray[i];
|
p->pArray[i-1] = p->pArray[i];
|
||||||
p->nSize--;
|
p->nSize--;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
static inline int Vec_IntRemove1( Vec_Int_t * p, int Entry )
|
static inline int Vec_IntRemove1( Vec_Int_t * p, int Entry )
|
||||||
{
|
{
|
||||||
int i;
|
int i, Size = p->nSize;
|
||||||
for ( i = 1; i < p->nSize; i++ )
|
for ( i = 1; i < Size; i++ )
|
||||||
if ( p->pArray[i] == Entry )
|
if ( p->pArray[i] == Entry )
|
||||||
break;
|
break;
|
||||||
if ( i >= p->nSize )
|
if ( i >= Size )
|
||||||
return 0;
|
return 0;
|
||||||
assert( i < p->nSize );
|
assert( i < Size );
|
||||||
for ( i++; i < p->nSize; i++ )
|
for ( i++; i < Size; i++ )
|
||||||
p->pArray[i-1] = p->pArray[i];
|
p->pArray[i-1] = p->pArray[i];
|
||||||
p->nSize--;
|
p->nSize--;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,14 @@ namespace eSLIM {
|
||||||
}
|
}
|
||||||
int replacement_size = synth.getSizeFromActivationVars(last_model);
|
int replacement_size = synth.getSizeFromActivationVars(last_model);
|
||||||
int replacement_delay = synth.getDelayFromDelayVariables(last_model);
|
int replacement_delay = synth.getDelayFromDelayVariables(last_model);
|
||||||
assert (replacement_delay > 0);
|
assert (replacement_delay > 0 || replacement_size == 0);
|
||||||
|
if (replacement_delay > 0) { // a constant circuit has already optimal depth
|
||||||
std::vector<bool> model = synth.reduceDelay(replacement_size, replacement_delay - 1);
|
std::vector<bool> model = synth.reduceDelay(replacement_size, replacement_delay - 1);
|
||||||
if (model.size() > 0) {
|
if (model.size() > 0) {
|
||||||
replacement_size = synth.getSizeFromActivationVars(model);
|
replacement_size = synth.getSizeFromActivationVars(model);
|
||||||
std::swap(last_model, model);
|
std::swap(last_model, model);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return synth.getReplacement(last_model, replacement_size);
|
return synth.getReplacement(last_model, replacement_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue