mirror of https://github.com/YosysHQ/abc.git
Crtical path detection for AIGs.
This commit is contained in:
parent
4e1b34d744
commit
e76768b9d3
|
|
@ -3564,10 +3564,435 @@ void Gia_ManFindMutualEquivsTest()
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints longest combinational paths between seq endpoints.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static char * Gia_ManPrintPathNameFallback( Gia_Man_t * p, int fCi, int iTerm, char * pBuffer )
|
||||
{
|
||||
if ( fCi )
|
||||
{
|
||||
if ( iTerm < Gia_ManPiNum(p) )
|
||||
sprintf( pBuffer, "pi%d", iTerm );
|
||||
else
|
||||
sprintf( pBuffer, "ro%d", iTerm - Gia_ManPiNum(p) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iTerm < Gia_ManPoNum(p) )
|
||||
sprintf( pBuffer, "po%d", iTerm );
|
||||
else
|
||||
sprintf( pBuffer, "ri%d", iTerm - Gia_ManPoNum(p) );
|
||||
}
|
||||
return pBuffer;
|
||||
}
|
||||
static int Gia_ManPrintPathNameBufferSize( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNames;
|
||||
char * pName;
|
||||
int i, nSize = 64;
|
||||
vNames = p->vNamesIn;
|
||||
if ( vNames )
|
||||
Vec_PtrForEachEntry( char *, vNames, pName, i )
|
||||
if ( pName )
|
||||
nSize = Abc_MaxInt( nSize, (int)strlen(pName) + 64 );
|
||||
vNames = p->vNamesOut;
|
||||
if ( vNames )
|
||||
Vec_PtrForEachEntry( char *, vNames, pName, i )
|
||||
if ( pName )
|
||||
nSize = Abc_MaxInt( nSize, (int)strlen(pName) + 64 );
|
||||
return nSize;
|
||||
}
|
||||
static void Gia_ManPrintPathCopyToken( char * pBuffer, char * pBeg, char * pEnd )
|
||||
{
|
||||
int nChars = pEnd ? (int)(pEnd - pBeg) : (int)strlen(pBeg);
|
||||
memcpy( pBuffer, pBeg, nChars );
|
||||
pBuffer[nChars] = 0;
|
||||
}
|
||||
static char * Gia_ManPrintPathName( Gia_Man_t * p, int fCi, int iTerm, char * pBuffer, int fFull, int fLeaf )
|
||||
{
|
||||
Vec_Ptr_t * vNames = fCi ? p->vNamesIn : p->vNamesOut;
|
||||
char * pName = vNames && iTerm < Vec_PtrSize(vNames) ? (char *)Vec_PtrEntry(vNames, iTerm) : NULL;
|
||||
char * pBeg, * pEnd, * pFirst, * pFirstEnd;
|
||||
if ( pName == NULL )
|
||||
return Gia_ManPrintPathNameFallback( p, fCi, iTerm, pBuffer );
|
||||
if ( fFull )
|
||||
return pName;
|
||||
if ( fLeaf )
|
||||
{
|
||||
pBeg = strrchr( pName, ' ' );
|
||||
return pBeg ? pBeg + 1 : pName;
|
||||
}
|
||||
pFirst = pName;
|
||||
pFirstEnd = strchr( pFirst, ' ' );
|
||||
for ( pBeg = pName; pBeg && *pBeg; pBeg = pEnd ? pEnd + 1 : NULL )
|
||||
{
|
||||
pEnd = strchr( pBeg, ' ' );
|
||||
if ( strstr( pBeg, "reg_" ) && (pEnd == NULL || pEnd > strstr( pBeg, "reg_" )) )
|
||||
{
|
||||
Gia_ManPrintPathCopyToken( pBuffer, pBeg, pEnd );
|
||||
return pBuffer;
|
||||
}
|
||||
}
|
||||
Gia_ManPrintPathCopyToken( pBuffer, pFirst, pFirstEnd );
|
||||
return pBuffer;
|
||||
}
|
||||
static char * Gia_ManPrintPathKind( Gia_Man_t * p, int fCi, int iTerm )
|
||||
{
|
||||
if ( fCi )
|
||||
return iTerm < Gia_ManPiNum(p) ? (char *)"PI" : (char *)"RO";
|
||||
return iTerm < Gia_ManPoNum(p) ? (char *)"PO" : (char *)"RI";
|
||||
}
|
||||
static int Gia_ManPrintPathTermIndex( Gia_Man_t * p, int fCi, int iTerm )
|
||||
{
|
||||
if ( fCi )
|
||||
return iTerm < Gia_ManPiNum(p) ? iTerm : iTerm - Gia_ManPiNum(p);
|
||||
return iTerm < Gia_ManPoNum(p) ? iTerm : iTerm - Gia_ManPoNum(p);
|
||||
}
|
||||
static int Gia_ManPrintPathParseBit( char * pName, char * pBase, int * pBit, char * pSuffix )
|
||||
{
|
||||
char * pLeft = strrchr( pName, '[' );
|
||||
char * pRight = pLeft ? strchr( pLeft, ']' ) : NULL;
|
||||
char * pTemp;
|
||||
if ( pLeft == NULL || pRight == NULL )
|
||||
return 0;
|
||||
for ( pTemp = pLeft + 1; pTemp < pRight; pTemp++ )
|
||||
if ( *pTemp < '0' || *pTemp > '9' )
|
||||
return 0;
|
||||
Gia_ManPrintPathCopyToken( pBase, pName, pLeft );
|
||||
Gia_ManPrintPathCopyToken( pSuffix, pRight + 1, NULL );
|
||||
*pBit = atoi( pLeft + 1 );
|
||||
return 1;
|
||||
}
|
||||
static void Gia_ManPrintPathFormatTermRange( char * pBuffer, char * pKind, int iBeg, int iEnd )
|
||||
{
|
||||
if ( iBeg == iEnd )
|
||||
sprintf( pBuffer, "%s[%d]", pKind, iBeg );
|
||||
else
|
||||
sprintf( pBuffer, "%s[%d..%d]", pKind, iBeg, iEnd );
|
||||
}
|
||||
static void Gia_ManPrintPathFormatNameRange( char * pBuffer, char * pNameBeg, char * pNameEnd, int nNameSize )
|
||||
{
|
||||
char * BaseBeg, * BaseEnd, * SuffixBeg, * SuffixEnd;
|
||||
int BitBeg, BitEnd;
|
||||
if ( !strcmp(pNameBeg, pNameEnd) )
|
||||
{
|
||||
sprintf( pBuffer, "%s", pNameBeg );
|
||||
return;
|
||||
}
|
||||
BaseBeg = ABC_ALLOC( char, nNameSize );
|
||||
BaseEnd = ABC_ALLOC( char, nNameSize );
|
||||
SuffixBeg = ABC_ALLOC( char, nNameSize );
|
||||
SuffixEnd = ABC_ALLOC( char, nNameSize );
|
||||
if ( Gia_ManPrintPathParseBit(pNameBeg, BaseBeg, &BitBeg, SuffixBeg) &&
|
||||
Gia_ManPrintPathParseBit(pNameEnd, BaseEnd, &BitEnd, SuffixEnd) &&
|
||||
!strcmp(BaseBeg, BaseEnd) && !strcmp(SuffixBeg, SuffixEnd) )
|
||||
sprintf( pBuffer, "%s[%d..%d]%s", BaseBeg, BitBeg, BitEnd, SuffixBeg );
|
||||
else
|
||||
sprintf( pBuffer, "%s..%s", pNameBeg, pNameEnd );
|
||||
ABC_FREE( BaseBeg );
|
||||
ABC_FREE( BaseEnd );
|
||||
ABC_FREE( SuffixBeg );
|
||||
ABC_FREE( SuffixEnd );
|
||||
}
|
||||
static int Gia_ManPrintPathCanGroup( Gia_Man_t * p, int Level0, int Source0, int Sink0, int Level1, int Source1, int Sink1, int nNameSize )
|
||||
{
|
||||
char * pStore, * Buffer0, * Buffer1, * Buffer2, * Buffer3, * Base0, * Base1, * Suffix0, * Suffix1;
|
||||
int Bit0, Bit1;
|
||||
int RetValue;
|
||||
if ( Level0 != Level1 || Source0 != Source1 )
|
||||
return 0;
|
||||
if ( (Sink0 < Gia_ManPoNum(p)) != (Sink1 < Gia_ManPoNum(p)) )
|
||||
return 0;
|
||||
if ( Gia_ManPrintPathTermIndex(p, 0, Sink1) != Gia_ManPrintPathTermIndex(p, 0, Sink0) + 1 )
|
||||
return 0;
|
||||
pStore = ABC_ALLOC( char, 8 * nNameSize );
|
||||
Buffer0 = pStore + 0 * nNameSize;
|
||||
Buffer1 = pStore + 1 * nNameSize;
|
||||
Buffer2 = pStore + 2 * nNameSize;
|
||||
Buffer3 = pStore + 3 * nNameSize;
|
||||
Base0 = pStore + 4 * nNameSize;
|
||||
Base1 = pStore + 5 * nNameSize;
|
||||
Suffix0 = pStore + 6 * nNameSize;
|
||||
Suffix1 = pStore + 7 * nNameSize;
|
||||
Gia_ManPrintPathName( p, 1, Source0, Buffer0, 0, 0 );
|
||||
Gia_ManPrintPathName( p, 1, Source1, Buffer1, 0, 0 );
|
||||
if ( strcmp(Buffer0, Buffer1) )
|
||||
{
|
||||
ABC_FREE( pStore );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManPrintPathName( p, 1, Source0, Buffer0, 0, 1 );
|
||||
Gia_ManPrintPathName( p, 1, Source1, Buffer1, 0, 1 );
|
||||
if ( strcmp(Buffer0, Buffer1) )
|
||||
{
|
||||
ABC_FREE( pStore );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManPrintPathName( p, 0, Sink0, Buffer2, 0, 0 );
|
||||
Gia_ManPrintPathName( p, 0, Sink1, Buffer3, 0, 0 );
|
||||
if ( !Gia_ManPrintPathParseBit(Buffer2, Base0, &Bit0, Suffix0) ||
|
||||
!Gia_ManPrintPathParseBit(Buffer3, Base1, &Bit1, Suffix1) )
|
||||
{
|
||||
ABC_FREE( pStore );
|
||||
return 0;
|
||||
}
|
||||
RetValue = !strcmp(Base0, Base1) && !strcmp(Suffix0, Suffix1) && Bit1 == Bit0 + 1;
|
||||
ABC_FREE( pStore );
|
||||
return RetValue;
|
||||
}
|
||||
static int Gia_ManPrintPathCandBetter( int Level0, int Source0, int Sink0, int Level1, int Source1, int Sink1 )
|
||||
{
|
||||
if ( Level0 != Level1 )
|
||||
return Level0 > Level1;
|
||||
if ( Source0 != Source1 )
|
||||
return Source0 < Source1;
|
||||
return Sink0 < Sink1;
|
||||
}
|
||||
static int Gia_ManPrintPathFaninBetter( int Level0, int Source0, int Level1, int Source1 )
|
||||
{
|
||||
if ( Source0 < 0 )
|
||||
return 0;
|
||||
if ( Source1 < 0 )
|
||||
return 1;
|
||||
if ( Level0 != Level1 )
|
||||
return Level0 > Level1;
|
||||
return Source0 < Source1;
|
||||
}
|
||||
static void Gia_ManPrintPathInsert( int * pLevels, int * pSources, int * pSinks, int * pDrivers, int * pnPaths, int nPathsMax, int Level, int Source, int Sink, int Driver )
|
||||
{
|
||||
int i, k, nPaths = *pnPaths;
|
||||
if ( Source < 0 )
|
||||
return;
|
||||
for ( i = 0; i < nPaths; i++ )
|
||||
if ( Gia_ManPrintPathCandBetter(Level, Source, Sink, pLevels[i], pSources[i], pSinks[i]) )
|
||||
break;
|
||||
if ( i == nPathsMax )
|
||||
return;
|
||||
if ( nPaths < nPathsMax )
|
||||
nPaths++;
|
||||
for ( k = nPaths - 1; k > i; k-- )
|
||||
{
|
||||
pLevels[k] = pLevels[k-1];
|
||||
pSources[k] = pSources[k-1];
|
||||
pSinks[k] = pSinks[k-1];
|
||||
pDrivers[k] = pDrivers[k-1];
|
||||
}
|
||||
pLevels[i] = Level;
|
||||
pSources[i] = Source;
|
||||
pSinks[i] = Sink;
|
||||
pDrivers[i] = Driver;
|
||||
*pnPaths = nPaths;
|
||||
}
|
||||
static void Gia_ManPrintPathOne( Gia_Man_t * p, Vec_Int_t * vPreds, int Source, int Sink, int Driver, int nNameSize )
|
||||
{
|
||||
Vec_Int_t * vPath = Vec_IntAlloc( 100 );
|
||||
char * pBuffer = ABC_ALLOC( char, 2 * nNameSize );
|
||||
char * pBuffer0 = pBuffer;
|
||||
char * pBuffer1 = pBuffer + nNameSize;
|
||||
int i, Id;
|
||||
for ( Id = Driver; Id > 0 && !Gia_ObjIsCi(Gia_ManObj(p, Id)); Id = Vec_IntEntry(vPreds, Id) )
|
||||
{
|
||||
Vec_IntPush( vPath, Id );
|
||||
if ( Vec_IntEntry(vPreds, Id) < 0 )
|
||||
break;
|
||||
}
|
||||
printf( " %s[%d] %s", Gia_ManPrintPathKind(p, 1, Source), Gia_ManPrintPathTermIndex(p, 1, Source), Gia_ManPrintPathName(p, 1, Source, pBuffer0, 1, 0) );
|
||||
Vec_IntForEachEntryReverse( vPath, Id, i )
|
||||
printf( " -> AND %d", Id );
|
||||
printf( " -> %s[%d] %s\n", Gia_ManPrintPathKind(p, 0, Sink), Gia_ManPrintPathTermIndex(p, 0, Sink), Gia_ManPrintPathName(p, 0, Sink, pBuffer1, 1, 0) );
|
||||
ABC_FREE( pBuffer );
|
||||
Vec_IntFree( vPath );
|
||||
}
|
||||
void Gia_ManPrintPath( Gia_Man_t * p, int nPathsMax, int fVerbose, int fSummary )
|
||||
{
|
||||
Vec_Int_t * vLevels, * vSources, * vPreds;
|
||||
Vec_Int_t * vGroupStarts, * vGroupEnds;
|
||||
Gia_Obj_t * pObj;
|
||||
int * pLevels, * pSources, * pSinks, * pDrivers;
|
||||
int nGroupsMax = nPathsMax;
|
||||
int nPathsAlloc, nNameSize, nLineSize, nSourceTermW, nSourceNameW, nSinkTermW;
|
||||
int nPaths = 0, Counts[4] = {0}, MaxLevels[4] = {0};
|
||||
int i, k, Id, FanId, Level, Source, Sink, Driver, Cost, LevelBest, SourceBest, FanBest, nGroups, iBeg, iEnd;
|
||||
char * Buffer0, * Buffer1, * Buffer2, * Buffer3, * Buffer4, * Buffer5, * Buffer6, * Buffer7, * Buffer8, * Buffer9, * Buffer10;
|
||||
if ( nPathsMax < 1 )
|
||||
nPathsMax = 1;
|
||||
nGroupsMax = nPathsMax;
|
||||
nPathsAlloc = Abc_MinInt( Gia_ManCoNum(p), Abc_MaxInt(32 * nGroupsMax, nGroupsMax) );
|
||||
nNameSize = Gia_ManPrintPathNameBufferSize( p );
|
||||
nLineSize = 4 * nNameSize + 100;
|
||||
Buffer0 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer1 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer2 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer3 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer4 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer5 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer6 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer7 = ABC_ALLOC( char, nLineSize );
|
||||
Buffer8 = ABC_ALLOC( char, nLineSize );
|
||||
Buffer9 = ABC_ALLOC( char, nLineSize );
|
||||
Buffer10 = ABC_ALLOC( char, nLineSize );
|
||||
vGroupStarts = Vec_IntAlloc( nGroupsMax );
|
||||
vGroupEnds = Vec_IntAlloc( nGroupsMax );
|
||||
vLevels = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
vSources = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
vPreds = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
Id = Gia_ObjId( p, pObj );
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
Vec_IntWriteEntry( vLevels, Id, 0 );
|
||||
Vec_IntWriteEntry( vSources, Id, Gia_ObjCioId(pObj) );
|
||||
continue;
|
||||
}
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
continue;
|
||||
Cost = (!p->fGiaSimple && Gia_ObjIsBuf(pObj)) ? 0 : (Gia_ObjIsMux(p, pObj) || Gia_ObjIsXor(pObj) ? 2 : 1);
|
||||
LevelBest = SourceBest = FanBest = -1;
|
||||
for ( k = 0; k < Gia_ObjFaninNum(p, pObj); k++ )
|
||||
{
|
||||
FanId = k == 2 ? Gia_ObjFaninId2(p, Id) : Gia_ObjFaninId(pObj, Id, k);
|
||||
Level = Vec_IntEntry( vLevels, FanId );
|
||||
Source = Vec_IntEntry( vSources, FanId );
|
||||
if ( Gia_ManPrintPathFaninBetter(Level, Source, LevelBest, SourceBest) )
|
||||
LevelBest = Level, SourceBest = Source, FanBest = FanId;
|
||||
}
|
||||
Vec_IntWriteEntry( vLevels, Id, LevelBest + Cost );
|
||||
Vec_IntWriteEntry( vSources, Id, SourceBest );
|
||||
Vec_IntWriteEntry( vPreds, Id, FanBest );
|
||||
}
|
||||
pLevels = ABC_ALLOC( int, nPathsAlloc );
|
||||
pSources = ABC_ALLOC( int, nPathsAlloc );
|
||||
pSinks = ABC_ALLOC( int, nPathsAlloc );
|
||||
pDrivers = ABC_ALLOC( int, nPathsAlloc );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
Driver = Gia_ObjFaninId0p( p, pObj );
|
||||
Level = Vec_IntEntry( vLevels, Driver );
|
||||
Source = Vec_IntEntry( vSources, Driver );
|
||||
Sink = Gia_ObjCioId( pObj );
|
||||
if ( Source >= 0 )
|
||||
{
|
||||
k = (Source >= Gia_ManPiNum(p) ? 2 : 0) + (Sink >= Gia_ManPoNum(p) ? 1 : 0);
|
||||
Counts[k]++;
|
||||
MaxLevels[k] = Abc_MaxInt( MaxLevels[k], Level );
|
||||
}
|
||||
Gia_ManPrintPathInsert( pLevels, pSources, pSinks, pDrivers, &nPaths, nPathsAlloc, Level, Source, Sink, Driver );
|
||||
}
|
||||
for ( i = 0, nGroups = 0; i < nPaths && nGroups < nGroupsMax; i = iEnd + 1, nGroups++ )
|
||||
{
|
||||
iBeg = iEnd = i;
|
||||
while ( iEnd + 1 < nPaths && Gia_ManPrintPathCanGroup(p, pLevels[iEnd], pSources[iEnd], pSinks[iEnd], pLevels[iEnd+1], pSources[iEnd+1], pSinks[iEnd+1], nNameSize) )
|
||||
iEnd++;
|
||||
Vec_IntPush( vGroupStarts, iBeg );
|
||||
Vec_IntPush( vGroupEnds, iEnd );
|
||||
}
|
||||
nSourceTermW = (int)strlen( "source" );
|
||||
nSourceNameW = 0;
|
||||
nSinkTermW = (int)strlen( "sink" );
|
||||
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
|
||||
{
|
||||
char * pSourceName, * pSourceLeaf, * pSinkNameBeg, * pSinkNameEnd, * pSinkLeafBeg, * pSinkLeafEnd;
|
||||
iEnd = Vec_IntEntry( vGroupEnds, i );
|
||||
pSourceName = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer0, 0, 0);
|
||||
pSourceLeaf = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer1, 0, 1);
|
||||
pSinkNameBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer2, 0, 0);
|
||||
pSinkNameEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer3, 0, 0);
|
||||
pSinkLeafBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer4, 0, 1);
|
||||
pSinkLeafEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer5, 0, 1);
|
||||
Gia_ManPrintPathFormatTermRange( Buffer6, Gia_ManPrintPathKind(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]) );
|
||||
sprintf( Buffer7, "%s", pSourceName );
|
||||
if ( strcmp(pSourceName, pSourceLeaf) )
|
||||
sprintf( Buffer7 + strlen(Buffer7), "->%s", pSourceLeaf );
|
||||
Gia_ManPrintPathFormatTermRange( Buffer8, Gia_ManPrintPathKind(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iEnd]) );
|
||||
Gia_ManPrintPathFormatNameRange( Buffer9, pSinkNameBeg, pSinkNameEnd, nNameSize );
|
||||
if ( strcmp(pSinkLeafBeg, pSinkLeafEnd) )
|
||||
Gia_ManPrintPathFormatNameRange( Buffer10, pSinkLeafBeg, pSinkLeafEnd, nNameSize );
|
||||
else
|
||||
sprintf( Buffer10, "%s", pSinkLeafBeg );
|
||||
if ( strcmp(Buffer9, Buffer10) )
|
||||
sprintf( Buffer9 + strlen(Buffer9), "<-%s", Buffer10 );
|
||||
nSourceTermW = Abc_MaxInt( nSourceTermW, (int)strlen(Buffer6) );
|
||||
nSourceNameW = Abc_MaxInt( nSourceNameW, (int)strlen(Buffer7) );
|
||||
nSinkTermW = Abc_MaxInt( nSinkTermW, (int)strlen(Buffer8) );
|
||||
}
|
||||
printf( "Grouped critical combinational paths:\n" );
|
||||
printf( " rank paths lev %-*s %-*s %-*s %s\n", nSourceTermW, "source", nSourceNameW, "", nSinkTermW, "sink", "" );
|
||||
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
|
||||
{
|
||||
char * pSourceName, * pSourceLeaf, * pSinkNameBeg, * pSinkNameEnd, * pSinkLeafBeg, * pSinkLeafEnd;
|
||||
iEnd = Vec_IntEntry( vGroupEnds, i );
|
||||
pSourceName = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer0, 0, 0);
|
||||
pSourceLeaf = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer1, 0, 1);
|
||||
pSinkNameBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer2, 0, 0);
|
||||
pSinkNameEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer3, 0, 0);
|
||||
pSinkLeafBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer4, 0, 1);
|
||||
pSinkLeafEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer5, 0, 1);
|
||||
Gia_ManPrintPathFormatTermRange( Buffer6, Gia_ManPrintPathKind(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]) );
|
||||
sprintf( Buffer7, "%s", pSourceName );
|
||||
if ( strcmp(pSourceName, pSourceLeaf) )
|
||||
sprintf( Buffer7 + strlen(Buffer7), "->%s", pSourceLeaf );
|
||||
Gia_ManPrintPathFormatTermRange( Buffer8, Gia_ManPrintPathKind(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iEnd]) );
|
||||
Gia_ManPrintPathFormatNameRange( Buffer9, pSinkNameBeg, pSinkNameEnd, nNameSize );
|
||||
if ( strcmp(pSinkLeafBeg, pSinkLeafEnd) )
|
||||
Gia_ManPrintPathFormatNameRange( Buffer10, pSinkLeafBeg, pSinkLeafEnd, nNameSize );
|
||||
else
|
||||
sprintf( Buffer10, "%s", pSinkLeafBeg );
|
||||
if ( strcmp(Buffer9, Buffer10) )
|
||||
sprintf( Buffer9 + strlen(Buffer9), "<-%s", Buffer10 );
|
||||
if ( iBeg == iEnd )
|
||||
sprintf( Buffer4, "%d", iBeg + 1 );
|
||||
else
|
||||
sprintf( Buffer4, "%d..%d", iBeg + 1, iEnd + 1 );
|
||||
printf( "%5d %-7s %3d %-*s %-*s %-*s %s\n", i + 1, Buffer4, pLevels[iBeg], nSourceTermW, Buffer6, nSourceNameW, Buffer7, nSinkTermW, Buffer8, Buffer9 );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "\nAIG paths:\n" );
|
||||
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
|
||||
Gia_ManPrintPathOne( p, vPreds, pSources[iBeg], pSinks[iBeg], pDrivers[iBeg], nNameSize );
|
||||
}
|
||||
if ( fSummary )
|
||||
{
|
||||
printf( "\nEndpoint summary:\n" );
|
||||
printf( " PI->PO : paths = %7d max levels = %6d\n", Counts[0], MaxLevels[0] );
|
||||
printf( " PI->RI : paths = %7d max levels = %6d\n", Counts[1], MaxLevels[1] );
|
||||
printf( " RO->PO : paths = %7d max levels = %6d\n", Counts[2], MaxLevels[2] );
|
||||
printf( " RO->RI : paths = %7d max levels = %6d\n", Counts[3], MaxLevels[3] );
|
||||
}
|
||||
ABC_FREE( pLevels );
|
||||
ABC_FREE( pSources );
|
||||
ABC_FREE( pSinks );
|
||||
ABC_FREE( pDrivers );
|
||||
ABC_FREE( Buffer0 );
|
||||
ABC_FREE( Buffer1 );
|
||||
ABC_FREE( Buffer2 );
|
||||
ABC_FREE( Buffer3 );
|
||||
ABC_FREE( Buffer4 );
|
||||
ABC_FREE( Buffer5 );
|
||||
ABC_FREE( Buffer6 );
|
||||
ABC_FREE( Buffer7 );
|
||||
ABC_FREE( Buffer8 );
|
||||
ABC_FREE( Buffer9 );
|
||||
ABC_FREE( Buffer10 );
|
||||
Vec_IntFree( vLevels );
|
||||
Vec_IntFree( vSources );
|
||||
Vec_IntFree( vPreds );
|
||||
Vec_IntFreeP( &vGroupStarts );
|
||||
Vec_IntFreeP( &vGroupEnds );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -668,6 +668,7 @@ static int Abc_CommandAbc9Divide ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9Pipeline ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Unpipeline ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Regio ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9PrintPath ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
|
|
@ -1527,6 +1528,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&unpipe", Abc_CommandAbc9Unpipeline, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "®io", Abc_CommandAbc9Regio, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&print_path", Abc_CommandAbc9PrintPath, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&eslim", Abc_CommandAbc9eSLIM, 0 );
|
||||
|
|
@ -61267,6 +61269,67 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9PrintPath( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Gia_ManPrintPath( Gia_Man_t * p, int nPaths, int fVerbose, int fSummary );
|
||||
int c, nPaths = 10, fVerbose = 0, fSummary = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nvsh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nPaths = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nPaths < 1 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 's':
|
||||
fSummary ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9PrintPath(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManPrintPath( pAbc->pGia, nPaths, fVerbose, fSummary );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &print_path [-N num] [-vsh]\n" );
|
||||
Abc_Print( -2, "\t prints longest combinational paths between sequential endpoints\n" );
|
||||
Abc_Print( -2, "\t-N num : number of path groups to print [default = %d]\n", nPaths );
|
||||
Abc_Print( -2, "\t-v : toggle printing one AIG path for each path group [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-s : toggle printing endpoint category summary [default = %s]\n", fSummary? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
Loading…
Reference in New Issue