Merge remote-tracking branch 'upstream' into yosys-experimental

This commit is contained in:
Miodrag Milanovic 2026-06-25 13:01:49 +02:00
commit 476b31cac5
24 changed files with 1844 additions and 65 deletions

View File

@ -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>

View File

@ -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>

5
.gitignore vendored
View File

@ -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/
@ -62,4 +65,4 @@ tags
/cmake /cmake
/cscope /cscope
abc.history abc.history

View File

@ -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

View 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 )
{ {

View File

@ -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

View File

@ -639,7 +639,9 @@ static inline int Sbl_CutIsFeasible( word CutI1, word CutI2, word CutN1, word Cu
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 <= 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;
} }

View File

@ -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;
} }

View File

@ -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 *) );
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View File

@ -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 );

View File

@ -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.]

View File

@ -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':

View File

@ -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

View File

@ -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 \

View File

@ -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 );
@ -836,6 +838,108 @@ usage:
SeeAlso [] 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*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/ ***********************************************************************/
int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
@ -2127,4 +2231,3 @@ usage:
ABC_NAMESPACE_IMPL_END ABC_NAMESPACE_IMPL_END

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
@ -1116,6 +1129,24 @@ void Scl_LibertyDumpTables( Vec_Str_t * vOut, Vec_Flt_t * vInd1, Vec_Flt_t * vIn
} }
// dump approximations // dump approximations
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 );
}
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++ ) for ( i = 0; i < 3; i++ )
Vec_StrPutF_( vOut, 0 ); Vec_StrPutF_( vOut, 0 );
for ( i = 0; i < 4; i++ ) for ( i = 0; i < 4; i++ )
@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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 []

View File

@ -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;

View File

@ -83,11 +83,13 @@ 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);
std::vector<bool> model = synth.reduceDelay(replacement_size, replacement_delay - 1); if (replacement_delay > 0) { // a constant circuit has already optimal depth
if (model.size() > 0) { std::vector<bool> model = synth.reduceDelay(replacement_size, replacement_delay - 1);
replacement_size = synth.getSizeFromActivationVars(model); if (model.size() > 0) {
std::swap(last_model, model); replacement_size = synth.getSizeFromActivationVars(model);
std::swap(last_model, model);
}
} }
return synth.getReplacement(last_model, replacement_size); return synth.getReplacement(last_model, replacement_size);
} }