mirror of https://github.com/YosysHQ/abc.git
Version abc50827
This commit is contained in:
parent
9093ca5320
commit
28db025b83
2
abc.dsp
2
abc.dsp
|
|
@ -1113,7 +1113,7 @@ SOURCE=.\src\opt\rwr\rwr.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rwr\rwrCut.c
|
||||
SOURCE=.\src\opt\rwr\rwrDec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
|
|
|||
7
abc.rc
7
abc.rc
|
|
@ -20,6 +20,7 @@ alias rv read_verilog
|
|||
alias rsup read_super mcnc5_old.super
|
||||
alias rlib read_library
|
||||
alias rw rewrite
|
||||
alias rwz rewrite -z
|
||||
alias rf refactor
|
||||
alias rfz refactor -z
|
||||
alias sa set autoexec ps
|
||||
|
|
@ -31,7 +32,7 @@ alias wl write_blif
|
|||
alias wp write_pla
|
||||
alias cnf "st; renode -c; write_cnf"
|
||||
alias prove "st; renode -c; sat"
|
||||
alias opt "st; b; renode; sop; ps"
|
||||
alias opts "st; b; renode; sop; st; b; ps"
|
||||
alias share "st; b; renode -m; fx; st; b; ps"
|
||||
alias opt "b; renode; sop; b; ps"
|
||||
alias share "b; renode -m; fx; b; ps"
|
||||
alias resyn "b; rwz; rfz; b; rwz; rfz; b; ps"
|
||||
|
||||
|
|
|
|||
|
|
@ -848,7 +848,7 @@ usage:
|
|||
int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp;
|
||||
int c;
|
||||
int fDuplicate;
|
||||
|
||||
|
|
@ -878,14 +878,25 @@ int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsAig(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Cannot balance a network that is not an AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkBalance( pNtk, fDuplicate );
|
||||
if ( Abc_NtkIsAig(pNtk) )
|
||||
{
|
||||
pNtkRes = Abc_NtkBalance( pNtk, fDuplicate );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNtkTemp = Abc_NtkStrash( pNtk, 0 );
|
||||
if ( pNtkTemp == NULL )
|
||||
{
|
||||
fprintf( pErr, "Strashing before balancing has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
pNtkRes = Abc_NtkBalance( pNtkTemp, fDuplicate );
|
||||
Abc_NtkDelete( pNtkTemp );
|
||||
}
|
||||
|
||||
// check if balancing worked
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Balancing has failed.\n" );
|
||||
|
|
@ -897,7 +908,7 @@ int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
usage:
|
||||
fprintf( pErr, "usage: balance [-dh]\n" );
|
||||
fprintf( pErr, "\t transforms an AIG into a well-balanced AIG\n" );
|
||||
fprintf( pErr, "\t transforms the current network into a well-balanced AIG\n" );
|
||||
fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -1327,27 +1338,32 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
bool fVerbose;
|
||||
bool fPrecompute;
|
||||
bool fUseZeros;
|
||||
bool fVerbose;
|
||||
// external functions
|
||||
extern void Rwr_Precompute();
|
||||
extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNet(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fVerbose = 0;
|
||||
fPrecompute = 0;
|
||||
fUseZeros = 0;
|
||||
fVerbose = 0;
|
||||
util_getopt_reset();
|
||||
while ( ( c = util_getopt( argc, argv, "zvh" ) ) != EOF )
|
||||
while ( ( c = util_getopt( argc, argv, "xzvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'z':
|
||||
case 'x':
|
||||
fPrecompute ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
fUseZeros ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -1381,7 +1397,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
// modify the current network
|
||||
if ( !Abc_NtkRewrite( pNtk ) )
|
||||
if ( !Abc_NtkRewrite( pNtk, fUseZeros, fVerbose ) )
|
||||
{
|
||||
fprintf( pErr, "Rewriting has failed.\n" );
|
||||
return 1;
|
||||
|
|
@ -1389,8 +1405,9 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: rewrite [-vh]\n" );
|
||||
fprintf( pErr, "usage: rewrite [-zvh]\n" );
|
||||
fprintf( pErr, "\t performs technology-independent rewriting of the AIG\n" );
|
||||
fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -1428,7 +1445,7 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
nConeSizeMax = 16;
|
||||
fUseZeros = 0;
|
||||
fUseDcs = 0;
|
||||
fVerbose = 1;
|
||||
fVerbose = 0;
|
||||
util_getopt_reset();
|
||||
while ( ( c = util_getopt( argc, argv, "NCzdvh" ) ) != EOF )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,8 +144,13 @@ struct Abc_Ntk_t_
|
|||
int nPos; // the number of primary outputs
|
||||
// the functionality manager
|
||||
void * pManFunc; // AIG manager, BDD manager, or memory manager for SOPs
|
||||
// the timing manager
|
||||
// the timing manager (for mapped networks)
|
||||
Abc_ManTime_t * pManTime; // stores arrival/required times for all nodes
|
||||
// the cut manager (for AIGs)
|
||||
void * pManCut; // stores information about the cuts computed for the nodes
|
||||
// level information (for AIGs)
|
||||
int LevelMax; // maximum number of levels
|
||||
Vec_Int_t * vLevelsR; // level in the reverse topological order
|
||||
// the external don't-care if given
|
||||
Abc_Ntk_t * pExdc; // the EXDC network
|
||||
// miscellaneous data members
|
||||
|
|
@ -423,6 +428,11 @@ extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFani
|
|||
extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
|
||||
extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
|
||||
extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode );
|
||||
/*=== abcCut.c ==========================================================*/
|
||||
extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj );
|
||||
extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj );
|
||||
extern void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj );
|
||||
extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj );
|
||||
/*=== abcDfs.c ==========================================================*/
|
||||
extern Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
|
||||
extern Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||
|
|
@ -572,7 +582,11 @@ extern void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtk );
|
|||
extern float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk );
|
||||
extern float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Int_t * Abc_NtkGetRequiredLevels( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR );
|
||||
extern int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj );
|
||||
extern int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj );
|
||||
/*=== abcTravId.c ==========================================================*/
|
||||
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NodeSetTravId( Abc_Obj_t * pObj, int TravId );
|
||||
|
|
@ -609,6 +623,7 @@ extern void Abc_NodeFreeFaninNames( Vec_Ptr_t * vNames );
|
|||
extern char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos );
|
||||
extern void Abc_NtkAlphaOrderSignals( Abc_Ntk_t * pNtk, int fComb );
|
||||
extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct Abc_Aig_t_
|
|||
Vec_Ptr_t * vStackReplaceOld; // the nodes to be replaced
|
||||
Vec_Ptr_t * vStackReplaceNew; // the nodes to be used for replacement
|
||||
Vec_Vec_t * vLevels; // the nodes to be updated
|
||||
Vec_Vec_t * vLevelsR; // the nodes to be updated
|
||||
};
|
||||
|
||||
// iterators through the entries in the linked lists of nodes
|
||||
|
|
@ -85,6 +86,9 @@ static void Abc_AigResize( Abc_Aig_t * pMan );
|
|||
static void Abc_AigReplace_int( Abc_Aig_t * pMan );
|
||||
static void Abc_AigDelete_int( Abc_Aig_t * pMan );
|
||||
static void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan );
|
||||
static void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan );
|
||||
static void Abc_AigRemoveFromLevelStructure( Vec_Vec_t * vStruct, Abc_Obj_t * pNode );
|
||||
static void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
|
|
@ -116,6 +120,7 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
|
|||
pMan->vStackReplaceOld = Vec_PtrAlloc( 100 );
|
||||
pMan->vStackReplaceNew = Vec_PtrAlloc( 100 );
|
||||
pMan->vLevels = Vec_VecAlloc( 100 );
|
||||
pMan->vLevelsR = Vec_VecAlloc( 100 );
|
||||
// save the current network
|
||||
pMan->pNtkAig = pNtkAig;
|
||||
// allocate constant nodes
|
||||
|
|
@ -199,6 +204,7 @@ void Abc_AigFree( Abc_Aig_t * pMan )
|
|||
assert( Vec_PtrSize( pMan->vStackReplaceNew ) == 0 );
|
||||
// free the table
|
||||
Vec_VecFree( pMan->vLevels );
|
||||
Vec_VecFree( pMan->vLevelsR );
|
||||
Vec_PtrFree( pMan->vStackDelete );
|
||||
Vec_PtrFree( pMan->vStackReplaceOld );
|
||||
Vec_PtrFree( pMan->vStackReplaceNew );
|
||||
|
|
@ -381,6 +387,9 @@ Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
|
|||
pAnd->pNext = pMan->pBins[Key];
|
||||
pMan->pBins[Key] = pAnd;
|
||||
pMan->nEntries++;
|
||||
// create the cuts if defined
|
||||
// if ( pAnd->pNtk->pManCut )
|
||||
// Abc_NodeGetCuts( pAnd->pNtk->pManCut, pAnd );
|
||||
return pAnd;
|
||||
}
|
||||
|
||||
|
|
@ -399,6 +408,7 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t *
|
|||
{
|
||||
Abc_Obj_t * pTemp;
|
||||
unsigned Key;
|
||||
assert( !Abc_ObjIsComplement(pAnd) );
|
||||
// order the arguments
|
||||
if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id )
|
||||
pTemp = p0, p0 = p1, p1 = pTemp;
|
||||
|
|
@ -412,6 +422,9 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t *
|
|||
Key = Abc_HashKey2( p0, p1, pMan->nBins );
|
||||
pAnd->pNext = pMan->pBins[Key];
|
||||
pMan->pBins[Key] = pAnd;
|
||||
// create the cuts if defined
|
||||
// if ( pAnd->pNtk->pManCut )
|
||||
// Abc_NodeGetCuts( pAnd->pNtk->pManCut, pAnd );
|
||||
return pAnd;
|
||||
}
|
||||
|
||||
|
|
@ -494,6 +507,9 @@ void Abc_AigAndDelete( Abc_Aig_t * pMan, Abc_Obj_t * pThis )
|
|||
}
|
||||
assert( pAnd == pThis );
|
||||
pMan->nEntries--;
|
||||
// delete the cuts if defined
|
||||
if ( pThis->pNtk->pManCut )
|
||||
Abc_NodeFreeCuts( pThis->pNtk->pManCut, pThis );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -644,9 +660,8 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew )
|
|||
Vec_PtrPush( pMan->vStackReplaceNew, pNew );
|
||||
while ( Vec_PtrSize(pMan->vStackReplaceOld) )
|
||||
Abc_AigReplace_int( pMan );
|
||||
// while ( Vec_PtrSize(pMan->vStackDelete) )
|
||||
// Abc_AigDelete_int( pMan );
|
||||
Abc_AigUpdateLevel_int( pMan );
|
||||
Abc_AigUpdateLevelR_int( pMan );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -705,8 +720,14 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan )
|
|||
Abc_ObjRemoveFanins( pFanout );
|
||||
// recreate the old fanout with new fanins and add it to the table
|
||||
Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout );
|
||||
// schedule the updated fanout for updating level
|
||||
// schedule the updated fanout for updating direct level
|
||||
assert( pFanout->fMarkA == 0 );
|
||||
pFanout->fMarkA = 1;
|
||||
Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
|
||||
// schedule the updated fanout for updating reverse level
|
||||
assert( pFanout->fMarkB == 0 );
|
||||
pFanout->fMarkB = 1;
|
||||
Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanout), pFanout );
|
||||
// the fanout has changed, update EXOR status of its fanouts
|
||||
Abc_ObjForEachFanout( pFanout, pFanoutFanout, v )
|
||||
if ( Abc_NodeIsAigAnd(pFanoutFanout) )
|
||||
|
|
@ -764,20 +785,111 @@ void Abc_AigDelete_int( Abc_Aig_t * pMan )
|
|||
|
||||
// collect the MFFC
|
||||
vNodes = Abc_NodeMffcCollect( pRoot );
|
||||
|
||||
// if reverse levels are specified, schedule fanins of MFFC for updating
|
||||
// currently, we do not do it because we do not know the correct level of the fanins
|
||||
// also, it is unlikely that this will make a difference since we are
|
||||
// processing the network forward while at this point fanins are left behind...
|
||||
/*
|
||||
if ( pObj->pNtk->vLevelsR )
|
||||
Vec_PtrForEachEntry( vNodes, pObj, k )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
if ( Abc_ObjIsCi(pObj) )
|
||||
continue;
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
if ( pFanin->fMarkB == 0 )
|
||||
{
|
||||
pFanin->fMarkB = 1;
|
||||
Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanin), pFanin );
|
||||
}
|
||||
pFanin = Abc_ObjFanin1(pObj);
|
||||
if ( pFanin->fMarkB == 0 )
|
||||
{
|
||||
pFanin->fMarkB = 1;
|
||||
Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanin), pFanin );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// delete the nodes in MFFC
|
||||
Vec_PtrForEachEntry( vNodes, pObj, k )
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObj) )
|
||||
continue;
|
||||
assert( pObj->fMarkA == 0 );
|
||||
assert( Abc_ObjFanoutNum(pObj) == 0 );
|
||||
// remove the node from the table
|
||||
Abc_AigAndDelete( pMan, pObj );
|
||||
// if the node is in the level structure, remove it
|
||||
if ( pObj->fMarkA )
|
||||
Abc_AigRemoveFromLevelStructure( pMan->vLevels, pObj );
|
||||
if ( pObj->fMarkB )
|
||||
Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pObj );
|
||||
// remove the node from the network
|
||||
//printf( "Removing " ); Abc_AigPrintNode( pObj );
|
||||
Abc_NtkDeleteObj( pObj );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the level of the node after it has changed.]
|
||||
|
||||
Description [This procedure is based on the observation that
|
||||
after the node's level has changed, the fanouts levels can change too,
|
||||
but the new fanout levels are always larger than the node's level.
|
||||
As a result, we can accumulate the nodes to be updated in the queue
|
||||
and process them in the increasing order of levels.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan )
|
||||
{
|
||||
Abc_Obj_t * pNode, * pFanout;
|
||||
Vec_Ptr_t * vVec;
|
||||
int LevelNew, i, k, v;
|
||||
|
||||
// go through the nodes and update the level of their fanouts
|
||||
Vec_VecForEachLevel( pMan->vLevels, vVec, i )
|
||||
{
|
||||
if ( Vec_PtrSize(vVec) == 0 )
|
||||
continue;
|
||||
Vec_PtrForEachEntry( vVec, pNode, k )
|
||||
{
|
||||
if ( pNode == NULL )
|
||||
continue;
|
||||
assert( Abc_ObjIsNode(pNode) );
|
||||
// clean the mark
|
||||
assert( pNode->fMarkA == 1 );
|
||||
pNode->fMarkA = 0;
|
||||
// iterate through the fanouts
|
||||
Abc_ObjForEachFanout( pNode, pFanout, v )
|
||||
{
|
||||
if ( Abc_ObjIsCo(pFanout) )
|
||||
continue;
|
||||
// get the new level of this fanout
|
||||
LevelNew = 1 + ABC_MAX( Abc_ObjFanin0(pFanout)->Level, Abc_ObjFanin1(pFanout)->Level );
|
||||
assert( LevelNew > i );
|
||||
if ( (int)pFanout->Level == LevelNew ) // no change
|
||||
continue;
|
||||
// if the fanout is present in the data structure, pull it out
|
||||
if ( pFanout->fMarkA )
|
||||
Abc_AigRemoveFromLevelStructure( pMan->vLevels, pFanout );
|
||||
// update the fanout level
|
||||
pFanout->Level = LevelNew;
|
||||
// add the fanout to the data structure to update its fanouts
|
||||
assert( pFanout->fMarkA == 0 );
|
||||
pFanout->fMarkA = 1;
|
||||
Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
|
||||
}
|
||||
}
|
||||
Vec_PtrClear( vVec );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the level of the node after it has changed.]
|
||||
|
|
@ -789,44 +901,111 @@ void Abc_AigDelete_int( Abc_Aig_t * pMan )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan )
|
||||
void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan )
|
||||
{
|
||||
Abc_Obj_t * pNode, * pFanout;
|
||||
Abc_Obj_t * pNode, * pFanin, * pFanout;
|
||||
Vec_Ptr_t * vVec;
|
||||
unsigned LevelNew;
|
||||
int i, k, v;
|
||||
int LevelNew, i, k, v, j;
|
||||
|
||||
// go through the nodes and update the level of their fanouts
|
||||
Vec_VecForEachLevel( pMan->vLevels, vVec, i )
|
||||
Vec_VecForEachLevel( pMan->vLevelsR, vVec, i )
|
||||
{
|
||||
if ( Vec_PtrSize(vVec) == 0 )
|
||||
continue;
|
||||
Vec_PtrForEachEntry( vVec, pNode, k )
|
||||
{
|
||||
// assert( Abc_ObjIsNode(pNode) );
|
||||
// for some reason, deleted nodes are encountered here!!!
|
||||
if ( !Abc_ObjIsNode(pNode) )
|
||||
if ( pNode == NULL )
|
||||
continue;
|
||||
// iterate through the fanouts
|
||||
Abc_ObjForEachFanout( pNode, pFanout, v )
|
||||
assert( Abc_ObjIsNode(pNode) );
|
||||
// clean the mark
|
||||
assert( pNode->fMarkB == 1 );
|
||||
pNode->fMarkB = 0;
|
||||
// iterate through the fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, v )
|
||||
{
|
||||
if ( Abc_ObjIsCo(pFanout) )
|
||||
if ( Abc_ObjIsCi(pFanin) )
|
||||
continue;
|
||||
// get the new level of this fanout
|
||||
LevelNew = 1 + ABC_MAX( Abc_ObjFanin0(pFanout)->Level, Abc_ObjFanin1(pFanout)->Level );
|
||||
if ( pFanout->Level == LevelNew ) // no change
|
||||
// get the new reverse level of this fanin
|
||||
LevelNew = 0;
|
||||
Abc_ObjForEachFanout( pFanin, pFanout, j )
|
||||
if ( LevelNew < Abc_NodeReadReverseLevel(pFanout) )
|
||||
LevelNew = Abc_NodeReadReverseLevel(pFanout);
|
||||
LevelNew += 1;
|
||||
assert( LevelNew > i );
|
||||
if ( Abc_NodeReadReverseLevel(pFanin) == LevelNew ) // no change
|
||||
continue;
|
||||
// update the fanout level
|
||||
pFanout->Level = LevelNew;
|
||||
// add the fanout to be updated
|
||||
Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
|
||||
// if the fanin is present in the data structure, pull it out
|
||||
if ( pFanin->fMarkB )
|
||||
Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pFanin );
|
||||
// update the reverse level
|
||||
Abc_NodeSetReverseLevel( pFanin, LevelNew );
|
||||
// add the fanin to the data structure to update its fanins
|
||||
assert( pFanin->fMarkB == 0 );
|
||||
pFanin->fMarkB = 1;
|
||||
Vec_VecPush( pMan->vLevelsR, LevelNew, pFanin );
|
||||
}
|
||||
}
|
||||
Vec_PtrClear( vVec );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes the node from the level structure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_AigRemoveFromLevelStructure( Vec_Vec_t * vStruct, Abc_Obj_t * pNode )
|
||||
{
|
||||
Vec_Ptr_t * vVecTemp;
|
||||
Abc_Obj_t * pTemp;
|
||||
int m;
|
||||
assert( pNode->fMarkA );
|
||||
vVecTemp = Vec_VecEntry( vStruct, pNode->Level );
|
||||
Vec_PtrForEachEntry( vVecTemp, pTemp, m )
|
||||
{
|
||||
if ( pTemp != pNode )
|
||||
continue;
|
||||
Vec_PtrWriteEntry( vVecTemp, m, NULL );
|
||||
break;
|
||||
}
|
||||
assert( m < Vec_PtrSize(vVecTemp) ); // found
|
||||
pNode->fMarkA = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes the node from the level structure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode )
|
||||
{
|
||||
Vec_Ptr_t * vVecTemp;
|
||||
Abc_Obj_t * pTemp;
|
||||
int m;
|
||||
assert( pNode->fMarkB );
|
||||
vVecTemp = Vec_VecEntry( vStruct, Abc_NodeReadReverseLevel(pNode) );
|
||||
Vec_PtrForEachEntry( vVecTemp, pTemp, m )
|
||||
{
|
||||
if ( pTemp != pNode )
|
||||
continue;
|
||||
Vec_PtrWriteEntry( vVecTemp, m, NULL );
|
||||
break;
|
||||
}
|
||||
assert( m < Vec_PtrSize(vVecTemp) ); // found
|
||||
pNode->fMarkB = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -404,6 +404,11 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
|
|||
printf( "Warning: Node %s has", Abc_ObjName(pObj) );
|
||||
printf( " duplicated fanin %s.\n", Abc_ObjName(Abc_ObjFanin(pObj,k)) );
|
||||
}
|
||||
|
||||
// save time: do not check large fanout lists
|
||||
if ( pObj->vFanouts.nSize > 20 )
|
||||
return Value;
|
||||
|
||||
// make sure fanouts are not duplicated
|
||||
for ( i = 0; i < pObj->vFanouts.nSize; i++ )
|
||||
for ( k = i + 1; k < pObj->vFanouts.nSize; k++ )
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
|
|
@ -78,8 +76,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
|||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
// compute the cuts to the internal node
|
||||
Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
Abc_NodeGetCuts( p, pObj );
|
||||
// add cuts due to choices
|
||||
if ( Abc_NodeIsAigChoice(pObj) )
|
||||
{
|
||||
|
|
@ -118,7 +115,7 @@ PRT( "Total", clock() - clk );
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the array of fanout counters.]
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -127,27 +124,63 @@ PRT( "Total", clock() - clk );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk )
|
||||
void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Vec_Int_t * vFanNums;
|
||||
Abc_Obj_t * pObj;//, * pFanout;
|
||||
int i;//, k, nFanouts;
|
||||
vFanNums = Vec_IntAlloc( 0 );
|
||||
Vec_IntFill( vFanNums, Abc_NtkObjNumMax(pNtk), -1 );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) )
|
||||
{
|
||||
Vec_IntWriteEntry( vFanNums, i, Abc_ObjFanoutNum(pObj) );
|
||||
/*
|
||||
// get the number of non-CO fanouts
|
||||
nFanouts = 0;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, k )
|
||||
if ( !Abc_ObjIsCo(pFanout) )
|
||||
nFanouts++;
|
||||
Vec_IntWriteEntry( vFanNums, i, nFanouts );
|
||||
*/
|
||||
}
|
||||
return vFanNums;
|
||||
void * pList;
|
||||
if ( pList = Abc_NodeReadCuts( p, pObj ) )
|
||||
return pList;
|
||||
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj) );
|
||||
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj) );
|
||||
return Abc_NodeGetCuts( p, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
return Cut_NodeReadCuts( p, pObj->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Cut_NodeFreeCuts( p, pObj->Id );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct Abc_ManRef_t_
|
|||
int fVerbose; // the verbosity flag
|
||||
// internal data structures
|
||||
DdManager * dd; // the BDD manager
|
||||
Vec_Int_t * vReqTimes; // required times for each node
|
||||
// Vec_Int_t * vReqTimes; // required times for each node
|
||||
Vec_Str_t * vCube; // temporary
|
||||
Vec_Int_t * vForm; // temporary
|
||||
Vec_Int_t * vLevNums; // temporary
|
||||
|
|
@ -51,6 +51,7 @@ struct Abc_ManRef_t_
|
|||
int timeDcs;
|
||||
int timeSop;
|
||||
int timeFact;
|
||||
int timeEval;
|
||||
int timeRes;
|
||||
int timeNtk;
|
||||
int timeTotal;
|
||||
|
|
@ -98,7 +99,7 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool
|
|||
pManCut = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax );
|
||||
pManRef = Abc_NtkManRefStart( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose );
|
||||
pManRef->vLeaves = Abc_NtkManCutReadLeaves( pManCut );
|
||||
pManRef->vReqTimes = Abc_NtkGetRequiredLevels( pNtk );
|
||||
Abc_NtkStartReverseLevels( pNtk );
|
||||
|
||||
// resynthesize each node once
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
|
|
@ -137,6 +138,7 @@ pManRef->timeTotal = clock() - clkStart;
|
|||
// delete the managers
|
||||
Abc_NtkManCutStop( pManCut );
|
||||
Abc_NtkManRefStop( pManRef );
|
||||
Abc_NtkStopReverseLevels( pNtk );
|
||||
// check
|
||||
if ( fCheck && !Abc_NtkCheck( pNtk ) )
|
||||
{
|
||||
|
|
@ -165,10 +167,13 @@ Vec_Int_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * v
|
|||
DdNode * bNodeFunc, * bNodeDc, * bNodeOn, * bNodeOnDc;
|
||||
char * pSop;
|
||||
int nBddNodes, nFtNodes, nNodesSaved, nNodesAdded;
|
||||
int i, clk;
|
||||
int i, Required, clk;
|
||||
|
||||
p->nNodesConsidered++;
|
||||
|
||||
// get the required level of this node
|
||||
Required = Abc_NodeReadRequiredLevel( pNode );
|
||||
|
||||
// get the function of the cut
|
||||
clk = clock();
|
||||
bNodeFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pNode, vFanins, p->vVisited ); Cudd_Ref( bNodeFunc );
|
||||
|
|
@ -186,7 +191,7 @@ clk = clock();
|
|||
|
||||
nMints = (1 << vFanins->nSize);
|
||||
nMintsDc = (int)Cudd_CountMinterm( p->dd, bNodeDc, vFanins->nSize );
|
||||
printf( "Percentage of minterms = %5.2f.\n", 100.0 * nMintsDc / nMints );
|
||||
// printf( "Percentage of minterms = %5.2f.\n", 100.0 * nMintsDc / nMints );
|
||||
|
||||
// get the ISF
|
||||
bNodeOn = Cudd_bddAnd( p->dd, bNodeFunc, Cudd_Not(bNodeDc) ); Cudd_Ref( bNodeOn );
|
||||
|
|
@ -204,13 +209,16 @@ p->timeDcs += clock() - clk;
|
|||
// always accept the case of constant node
|
||||
if ( Cudd_IsConstant(bNodeFunc) )
|
||||
{
|
||||
p->nNodesGained += Abc_NodeMffcSize( pNode );
|
||||
p->nLastGain = Abc_NodeMffcSize( pNode );
|
||||
p->nNodesGained += p->nLastGain;
|
||||
p->nNodesRefactored++;
|
||||
// get the costant node
|
||||
pFanin = Abc_ObjNotCond( Abc_AigConst1(pNode->pNtk->pManFunc), Cudd_IsComplement(bNodeFunc) );
|
||||
Abc_AigReplace( pNode->pNtk->pManFunc, pNode, pFanin );
|
||||
// get the constant node
|
||||
// pFanin = Abc_ObjNotCond( Abc_AigConst1(pNode->pNtk->pManFunc), Cudd_IsComplement(bNodeFunc) );
|
||||
// Abc_AigReplace( pNode->pNtk->pManFunc, pNode, pFanin );
|
||||
// Cudd_RecursiveDeref( p->dd, bNodeFunc );
|
||||
//printf( "Gain = %d.\n", p->nLastGain );
|
||||
Cudd_RecursiveDeref( p->dd, bNodeFunc );
|
||||
return NULL;
|
||||
return Ft_FactorConst( !Cudd_IsComplement(bNodeFunc) );
|
||||
}
|
||||
|
||||
// get the SOP of the cut
|
||||
|
|
@ -241,8 +249,10 @@ p->timeFact += clock() - clk;
|
|||
pFanin->vFanouts.nSize--;
|
||||
|
||||
// detect how many new nodes will be added (while taking into account reused nodes)
|
||||
clk = clock();
|
||||
nNodesAdded = Abc_NodeStrashDecCount( pNode->pNtk->pManFunc, pNode, vFanins, vForm,
|
||||
p->vLevNums, nNodesSaved, Vec_IntEntry( p->vReqTimes, pNode->Id ) );
|
||||
p->vLevNums, nNodesSaved, Required );
|
||||
p->timeEval += clock() - clk;
|
||||
// quit if there is no improvement
|
||||
if ( nNodesAdded == -1 || nNodesAdded == nNodesSaved && !fUseZeros )
|
||||
{
|
||||
|
|
@ -316,7 +326,7 @@ Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUse
|
|||
void Abc_NtkManRefStop( Abc_ManRef_t * p )
|
||||
{
|
||||
Extra_StopManager( p->dd );
|
||||
Vec_IntFree( p->vReqTimes );
|
||||
// Vec_IntFree( p->vReqTimes );
|
||||
Vec_PtrFree( p->vVisited );
|
||||
Vec_IntFree( p->vLevNums );
|
||||
Vec_StrFree( p->vCube );
|
||||
|
|
@ -337,15 +347,16 @@ void Abc_NtkManRefStop( Abc_ManRef_t * p )
|
|||
void Abc_NtkManRefPrintStats( Abc_ManRef_t * p )
|
||||
{
|
||||
printf( "Refactoring statistics:\n" );
|
||||
printf( "Nodes considered = %6d.\n", p->nNodesConsidered );
|
||||
printf( "Nodes refactored = %6d.\n", p->nNodesRefactored );
|
||||
printf( "Calculated gain = %6d.\n", p->nNodesGained );
|
||||
printf( "Nodes considered = %8d.\n", p->nNodesConsidered );
|
||||
printf( "Nodes refactored = %8d.\n", p->nNodesRefactored );
|
||||
printf( "Calculated gain = %8d.\n", p->nNodesGained );
|
||||
PRT( "Cuts ", p->timeCut );
|
||||
PRT( "Resynthesis", p->timeRes );
|
||||
PRT( " BDD ", p->timeBdd );
|
||||
PRT( " DCs ", p->timeDcs );
|
||||
PRT( " SOP ", p->timeSop );
|
||||
PRT( " FF ", p->timeFact );
|
||||
PRT( " Eval ", p->timeEval );
|
||||
PRT( "AIG update ", p->timeNtk );
|
||||
PRT( "TOTAL ", p->timeTotal );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,10 +124,7 @@ int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t
|
|||
int Counter;
|
||||
// label visited nodes
|
||||
if ( fLabel )
|
||||
{
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
//printf( "Labeling " ); Abc_AigPrintNode( pNode );
|
||||
}
|
||||
// collect visited nodes
|
||||
if ( vNodes )
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
|
|
|
|||
|
|
@ -20,11 +20,15 @@
|
|||
|
||||
#include "abc.h"
|
||||
#include "rwr.h"
|
||||
#include "ft.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop );
|
||||
static void Abc_NodePrintCuts( Abc_Obj_t * pNode );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -40,20 +44,28 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRewrite( Abc_Ntk_t * pNtk )
|
||||
int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose )
|
||||
{
|
||||
int fCheck = 1;
|
||||
int fDrop = 0;
|
||||
ProgressBar * pProgress;
|
||||
Rwr_Man_t * p;
|
||||
Cut_Man_t * pManCut;
|
||||
Rwr_Man_t * pManRwr;
|
||||
Abc_Obj_t * pNode;
|
||||
int i, nNodes, nGain;
|
||||
int clk, clkStart = clock();
|
||||
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
// start the rewriting manager
|
||||
p = Rwr_ManStart( 0 );
|
||||
if ( p == NULL )
|
||||
pManRwr = Rwr_ManStart( 0 );
|
||||
if ( pManRwr == NULL )
|
||||
return 0;
|
||||
Rwr_ManPrepareNetwork( p, pNtk );
|
||||
Abc_NtkStartReverseLevels( pNtk );
|
||||
// start the cut manager
|
||||
clk = clock();
|
||||
pManCut = Abc_NtkStartCutManForRewrite( pNtk, fDrop );
|
||||
Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
|
||||
pNtk->pManCut = pManCut;
|
||||
|
||||
// resynthesize each node once
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
|
|
@ -68,12 +80,28 @@ int Abc_NtkRewrite( Abc_Ntk_t * pNtk )
|
|||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
// for each cut, try to resynthesize it
|
||||
if ( (nGain = Rwr_NodeRewrite( p, pNode )) >= 0 )
|
||||
Abc_NodeUpdate( pNode, Rwr_ManReadFanins(p), Rwr_ManReadDecs(p), nGain );
|
||||
nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUseZeros );
|
||||
if ( nGain > 0 || nGain == 0 && fUseZeros )
|
||||
{
|
||||
Vec_Int_t * vForm = Rwr_ManReadDecs(pManRwr);
|
||||
Vec_Ptr_t * vFanins = Rwr_ManReadFanins(pManRwr);
|
||||
int fCompl = Rwr_ManReadCompl(pManRwr);
|
||||
// complement the FF if needed
|
||||
if ( fCompl ) Ft_FactorComplement( vForm );
|
||||
Abc_NodeUpdate( pNode, vFanins, vForm, nGain );
|
||||
if ( fCompl ) Ft_FactorComplement( vForm );
|
||||
}
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
// delete the manager
|
||||
Rwr_ManStop( p );
|
||||
Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart );
|
||||
// print stats
|
||||
if ( fVerbose )
|
||||
Rwr_ManPrintStats( pManRwr );
|
||||
// delete the managers
|
||||
Rwr_ManStop( pManRwr );
|
||||
Cut_ManStop( pManCut );
|
||||
pNtk->pManCut = NULL;
|
||||
Abc_NtkStopReverseLevels( pNtk );
|
||||
// check
|
||||
if ( fCheck && !Abc_NtkCheck( pNtk ) )
|
||||
{
|
||||
|
|
@ -84,6 +112,70 @@ int Abc_NtkRewrite( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the cut manager for rewriting.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop )
|
||||
{
|
||||
static Cut_Params_t Params, * pParams = &Params;
|
||||
Cut_Man_t * pManCut;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// start the cut manager
|
||||
memset( pParams, 0, sizeof(Cut_Params_t) );
|
||||
pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts)
|
||||
pParams->nKeepMax = 250; // the max number of cuts kept at a node
|
||||
pParams->fTruth = 1; // compute truth tables
|
||||
pParams->fHash = 1; // hash cuts to detect unique
|
||||
pParams->fFilter = 0; // filter dominated cuts
|
||||
pParams->fSeq = 0; // compute sequential cuts
|
||||
pParams->fDrop = fDrop; // drop cuts on the fly
|
||||
pParams->fVerbose = 0; // the verbosiness flag
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
pManCut = Cut_ManStart( pParams );
|
||||
if ( pParams->fDrop )
|
||||
Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
|
||||
// set cuts for PIs
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_NodeSetTriv( pManCut, pObj->Id );
|
||||
return pManCut;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the cuts at the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodePrintCuts( Abc_Obj_t * pNode )
|
||||
{
|
||||
Cut_Cut_t * pCut;
|
||||
unsigned uTruth;
|
||||
printf( "\nNode %s\n", Abc_ObjName(pNode) );
|
||||
for ( pCut = (Cut_Cut_t *)pNode->pCopy; pCut; pCut = pCut->pNext )
|
||||
{
|
||||
uTruth = pCut->uTruth;
|
||||
Extra_PrintBinary( stdout, &uTruth, 16 );
|
||||
printf( " " );
|
||||
Cut_CutPrint( pCut );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -318,12 +318,12 @@ Abc_Obj_t * Abc_NodeStrashDec( Abc_Aig_t * pMan, Vec_Ptr_t * vFanins, Vec_Int_t
|
|||
nVars = Ft_FactorGetNumVars( vForm );
|
||||
assert( nVars >= 0 );
|
||||
assert( vForm->nSize > nVars );
|
||||
assert( nVars == vFanins->nSize );
|
||||
|
||||
// check for constant function
|
||||
pFtNode = Ft_NodeRead( vForm, 0 );
|
||||
if ( pFtNode->fConst )
|
||||
return Abc_ObjNotCond( Abc_AigConst1(pMan), pFtNode->fCompl );
|
||||
assert( nVars == vFanins->nSize );
|
||||
|
||||
// compute the function of other nodes
|
||||
for ( i = nVars; i < vForm->nSize; i++ )
|
||||
|
|
@ -365,17 +365,17 @@ int Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, Vec_Ptr_t * vFa
|
|||
nVars = Ft_FactorGetNumVars( vForm );
|
||||
assert( nVars >= 0 );
|
||||
assert( vForm->nSize > nVars );
|
||||
assert( nVars == vFanins->nSize ); // set the fanin number to nVars???
|
||||
|
||||
// check for constant function
|
||||
pFtNode = Ft_NodeRead( vForm, 0 );
|
||||
if ( pFtNode->fConst )
|
||||
return 0;
|
||||
assert( nVars == vFanins->nSize );
|
||||
|
||||
// set the levels
|
||||
Vec_IntClear( vLevels );
|
||||
Vec_PtrForEachEntry( vFanins, pAnd, i )
|
||||
Vec_IntPush( vLevels, pAnd->Level );
|
||||
Vec_IntPush( vLevels, Abc_ObjRegular(pAnd)->Level );
|
||||
|
||||
// compute the function of other nodes
|
||||
Counter = 0;
|
||||
|
|
@ -422,9 +422,17 @@ int Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, Vec_Ptr_t * vFa
|
|||
}
|
||||
|
||||
// count the number of new levels
|
||||
if ( pAnd && Abc_ObjRegular(pAnd) == Abc_AigConst1(pMan) )
|
||||
LevelNew = 0;
|
||||
else
|
||||
LevelNew = -1;
|
||||
if ( pAnd )
|
||||
{
|
||||
if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pMan) )
|
||||
LevelNew = 0;
|
||||
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) )
|
||||
LevelNew = (int)Abc_ObjRegular(pAnd0)->Level;
|
||||
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd1) )
|
||||
LevelNew = (int)Abc_ObjRegular(pAnd1)->Level;
|
||||
}
|
||||
if ( LevelNew == -1 )
|
||||
LevelNew = 1 + ABC_MAX( Vec_IntEntry(vLevels, pFtNode->iFanin0), Vec_IntEntry(vLevels, pFtNode->iFanin1) );
|
||||
|
||||
// assert( pAnd == NULL || LevelNew == LevelOld );
|
||||
|
|
@ -433,7 +441,11 @@ int Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, Vec_Ptr_t * vFa
|
|||
LevelOld = (int)Abc_ObjRegular(pAnd)->Level;
|
||||
if ( LevelNew != LevelOld )
|
||||
{
|
||||
int x = 0;
|
||||
int x = 0;
|
||||
Abc_Obj_t * pFanin0, * pFanin1;
|
||||
pFanin0 = Abc_ObjFanin0( Abc_ObjRegular(pAnd) );
|
||||
pFanin1 = Abc_ObjFanin1( Abc_ObjRegular(pAnd) );
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -626,9 +626,49 @@ void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
|
|||
pTimeOut->Worst = ABC_MAX( pTimeOut->Rise, pTimeOut->Fall );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the array of required times.]
|
||||
Synopsis [Prepares the AIG for the comptuation of required levels.]
|
||||
|
||||
Description [This procedure should be called before the required times
|
||||
are used. It starts internal data structures, which records the level
|
||||
from the COs of the AIG nodes in reverse topologogical order.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj, * pFanout;
|
||||
int i, k, nLevelsCur;
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
// remember the maximum number of direct levels
|
||||
pNtk->LevelMax = Abc_AigGetLevelNum(pNtk);
|
||||
// start the reverse levels
|
||||
pNtk->vLevelsR = Vec_IntAlloc( 0 );
|
||||
Vec_IntFill( pNtk->vLevelsR, Abc_NtkObjNumMax(pNtk), 0 );
|
||||
// compute levels in reverse topological order
|
||||
vNodes = Abc_NtkDfsReverse( pNtk );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
nLevelsCur = 0;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, k )
|
||||
if ( nLevelsCur < Vec_IntEntry(pNtk->vLevelsR, pFanout->Id) )
|
||||
nLevelsCur = Vec_IntEntry(pNtk->vLevelsR, pFanout->Id);
|
||||
Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, nLevelsCur + 1 );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans the data structures used to compute required levels.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -637,36 +677,75 @@ void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkGetRequiredLevels( Abc_Ntk_t * pNtk )
|
||||
void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vReqTimes;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj, * pFanout;
|
||||
int i, k, nLevelsMax, nLevelsCur;
|
||||
// start the required times
|
||||
vReqTimes = Vec_IntAlloc( 0 );
|
||||
Vec_IntFill( vReqTimes, Abc_NtkObjNumMax(pNtk), ABC_INFINITY );
|
||||
// compute levels in reverse topological order
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Vec_IntWriteEntry( vReqTimes, pObj->Id, 0 );
|
||||
vNodes = Abc_NtkDfsReverse( pNtk );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
nLevelsCur = 0;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, k )
|
||||
if ( nLevelsCur < Vec_IntEntry(vReqTimes, pFanout->Id) )
|
||||
nLevelsCur = Vec_IntEntry(vReqTimes, pFanout->Id);
|
||||
Vec_IntWriteEntry( vReqTimes, pObj->Id, nLevelsCur + 1 );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// convert levels into required times: RetTime = NumLevels + 1 - Level
|
||||
nLevelsMax = Abc_AigGetLevelNum(pNtk) + 1;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
Vec_IntWriteEntry( vReqTimes, pObj->Id, nLevelsMax - Vec_IntEntry(vReqTimes, pObj->Id) );
|
||||
// Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
// printf( "(%d,%d)", pObj->Level, Vec_IntEntry(vReqTimes, pObj->Id) );
|
||||
// printf( "\n" );
|
||||
return vReqTimes;
|
||||
assert( pNtk->vLevelsR );
|
||||
Vec_IntFree( pNtk->vLevelsR );
|
||||
pNtk->vLevelsR = NULL;
|
||||
pNtk->LevelMax = 0;
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the reverse level of the node.]
|
||||
|
||||
Description [The reverse level is the level of the node in reverse
|
||||
topological order, starting from the COs.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = pObj->pNtk;
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
assert( pNtk->vLevelsR );
|
||||
Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 );
|
||||
Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, LevelR );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the reverse level of the node.]
|
||||
|
||||
Description [The reverse level is the level of the node in reverse
|
||||
topological order, starting from the COs.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = pObj->pNtk;
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
assert( pNtk->vLevelsR );
|
||||
Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 );
|
||||
return Vec_IntEntry(pNtk->vLevelsR, pObj->Id);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns required level of the node.]
|
||||
|
||||
Description [Converts the reverse levels of the node into its required
|
||||
level as follows: ReqLevel(Node) = MaxLevels(Ntk) + 1 - LevelR(Node).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = pObj->pNtk;
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
assert( pNtk->vLevelsR );
|
||||
return pNtk->LevelMax + 1 - Vec_IntEntry(pNtk->vLevelsR, pObj->Id);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1021,6 +1021,30 @@ void Abc_NtkShortNames( Abc_Ntk_t * pNtk )
|
|||
pNtk->tObj2Name = tObj2NameNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the array of fanout counters.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vFanNums;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
vFanNums = Vec_IntAlloc( 0 );
|
||||
Vec_IntFill( vFanNums, Abc_NtkObjNumMax(pNtk), -1 );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) )
|
||||
Vec_IntWriteEntry( vFanNums, i, Abc_ObjFanoutNum(pObj) );
|
||||
return vFanNums;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -674,7 +674,7 @@ void Extra_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** p
|
|||
if ( uCanons[uTruth] )
|
||||
{
|
||||
assert( uTruth > uCanons[uTruth] );
|
||||
uMap[uTruth] = uMap[uCanons[uTruth]];
|
||||
uMap[~uTruth & 0xFFFF] = uMap[uTruth] = uMap[uCanons[uTruth]];
|
||||
continue;
|
||||
}
|
||||
uMap[uTruth] = nClasses++;
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ struct Abc_Fan_t_ // 1 word
|
|||
typedef struct Vec_Fan_t_ Vec_Fan_t;
|
||||
struct Vec_Fan_t_
|
||||
{
|
||||
int nSize;
|
||||
int nCap;
|
||||
int nSize;
|
||||
Abc_Fan_t * pArray;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
typedef struct Vec_Int_t_ Vec_Int_t;
|
||||
struct Vec_Int_t_
|
||||
{
|
||||
int nSize;
|
||||
int nCap;
|
||||
int nSize;
|
||||
int * pArray;
|
||||
};
|
||||
|
||||
|
|
@ -322,9 +322,31 @@ static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
|
|||
{
|
||||
int i;
|
||||
Vec_IntGrow( p, nSize );
|
||||
p->nSize = nSize;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
typedef struct Vec_Ptr_t_ Vec_Ptr_t;
|
||||
struct Vec_Ptr_t_
|
||||
{
|
||||
int nSize;
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
|
|
@ -323,9 +323,31 @@ static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
|
|||
{
|
||||
int i;
|
||||
Vec_PtrGrow( p, nSize );
|
||||
p->nSize = nSize;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_PtrGrow( p, nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
typedef struct Vec_Str_t_ Vec_Str_t;
|
||||
struct Vec_Str_t_
|
||||
{
|
||||
int nSize;
|
||||
int nCap;
|
||||
int nSize;
|
||||
char * pArray;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@
|
|||
typedef struct Vec_Vec_t_ Vec_Vec_t;
|
||||
struct Vec_Vec_t_
|
||||
{
|
||||
int nSize;
|
||||
int nCap;
|
||||
void ** pArray;
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -55,6 +55,8 @@ struct Vec_Vec_t_
|
|||
for ( i = LevelStart; (i < Vec_PtrSize(vGlob)) && (((vVec) = Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
|
||||
// iteratores through entries
|
||||
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
|
||||
|
|
@ -94,6 +96,28 @@ static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
|
|||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecStart( int nSize )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
int i;
|
||||
p = Vec_VecAlloc( nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = nSize;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ extern void Cut_NodeWriteCuts( Cut_Man_t * p, int Node, Cut_Cut_t *
|
|||
extern void Cut_NodeFreeCuts( Cut_Man_t * p, int Node );
|
||||
extern void Cut_NodeSetComputedAsNew( Cut_Man_t * p, int Node );
|
||||
extern void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node );
|
||||
extern void Cut_CutPrint( Cut_Cut_t * pCut );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ struct Cut_ManStruct_t_
|
|||
int nCutsPeak;
|
||||
int nCutsTriv;
|
||||
int nCutsNode;
|
||||
int nNodes;
|
||||
// runtime
|
||||
int timeMerge;
|
||||
int timeUnion;
|
||||
|
|
|
|||
|
|
@ -141,8 +141,9 @@ void Cut_ManPrintStats( Cut_Man_t * p )
|
|||
printf( "Peak cuts = %8d.\n", p->nCutsPeak );
|
||||
printf( "Total allocated = %8d.\n", p->nCutsAlloc );
|
||||
printf( "Total deallocated = %8d.\n", p->nCutsDealloc );
|
||||
printf( "The cut size = %3d bytes.\n", p->EntrySize );
|
||||
printf( "Peak memory = %.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
|
||||
printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes );
|
||||
printf( "The cut size = %8d bytes.\n", p->EntrySize );
|
||||
printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
|
||||
PRT( "Merge ", p->timeMerge );
|
||||
PRT( "Union ", p->timeUnion );
|
||||
PRT( "Hash ", Cut_TableReadTime(p->tTable) );
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ static void Cut_CutFilter( Cut_Man_t * p, Cut_Cut_t * pList );
|
|||
***********************************************************************/
|
||||
Cut_Cut_t * Cut_NodeReadCuts( Cut_Man_t * p, int Node )
|
||||
{
|
||||
if ( Node >= p->vCuts->nSize )
|
||||
return NULL;
|
||||
return Vec_PtrEntry( p->vCuts, Node );
|
||||
}
|
||||
|
||||
|
|
@ -209,6 +211,7 @@ Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1,
|
|||
}
|
||||
finish :
|
||||
// set the list at the node
|
||||
Vec_PtrFillExtra( p->vCuts, Node + 1, NULL );
|
||||
assert( Cut_NodeReadCuts(p, Node) == NULL );
|
||||
pList0 = Cut_ListFinish( &SuperList );
|
||||
Cut_NodeWriteCuts( p, Node, pList0 );
|
||||
|
|
@ -227,6 +230,7 @@ clk = clock();
|
|||
if ( p->pParams->fFilter )
|
||||
Cut_CutFilter( p, pList0 );
|
||||
p->timeFilter += clock() - clk;
|
||||
p->nNodes++;
|
||||
return pList0;
|
||||
}
|
||||
|
||||
|
|
@ -387,6 +391,7 @@ clk = clock();
|
|||
if ( p->pParams->fFilter )
|
||||
Cut_CutFilter( p, pList );
|
||||
p->timeFilter += clock() - clk;
|
||||
p->nNodes -= vNodes->nSize - 1;
|
||||
return pList;
|
||||
}
|
||||
|
||||
|
|
@ -498,7 +503,7 @@ void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node )
|
|||
void Cut_CutPrint( Cut_Cut_t * pCut )
|
||||
{
|
||||
int i;
|
||||
assert( pCut->nLeaves > 1 );
|
||||
assert( pCut->nLeaves > 0 );
|
||||
printf( "%d : {", pCut->nLeaves );
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
printf( " %d", pCut->pLeaves[i] );
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
SRC += src/opt/rwr/rwrCut.c \
|
||||
SRC += src/opt/rwr/rwrDec.c \
|
||||
src/opt/rwr/rwrEva.c \
|
||||
src/opt/rwr/rwrExp.c \
|
||||
src/opt/rwr/rwrLib.c \
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "abc.h"
|
||||
#include "cut.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
|
|
@ -39,7 +40,6 @@
|
|||
|
||||
typedef struct Rwr_Man_t_ Rwr_Man_t;
|
||||
typedef struct Rwr_Node_t_ Rwr_Node_t;
|
||||
typedef struct Rwr_Cut_t_ Rwr_Cut_t;
|
||||
|
||||
struct Rwr_Man_t_
|
||||
{
|
||||
|
|
@ -50,7 +50,7 @@ struct Rwr_Man_t_
|
|||
char * pPerms; // canonical permutations
|
||||
unsigned char * pMap; // mapping of functions into class numbers
|
||||
char * pPractical; // practical NPN classes
|
||||
unsigned short ** puPerms43; // four-var permutations for three var functions
|
||||
char ** pPerms4; // four-var permutations
|
||||
// node space
|
||||
Vec_Ptr_t * vForest; // all the nodes
|
||||
Rwr_Node_t ** pTable; // the hash table of nodes by their canonical form
|
||||
|
|
@ -61,19 +61,26 @@ struct Rwr_Man_t_
|
|||
int nConsidered; // the number of nodes considered
|
||||
int nAdded; // the number of nodes added to lists
|
||||
int nClasses; // the number of NN classes
|
||||
// intermediate data
|
||||
Vec_Int_t * vFanNums; // the number of fanouts of each node (used to free cuts)
|
||||
Vec_Int_t * vReqTimes; // the required times for each node (used for delay-driven evalution)
|
||||
// the result of resynthesis
|
||||
int fCompl; // indicates if the output of FF should be complemented
|
||||
Vec_Int_t * vForm; // the decomposition tree (temporary)
|
||||
Vec_Int_t * vLevNums; // the array of levels (temporary)
|
||||
Vec_Ptr_t * vFanins; // the fanins array (temporary)
|
||||
int nGainMax;
|
||||
Vec_Ptr_t * vFaninsCur; // the fanins array (temporary)
|
||||
Vec_Int_t * vLevNums; // the array of levels (temporary)
|
||||
// node statistics
|
||||
int nNodesConsidered;
|
||||
int nNodesRewritten;
|
||||
int nNodesGained;
|
||||
int nScores[222];
|
||||
int nCutsGood;
|
||||
int nCutsBad;
|
||||
int nSubgraphs;
|
||||
// runtime statistics
|
||||
int time1;
|
||||
int time2;
|
||||
int time3;
|
||||
int time4;
|
||||
int timeStart;
|
||||
int timeCut;
|
||||
int timeRes;
|
||||
int timeEval;
|
||||
int timeTotal;
|
||||
};
|
||||
|
||||
struct Rwr_Node_t_ // 24 bytes
|
||||
|
|
@ -90,18 +97,6 @@ struct Rwr_Node_t_ // 24 bytes
|
|||
Rwr_Node_t * pNext; // next in the table
|
||||
};
|
||||
|
||||
struct Rwr_Cut_t_ // 24 bytes
|
||||
{
|
||||
unsigned nLeaves : 3; // the number of leaves
|
||||
unsigned fTime : 1; // set to 1 if meets the required times
|
||||
unsigned fGain : 1; // set to 1 if does not increase nodes
|
||||
unsigned Volume : 11; // the gain in the number of nodes
|
||||
unsigned uTruth : 16; // the truth table
|
||||
Abc_Obj_t * ppLeaves[4]; // the leaves
|
||||
Rwr_Cut_t * pNext; // the next cut in the list
|
||||
};
|
||||
|
||||
|
||||
// manipulation of complemented attributes
|
||||
static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned)p) & 01); }
|
||||
static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) & ~01); }
|
||||
|
|
@ -116,12 +111,10 @@ static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_N
|
|||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== rwrCut.c ========================================================*/
|
||||
extern void Rwr_NtkStartCuts( Rwr_Man_t * p, Abc_Ntk_t * pNtk );
|
||||
extern void Rwr_NodeComputeCuts( Rwr_Man_t * p, Abc_Obj_t * pNode );
|
||||
/*=== rwrEva.c ========================================================*/
|
||||
extern int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode );
|
||||
/*=== rwrDec.c ========================================================*/
|
||||
extern void Rwr_ManPreprocess( Rwr_Man_t * p );
|
||||
/*=== rwrEva.c ========================================================*/
|
||||
extern int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros );
|
||||
/*=== rwrLib.c ========================================================*/
|
||||
extern void Rwr_ManPrecompute( Rwr_Man_t * p );
|
||||
extern Rwr_Node_t * Rwr_ManAddVar( Rwr_Man_t * p, unsigned uTruth, int fPrecompute );
|
||||
|
|
@ -131,14 +124,18 @@ extern void Rwr_ManIncTravId( Rwr_Man_t * p );
|
|||
/*=== rwrMan.c ========================================================*/
|
||||
extern Rwr_Man_t * Rwr_ManStart( bool fPrecompute );
|
||||
extern void Rwr_ManStop( Rwr_Man_t * p );
|
||||
extern void Rwr_ManPrintStats( Rwr_Man_t * p );
|
||||
extern void Rwr_ManPrepareNetwork( Rwr_Man_t * p, Abc_Ntk_t * pNtk );
|
||||
extern Vec_Ptr_t * Rwr_ManReadFanins( Rwr_Man_t * p );
|
||||
extern Vec_Int_t * Rwr_ManReadDecs( Rwr_Man_t * p );
|
||||
extern int Rwr_ManReadCompl( Rwr_Man_t * p );
|
||||
extern void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time );
|
||||
extern void Rwr_ManAddTimeTotal( Rwr_Man_t * p, int Time );
|
||||
/*=== rwrPrint.c ========================================================*/
|
||||
extern void Rwr_ManPrint( Rwr_Man_t * p );
|
||||
/*=== rwrUtil.c ========================================================*/
|
||||
extern void Rwr_ManWriteToArray( Rwr_Man_t * p );
|
||||
extern void Rwr_ManLoadFromArray( Rwr_Man_t * p );
|
||||
extern void Rwr_ManLoadFromArray( Rwr_Man_t * p, int fVerbose );
|
||||
extern void Rwr_ManWriteToFile( Rwr_Man_t * p, char * pFileName );
|
||||
extern void Rwr_ManLoadFromFile( Rwr_Man_t * p, char * pFileName );
|
||||
extern Vec_Int_t * Rwt_NtkFanoutCounters( Abc_Ntk_t * pNtk );
|
||||
|
|
|
|||
|
|
@ -1,254 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rwrCut.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware AIG rewriting package.]
|
||||
|
||||
Synopsis [Cut computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rwrCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rwr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Rwr_Cut_t * Rwr_CutAlloc( Rwr_Man_t * p );
|
||||
static Rwr_Cut_t * Rwr_CutCreateTriv( Rwr_Man_t * p, Abc_Obj_t * pNode );
|
||||
static Rwr_Cut_t * Rwr_CutsMerge( Rwr_Man_t * p, Rwr_Cut_t * pCut0, Rwr_Cut_t * pCut1, int fCompl0, int fCompl1 );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes cuts for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_NtkStartCuts( Rwr_Man_t * p, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
// set the trivial cuts
|
||||
Abc_NtkCleanCopy( pNtk );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
pNode->pCopy = (Abc_Obj_t *)Rwr_CutCreateTriv( p, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes cuts for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_NodeComputeCuts( Rwr_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Rwr_Cut_t * pCuts0, * pCuts1, * pTemp0, * pTemp1, * pCut;
|
||||
Rwr_Cut_t * pList = NULL, ** ppPlace = &pList; // linked list of cuts
|
||||
assert( Abc_ObjIsNode(pNode) );
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
return;
|
||||
// create the elementary cut
|
||||
pCut = Rwr_CutCreateTriv( p, pNode );
|
||||
// add it to the linked list
|
||||
*ppPlace = pCut; ppPlace = &pCut->pNext;
|
||||
// create cuts by merging pairwise
|
||||
pCuts0 = (Rwr_Cut_t *)Abc_ObjFanin0(pNode)->pCopy;
|
||||
pCuts1 = (Rwr_Cut_t *)Abc_ObjFanin1(pNode)->pCopy;
|
||||
assert( pCuts0 && pCuts1 );
|
||||
for ( pTemp0 = pCuts0; pTemp0; pTemp0 = pTemp0->pNext )
|
||||
for ( pTemp1 = pCuts1; pTemp1; pTemp1 = pTemp1->pNext )
|
||||
{
|
||||
pCut = Rwr_CutsMerge( p, pTemp0, pTemp1, Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode) );
|
||||
if ( pCut == NULL )
|
||||
continue;
|
||||
// add it to the linked list
|
||||
*ppPlace = pCut; ppPlace = &pCut->pNext;
|
||||
}
|
||||
// set the linked list
|
||||
pNode->pCopy = (Abc_Obj_t *)pList;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start the cut computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Rwr_Cut_t * Rwr_CutsMerge( Rwr_Man_t * p, Rwr_Cut_t * pCut0, Rwr_Cut_t * pCut1, int fCompl0, int fCompl1 )
|
||||
{
|
||||
Abc_Obj_t * ppNodes[4], * pNodeTemp;
|
||||
Rwr_Cut_t * pCut;
|
||||
unsigned uPhase, uTruth0, uTruth1;
|
||||
int i, k, min, nTotal;
|
||||
|
||||
// solve the most typical case: both cuts are four input
|
||||
if ( pCut0->nLeaves == 4 && pCut1->nLeaves == 4 )
|
||||
{
|
||||
for ( i = 0; i < 4; i++ )
|
||||
if ( pCut0->ppLeaves[i] != pCut1->ppLeaves[i] )
|
||||
return NULL;
|
||||
// create the cut
|
||||
pCut = Rwr_CutAlloc( p );
|
||||
pCut->nLeaves = 4;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
pCut->ppLeaves[i] = pCut0->ppLeaves[i];
|
||||
pCut->uTruth = (fCompl0? ~pCut0->uTruth : pCut0->uTruth) & (fCompl1? ~pCut1->uTruth : pCut1->uTruth) & 0xFFFF;
|
||||
return pCut;
|
||||
}
|
||||
|
||||
// create the set of new nodes
|
||||
// count the number of unique entries in pCut1
|
||||
nTotal = pCut0->nLeaves;
|
||||
for ( i = 0; i < (int)pCut1->nLeaves; i++ )
|
||||
{
|
||||
// try to find this entry among the leaves of pCut0
|
||||
for ( k = 0; k < (int)pCut0->nLeaves; k++ )
|
||||
if ( pCut1->ppLeaves[i] == pCut0->ppLeaves[k] )
|
||||
break;
|
||||
if ( k < (int)pCut0->nLeaves ) // found
|
||||
continue;
|
||||
// we found a new entry to add
|
||||
if ( nTotal == 4 )
|
||||
return NULL;
|
||||
ppNodes[nTotal++] = pCut1->ppLeaves[i];
|
||||
}
|
||||
// we know that the feasible cut exists
|
||||
|
||||
// add the starting entries
|
||||
for ( k = 0; k < (int)pCut0->nLeaves; k++ )
|
||||
ppNodes[k] = pCut0->ppLeaves[k];
|
||||
|
||||
// selection-sort the entries
|
||||
for ( i = 0; i < nTotal - 1; i++ )
|
||||
{
|
||||
min = i;
|
||||
for ( k = i+1; k < nTotal; k++ )
|
||||
if ( ppNodes[k]->Id < ppNodes[min]->Id )
|
||||
min = k;
|
||||
pNodeTemp = ppNodes[i];
|
||||
ppNodes[i] = ppNodes[min];
|
||||
ppNodes[min] = pNodeTemp;
|
||||
}
|
||||
|
||||
// find the mapping from the old nodes to the new
|
||||
if ( pCut0->nLeaves == 4 )
|
||||
uTruth0 = pCut0->uTruth;
|
||||
else
|
||||
{
|
||||
uPhase = 0;
|
||||
for ( i = 0; i < (int)pCut0->nLeaves; i++ )
|
||||
{
|
||||
for ( k = 0; k < nTotal; k++ )
|
||||
if ( pCut0->ppLeaves[i] == ppNodes[k] )
|
||||
break;
|
||||
uPhase |= (1 << k);
|
||||
}
|
||||
assert( uPhase < 16 );
|
||||
assert( pCut0->uTruth < 256 );
|
||||
uTruth0 = p->puPerms43[pCut0->uTruth][uPhase];
|
||||
}
|
||||
|
||||
// find the mapping from the old nodes to the new
|
||||
if ( pCut1->nLeaves == 4 )
|
||||
uTruth1 = pCut1->uTruth;
|
||||
else
|
||||
{
|
||||
uPhase = 0;
|
||||
for ( i = 0; i < (int)pCut1->nLeaves; i++ )
|
||||
{
|
||||
for ( k = 0; k < nTotal; k++ )
|
||||
if ( pCut1->ppLeaves[i] == ppNodes[k] )
|
||||
break;
|
||||
uPhase |= (1 << k);
|
||||
}
|
||||
assert( uPhase < 16 );
|
||||
assert( pCut1->uTruth < 256 );
|
||||
uTruth1 = p->puPerms43[pCut1->uTruth][uPhase];
|
||||
}
|
||||
|
||||
// create the cut
|
||||
pCut = Rwr_CutAlloc( p );
|
||||
pCut->nLeaves = nTotal;
|
||||
for ( i = 0; i < nTotal; i++ )
|
||||
pCut->ppLeaves[i] = ppNodes[i];
|
||||
pCut->uTruth = (fCompl0? ~uTruth0 : uTruth0) & (fCompl1? ~uTruth1 : uTruth1) & 0xFFFF;
|
||||
return pCut;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start the cut computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Rwr_Cut_t * Rwr_CutAlloc( Rwr_Man_t * p )
|
||||
{
|
||||
Rwr_Cut_t * pCut;
|
||||
pCut = (Rwr_Cut_t *)Extra_MmFixedEntryFetch( p->pMmNode );
|
||||
memset( pCut, 0, sizeof(Rwr_Cut_t) );
|
||||
return pCut;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start the cut computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Rwr_Cut_t * Rwr_CutCreateTriv( Rwr_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Rwr_Cut_t * pCut;
|
||||
pCut = Rwr_CutAlloc( p );
|
||||
pCut->nLeaves = 1;
|
||||
pCut->ppLeaves[0] = pNode;
|
||||
pCut->uTruth = 0xAAAA;
|
||||
return pCut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rwrDec.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware AIG rewriting package.]
|
||||
|
||||
Synopsis [Evaluation and decomposition procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rwrDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rwr.h"
|
||||
#include "ft.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Vec_Int_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode );
|
||||
static int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm );
|
||||
static void Rwr_FactorVerify( Vec_Int_t * vForm, unsigned uTruth );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Preprocesses computed library of subgraphs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_ManPreprocess( Rwr_Man_t * p )
|
||||
{
|
||||
Rwr_Node_t * pNode;
|
||||
int i, k;
|
||||
// put the nodes into the structure
|
||||
p->vClasses = Vec_VecStart( 222 );
|
||||
for ( i = 0; i < p->nFuncs; i++ )
|
||||
{
|
||||
if ( p->pTable[i] == NULL )
|
||||
continue;
|
||||
// consider all implementations of this function
|
||||
for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext )
|
||||
{
|
||||
assert( pNode->uTruth == p->pTable[i]->uTruth );
|
||||
assert( p->pMap[pNode->uTruth] >= 0 && p->pMap[pNode->uTruth] < 222 );
|
||||
Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode );
|
||||
}
|
||||
}
|
||||
// compute decomposition forms for each node
|
||||
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
|
||||
pNode->pNext = (Rwr_Node_t *)Rwr_NodePreprocess( p, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Preprocesses subgraphs rooted at this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode )
|
||||
{
|
||||
Vec_Int_t * vForm;
|
||||
int i, Root;
|
||||
// consider constant
|
||||
if ( pNode->uTruth == 0 )
|
||||
return Ft_FactorConst( 0 );
|
||||
// consider the case of elementary var
|
||||
if ( pNode->uTruth == 0x00FF )
|
||||
return Ft_FactorVar( 3, 4, 1 );
|
||||
// start the factored form
|
||||
vForm = Vec_IntAlloc( 10 );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
Vec_IntPush( vForm, 0 );
|
||||
// collect the nodes
|
||||
Rwr_ManIncTravId( p );
|
||||
Root = Rwr_TravCollect_rec( p, pNode, vForm );
|
||||
if ( Root & 1 )
|
||||
Ft_FactorComplement( vForm );
|
||||
// verify the factored form
|
||||
Rwr_FactorVerify( vForm, pNode->uTruth );
|
||||
return vForm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm )
|
||||
{
|
||||
Ft_Node_t Node, NodeA, NodeB;
|
||||
int Node0, Node1;
|
||||
// elementary variable
|
||||
if ( pNode->fUsed )
|
||||
return ((pNode->Id - 1) << 1);
|
||||
// previously visited node
|
||||
if ( pNode->TravId == p->nTravIds )
|
||||
return pNode->Volume;
|
||||
pNode->TravId = p->nTravIds;
|
||||
// solve for children
|
||||
Node0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), vForm );
|
||||
Node1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), vForm );
|
||||
// create the decomposition node(s)
|
||||
if ( pNode->fExor )
|
||||
{
|
||||
assert( !Rwr_IsComplement(pNode->p0) );
|
||||
assert( !Rwr_IsComplement(pNode->p1) );
|
||||
NodeA.fIntern = 1;
|
||||
NodeA.fConst = 0;
|
||||
NodeA.fCompl = 0;
|
||||
NodeA.fCompl0 = !(Node0 & 1);
|
||||
NodeA.fCompl1 = (Node1 & 1);
|
||||
NodeA.iFanin0 = (Node0 >> 1);
|
||||
NodeA.iFanin1 = (Node1 >> 1);
|
||||
Vec_IntPush( vForm, Ft_Node2Int(NodeA) );
|
||||
|
||||
NodeB.fIntern = 1;
|
||||
NodeB.fConst = 0;
|
||||
NodeB.fCompl = 0;
|
||||
NodeB.fCompl0 = (Node0 & 1);
|
||||
NodeB.fCompl1 = !(Node1 & 1);
|
||||
NodeB.iFanin0 = (Node0 >> 1);
|
||||
NodeB.iFanin1 = (Node1 >> 1);
|
||||
Vec_IntPush( vForm, Ft_Node2Int(NodeB) );
|
||||
|
||||
Node.fIntern = 1;
|
||||
Node.fConst = 0;
|
||||
Node.fCompl = 0;
|
||||
Node.fCompl0 = 1;
|
||||
Node.fCompl1 = 1;
|
||||
Node.iFanin0 = vForm->nSize - 2;
|
||||
Node.iFanin1 = vForm->nSize - 1;
|
||||
Vec_IntPush( vForm, Ft_Node2Int(Node) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Node.fIntern = 1;
|
||||
Node.fConst = 0;
|
||||
Node.fCompl = 0;
|
||||
Node.fCompl0 = Rwr_IsComplement(pNode->p0) ^ (Node0 & 1);
|
||||
Node.fCompl1 = Rwr_IsComplement(pNode->p1) ^ (Node1 & 1);
|
||||
Node.iFanin0 = (Node0 >> 1);
|
||||
Node.iFanin1 = (Node1 >> 1);
|
||||
Vec_IntPush( vForm, Ft_Node2Int(Node) );
|
||||
}
|
||||
// save the number of this node
|
||||
pNode->Volume = ((vForm->nSize - 1) << 1) | pNode->fExor;
|
||||
return pNode->Volume;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies the factored form.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_FactorVerify( Vec_Int_t * vForm, unsigned uTruthGold )
|
||||
{
|
||||
Ft_Node_t * pFtNode;
|
||||
Vec_Int_t * vTruths;
|
||||
unsigned uTruth, uTruth0, uTruth1;
|
||||
int i;
|
||||
|
||||
vTruths = Vec_IntAlloc( vForm->nSize );
|
||||
Vec_IntPush( vTruths, 0xAAAA );
|
||||
Vec_IntPush( vTruths, 0xCCCC );
|
||||
Vec_IntPush( vTruths, 0xF0F0 );
|
||||
Vec_IntPush( vTruths, 0xFF00 );
|
||||
|
||||
assert( Ft_FactorGetNumVars( vForm ) == 4 );
|
||||
for ( i = 4; i < vForm->nSize; i++ )
|
||||
{
|
||||
pFtNode = Ft_NodeRead( vForm, i );
|
||||
// make sure there are no elementary variables
|
||||
assert( pFtNode->iFanin0 != pFtNode->iFanin1 );
|
||||
|
||||
uTruth0 = vTruths->pArray[pFtNode->iFanin0];
|
||||
uTruth0 = pFtNode->fCompl0? ~uTruth0 : uTruth0;
|
||||
|
||||
uTruth1 = vTruths->pArray[pFtNode->iFanin1];
|
||||
uTruth1 = pFtNode->fCompl1? ~uTruth1 : uTruth1;
|
||||
|
||||
uTruth = uTruth0 & uTruth1;
|
||||
Vec_IntPush( vTruths, uTruth );
|
||||
}
|
||||
// complement if necessary
|
||||
if ( pFtNode->fCompl )
|
||||
uTruth = ~uTruth;
|
||||
uTruth &= 0xFFFF;
|
||||
if ( uTruth != uTruthGold )
|
||||
printf( "Verification failed\n" );
|
||||
Vec_IntFree( vTruths );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut, int NodeMax, int LevelMax );
|
||||
static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
|
|
@ -49,37 +49,101 @@ static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode )
|
||||
int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros )
|
||||
{
|
||||
int fVeryVerbose = 0;
|
||||
Vec_Int_t * vForm;
|
||||
Rwr_Cut_t * pCut;
|
||||
Cut_Cut_t * pCut;
|
||||
Abc_Obj_t * pFanin;
|
||||
unsigned uPhase, uTruthBest;
|
||||
char * pPerm;
|
||||
int Required, nNodesSaved;
|
||||
int i, BestGain = -1;
|
||||
// compute the cuts for this node
|
||||
Rwr_NodeComputeCuts( p, pNode );
|
||||
int i, GainCur, GainBest = -1;
|
||||
int clk;
|
||||
|
||||
p->nNodesConsidered++;
|
||||
// get the required times
|
||||
Required = Vec_IntEntry( p->vReqTimes, pNode->Id );
|
||||
// label MFFC with current ID
|
||||
nNodesSaved = Abc_NodeMffcLabel( pNode );
|
||||
Required = Abc_NodeReadRequiredLevel( pNode );
|
||||
// get the node's cuts
|
||||
clk = clock();
|
||||
pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode );
|
||||
assert( pCut != NULL );
|
||||
p->timeCut += clock() - clk;
|
||||
|
||||
// go through the cuts
|
||||
for ( pCut = (Rwr_Cut_t *)pNode->pCopy, pCut = pCut->pNext; pCut; pCut = pCut->pNext )
|
||||
clk = clock();
|
||||
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
|
||||
{
|
||||
// evaluate the cut
|
||||
vForm = Rwr_CutEvaluate( p, pNode, pCut, nNodesSaved, Required );
|
||||
// check if the cut is better than the currently best one
|
||||
if ( vForm != NULL && BestGain < (int)pCut->Volume )
|
||||
// consider only 4-input cuts
|
||||
if ( pCut->nLeaves < 4 )
|
||||
continue;
|
||||
// get the fanin permutation
|
||||
pPerm = p->pPerms4[ p->pPerms[pCut->uTruth] ];
|
||||
uPhase = p->pPhases[pCut->uTruth];
|
||||
// collect fanins with the corresponding permutation/phase
|
||||
Vec_PtrClear( p->vFaninsCur );
|
||||
Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 );
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
{
|
||||
pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[pPerm[i]] );
|
||||
if ( pFanin == NULL )
|
||||
break;
|
||||
pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) );
|
||||
Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
|
||||
}
|
||||
if ( i != (int)pCut->nLeaves )
|
||||
{
|
||||
p->nCutsBad++;
|
||||
continue;
|
||||
}
|
||||
p->nCutsGood++;
|
||||
|
||||
// mark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Abc_ObjRegular(pFanin)->vFanouts.nSize++;
|
||||
// label MFFC with current ID
|
||||
Abc_NtkIncrementTravId( pNode->pNtk );
|
||||
nNodesSaved = Abc_NodeMffcLabel( pNode );
|
||||
// unmark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Abc_ObjRegular(pFanin)->vFanouts.nSize--;
|
||||
|
||||
// evaluate the cut
|
||||
vForm = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur );
|
||||
|
||||
// check if the cut is better than the current best one
|
||||
if ( vForm != NULL && GainBest < GainCur )
|
||||
{
|
||||
assert( pCut->Volume >= 0 );
|
||||
BestGain = pCut->Volume;
|
||||
// save this form
|
||||
p->vForm = vForm;
|
||||
// collect fanins
|
||||
GainBest = GainCur;
|
||||
p->vForm = vForm;
|
||||
p->fCompl = ((uPhase & (1<<4)) > 0);
|
||||
uTruthBest = pCut->uTruth;
|
||||
// collect fanins in the
|
||||
Vec_PtrClear( p->vFanins );
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
Vec_PtrPush( p->vFanins, pCut->ppLeaves[i] );
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Vec_PtrPush( p->vFanins, pFanin );
|
||||
}
|
||||
}
|
||||
return BestGain;
|
||||
p->timeRes += clock() - clk;
|
||||
|
||||
if ( GainBest == -1 || GainBest == 0 && !fUseZeros )
|
||||
return GainBest;
|
||||
|
||||
p->nScores[p->pMap[uTruthBest]]++;
|
||||
p->nNodesRewritten++;
|
||||
p->nNodesGained += GainBest;
|
||||
|
||||
// report the progress
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "Node %6s : ", Abc_ObjName(pNode) );
|
||||
printf( "Fanins = %d. ", p->vFanins->nSize );
|
||||
printf( "Cone = %2d. ", p->vForm->nSize - 4 );
|
||||
printf( "GAIN = %2d. ", GainBest );
|
||||
printf( "\n" );
|
||||
}
|
||||
return GainBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -93,161 +157,39 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut, int NodeMax, int LevelMax )
|
||||
Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest )
|
||||
{
|
||||
Vec_Ptr_t Vector = {0,0,0}, * vFanins = &Vector;
|
||||
Vec_Ptr_t * vSubgraphs;
|
||||
Vec_Int_t * vFormBest;
|
||||
Rwr_Node_t * pNode;
|
||||
int GainCur, GainBest = -1, i;
|
||||
int nNodesAdded, GainBest = -1, i;
|
||||
int clk = clock();
|
||||
// find the matching class of subgraphs
|
||||
vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[pCut->uTruth] );
|
||||
p->nSubgraphs += vSubgraphs->nSize;
|
||||
// determine the best subgraph
|
||||
Vec_PtrForEachEntry( vSubgraphs, pNode, i )
|
||||
{
|
||||
// create the fanin array
|
||||
vFanins->nSize = pCut->nLeaves;
|
||||
vFanins->pArray = pCut->ppLeaves;
|
||||
// detect how many unlabeled nodes will be reused
|
||||
GainCur = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFanins, (Vec_Int_t *)pNode->pNext,
|
||||
p->vLevNums, NodeMax, LevelMax );
|
||||
if ( GainBest < GainCur )
|
||||
nNodesAdded = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFaninsCur,
|
||||
(Vec_Int_t *)pNode->pNext, p->vLevNums, nNodesSaved, LevelMax );
|
||||
if ( nNodesAdded == -1 )
|
||||
continue;
|
||||
assert( nNodesSaved >= nNodesAdded );
|
||||
// count the gain at this node
|
||||
if ( GainBest < nNodesSaved - nNodesAdded )
|
||||
{
|
||||
GainBest = GainCur;
|
||||
GainBest = nNodesSaved - nNodesAdded;
|
||||
vFormBest = (Vec_Int_t *)pNode->pNext;
|
||||
}
|
||||
}
|
||||
p->timeEval += clock() - clk;
|
||||
if ( GainBest == -1 )
|
||||
return NULL;
|
||||
pCut->Volume = GainBest;
|
||||
*pGainBest = GainBest;
|
||||
return vFormBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm )
|
||||
{
|
||||
Ft_Node_t Node, NodeA, NodeB;
|
||||
int Node0, Node1;
|
||||
// elementary variable
|
||||
if ( pNode->fUsed )
|
||||
return ((pNode->Id - 1) << 1);
|
||||
// previously visited node
|
||||
if ( pNode->TravId == p->nTravIds )
|
||||
return pNode->Volume;
|
||||
pNode->TravId = p->nTravIds;
|
||||
// solve for children
|
||||
Node0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), vForm );
|
||||
Node1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), vForm );
|
||||
// create the decomposition node(s)
|
||||
if ( pNode->fExor )
|
||||
{
|
||||
assert( !Rwr_IsComplement(pNode->p0) );
|
||||
assert( !Rwr_IsComplement(pNode->p1) );
|
||||
NodeA.fIntern = 1;
|
||||
NodeA.fConst = 0;
|
||||
NodeA.fCompl = 0;
|
||||
NodeA.fCompl0 = !(Node0 & 1);
|
||||
NodeA.fCompl1 = (Node1 & 1);
|
||||
NodeA.iFanin0 = (Node0 >> 1);
|
||||
NodeA.iFanin1 = (Node1 >> 1);
|
||||
Vec_IntPush( vForm, Ft_Node2Int(NodeA) );
|
||||
|
||||
NodeB.fIntern = 1;
|
||||
NodeB.fConst = 0;
|
||||
NodeB.fCompl = 0;
|
||||
NodeB.fCompl0 = (Node0 & 1);
|
||||
NodeB.fCompl1 = !(Node1 & 1);
|
||||
NodeB.iFanin0 = (Node0 >> 1);
|
||||
NodeB.iFanin1 = (Node1 >> 1);
|
||||
Vec_IntPush( vForm, Ft_Node2Int(NodeB) );
|
||||
|
||||
Node.fIntern = 1;
|
||||
Node.fConst = 0;
|
||||
Node.fCompl = 0;
|
||||
Node.fCompl0 = 1;
|
||||
Node.fCompl1 = 1;
|
||||
Node.iFanin0 = vForm->nSize - 2;
|
||||
Node.iFanin1 = vForm->nSize - 1;
|
||||
Vec_IntPush( vForm, Ft_Node2Int(Node) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Node.fIntern = 1;
|
||||
Node.fConst = 0;
|
||||
Node.fCompl = 0;
|
||||
Node.fCompl0 = Rwr_IsComplement(pNode->p0) ^ (Node0 & 1);
|
||||
Node.fCompl1 = Rwr_IsComplement(pNode->p1) ^ (Node1 & 1);
|
||||
Node.iFanin0 = (Node0 >> 1);
|
||||
Node.iFanin1 = (Node1 >> 1);
|
||||
Vec_IntPush( vForm, Ft_Node2Int(Node) );
|
||||
}
|
||||
// save the number of this node
|
||||
pNode->Volume = ((vForm->nSize - 1) << 1) | pNode->fExor;
|
||||
return pNode->Volume;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Preprocesses subgraphs rooted at this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode )
|
||||
{
|
||||
Vec_Int_t * vForm;
|
||||
int i, Root;
|
||||
vForm = Vec_IntAlloc( 10 );
|
||||
for ( i = 0; i < 5; i++ )
|
||||
Vec_IntPush( vForm, 0 );
|
||||
// collect the nodes
|
||||
Rwr_ManIncTravId( p );
|
||||
Root = Rwr_TravCollect_rec( p, pNode, vForm );
|
||||
if ( Root & 1 )
|
||||
Ft_FactorComplement( vForm );
|
||||
pNode->pNext = (Rwr_Node_t *)vForm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Preprocesses computed library of subgraphs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_ManPreprocess( Rwr_Man_t * p )
|
||||
{
|
||||
Rwr_Node_t * pNode;
|
||||
int i, k;
|
||||
// put the nodes into the structure
|
||||
p->vClasses = Vec_VecAlloc( 222 );
|
||||
for ( i = 0; i < p->nFuncs; i++ )
|
||||
for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext )
|
||||
Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode );
|
||||
// compute decomposition forms for each node
|
||||
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
|
||||
Rwr_NodePreprocess( p, pNode );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -49,14 +49,13 @@ Rwr_Man_t * Rwr_ManStart( bool fPrecompute )
|
|||
// canonical forms, phases, perms
|
||||
clk = clock();
|
||||
Extra_Truth4VarNPN( &p->puCanons, &p->pPhases, &p->pPerms, &p->pMap );
|
||||
PRT( "NPN classes precomputation time", clock() - clk );
|
||||
//PRT( "NPN classes precomputation time", clock() - clk );
|
||||
// initialize practical NPN classes
|
||||
p->pPractical = Rwr_ManGetPractical( p );
|
||||
// create the table
|
||||
p->pTable = ALLOC( Rwr_Node_t *, p->nFuncs );
|
||||
memset( p->pTable, 0, sizeof(Rwr_Node_t *) * p->nFuncs );
|
||||
// create the elementary nodes
|
||||
assert( sizeof(Rwr_Node_t) == sizeof(Rwr_Cut_t) );
|
||||
p->pMmNode = Extra_MmFixedStart( sizeof(Rwr_Node_t) );
|
||||
p->vForest = Vec_PtrAlloc( 100 );
|
||||
Rwr_ManAddVar( p, 0x0000, fPrecompute ); // constant 0
|
||||
|
|
@ -66,10 +65,11 @@ PRT( "NPN classes precomputation time", clock() - clk );
|
|||
Rwr_ManAddVar( p, 0xFF00, fPrecompute ); // var D
|
||||
p->nClasses = 5;
|
||||
// other stuff
|
||||
p->nTravIds = 1;
|
||||
p->puPerms43 = Extra_TruthPerm43();
|
||||
p->vLevNums = Vec_IntAlloc( 50 );
|
||||
p->vFanins = Vec_PtrAlloc( 50 );
|
||||
p->nTravIds = 1;
|
||||
p->pPerms4 = Extra_Permutations( 4 );
|
||||
p->vLevNums = Vec_IntAlloc( 50 );
|
||||
p->vFanins = Vec_PtrAlloc( 50 );
|
||||
p->vFaninsCur = Vec_PtrAlloc( 50 );
|
||||
if ( fPrecompute )
|
||||
{ // precompute subgraphs
|
||||
Rwr_ManPrecompute( p );
|
||||
|
|
@ -78,11 +78,11 @@ PRT( "NPN classes precomputation time", clock() - clk );
|
|||
}
|
||||
else
|
||||
{ // load saved subgraphs
|
||||
Rwr_ManLoadFromArray( p );
|
||||
// Rwr_ManPrint( p );
|
||||
Rwr_ManLoadFromArray( p, 0 );
|
||||
Rwr_ManPrint( p );
|
||||
Rwr_ManPreprocess( p );
|
||||
return NULL;
|
||||
}
|
||||
p->timeStart = clock() - clk;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -106,16 +106,15 @@ void Rwr_ManStop( Rwr_Man_t * p )
|
|||
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
|
||||
Vec_IntFree( (Vec_Int_t *)pNode->pNext );
|
||||
}
|
||||
if ( p->vFanNums ) Vec_IntFree( p->vFanNums );
|
||||
if ( p->vReqTimes ) Vec_IntFree( p->vReqTimes );
|
||||
if ( p->vClasses ) Vec_VecFree( p->vClasses );
|
||||
Vec_PtrFree( p->vForest );
|
||||
Vec_IntFree( p->vLevNums );
|
||||
Vec_PtrFree( p->vFanins );
|
||||
Vec_PtrFree( p->vFaninsCur );
|
||||
Extra_MmFixedStop( p->pMmNode, 0 );
|
||||
free( p->pTable );
|
||||
free( p->pPractical );
|
||||
free( p->puPerms43 );
|
||||
free( p->pPerms4 );
|
||||
free( p->puCanons );
|
||||
free( p->pPhases );
|
||||
free( p->pPerms );
|
||||
|
|
@ -123,6 +122,46 @@ void Rwr_ManStop( Rwr_Man_t * p )
|
|||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_ManPrintStats( Rwr_Man_t * p )
|
||||
{
|
||||
int i, Counter = 0;
|
||||
for ( i = 0; i < 222; i++ )
|
||||
Counter += (p->nScores[i] > 0);
|
||||
|
||||
printf( "Rewriting statistics:\n" );
|
||||
printf( "Total cuts tries = %8d.\n", p->nCutsGood );
|
||||
printf( "Bad cuts found = %8d.\n", p->nCutsBad );
|
||||
printf( "Total subgraphs = %8d.\n", p->nSubgraphs );
|
||||
printf( "Used NPN classes = %8d.\n", Counter );
|
||||
printf( "Nodes considered = %8d.\n", p->nNodesConsidered );
|
||||
printf( "Nodes rewritten = %8d.\n", p->nNodesRewritten );
|
||||
printf( "Calculated gain = %8d.\n", p->nNodesGained );
|
||||
PRT( "Start ", p->timeStart );
|
||||
PRT( "Cuts ", p->timeCut );
|
||||
PRT( "Resynthesis ", p->timeRes );
|
||||
PRT( " Eval ", p->timeEval );
|
||||
PRT( "TOTAL ", p->timeTotal );
|
||||
|
||||
/*
|
||||
printf( "The scores are : " );
|
||||
for ( i = 0; i < 222; i++ )
|
||||
if ( p->nScores[i] > 0 )
|
||||
printf( "%d=%d ", i, p->nScores[i] );
|
||||
printf( "\n" );
|
||||
*/
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns elementary cuts to the PIs.]
|
||||
|
|
@ -137,11 +176,11 @@ void Rwr_ManStop( Rwr_Man_t * p )
|
|||
void Rwr_ManPrepareNetwork( Rwr_Man_t * p, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
// save the fanout counters for all internal nodes
|
||||
p->vFanNums = Rwt_NtkFanoutCounters( pNtk );
|
||||
// p->vFanNums = Rwt_NtkFanoutCounters( pNtk );
|
||||
// precompute the required times for all internal nodes
|
||||
p->vReqTimes = Abc_NtkGetRequiredLevels( pNtk );
|
||||
// p->vReqTimes = Abc_NtkGetRequiredLevels( pNtk );
|
||||
// start the cut computation
|
||||
Rwr_NtkStartCuts( p, pNtk );
|
||||
// Rwr_NtkStartCuts( p, pNtk );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -176,6 +215,54 @@ Vec_Int_t * Rwr_ManReadDecs( Rwr_Man_t * p )
|
|||
return p->vForm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwr_ManReadCompl( Rwr_Man_t * p )
|
||||
{
|
||||
return p->fCompl;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time )
|
||||
{
|
||||
p->timeCut += Time;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_ManAddTimeTotal( Rwr_Man_t * p, int Time )
|
||||
{
|
||||
p->timeTotal += Time;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -209,17 +209,17 @@ void Rwr_ManPrint( Rwr_Man_t * p )
|
|||
FILE * pFile;
|
||||
Rwr_Node_t * pNode;
|
||||
unsigned uTruth;
|
||||
int Counter, Volume, nFuncs, i;
|
||||
int Limit, Counter, Volume, nFuncs, i;
|
||||
pFile = fopen( "graph_lib.txt", "w" );
|
||||
Counter = 0;
|
||||
nFuncs = (1 << 16);
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
Limit = (1 << 16);
|
||||
for ( i = 0; i < Limit; i++ )
|
||||
{
|
||||
if ( p->pTable[i] == NULL )
|
||||
continue;
|
||||
if ( i != p->puCanons[i] )
|
||||
continue;
|
||||
fprintf( pFile, "\nClass %3d ", Counter++ );
|
||||
fprintf( pFile, "\nClass %3d. Func %6d. ", p->pMap[i], Counter++ );
|
||||
Rwr_GetBushVolume( p, i, &Volume, &nFuncs );
|
||||
fprintf( pFile, "Functions = %2d. Volume = %2d. ", nFuncs, Volume );
|
||||
uTruth = i;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ void Rwr_ManWriteToArray( Rwr_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_ManLoadFromArray( Rwr_Man_t * p )
|
||||
void Rwr_ManLoadFromArray( Rwr_Man_t * p, int fVerbose )
|
||||
{
|
||||
unsigned short * pArray = s_RwtAigSubgraphs;
|
||||
Rwr_Node_t * p0, * p1;
|
||||
|
|
@ -119,8 +119,11 @@ void Rwr_ManLoadFromArray( Rwr_Man_t * p )
|
|||
Rwr_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor );
|
||||
}
|
||||
nEntries = i - 1;
|
||||
printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded );
|
||||
printf( "The number of nodes loaded = %d. ", nEntries ); PRT( "Loading", clock() - clk );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded );
|
||||
printf( "The number of nodes loaded = %d. ", nEntries ); PRT( "Loading", clock() - clk );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ extern Vec_Int_t * Ft_Factor( char * pSop );
|
|||
extern int Ft_FactorGetNumNodes( Vec_Int_t * vForm );
|
||||
extern int Ft_FactorGetNumVars( Vec_Int_t * vForm );
|
||||
extern void Ft_FactorComplement( Vec_Int_t * vForm );
|
||||
extern Vec_Int_t * Ft_FactorConst( int fConst1 );
|
||||
extern Vec_Int_t * Ft_FactorVar( int iVar, int nVars, int fCompl );
|
||||
/*=== ftPrint.c =====================================================*/
|
||||
extern void Ft_FactorPrint( FILE * pFile, Vec_Int_t * vForm, char * pNamesIn[], char * pNameOut );
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ static Ft_Node_t * Ft_FactorTrivialCubeCascade( Vec_Int_t * vForm, Mvc_Cov
|
|||
static Ft_Node_t * Ft_FactorNodeCreate( Vec_Int_t * vForm, int Type, Ft_Node_t * pNode1, Ft_Node_t * pNode2 );
|
||||
static Ft_Node_t * Ft_FactorLeafCreate( Vec_Int_t * vForm, int iLit );
|
||||
static void Ft_FactorFinalize( Vec_Int_t * vForm, Ft_Node_t * pNode, int nVars );
|
||||
static Vec_Int_t * Ft_FactorConst( int fConst1 );
|
||||
|
||||
// temporary procedures that work with the covers
|
||||
static Mvc_Cover_t * Ft_ConvertSopToMvc( char * pSop );
|
||||
|
|
@ -320,6 +319,8 @@ Ft_Node_t * Ft_FactorTrivialTree_rec( Vec_Int_t * vForm, Ft_Node_t ** ppNodes, i
|
|||
return ppNodes[0];
|
||||
|
||||
// split the nodes into two parts
|
||||
// nNodes1 = nNodes/2;
|
||||
// nNodes2 = nNodes - nNodes1;
|
||||
nNodes2 = nNodes/2;
|
||||
nNodes1 = nNodes - nNodes2;
|
||||
|
||||
|
|
@ -613,6 +614,32 @@ Vec_Int_t * Ft_FactorConst( int fConst1 )
|
|||
return vForm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a constant 0 or 1 factored form.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ft_FactorVar( int iVar, int nVars, int fCompl )
|
||||
{
|
||||
Vec_Int_t * vForm;
|
||||
Ft_Node_t * pNode;
|
||||
// create the elementary variable node
|
||||
vForm = Vec_IntAlloc( nVars + 1 );
|
||||
Vec_IntFill( vForm, nVars + 1, 0 );
|
||||
pNode = Ft_NodeReadLast( vForm );
|
||||
pNode->iFanin0 = iVar;
|
||||
pNode->iFanin1 = iVar;
|
||||
pNode->fIntern = 1;
|
||||
pNode->fCompl = fCompl;
|
||||
return vForm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue