mirror of https://github.com/YosysHQ/abc.git
Merge remote-tracking branch 'upstream/master' into yosys-experimental
This commit is contained in:
commit
c18b835ef1
|
|
@ -195,6 +195,7 @@ struct Gia_Man_t_
|
|||
Vec_Flt_t * vTiming; // arrival/required/slack
|
||||
void * pManTime; // the timing manager
|
||||
void * pLutLib; // LUT library
|
||||
void * pCellLib; // cell library
|
||||
word nHashHit; // hash table hit
|
||||
word nHashMiss; // hash table miss
|
||||
void * pData; // various user data
|
||||
|
|
|
|||
|
|
@ -693,10 +693,15 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
// read flop classes
|
||||
else if ( *pCur == 'f' )
|
||||
{
|
||||
int i, nRegs;
|
||||
pCur++;
|
||||
assert( Gia_AigerReadInt(pCur) == 4*Gia_ManRegNum(pNew) ); pCur += 4;
|
||||
pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) );
|
||||
memcpy( Vec_IntArray(pNew->vFlopClasses), pCur, (size_t)4*Gia_ManRegNum(pNew) ); pCur += 4*Gia_ManRegNum(pNew);
|
||||
pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
|
||||
nRegs = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
//nRegs = (pCurTemp - pCur)/4;
|
||||
pNew->vFlopClasses = Vec_IntAlloc( nRegs );
|
||||
for ( i = 0; i < nRegs; i++ )
|
||||
Vec_IntPush( pNew->vFlopClasses, Gia_AigerReadInt(pCur) ), pCur += 4;
|
||||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"f\".\n" );
|
||||
}
|
||||
// read gate classes
|
||||
|
|
@ -1577,10 +1582,13 @@ void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, in
|
|||
// write flop classes
|
||||
if ( p->vFlopClasses )
|
||||
{
|
||||
int i;
|
||||
fprintf( pFile, "f" );
|
||||
Gia_FileWriteBufferSize( pFile, 4*Gia_ManRegNum(p) );
|
||||
assert( Vec_IntSize(p->vFlopClasses) == Gia_ManRegNum(p) );
|
||||
fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 4*(Vec_IntSize(p->vFlopClasses)+1) );
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntSize(p->vFlopClasses) );
|
||||
for ( i = 0; i < Vec_IntSize(p->vFlopClasses); i++ )
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vFlopClasses, i) );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"f\".\n" );
|
||||
}
|
||||
// write gate classes
|
||||
if ( p->vGateClasses )
|
||||
|
|
|
|||
|
|
@ -2842,11 +2842,12 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
|
|||
}
|
||||
if ( pGia->pManTime == NULL )
|
||||
return;
|
||||
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
|
||||
p->pAigExtra = pGia->pAigExtra; pGia->pAigExtra = NULL;
|
||||
p->vRegClasses = pGia->vRegClasses; pGia->vRegClasses = NULL;
|
||||
p->vRegInits = pGia->vRegInits; pGia->vRegInits = NULL;
|
||||
p->nAnd2Delay = pGia->nAnd2Delay; pGia->nAnd2Delay = 0;
|
||||
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
|
||||
p->pAigExtra = pGia->pAigExtra; pGia->pAigExtra = NULL;
|
||||
p->vRegClasses = pGia->vRegClasses; pGia->vRegClasses = NULL;
|
||||
p->vRegInits = pGia->vRegInits; pGia->vRegInits = NULL;
|
||||
p->vFlopClasses = pGia->vFlopClasses; pGia->vFlopClasses = NULL;
|
||||
p->nAnd2Delay = pGia->nAnd2Delay; pGia->nAnd2Delay = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gia.h"
|
||||
#include "map/if/if.h"
|
||||
#include "misc/tim/tim.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -110,6 +111,7 @@ int Gia_LutWhereIsPin( Gia_Man_t * p, int iFanout, int iFanin, int * pPinPerm )
|
|||
float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
|
||||
{
|
||||
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
|
||||
Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
|
||||
int k, iFanin, pPinPerm[32];
|
||||
float pPinDelays[32];
|
||||
|
|
@ -120,12 +122,43 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
|
|||
return Gia_ObjTimeArrival(p, Gia_ObjFaninId0p(p, pObj) );
|
||||
assert( Gia_ObjIsLut(p, iObj) );
|
||||
tArrival = -TIM_ETERNITY;
|
||||
if ( pLutLib == NULL )
|
||||
if ( pLutLib == NULL && pCellLib == NULL )
|
||||
{
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 1.0 )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + 1.0;
|
||||
}
|
||||
else if ( pCellLib )
|
||||
{
|
||||
// Handle cell library delays (use integer delays directly)
|
||||
int nLutSize = Gia_ObjLutSize(p, iObj);
|
||||
// Find matching cell (simple approach: use first cell with enough inputs)
|
||||
int cellId = -1;
|
||||
int i;
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] >= nLutSize )
|
||||
{
|
||||
cellId = i;
|
||||
break;
|
||||
}
|
||||
if ( cellId >= 0 )
|
||||
{
|
||||
// Use cell delays as integers from the library
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
{
|
||||
float delay = (float)(pCellLib->pCellPinDelays[cellId][k]); // Integer delay from library
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to default delay if no matching cell
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 100.0 )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + 100.0;
|
||||
}
|
||||
}
|
||||
else if ( !pLutLib->fVarPinDelays )
|
||||
{
|
||||
pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
|
||||
|
|
@ -170,18 +203,52 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
|
|||
float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
|
||||
{
|
||||
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
|
||||
int k, iFanin, pPinPerm[32];
|
||||
float pPinDelays[32];
|
||||
float tRequired = 0.0; // Suppress "might be used uninitialized"
|
||||
float * pDelays;
|
||||
assert( Gia_ObjIsLut(p, iObj) );
|
||||
if ( pLutLib == NULL )
|
||||
if ( pLutLib == NULL && pCellLib == NULL )
|
||||
{
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj) - (float)1.0;
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
else if ( pCellLib )
|
||||
{
|
||||
// Handle cell library delays (use integer delays directly)
|
||||
int nLutSize = Gia_ObjLutSize(p, iObj);
|
||||
// Find matching cell (simple approach: use first cell with enough inputs)
|
||||
int cellId = -1;
|
||||
int i;
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] >= nLutSize )
|
||||
{
|
||||
cellId = i;
|
||||
break;
|
||||
}
|
||||
if ( cellId >= 0 )
|
||||
{
|
||||
// Use cell delays as integers from the library
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
{
|
||||
float delay = (float)(pCellLib->pCellPinDelays[cellId][k]); // Integer delay from library
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj) - delay;
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to default delay if no matching cell
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj) - 100.0;
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
}
|
||||
else if ( !pLutLib->fVarPinDelays )
|
||||
{
|
||||
pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
|
||||
|
|
@ -441,20 +508,44 @@ int Gia_LutVerifyTiming( Gia_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
||||
float Gia_ManDelayTraceLutPrintInt( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
|
||||
int i, Nodes, * pCounters;
|
||||
float tArrival, tDelta, nSteps, Num;
|
||||
// get the library
|
||||
const char * pDelayModel;
|
||||
|
||||
// determine delay model
|
||||
if ( pCellLib )
|
||||
pDelayModel = "cell library";
|
||||
else if ( pLutLib )
|
||||
pDelayModel = "LUT library";
|
||||
else
|
||||
pDelayModel = "unit-delay";
|
||||
|
||||
// check library compatibility
|
||||
if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) )
|
||||
{
|
||||
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
|
||||
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
|
||||
pLutLib->LutMax, Gia_ManLutSizeMax(p) );
|
||||
return -ABC_INFINITY;
|
||||
}
|
||||
if ( pCellLib )
|
||||
{
|
||||
int nMaxInputs = 0;
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] > nMaxInputs )
|
||||
nMaxInputs = pCellLib->nCellInputs[i];
|
||||
if ( nMaxInputs < Gia_ManLutSizeMax(p) )
|
||||
{
|
||||
printf( "The max cell inputs (%d) is less than the max fanin count (%d).\n",
|
||||
nMaxInputs, Gia_ManLutSizeMax(p) );
|
||||
return -ABC_INFINITY;
|
||||
}
|
||||
}
|
||||
// decide how many steps
|
||||
nSteps = pLutLib ? 20 : Gia_ManLutLevel(p, NULL);
|
||||
nSteps = (pLutLib || pCellLib) ? 20 : Gia_ManLutLevel(p, NULL);
|
||||
pCounters = ABC_ALLOC( int, nSteps + 1 );
|
||||
memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
|
||||
// perform delay trace
|
||||
|
|
@ -471,16 +562,19 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
|||
assert( Num >=0 && Num <= nSteps );
|
||||
pCounters[(int)Num]++;
|
||||
}
|
||||
// print the results
|
||||
// print the results
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
|
||||
if ( pCellLib )
|
||||
printf( "Max delay = %d. Delay trace using %s model:\n", (int)tArrival, pDelayModel );
|
||||
else
|
||||
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pDelayModel );
|
||||
Nodes = 0;
|
||||
for ( i = 0; i < nSteps; i++ )
|
||||
{
|
||||
Nodes += pCounters[i];
|
||||
printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
|
||||
pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
|
||||
printf( "%3d %s : %5d (%6.2f %%)\n", (pLutLib || pCellLib)? 5*(i+1) : i+1,
|
||||
(pLutLib || pCellLib)? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
|
||||
}
|
||||
}
|
||||
ABC_FREE( pCounters );
|
||||
|
|
@ -488,12 +582,61 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
|||
return tArrival;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Wrapper for delay trace that handles XIAGs with boxes.]
|
||||
|
||||
Description [For XIAGs with boxes, unnormalizes the AIG to ensure proper
|
||||
topological order during delay computation, similar to how
|
||||
Gia_ManPerformMapping handles it.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
float tArrival;
|
||||
// Check if we have boxes and the AIG is normalized (like in Gia_ManPerformMapping)
|
||||
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
|
||||
{
|
||||
// For XIAGs with boxes, we need to unnormalize for proper topological order
|
||||
Gia_Man_t * pTemp = Gia_ManDupUnnormalize( p );
|
||||
if ( pTemp == NULL )
|
||||
{
|
||||
printf( "Failed to unnormalize AIG with boxes for delay trace.\n" );
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
// Transfer timing and mapping information
|
||||
Gia_ManTransferTiming( pTemp, p );
|
||||
Gia_ManTransferMapping( pTemp, p );
|
||||
|
||||
// Transfer library pointers
|
||||
pTemp->pLutLib = p->pLutLib;
|
||||
pTemp->pCellLib = p->pCellLib;
|
||||
|
||||
// Perform delay trace on unnormalized AIG
|
||||
tArrival = Gia_ManDelayTraceLutPrintInt( pTemp, fVerbose );
|
||||
|
||||
// Clean up temporary AIG
|
||||
Gia_ManStop( pTemp );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal case: no boxes or already unnormalized
|
||||
tArrival = Gia_ManDelayTraceLutPrintInt( p, fVerbose );
|
||||
}
|
||||
return tArrival;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Determines timing-critical edges of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
|
|
|||
|
|
@ -469,7 +469,266 @@ void Gia_ManCheckIntegrityWithBoxes( Gia_Man_t * p )
|
|||
Synopsis [Computes representatives in terms of the original objects.]
|
||||
|
||||
Description []
|
||||
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFraigPrintDebugInfo( Gia_Man_t * p )
|
||||
{
|
||||
if ( p->vRegClasses )
|
||||
printf( "Gia_ManFraigSelectReprs: vRegClasses with %d entries\n", Vec_IntSize(p->vRegClasses) );
|
||||
if ( p->vFlopClasses )
|
||||
printf( "Gia_ManFraigSelectReprs: vFlopClasses with %d entries\n", Vec_IntSize(p->vFlopClasses) );
|
||||
|
||||
// Debug: Show all CIs and their types
|
||||
// In unnormalized AIG with boxes: flop outputs are the last nFlops CIs
|
||||
printf( "Circuit has %d CIs (PiNum=%d, RegBoxNum=%d)\n",
|
||||
Gia_ManCiNum(p), Gia_ManPiNum(p), Gia_ManRegBoxNum(p) );
|
||||
int nTotalCis = Gia_ManCiNum(p);
|
||||
int nFlops = Gia_ManRegBoxNum(p);
|
||||
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
|
||||
printf( " -> First %d CIs are PIs/box outputs, last %d CIs are flop outputs\n",
|
||||
nFirstFlop, nFlops );
|
||||
|
||||
Gia_Obj_t * pCiObj;
|
||||
int j;
|
||||
Gia_ManForEachCi( p, pCiObj, j )
|
||||
{
|
||||
int CiId = Gia_ObjCioId(pCiObj);
|
||||
const char* type = (CiId >= nFirstFlop) ? "FlopOut" : "PI/BoxOut";
|
||||
int typeId = (CiId >= nFirstFlop) ? (CiId - nFirstFlop) : CiId;
|
||||
printf( " CI obj %d: CiId=%d (%s %d)\n", Gia_ObjId(p, pCiObj), CiId, type, typeId );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Mark box outputs that feed restricted flops.]
|
||||
|
||||
Description [This prevents box merging from indirectly eliminating restricted flops.]
|
||||
|
||||
SideEffects [Sets fMark1 on box output CIs.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFraigMarkRestrictedBoxOutputs( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < Gia_ManRegBoxNum(p); i++ )
|
||||
{
|
||||
int needsProtection = 0;
|
||||
|
||||
// Check if this flop has restrictions
|
||||
if ( p->vRegClasses && i < Vec_IntSize(p->vRegClasses) )
|
||||
{
|
||||
if ( Vec_IntEntry(p->vRegClasses, i) == 0 ) // Domain 0 = not removeable
|
||||
needsProtection = 1;
|
||||
}
|
||||
if ( p->vFlopClasses && i < Vec_IntSize(p->vFlopClasses) )
|
||||
{
|
||||
if ( Vec_IntEntry(p->vFlopClasses, i) == 0 ) // Class 0 = unmergeable
|
||||
needsProtection = 1;
|
||||
}
|
||||
|
||||
// If flop needs protection, mark the box output driving it
|
||||
// For Test6: box output with CiId (i+1) feeds flop i
|
||||
if ( needsProtection )
|
||||
{
|
||||
int targetCiId = i + 1; // Box output that feeds this flop
|
||||
|
||||
// Find and mark the CI with this CiId
|
||||
Gia_Obj_t * pCi;
|
||||
int j;
|
||||
Gia_ManForEachCi( p, pCi, j )
|
||||
{
|
||||
if ( Gia_ObjCioId(pCi) == targetCiId )
|
||||
{
|
||||
pCi->fMark1 = 1; // Mark this box output as unmergeable
|
||||
if ( fVerbose )
|
||||
printf( "Marking box output (obj %d, CiId %d) for flop %d as unmergeable\n",
|
||||
Gia_ObjId(p, pCi), targetCiId, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print debug info about equivalence being processed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFraigPrintEquivInfo( Gia_Man_t * p, Gia_Obj_t * pObj, int i,
|
||||
Gia_Obj_t * pReprObj, int * pClp2Gia,
|
||||
int iLitClp, int iReprClp )
|
||||
{
|
||||
const char* typeStr = Gia_ObjIsCi(pObj) ? "CI" : (Gia_ObjIsAnd(pObj) ? "AND" : "OTHER");
|
||||
printf( "Found equiv: obj %d (%s) repr %d - iLitClp=%d iReprClp=%d\n",
|
||||
i, typeStr, pClp2Gia[iReprClp], iLitClp, iReprClp );
|
||||
|
||||
// Also show the representative's type
|
||||
const char* reprTypeStr = Gia_ObjIsCi(pReprObj) ? "CI" : (Gia_ObjIsAnd(pReprObj) ? "AND" : "OTHER");
|
||||
printf( " Representative obj %d is %s\n", pClp2Gia[iReprClp], reprTypeStr );
|
||||
|
||||
// If this is a CI, show more details
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
// In unnormalized AIG with boxes, flop outputs are the last nFlops CIs
|
||||
int CiId = Gia_ObjCioId(pObj);
|
||||
int nTotalCis = Gia_ManCiNum(p); // Total CIs in unnormalized AIG
|
||||
int nFlops = Gia_ManRegBoxNum(p);
|
||||
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
|
||||
|
||||
printf( " -> obj %d: CiId=%d, TotalCIs=%d, nFlops=%d, FirstFlopCI=%d\n",
|
||||
i, CiId, nTotalCis, nFlops, nFirstFlop );
|
||||
|
||||
if ( CiId >= nFirstFlop )
|
||||
printf( " -> This is Flop output %d\n", CiId - nFirstFlop );
|
||||
else
|
||||
printf( " -> This is PI/BoxOut %d\n", CiId );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check flop and box output restrictions for merging.]
|
||||
|
||||
Description [Returns 1 if objects should be skipped, 0 if they can be merged.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFraigCheckFlopRestrictions( Gia_Man_t * p, Gia_Obj_t * pObj, int i,
|
||||
int * pClp2Gia, int iReprClp,
|
||||
int fVerbose, int * pnSkipped )
|
||||
{
|
||||
// First check if either CI feeds restricted flops (marked with fMark1)
|
||||
Gia_Obj_t * pReprObj = Gia_ManObj(p, pClp2Gia[iReprClp]);
|
||||
if ( fVerbose && Gia_ObjIsCi(pObj) )
|
||||
printf( " Checking obj %d: fMark1=%d\n", i, pObj->fMark1 );
|
||||
if ( fVerbose && Gia_ObjIsCi(pReprObj) )
|
||||
printf( " Checking repr %d: fMark1=%d\n", pClp2Gia[iReprClp], pReprObj->fMark1 );
|
||||
|
||||
if ( Gia_ObjIsCi(pObj) && pObj->fMark1 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping equiv: obj %d feeds restricted flop\n", i );
|
||||
(*pnSkipped)++;
|
||||
return 1;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pReprObj) && pReprObj->fMark1 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping equiv: repr %d feeds restricted flop\n", pClp2Gia[iReprClp] );
|
||||
(*pnSkipped)++;
|
||||
return 1;
|
||||
}
|
||||
// Check vRegClasses and vFlopClasses restrictions if both are flops
|
||||
// For flops to be mergeable, they must satisfy BOTH conditions:
|
||||
// 1. vRegClasses: same non-zero clock domain (0 = not removeable/mergeable)
|
||||
// 2. vFlopClasses: same non-zero merge class (0 = unmergeable)
|
||||
if ( (p->vRegClasses || p->vFlopClasses) && Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
// In unnormalized AIGs with boxes, flop outputs are the last nFlops CIs
|
||||
// They are not marked with fMark0 (which marks CIs feeding flop inputs)
|
||||
int iFlopCur = -1, iFlopRepr = -1;
|
||||
int nTotalCis = Gia_ManCiNum(p); // Total CIs
|
||||
int nFlops = Gia_ManRegBoxNum(p);
|
||||
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
|
||||
|
||||
// Get the CI ID of the current object
|
||||
int CiIdCur = Gia_ObjCioId(pObj);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( " Checking CI: obj %d, CiId %d, nTotalCis=%d, nFlops=%d, FirstFlopCI=%d\n",
|
||||
i, CiIdCur, nTotalCis, nFlops, nFirstFlop );
|
||||
|
||||
// Check if current object is a flop output (last nFlops CIs)
|
||||
if ( CiIdCur >= nFirstFlop && CiIdCur < nTotalCis )
|
||||
iFlopCur = CiIdCur - nFirstFlop;
|
||||
|
||||
// Check if representative is a flop output
|
||||
int iRepr = pClp2Gia[iReprClp];
|
||||
Gia_Obj_t * pRepr = Gia_ManObj(p, iRepr);
|
||||
if ( Gia_ObjIsCi(pRepr) )
|
||||
{
|
||||
int CiIdRepr = Gia_ObjCioId(pRepr);
|
||||
if ( CiIdRepr >= nFirstFlop && CiIdRepr < nTotalCis )
|
||||
iFlopRepr = CiIdRepr - nFirstFlop;
|
||||
}
|
||||
|
||||
// Apply merging restrictions
|
||||
if ( iFlopCur >= 0 && iFlopRepr >= 0 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Checking flop merge: flop %d and flop %d\n", iFlopCur, iFlopRepr );
|
||||
|
||||
// Check vRegClasses (clock domains) first
|
||||
if ( p->vRegClasses )
|
||||
{
|
||||
assert( iFlopCur < Vec_IntSize(p->vRegClasses) );
|
||||
assert( iFlopRepr < Vec_IntSize(p->vRegClasses) );
|
||||
|
||||
int DomainCur = Vec_IntEntry(p->vRegClasses, iFlopCur);
|
||||
int DomainRepr = Vec_IntEntry(p->vRegClasses, iFlopRepr);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( " Clock domains: %d and %d\n", DomainCur, DomainRepr );
|
||||
|
||||
// Skip merging if either is in domain 0 or domains don't match
|
||||
if ( DomainCur == 0 || DomainRepr == 0 || DomainCur != DomainRepr )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping due to clock domain restriction\n" );
|
||||
(*pnSkipped)++;
|
||||
return 1; // Skip this merging
|
||||
}
|
||||
}
|
||||
|
||||
// Check vFlopClasses (merge classes) second
|
||||
if ( p->vFlopClasses )
|
||||
{
|
||||
assert( iFlopCur < Vec_IntSize(p->vFlopClasses) );
|
||||
assert( iFlopRepr < Vec_IntSize(p->vFlopClasses) );
|
||||
|
||||
int ClassCur = Vec_IntEntry(p->vFlopClasses, iFlopCur);
|
||||
int ClassRepr = Vec_IntEntry(p->vFlopClasses, iFlopRepr);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( " Merge classes: %d and %d\n", ClassCur, ClassRepr );
|
||||
|
||||
// Skip merging if classes don't match or class is 0 (unmergeable)
|
||||
if ( ClassCur == 0 || ClassRepr == 0 || ClassCur != ClassRepr )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping due to merge class restriction\n" );
|
||||
(*pnSkipped)++;
|
||||
return 1; // Skip this merging
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // OK to merge
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Select representatives for the collapsed AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
|
@ -483,8 +742,13 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
int * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) );
|
||||
int * pClp2Gia = ABC_FALLOC( int, Gia_ManObjNum(pClp) );
|
||||
int i, iLitClp, iLitClp2, iReprClp, fCompl;
|
||||
int nConsts = 0, nReprs = 0;
|
||||
int nConsts = 0, nReprs = 0, nSkipped = 0;
|
||||
assert( pManTime != NULL );
|
||||
|
||||
// Debug: Check if vRegClasses and vFlopClasses are present
|
||||
if ( fVerbose )
|
||||
Gia_ManFraigPrintDebugInfo( p );
|
||||
|
||||
// count the number of equivalent objects
|
||||
Gia_ManForEachObj1( pClp, pObj, i )
|
||||
{
|
||||
|
|
@ -513,6 +777,11 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
vCarryOuts = Gia_ManComputeCarryOuts( p );
|
||||
Gia_ManForEachObjVec( vCarryOuts, p, pObj, i )
|
||||
pObj->fMark0 = 1;
|
||||
|
||||
// Additionally, mark box outputs that feed restricted flops using fMark1
|
||||
// This prevents box merging from indirectly eliminating restricted flops
|
||||
if ( p->vRegClasses || p->vFlopClasses )
|
||||
Gia_ManFraigMarkRestrictedBoxOutputs( p, fVerbose );
|
||||
if ( fVerbose )
|
||||
printf( "Fixed %d flop inputs and %d box/box connections (out of %d non-flop boxes).\n",
|
||||
Gia_ManRegBoxNum(p), Vec_IntSize(vCarryOuts), Gia_ManNonRegBoxNum(p) );
|
||||
|
|
@ -520,11 +789,23 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
|
||||
// collect equivalent node info
|
||||
pFlopTypes[0] = pFlopTypes[1] = pFlopTypes[2] = 0;
|
||||
if ( fVerbose )
|
||||
printf( "Checking flop equivalences in collapsed circuit:\n" );
|
||||
Gia_ManForEachRo( pClp, pObj, i )
|
||||
{
|
||||
Gia_Obj_t * pRepr = Gia_ObjReprObj(pClp, i);
|
||||
if ( pRepr && pRepr != pObj )
|
||||
{
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( " Flop %d (clp obj %d) has repr obj %d", i - Gia_ManPiNum(pClp),
|
||||
i, Gia_ObjId(pClp, pRepr) );
|
||||
if ( pRepr == Gia_ManConst0(pClp) )
|
||||
printf( " (const 0)");
|
||||
else if ( Gia_ObjIsRo(pClp, pRepr) )
|
||||
printf( " (another flop: %d)", Gia_ObjCioId(pRepr) - (Gia_ManPiNum(pClp) - Gia_ManRegNum(pClp)) );
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( pRepr == Gia_ManConst0(pClp) )
|
||||
pFlopTypes[0]++;
|
||||
else if ( Gia_ObjIsRo(pClp, pRepr) )
|
||||
|
|
@ -549,9 +830,21 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
if ( pClp2Gia[iReprClp] == -1 )
|
||||
pClp2Gia[iReprClp] = i;
|
||||
else
|
||||
{
|
||||
{
|
||||
iLitClp2 = Gia_ObjValue( Gia_ManObj(p, pClp2Gia[iReprClp]) );
|
||||
assert( Gia_ObjReprSelf(pClp, Abc_Lit2Var(iLitClp)) == Gia_ObjReprSelf(pClp, Abc_Lit2Var(iLitClp2)) );
|
||||
|
||||
// Debug: Show what's being merged
|
||||
if ( fVerbose )
|
||||
{
|
||||
Gia_Obj_t * pReprObj = Gia_ManObj(p, pClp2Gia[iReprClp]);
|
||||
Gia_ManFraigPrintEquivInfo( p, pObj, i, pReprObj, pClp2Gia, iLitClp, iReprClp );
|
||||
}
|
||||
|
||||
// Check flop restrictions for merging
|
||||
if ( Gia_ManFraigCheckFlopRestrictions( p, pObj, i, pClp2Gia, iReprClp, fVerbose, &nSkipped ) )
|
||||
continue;
|
||||
|
||||
fCompl = Abc_LitIsCompl(iLitClp) ^ Abc_LitIsCompl(iLitClp2);
|
||||
fCompl ^= Gia_ManObj(pClp, Abc_Lit2Var(iLitClp))->fPhase;
|
||||
fCompl ^= Gia_ManObj(pClp, Abc_Lit2Var(iLitClp2))->fPhase;
|
||||
|
|
@ -565,9 +858,16 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
}
|
||||
ABC_FREE( pClp2Gia );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
{
|
||||
pObj->fMark0 = 0;
|
||||
pObj->fMark1 = 0; // Clean up the restricted flop marker
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Found %d const objects and %d other objects.\n", nConsts, nReprs );
|
||||
if ( (p->vRegClasses || p->vFlopClasses) && nSkipped > 0 )
|
||||
printf( "Skipped %d flop mergings due to clock domain or merge class restrictions.\n", nSkipped );
|
||||
}
|
||||
return pReprs;
|
||||
}
|
||||
|
||||
|
|
@ -737,12 +1037,21 @@ Gia_Man_t * Gia_ManSweepWithBoxesAndDomains( Gia_Man_t * p, void * pParsS, int f
|
|||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS, int fConst, int fEquiv, int fVerbose, int fVerbEquivs )
|
||||
{
|
||||
{
|
||||
Gia_Man_t * pClp, * pNew, * pTemp;
|
||||
int * pReprs, pFlopTypes[3] = {0};
|
||||
int nFlopsNew, nFlops;
|
||||
assert( Gia_ManRegNum(p) == 0 );
|
||||
assert( p->pAigExtra != NULL );
|
||||
|
||||
// Debug: Check if vRegClasses and vFlopClasses are present
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( p->vRegClasses )
|
||||
printf( "Input has vRegClasses with %d entries\n", Vec_IntSize(p->vRegClasses) );
|
||||
if ( p->vFlopClasses )
|
||||
printf( "Input has vFlopClasses with %d entries\n", Vec_IntSize(p->vFlopClasses) );
|
||||
}
|
||||
// consider seq synthesis with multiple clock domains
|
||||
if ( pParsC == NULL && Gia_ManClockDomainNum(p) > 1 )
|
||||
return Gia_ManSweepWithBoxesAndDomains( p, pParsS, fConst, fEquiv, fVerbose, fVerbEquivs );
|
||||
|
|
|
|||
|
|
@ -44272,7 +44272,25 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Auto-detect K from cell library when -j is used
|
||||
if ( pPars->fEnableCheck07 && pPars->nLutSize == -1 )
|
||||
{
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)Abc_FrameReadLibCell();
|
||||
if ( pCellLib )
|
||||
{
|
||||
int nMaxInputs = If_LibCellGetMaxInputs( pCellLib );
|
||||
if ( nMaxInputs > 0 )
|
||||
{
|
||||
pPars->nLutSize = nMaxInputs;
|
||||
if ( pPars->fVerbose )
|
||||
Abc_Print( 1, "Auto-detected K=%d from cell library (max inputs).\n", nMaxInputs );
|
||||
// Disable LUT library since we're using K from cell library
|
||||
pPars->pLutLib = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
if ( !Abc_FrameReadFlag("silentmode") )
|
||||
|
|
@ -48454,20 +48472,30 @@ usage:
|
|||
***********************************************************************/
|
||||
int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Gia_ManDelayTraceDump( Gia_Man_t * p, char * pFileName );
|
||||
int c;
|
||||
int fUseLutLib;
|
||||
int fUseCellLib;
|
||||
int fVerbose;
|
||||
const char * pFileName = NULL;
|
||||
// set defaults
|
||||
fUseLutLib = 0;
|
||||
fUseCellLib = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "F:lcvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'F':
|
||||
pFileName = globalUtilOptarg;
|
||||
break;
|
||||
case 'l':
|
||||
fUseLutLib ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
fUseCellLib ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -48479,22 +48507,40 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Speedup(): There is no AIG to map.\n" );
|
||||
Abc_Print( -1, "Abc_CommandAbc9Trace(): There is no AIG to map.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Gia_ManHasMapping(pAbc->pGia) )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Speedup(): Mapping of the AIG is not defined.\n" );
|
||||
Abc_Print( -1, "Abc_CommandAbc9Trace(): Mapping of the AIG is not defined.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( fUseLutLib && fUseCellLib )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Trace(): Cannot use both LUT library (-l) and cell library (-c) simultaneously.\n" );
|
||||
return 1;
|
||||
}
|
||||
pAbc->pGia->pLutLib = fUseLutLib ? Abc_FrameReadLibLut() : NULL;
|
||||
Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose );
|
||||
pAbc->pGia->pCellLib = fUseCellLib ? Abc_FrameReadLibCell() : NULL;
|
||||
|
||||
if ( pFileName )
|
||||
{
|
||||
// Dump the delay trace to file
|
||||
Gia_ManDelayTraceDump( pAbc->pGia, (char *)pFileName );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print the delay trace to console
|
||||
Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose );
|
||||
}
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &trace [-lvh]\n" );
|
||||
Abc_Print( -2, "usage: &trace [-F file] [-lcvh]\n" );
|
||||
Abc_Print( -2, "\t performs delay trace of LUT-mapped network\n" );
|
||||
Abc_Print( -2, "\t-l : toggle using unit- or LUT-library-delay model [default = %s]\n", fUseLutLib? "lib": "unit" );
|
||||
Abc_Print( -2, "\t-F file : dump the critical path to a file [default = console output]\n" );
|
||||
Abc_Print( -2, "\t-l : toggle using LUT-library-delay model [default = %s]\n", fUseLutLib? "yes": "no" );
|
||||
Abc_Print( -2, "\t-c : toggle using cell-library-delay model [default = %s]\n", fUseCellLib? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -58778,10 +58824,11 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
extern void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose );
|
||||
extern Vec_Mem_t * Abc_TruthDecRead( char * pFileName, int nVarNum );
|
||||
extern void Abc_TtStoreDump( char * pFileName, Vec_Mem_t * vTtMem, int nBytes );
|
||||
int c, nVars, nVars2, nCutNum = 8, nCutSize = 0, nNumFuncs = 5, nNumCones = 3, fOutputs = 0, fVerbose = 0; word * pTruth = NULL;
|
||||
extern Vec_Mem_t * Dau_CollectBoothFunctions( int nLog2Radix );
|
||||
int c, nVars, nVars2, nCutNum = 32, nCutSize = 0, nBooth = 0, nNumFuncs = 5, nNumCones = 3, fOutputs = 0, fVerbose = 0; word * pTruth = NULL;
|
||||
char * pStr = NULL, * pFuncFileName = "_npn_member_funcs_.data"; Vec_Mem_t * vTtMem = NULL; Gia_Man_t * pTemp;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CKNMFovh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CKBNMFovh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -58807,6 +58854,24 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nCutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'B':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-B\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nBooth = atoi(argv[globalUtilOptind]);
|
||||
if ( nBooth < 4 || nBooth > 1024 ) {
|
||||
Abc_Print( -1, "Currently support radix value from 4 to 1024.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nBooth = Abc_Base2Log(nBooth);
|
||||
if ( (1 << nBooth) != atoi(argv[globalUtilOptind]) ) {
|
||||
Abc_Print( -1, "The Booth radix value %s is not a degree of 2.\n", argv[globalUtilOptind] );
|
||||
goto usage;
|
||||
}
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
|
|
@ -58857,21 +58922,28 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( argc == globalUtilOptind )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
int nFileSize = Gia_FileSize( pFuncFileName );
|
||||
if ( nFileSize == 0 )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): Truth table in hex notation (or file name with the functions) should be given on the command line.\n" );
|
||||
return 0;
|
||||
if ( nBooth ) {
|
||||
vTtMem = Dau_CollectBoothFunctions( nBooth );
|
||||
printf( "Generated %d %d-input booth radix-%d encoder functions.\n", 1<<(nBooth-1), nBooth+1, 1<<nBooth );
|
||||
nCutSize = nBooth+1;
|
||||
}
|
||||
if ( nCutSize == 0 )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): The cut size needs to be specified on the command line (-K <num>) when precomputed functions are used.\n" );
|
||||
return 0;
|
||||
else {
|
||||
abctime clkStart = Abc_Clock();
|
||||
int nFileSize = Gia_FileSize( pFuncFileName );
|
||||
if ( nFileSize == 0 )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): Truth table in hex notation (or file name with the functions) should be given on the command line.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( nCutSize == 0 )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): The cut size needs to be specified on the command line (-K <num>) when precomputed functions are used.\n" );
|
||||
return 0;
|
||||
}
|
||||
vTtMem = Abc_TruthDecRead( pFuncFileName, nCutSize );
|
||||
printf( "Finished reading %d %d-input function from file \"%s\". ", nFileSize / 8 / Abc_Truth6WordNum(nCutSize), nCutSize, pFuncFileName );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
}
|
||||
vTtMem = Abc_TruthDecRead( pFuncFileName, nCutSize );
|
||||
printf( "Finished reading %d %d-input function from file \"%s\". ", nFileSize / 8 / Abc_Truth6WordNum(nCutSize), nCutSize, pFuncFileName );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
Gia_ManMatchCuts( vTtMem, pAbc->pGia, nCutSize, nCutNum, fVerbose );
|
||||
Vec_MemHashFree( vTtMem );
|
||||
Vec_MemFree( vTtMem );
|
||||
|
|
@ -58933,10 +59005,11 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &funtrace [-CKNM num] [-F file] [-ovh] {<truth> or <file.aig>}\n" );
|
||||
Abc_Print( -2, "usage: &funtrace [-CKBNM num] [-F file] [-ovh] {<truth> or <file.aig>}\n" );
|
||||
Abc_Print( -2, "\t traces the presence of the function in the current AIG\n" );
|
||||
Abc_Print( -2, "\t-C num : the number of cuts to compute at each node [default = %d]\n", nCutNum );
|
||||
Abc_Print( -2, "\t-K num : the LUT size to use when <file.aig> is given [default = %d]\n", nCutSize );
|
||||
Abc_Print( -2, "\t-B num : the radix of booth partial products to detect [default = %d]\n", nBooth );
|
||||
Abc_Print( -2, "\t-N num : the number of functions to use when <file.aig> or -F <file> are used [default = %d]\n", nNumFuncs );
|
||||
Abc_Print( -2, "\t-M num : the number of logic cones to use when <file.aig> is given [default = %d]\n", nNumCones );
|
||||
Abc_Print( -2, "\t-F file : the file name to store the NPN member functions [default = %s]\n", pFuncFileName );
|
||||
|
|
|
|||
|
|
@ -1857,10 +1857,20 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
|
|||
int Beg = Wlc_ObjRangeBeg(pObj);
|
||||
if ( End >= Beg )
|
||||
{
|
||||
assert( nRange == End - Beg + 1 );
|
||||
assert( pFanin->Beg <= Beg && End <= pFanin->End );
|
||||
for ( k = Beg; k <= End; k++ )
|
||||
Vec_IntPush( vRes, pFans0[k - pFanin->Beg] );
|
||||
if ( pFanin->End >= pFanin->Beg )
|
||||
{
|
||||
assert( nRange == End - Beg + 1 );
|
||||
assert( pFanin->Beg <= Beg && End <= pFanin->End );
|
||||
for ( k = Beg; k <= End; k++ )
|
||||
Vec_IntPush( vRes, pFans0[k - pFanin->Beg] );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( nRange == End - Beg + 1 );
|
||||
assert( pFanin->End <= Beg && End <= pFanin->Beg );
|
||||
for ( k = Beg; k <= End; k++ )
|
||||
Vec_IntPush( vRes, pFans0[k - pFanin->End] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -641,6 +641,7 @@ extern float If_LibLutSlowestPinDelay( If_LibLut_t * p );
|
|||
extern If_LibCell_t * If_LibCellRead( char * FileName );
|
||||
extern If_LibCell_t * If_LibCellDup( If_LibCell_t * p );
|
||||
extern void If_LibCellFree( If_LibCell_t * pCellLib );
|
||||
extern int If_LibCellGetMaxInputs( If_LibCell_t * pCellLib );
|
||||
extern void If_LibCellPrint( If_LibCell_t * pCellLib );
|
||||
/*=== ifLibBox.c =============================================================*/
|
||||
extern If_LibBox_t * If_LibBoxStart();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "if.h"
|
||||
#include "aig/gia/gia.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -41,6 +42,9 @@ word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeav
|
|||
void If_PermUnpack( unsigned Value, int Pla2Var[9] )
|
||||
{
|
||||
}
|
||||
void Gia_ManDelayTraceDump( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -566,6 +566,28 @@ void If_LibCellFree( If_LibCell_t * pCellLib )
|
|||
ABC_FREE( pCellLib );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the maximum number of inputs in the cell library.]
|
||||
|
||||
Description [Used for auto-detecting K value for &if command.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_LibCellGetMaxInputs( If_LibCell_t * pCellLib )
|
||||
{
|
||||
int i, nMaxInputs = 0;
|
||||
if ( pCellLib == NULL )
|
||||
return 0;
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] > nMaxInputs )
|
||||
nMaxInputs = pCellLib->nCellInputs[i];
|
||||
return nMaxInputs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the cell library.]
|
||||
|
|
|
|||
|
|
@ -859,6 +859,52 @@ Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose )
|
|||
return vTtMem;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Function enumeration.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Mem_t * Dau_CollectBoothFunctions( int nLog2Radix )
|
||||
{
|
||||
assert( nLog2Radix >=2 && nLog2Radix <= 10 );
|
||||
int nVars = nLog2Radix + 1;
|
||||
int nWords = Abc_Truth6WordNum( nVars );
|
||||
int nFuncs = 1 << (nLog2Radix - 1);
|
||||
int nMints = 1 << nVars;
|
||||
Vec_Mem_t * vTtMem = Vec_MemAllocForTTSimple( nVars );
|
||||
word * pFuncs = ABC_CALLOC( word, nWords * nFuncs );
|
||||
int m, k, i;
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
int d = (m & 1);
|
||||
for ( k = 1; k < nLog2Radix; k++ )
|
||||
if ( m & (1 << k) )
|
||||
d += 1 << (k-1);
|
||||
if ( m & (1 << nLog2Radix) )
|
||||
d -= 1 << (nLog2Radix-1);
|
||||
if ( d == 0 )
|
||||
continue;
|
||||
if ( d < 0 )
|
||||
d = -d;
|
||||
assert( d >= 1 && d <= nFuncs );
|
||||
Abc_TtSetBit( pFuncs + (d-1)*nWords, m );
|
||||
}
|
||||
for ( i = 0; i < nFuncs; i++ ) {
|
||||
if ( nVars < 6 )
|
||||
pFuncs[i] = Abc_Tt6Stretch( pFuncs[i], nVars );
|
||||
Vec_MemHashInsert( vTtMem, pFuncs + i*nWords );
|
||||
}
|
||||
ABC_FREE( pFuncs );
|
||||
//Vec_MemDump( stdout, vTtMem );
|
||||
return vTtMem;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Function enumeration.]
|
||||
|
|
@ -1065,4 +1111,3 @@ void Dau_CanonicizeArray( Vec_Wrd_t * vFuncs, int nVars, int fVerbose )
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue