Commit 103fa22e by Alan Mishchenko

Version abc60803

parent 7e8e0320
......@@ -2114,6 +2114,10 @@ SOURCE=.\src\temp\ivy\ivyFanout.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyIsop.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyMan.c
# End Source File
# Begin Source File
......@@ -2166,6 +2170,10 @@ SOURCE=.\src\temp\player\playerCore.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\player\playerFast.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\player\playerMan.c
# End Source File
# Begin Source File
......
# global parameters
#set check # checks intermediate networks
#set checkfio # prints warnings when fanins/fanouts are duplicated
set checkread # checks new networks after reading from file
set backup # saves backup networks retrived by "undo" and "recall"
set savesteps 1 # sets the maximum number of backup networks to save
#set checkread # checks new networks after reading from file
#set backup # saves backup networks retrived by "undo" and "recall"
#set savesteps 1 # sets the maximum number of backup networks to save
# program names for internal calls
set dotwin dot.exe
......
......@@ -640,6 +640,7 @@ extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth );
extern char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover );
extern int Abc_SopGetCubeNum( char * pSop );
extern int Abc_SopGetLitNum( char * pSop );
extern int Abc_SopGetVarNum( char * pSop );
......
......@@ -357,6 +357,32 @@ int Abc_NodeMffsInside( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vIns
return Count1;
}
/**Function*************************************************************
Synopsis [Collects the internal nodes of the MFFC limited by cut.]
Description []
SideEffects [Increments the trav ID and marks visited nodes.]
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode )
{
Vec_Ptr_t * vInside;
int Count1, Count2;
// dereference the node
Count1 = Abc_NodeDeref_rec( pNode );
// collect the nodes inside the MFFC
vInside = Vec_PtrAlloc( 10 );
Abc_NodeMffsConeSupp( pNode, vInside, NULL );
// reference it back
Count2 = Abc_NodeRef_rec( pNode );
assert( Count1 == Count2 );
return vInside;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -401,6 +401,44 @@ char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTru
/**Function*************************************************************
Synopsis [Creates the cover from the ISOP computed from TT.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover )
{
char * pSop, * pCube;
int i, k, Entry, Literal;
assert( Vec_IntSize(vCover) > 0 );
if ( Vec_IntSize(vCover) == 0 )
return NULL;
// start the cover
pSop = Abc_SopStart( pMan, Vec_IntSize(vCover), nVars );
// create cubes
Vec_IntForEachEntry( vCover, Entry, i )
{
pCube = pSop + i * (nVars + 3);
for ( k = 0; k < nVars; k++ )
{
Literal = 3 & (Entry >> (k << 1));
if ( Literal == 1 )
pCube[k] = '1';
else if ( Literal == 2 )
pCube[k] = '0';
else if ( Literal != 0 )
assert( 0 );
}
}
return pSop;
}
/**Function*************************************************************
Synopsis [Reads the number of cubes in the cover.]
Description []
......
......@@ -32,6 +32,7 @@ static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
extern int nTotal, nGood, nEqual;
static Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
static int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......@@ -117,7 +118,9 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
Vec_IntFree( vChoices );
PRT( "Total", clock() - clk );
Cut_ManPrintStats( p );
PRT( "TOTAL ", clock() - clk );
printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) );
//Abc_NtkPrintCuts( p, pNtk, 0 );
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
......@@ -279,7 +282,8 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
pObj->fMarkC = 0;
if ( pParams->fVerbose )
{
PRT( "Total", clock() - clk );
Cut_ManPrintStats( p );
PRT( "TOTAL ", clock() - clk );
printf( "Converged after %d iterations.\n", nIters );
}
//Abc_NtkPrintCuts( p, pNtk, 1 );
......@@ -288,6 +292,27 @@ printf( "Converged after %d iterations.\n", nIters );
/**Function*************************************************************
Synopsis [Computes area.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p )
{
Abc_Obj_t * pObj;
int Counter, i;
Counter = 0;
Abc_NtkForEachCo( pNtk, pObj, i )
Counter += Cut_ManMappingArea_rec( p, Abc_ObjFaninId0(pObj) );
return Counter;
}
/**Function*************************************************************
Synopsis [Computes the cuts for the network.]
Description []
......@@ -479,21 +504,51 @@ void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
{
Vec_Int_t * vAttrs;
Abc_Obj_t * pObj;
int i;
// Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;//, * pTemp;
int i;//, k;
int nNodesTotal = 0, nMffcsTotal = 0;
extern Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode );
vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
// Abc_NtkForEachCi( pNtk, pObj, i )
// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjIsNode(pObj) )
nNodesTotal++;
if ( Abc_ObjIsCo(pObj) && Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
nMffcsTotal += Abc_NodeMffcSize( Abc_ObjFanin0(pObj) );
// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
// if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) )
{
int nMffc = Abc_NodeMffcSize(pObj);
nMffcsTotal += Abc_NodeMffcSize(pObj);
// printf( "%d ", nMffc );
if ( nMffc > 2 || Abc_ObjFanoutNum(pObj) > 8 )
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
}
}
/*
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Vec_IntEntry( vAttrs, pObj->Id ) )
{
vNodes = Abc_NodeMffsInsideCollect( pObj );
Vec_PtrForEachEntry( vNodes, pTemp, k )
if ( pTemp != pObj )
Vec_IntWriteEntry( vAttrs, pTemp->Id, 0 );
Vec_PtrFree( vNodes );
}
}
*/
printf( "Total nodes = %d. Total MFFC nodes = %d.\n", nNodesTotal, nMffcsTotal );
return vAttrs;
}
......@@ -533,7 +588,7 @@ int Abc_NtkSubDagSize_rec( Abc_Obj_t * pObj, Vec_Int_t * vAttrs )
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
{
Vec_Int_t * vAttrs;
Abc_Obj_t * pObj;
......
......@@ -25,7 +25,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose );
static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose );
static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga );
......@@ -44,7 +44,7 @@ static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNo
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fVerbose )
Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose )
{
int fShowSwitching = 1;
Abc_Ntk_t * pNtkNew;
......@@ -68,11 +68,13 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int
}
// perform FPGA mapping
pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fVerbose );
pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose );
if ( pSwitching ) Vec_IntFree( vSwitching );
if ( pMan == NULL )
return NULL;
Fpga_ManSetSwitching( pMan, fSwitching );
Fpga_ManSetLatchPaths( pMan, fLatchPaths );
Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) );
Fpga_ManSetDelayTarget( pMan, DelayTarget );
if ( !Fpga_Mapping( pMan ) )
{
......@@ -113,13 +115,14 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int
SeeAlso []
***********************************************************************/
Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose )
Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose )
{
Fpga_Man_t * pMan;
ProgressBar * pProgress;
Fpga_Node_t * pNodeFpga;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pFanin, * pPrev;
float * pfArrivals;
int i;
assert( Abc_NtkIsStrash(pNtk) );
......@@ -130,7 +133,13 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching,
return NULL;
Fpga_ManSetAreaRecovery( pMan, fRecovery );
Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) );
pfArrivals = Abc_NtkGetCiArrivalFloats(pNtk);
if ( fLatchPaths )
{
for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
pfArrivals[i] = -FPGA_FLOAT_LARGE;
}
Fpga_ManSetInputArrivals( pMan, pfArrivals );
// create PIs and remember them in the old nodes
Abc_NtkCleanCopy( pNtk );
......
......@@ -63,8 +63,8 @@ Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int f
// perform fraiging
pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes, fExdc );
// add algebraic choices
if ( pPars->fChoicing )
Fraig_ManAddChoices( pMan, 0, 6 );
// if ( pPars->fChoicing )
// Fraig_ManAddChoices( pMan, 0, 6 );
// prove the miter if asked to
if ( pPars->fTryProve )
Fraig_ManProveMiter( pMan );
......
......@@ -50,7 +50,7 @@ static inline Abc_Obj_t * Abc_EdgeToNode( Abc_Ntk_t * p, Abc_Edge_t Edge ) {
static inline Abc_Obj_t * Abc_ObjFanin0Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ); }
static inline Abc_Obj_t * Abc_ObjFanin1Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ); }
static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......@@ -67,7 +67,7 @@ static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
SeeAlso []
***********************************************************************/
Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq )
Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
{
Ivy_Man_t * pMan;
int fCleanup = 1;
......@@ -101,7 +101,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq )
if ( fSeq )
{
int nLatches = Abc_NtkLatchNum(pNtk);
int * pInit = Abc_NtkCollectLatchValues( pNtk );
int * pInit = Abc_NtkCollectLatchValues( pNtk, fUseDc );
Ivy_ManMakeSeq( pMan, nLatches, pInit );
FREE( pInit );
// Ivy_ManPrintStats( pMan );
......@@ -160,7 +160,7 @@ Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan;
pMan = Abc_NtkIvyBefore( pNtk, 1 );
pMan = Abc_NtkIvyBefore( pNtk, 1, 0 );
if ( pMan == NULL )
return NULL;
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 );
......@@ -183,7 +183,7 @@ void Abc_NtkIvyCuts( Abc_Ntk_t * pNtk, int nInputs )
{
extern void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs );
Ivy_Man_t * pMan;
pMan = Abc_NtkIvyBefore( pNtk, 1 );
pMan = Abc_NtkIvyBefore( pNtk, 1, 0 );
if ( pMan == NULL )
return;
Ivy_CutComputeAll( pMan, nInputs );
......@@ -205,7 +205,7 @@ Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroC
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan;
pMan = Abc_NtkIvyBefore( pNtk, 0 );
pMan = Abc_NtkIvyBefore( pNtk, 0, 0 );
if ( pMan == NULL )
return NULL;
Ivy_ManRewritePre( pMan, fUpdateLevel, fUseZeroCost, fVerbose );
......@@ -225,11 +225,35 @@ Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroC
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkIvyRewriteSeq( Abc_Ntk_t * pNtk, int fUseZeroCost, int fVerbose )
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan;
pMan = Abc_NtkIvyBefore( pNtk, 1, 1 );
if ( pMan == NULL )
return NULL;
Ivy_ManRewriteSeq( pMan, fUseZeroCost, fVerbose );
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 );
Ivy_ManStop( pMan );
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose )
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan, * pTemp;
pMan = Abc_NtkIvyBefore( pNtk, 0 );
pMan = Abc_NtkIvyBefore( pNtk, 0, 0 );
if ( pMan == NULL )
return NULL;
pMan = Ivy_ManResyn( pTemp = pMan, fUpdateLevel, fVerbose );
......@@ -253,11 +277,11 @@ Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose )
Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan, * pTemp;
Ivy_Man_t * pMan;//, * pTemp;
int fCleanup = 1;
int nNodes;
int nLatches = Abc_NtkLatchNum(pNtk);
int * pInit = Abc_NtkCollectLatchValues( pNtk );
int * pInit = Abc_NtkCollectLatchValues( pNtk, 0 );
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
......@@ -304,7 +328,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
// pMan = Ivy_ManResyn( pTemp = pMan, 1, 0 );
// Ivy_ManStop( pTemp );
Ivy_ManTestCutsAll( pMan );
// Ivy_ManTestCutsAll( pMan );
// Ivy_ManPrintStats( pMan );
......@@ -319,6 +343,10 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
// Ivy_ManRequiredLevels( pMan );
Pla_ManFastLutMap( pMan, 8 );
Ivy_ManStop( pMan );
return NULL;
/*
// convert from the AIG manager
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
// pNtkAig = Abc_NtkFromAigSeq( pNtk, pMan );
......@@ -341,6 +369,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
FREE( pInit );
return pNtkAig;
*/
}
......@@ -717,14 +746,14 @@ Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, cha
SeeAlso []
***********************************************************************/
int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs )
{
Abc_Obj_t * pLatch;
int * pArray, i;
pArray = ALLOC( int, Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
if ( Abc_LatchIsInitDc(pLatch) )
if ( fUseDcs || Abc_LatchIsInitDc(pLatch) )
pArray[i] = IVY_INIT_DC;
else if ( Abc_LatchIsInit1(pLatch) )
pArray[i] = IVY_INIT_1;
......
......@@ -300,6 +300,7 @@ void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk )
nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) );
else
nFanouts = Abc_ObjFanoutNum(pNode);
// nFanouts = Abc_NodeMffcSize(pNode);
if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize )
{
nOldSize = vFanins->nSize;
......
......@@ -396,6 +396,26 @@ void Abc_NtkCollectSupergate( Abc_Obj_t * pNode, int fStopAtMux, Vec_Ptr_t * vNo
/**Function*************************************************************
Synopsis [Computes the factor of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkNodeFactor( Abc_Obj_t * pObj, int nLevelMax )
{
// nLevelMax = ((nLevelMax)/2)*3;
assert( pObj->Level <= nLevelMax );
// return (int)(100000000.0 * pow(0.999, nLevelMax - pObj->Level));
return (int)(100000000.0 * (1 + 0.01 * pObj->Level));
// return (int)(100000000.0 / ((nLevelMax)/2)*3 - pObj->Level);
}
/**Function*************************************************************
Synopsis [Sets up the SAT solver.]
Description []
......@@ -409,11 +429,13 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
{
Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
Vec_Ptr_t * vNodes, * vSuper;
// Vec_Int_t * vLevels;
Vec_Int_t * vVars, * vFanio;
Vec_Vec_t * vCircuit;
int i, k, fUseMuxes = 1;
int clk1 = clock(), clk;
int fOrderCiVarsFirst = 0;
int nLevelsMax = Abc_AigGetLevelNum(pNtk);
assert( Abc_NtkIsStrash(pNtk) );
......@@ -422,9 +444,9 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
pNode->pCopy = NULL;
// start the data structures
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
if ( fJFront )
vCircuit = Vec_VecAlloc( 1000 );
// vCircuit = Vec_VecStart( 184 );
......@@ -565,7 +587,16 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
// Asat_JManStop( pSat );
// PRT( "Total", clock() - clk1 );
}
/*
// create factors
vLevels = Vec_IntStart( Vec_PtrSize(vNodes) ); // the reverse levels of the nodes
Abc_NtkForEachObj( pNtk, pNode, i )
if ( pNode->fMarkA )
Vec_IntWriteEntry( vLevels, (int)pNode->pCopy, Abc_NtkNodeFactor(pNode, nLevelsMax) );
assert( Vec_PtrSize(vNodes) == Vec_IntSize(vLevels) );
Asat_SolverSetFactors( pSat, Vec_IntReleaseArray(vLevels) );
Vec_IntFree( vLevels );
*/
// delete
Vec_IntFree( vVars );
Vec_PtrFree( vNodes );
......
......@@ -136,9 +136,11 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
{
extern void Rwt_ManGlobalStop();
extern void undefine_cube_size();
extern void Ivy_TruthManStop();
// Abc_HManStop();
undefine_cube_size();
Rwt_ManGlobalStop();
Ivy_TruthManStop();
if ( p->pManDec ) Dec_ManStop( p->pManDec );
if ( p->dd ) Extra_StopManager( p->dd );
Abc_FrameDeleteAllNetworks( p );
......
......@@ -96,8 +96,9 @@ extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNode
extern void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices );
extern void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose );
extern void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching );
extern void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget );
extern void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths );
extern void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches );
extern void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget );
extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName );
extern int Fpga_LibReadLutMax( Fpga_LutLib_t * pLib );
......
......@@ -100,6 +100,9 @@ int Fpga_MappingPostProcess( Fpga_Man_t * p )
float aAreaTotalCur, aAreaTotalCur2;
int Iter, clk;
if ( p->fVerbose )
printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) );
// compute area, set references, and collect nodes used in the mapping
Iter = 1;
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
......
......@@ -66,8 +66,9 @@ void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p
void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ) { p->nChoices = nChoices; }
void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; }
void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths ) { p->fLatchPaths = fLatchPaths; }
void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; }
void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; }
void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; }
/**Function*************************************************************
......
......@@ -35,9 +35,9 @@ struct Fpga_CutTableStrutct_t
};
// the largest number of cuts considered
#define FPGA_CUTS_MAX_COMPUTE 5000
#define FPGA_CUTS_MAX_COMPUTE 500
// the largest number of cuts used
#define FPGA_CUTS_MAX_USE 2000
#define FPGA_CUTS_MAX_USE 200
// primes used to compute the hash key
static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 };
......
......@@ -122,6 +122,7 @@ struct Fpga_ManStruct_t_
int fAreaRecovery; // the flag to use area flow as the first parameter
int fVerbose; // the verbosiness flag
int fSwitching; // minimize the switching activity (instead of area)
int fLatchPaths; // optimize latch paths for delay, other paths for area
int nTravIds; // the counter of traversal IDs
float DelayTarget; // the target required times
......
......@@ -87,13 +87,34 @@ float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p )
{
float fRequired;
int i;
if ( p->fLatchPaths && p->nLatches == 0 )
{
printf( "Delay optimization of latch path is not performed because there is no latches.\n" );
p->fLatchPaths = 0;
}
// get the critical PO arrival time
fRequired = -FPGA_FLOAT_LARGE;
for ( i = 0; i < p->nOutputs; i++ )
if ( p->fLatchPaths )
{
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
continue;
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ )
{
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
continue;
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
}
// printf( "Required latches = %5.1f\n", fRequired );
}
else
{
for ( i = 0; i < p->nOutputs; i++ )
{
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
continue;
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
}
// printf( "Required outputs = %5.1f\n", fRequired );
}
return fRequired;
}
......@@ -148,10 +169,23 @@ void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired )
for ( i = 0; i < p->vAnds->nSize; i++ )
p->vAnds->pArray[i]->tRequired = FPGA_FLOAT_LARGE;
// set the required times for the POs
for ( i = 0; i < p->nOutputs; i++ )
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
if ( p->fLatchPaths )
for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ )
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
else
for ( i = 0; i < p->nOutputs; i++ )
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
// collect nodes reachable from POs in the DFS order through the best cuts
Fpga_TimePropagateRequired( p, p->vMapping );
/*
{
int Counter = 0;
for ( i = 0; i < p->vAnds->nSize; i++ )
if ( p->vAnds->pArray[i]->tRequired > FPGA_FLOAT_LARGE - 100 )
Counter++;
printf( "The number of nodes with large required times = %d.\n", Counter );
}
*/
}
/**Function*************************************************************
......
......@@ -662,7 +662,7 @@ void Extra_TruthMux( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nV
for ( i = 0; i < Step; i++ )
{
pOut[i] = pCof0[i];
pOut[Step+i] = pCof1[i];
pOut[Step+i] = pCof1[Step+i];
}
pOut += 2*Step;
}
......
......@@ -46,8 +46,8 @@ Nm_Man_t * Nm_ManCreate( int nSize )
p = ALLOC( Nm_Man_t, 1 );
memset( p, 0, sizeof(Nm_Man_t) );
// set the parameters
p->nSizeFactor = 3; // determined how much larger the table should be compared to data in it
p->nGrowthFactor = 3; // determined how much the table grows after resizing
p->nSizeFactor = 4; // determined how much larger the table should be compared to data in it
p->nGrowthFactor = 4; // determined how much the table grows after resizing
// allocate and clean the bins
p->nBins = Cudd_PrimeNm(p->nSizeFactor*nSize);
p->pBinsI2N = ALLOC( Nm_Entry_t *, p->nBins );
......
......@@ -44,7 +44,7 @@ static unsigned Nm_HashString( char * pName, int TableSize )
};
unsigned i, Key = 0;
for ( i = 0; pName[i] != '\0'; i++ )
Key ^= s_Primes[i%10]*pName[i]*pName[i];
Key ^= s_Primes[i%10]*pName[i]*pName[i]*pName[i];
return Key % TableSize;
}
......
......@@ -525,10 +525,18 @@ static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
{
int i;
// delete assuming that it is closer to the end
for ( i = p->nSize - 1; i >= 0; i-- )
if ( p->pArray[i] == Entry )
break;
assert( i >= 0 );
/*
// delete assuming that it is closer to the beginning
for ( i = 0; i < p->nSize; i++ )
if ( p->pArray[i] == Entry )
break;
assert( i < p->nSize );
*/
for ( i++; i < p->nSize; i++ )
p->pArray[i-1] = p->pArray[i];
p->nSize--;
......
......@@ -65,6 +65,7 @@ struct Cut_ParamsStruct_t_
int fLocal; // compute only local cuts
int fRecord; // record the cut computation flow
int fFancy; // perform fancy computations
int fMap; // computes delay of FPGA mapping with cuts
int fVerbose; // the verbosiness flag
};
......@@ -129,6 +130,7 @@ extern void Cut_ManIncrementDagNodes( Cut_Man_t * p );
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode );
extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes );
extern Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst );
extern int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node );
/*=== cutSeq.c ==========================================================*/
extern void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int nLat0, int nLat1, int fTriv, int CutSetNum );
extern void Cut_NodeNewMergeWithOld( Cut_Man_t * p, int Node );
......
......@@ -71,6 +71,11 @@ struct Cut_ManStruct_t_
Vec_Int_t * vNodeCuts; // the number of cuts for each node
Vec_Int_t * vNodeStarts; // the number of the starting cut of each node
Vec_Int_t * vCutPairs; // the pairs of parent cuts for each cut
// minimum delay mapping with the given cuts
Vec_Ptr_t * vCutsMax;
Vec_Int_t * vDelays;
Vec_Int_t * vDelays2;
int nDelayMin;
// statistics
int nCutsCur;
int nCutsAlloc;
......@@ -88,6 +93,7 @@ struct Cut_ManStruct_t_
int timeTruth;
int timeFilter;
int timeHash;
int timeMap;
};
// iterator through all the cuts of the list
......
......@@ -95,6 +95,13 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
p->vNodeStarts = Vec_IntStart( pParams->nIdsMax );
p->vCutPairs = Vec_IntAlloc( 0 );
}
// allocate storage for delays
if ( pParams->fMap && !p->pParams->fSeq )
{
p->vDelays = Vec_IntStart( pParams->nIdsMax );
p->vDelays2 = Vec_IntStart( pParams->nIdsMax );
p->vCutsMax = Vec_PtrStart( pParams->nIdsMax );
}
// memory for cuts
p->pMmCuts = Extra_MmFixedStart( p->EntrySize );
p->vTemp = Vec_PtrAlloc( 100 );
......@@ -130,6 +137,9 @@ void Cut_ManStop( Cut_Man_t * p )
if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts );
if ( p->vTemp ) Vec_PtrFree( p->vTemp );
if ( p->vCutsMax ) Vec_PtrFree( p->vCutsMax );
if ( p->vDelays ) Vec_IntFree( p->vDelays );
if ( p->vDelays2 ) Vec_IntFree( p->vDelays2 );
if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts );
if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts );
if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs );
......@@ -168,13 +178,20 @@ void Cut_ManPrintStats( Cut_Man_t * p )
printf( "The cut size = %8d bytes.\n", p->EntrySize );
printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
printf( "Total nodes = %8d.\n", p->nNodes );
if ( p->pParams->fDag || p->pParams->fTree )
{
printf( "DAG nodes = %8d.\n", p->nNodesDag );
printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag );
}
printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts );
if ( p->pParams->fMap && !p->pParams->fSeq )
printf( "Mapping delay = %8d.\n", p->nDelayMin );
PRT( "Merge ", p->timeMerge );
PRT( "Union ", p->timeUnion );
PRT( "Filter", p->timeFilter );
PRT( "Truth ", p->timeTruth );
PRT( "Map ", p->timeMap );
// printf( "Nodes = %d. Multi = %d. Cuts = %d. Multi = %d.\n",
// p->nNodes, p->nNodesMulti, p->nCutsCur-p->nCutsTriv, p->nCutsMulti );
// printf( "Count0 = %d. Count1 = %d. Count2 = %d.\n\n", p->Count0, p->Count1, p->Count2 );
......
......@@ -24,6 +24,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 );
static int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -396,15 +399,157 @@ p->timeMerge += clock() - clk;
// set the list at the node
Vec_PtrFillExtra( p->vCutsNew, Node + 1, NULL );
assert( Cut_NodeReadCutsNew(p, Node) == NULL );
/////
pList->pNext = NULL;
/////
Cut_NodeWriteCutsNew( p, Node, pList );
// filter the cuts
//clk = clock();
// if ( p->pParams->fFilter )
// Cut_CutFilter( p, pList0 );
//p->timeFilter += clock() - clk;
// perform mapping of this node with these cuts
clk = clock();
if ( p->pParams->fMap && !p->pParams->fSeq )
{
// int Delay1, Delay2;
// Delay1 = Cut_NodeMapping( p, pList, Node, Node0, Node1 );
// Delay2 = Cut_NodeMapping2( p, pList, Node, Node0, Node1 );
// assert( Delay1 >= Delay2 );
Cut_NodeMapping( p, pList, Node, Node0, Node1 );
}
p->timeMap += clock() - clk;
return pList;
}
/**Function*************************************************************
Synopsis [Returns optimum delay mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 )
{
Cut_Cut_t * pCut;
int DelayMin, DelayCur, i;
if ( pCuts == NULL )
p->nDelayMin = -1;
if ( p->nDelayMin == -1 )
return -1;
DelayMin = 1000000;
Cut_ListForEachCut( pCuts, pCut )
{
if ( pCut->nLeaves == 1 )
continue;
DelayCur = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
if ( DelayCur < Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) )
DelayCur = Vec_IntEntry(p->vDelays, pCut->pLeaves[i]);
if ( DelayMin > DelayCur )
DelayMin = DelayCur;
}
if ( DelayMin == 1000000 )
{
p->nDelayMin = -1;
return -1;
}
DelayMin++;
Vec_IntWriteEntry( p->vDelays, Node, DelayMin );
if ( p->nDelayMin < DelayMin )
p->nDelayMin = DelayMin;
return DelayMin;
}
/**Function*************************************************************
Synopsis [Returns optimum delay mapping using the largest cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 )
{
Cut_Cut_t * pCut0, * pCut1, * pCut;
int Delay0, Delay1, Delay;
// get the fanin cuts
Delay0 = Vec_IntEntry( p->vDelays2, Node0 );
Delay1 = Vec_IntEntry( p->vDelays2, Node1 );
pCut0 = (Delay0 == 0) ? Vec_PtrEntry( p->vCutsNew, Node0 ) : Vec_PtrEntry( p->vCutsMax, Node0 );
pCut1 = (Delay1 == 0) ? Vec_PtrEntry( p->vCutsNew, Node1 ) : Vec_PtrEntry( p->vCutsMax, Node1 );
if ( Delay0 == Delay1 )
Delay = (Delay0 == 0) ? Delay0 + 1: Delay0;
else if ( Delay0 > Delay1 )
{
Delay = Delay0;
pCut1 = Vec_PtrEntry( p->vCutsNew, Node1 );
assert( pCut1->nLeaves == 1 );
}
else // if ( Delay0 < Delay1 )
{
Delay = Delay1;
pCut0 = Vec_PtrEntry( p->vCutsNew, Node0 );
assert( pCut0->nLeaves == 1 );
}
// merge the cuts
if ( pCut0->nLeaves < pCut1->nLeaves )
pCut = Cut_CutMergeTwo( p, pCut1, pCut0 );
else
pCut = Cut_CutMergeTwo( p, pCut0, pCut1 );
if ( pCut == NULL )
{
Delay++;
pCut = Cut_CutAlloc( p );
pCut->nLeaves = 2;
pCut->pLeaves[0] = Node0 < Node1 ? Node0 : Node1;
pCut->pLeaves[1] = Node0 < Node1 ? Node1 : Node0;
}
assert( Delay > 0 );
Vec_IntWriteEntry( p->vDelays2, Node, Delay );
Vec_PtrWriteEntry( p->vCutsMax, Node, pCut );
if ( p->nDelayMin < Delay )
p->nDelayMin = Delay;
return Delay;
}
/**Function*************************************************************
Synopsis [Computes area after mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node )
{
Cut_Cut_t * pCut;
int i, Counter;
if ( p->vCutsMax == NULL )
return 0;
pCut = Vec_PtrEntry( p->vCutsMax, Node );
if ( pCut == NULL || pCut->nLeaves == 1 )
return 0;
Counter = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Counter += Cut_ManMappingArea_rec( p, pCut->pLeaves[i] );
Vec_PtrWriteEntry( p->vCutsMax, Node, NULL );
return 1 + Counter;
}
/**Function*************************************************************
Synopsis [Computes the cuts by merging cuts at two nodes.]
......
/**CFile****************************************************************
FileName [vec.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Resizable arrays.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __VEC_H__
#define __VEC_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define inline __inline // compatible with MS VS 6.0
#endif
#include "vecInt.h"
#include "vecStr.h"
#include "vecPtr.h"
#include "vecVec.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [vecVec.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Resizable arrays.]
Synopsis [Resizable vector of resizable vectors.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __VEC_VEC_H__
#define __VEC_VEC_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Vec_Vec_t_ Vec_Vec_t;
struct Vec_Vec_t_
{
int nCap;
int nSize;
void ** pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
// iterators through levels
#define Vec_VecForEachLevel( vGlob, vVec, i ) \
for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
// iteratores through entries
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
for ( i = LevelStart; i <= LevelStop; i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates a vector with the given capacity.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
{
Vec_Vec_t * p;
p = ALLOC( Vec_Vec_t, 1 );
if ( nCap > 0 && nCap < 8 )
nCap = 8;
p->nSize = 0;
p->nCap = nCap;
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
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 [Allocates a vector with the given capacity.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
{
int i;
if ( p->nSize >= Level + 1 )
return;
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
for ( i = p->nSize; i <= Level; i++ )
p->pArray[i] = Vec_PtrAlloc( 0 );
p->nSize = Level + 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_VecSize( Vec_Vec_t * p )
{
return p->nSize;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
{
assert( i >= 0 && i < p->nSize );
return p->pArray[i];
}
/**Function*************************************************************
Synopsis [Frees the vector.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecFree( Vec_Vec_t * p )
{
Vec_Ptr_t * vVec;
int i;
Vec_VecForEachLevel( p, vVec, i )
Vec_PtrFree( vVec );
Vec_PtrFree( (Vec_Ptr_t *)p );
}
/**Function*************************************************************
Synopsis [Frees the vector of vectors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_VecSizeSize( Vec_Vec_t * p )
{
Vec_Ptr_t * vVec;
int i, Counter = 0;
Vec_VecForEachLevel( p, vVec, i )
Counter += vVec->nSize;
return Counter;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecClear( Vec_Vec_t * p )
{
Vec_Ptr_t * vVec;
int i;
Vec_VecForEachLevel( p, vVec, i )
Vec_PtrClear( vVec );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
{
if ( p->nSize < Level + 1 )
{
int i;
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
for ( i = p->nSize; i < Level + 1; i++ )
p->pArray[i] = Vec_PtrAlloc( 0 );
p->nSize = Level + 1;
}
Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
{
if ( p->nSize < Level + 1 )
Vec_VecPush( p, Level, Entry );
else
Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -51,11 +51,15 @@ struct Dec_Node_t_
Dec_Edge_t eEdge1; // the right child of the node
// other info
void * pFunc; // the function of the node (BDD or AIG)
unsigned Level : 16; // the level of this node in the global AIG
unsigned Level : 14; // the level of this node in the global AIG
// printing info
unsigned fNodeOr : 1; // marks the original OR node
unsigned fCompl0 : 1; // marks the original complemented edge
unsigned fCompl1 : 1; // marks the original complemented edge
// latch info
unsigned nLat0 : 5; // the number of latches on the first edge
unsigned nLat1 : 5; // the number of latches on the second edge
unsigned nLat2 : 5; // the number of latches on the output edge
};
typedef struct Dec_Graph_t_ Dec_Graph_t;
......
......@@ -27,6 +27,7 @@
static Dec_Graph_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 );
static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......@@ -72,6 +73,8 @@ clk = clock();
assert( pCut != NULL );
p->timeCut += clock() - clk;
//printf( " %d", Rwr_CutCountNumNodes(pNode, pCut) );
// go through the cuts
clk = clock();
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
......@@ -104,6 +107,15 @@ clk = clock();
}
p->nCutsGood++;
{
int Counter = 0;
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 )
Counter++;
if ( Counter > 2 )
continue;
}
clk2 = clock();
/*
printf( "Considering: (" );
......@@ -306,6 +318,72 @@ int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
return RetValue;
}
/**Function*************************************************************
Synopsis [Count the nodes in the cut space of a node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes )
{
int i;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
if ( pCut->pLeaves[i] == pObj->Id )
{
// check if the node is collected
if ( pObj->fMarkC == 0 )
{
pObj->fMarkC = 1;
Vec_PtrPush( vNodes, pObj );
}
return;
}
assert( Abc_ObjIsNode(pObj) );
// check if the node is collected
if ( pObj->fMarkC == 0 )
{
pObj->fMarkC = 1;
Vec_PtrPush( vNodes, pObj );
}
// traverse the fanins
Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes );
Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes );
}
/**Function*************************************************************
Synopsis [Count the nodes in the cut space of a node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut )
{
Vec_Ptr_t * vNodes;
int i, Counter;
// collect all nodes
vNodes = Vec_PtrAlloc( 100 );
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes );
// clean all nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->fMarkC = 0;
// delete and return
Counter = Vec_PtrSize(vNodes);
Vec_PtrFree( vNodes );
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -209,6 +209,23 @@ void Asat_SolverSetPrefVars(solver * s, int * pPrefVars, int nPrefVars)
s->nPrefVars = nPrefVars;
}
/**Function*************************************************************
Synopsis [Sets the preferred variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_SolverSetFactors(solver * s, int * pFactors)
{
assert( s->factors == NULL );
s->factors = pFactors;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -254,6 +254,7 @@ static inline void act_var_rescale(solver* s) {
static inline void act_var_bump(solver* s, int v) {
double* activity = s->activity;
if ((activity[v] += s->var_inc) > 1e100)
// if ((activity[v] += s->var_inc*s->factors[v]/100000000) > 1e100)
act_var_rescale(s);
//printf("bump %d %f\n", v-1, activity[v]);
......@@ -947,6 +948,7 @@ solver* solver_new(void)
// initialize arrays
s->wlists = 0;
s->activity = 0;
s->factors = 0;
s->assigns = 0;
s->orderpos = 0;
s->reasons = 0;
......@@ -1039,9 +1041,9 @@ void solver_delete(solver* s)
free(s->trail );
free(s->tags );
}
if ( s->pJMan ) Asat_JManStop( s );
if ( s->pPrefVars ) free( s->pPrefVars );
if ( s->factors ) free( s->factors );
free(s);
}
......
......@@ -89,6 +89,7 @@ extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName,
int incrementVars);
extern void Asat_SatPrintStats( FILE * pFile, solver * p );
extern void Asat_SolverSetPrefVars( solver * s, int * pPrefVars, int nPrefVars );
extern void Asat_SolverSetFactors( solver * s, int * pFactors );
// J-frontier support
extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit );
......@@ -127,6 +128,7 @@ struct solver_t
vec* wlists; //
double* activity; // A heuristic measurement of the activity of a variable.
int * factors; // the factor of variable activity
lbool* assigns; // Current values of variables.
int* orderpos; // Index in variable order.
clause** reasons; //
......
......@@ -326,7 +326,7 @@ int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t *
Fraig_ManCreateSolver( p );
// make sure the SAT solver has enough variables
for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
Msat_SolverAddVar( p->pSat );
Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
......@@ -543,7 +543,7 @@ int Fraig_NodeIsImplication( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t
Fraig_ManCreateSolver( p );
// make sure the SAT solver has enough variables
for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
Msat_SolverAddVar( p->pSat );
Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
// get the logic cone
clk = clock();
......@@ -642,7 +642,7 @@ int Fraig_ManCheckClauseUsingSat( Fraig_Man_t * p, Fraig_Node_t * pNode1, Fraig_
Fraig_ManCreateSolver( p );
// make sure the SAT solver has enough variables
for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
Msat_SolverAddVar( p->pSat );
Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
// get the logic cone
clk = clock();
......
......@@ -80,7 +80,7 @@ typedef enum { MSAT_FALSE = -1, MSAT_UNKNOWN = 0, MSAT_TRUE = 1 } Msat_Type_t;
extern bool Msat_SolverParseDimacs( FILE * pFile, Msat_Solver_t ** p, int fVerbose );
/*=== satSolver.c ===========================================================*/
// adding vars, clauses, simplifying the database, and solving
extern bool Msat_SolverAddVar( Msat_Solver_t * p );
extern bool Msat_SolverAddVar( Msat_Solver_t * p, int Level );
extern bool Msat_SolverAddClause( Msat_Solver_t * p, Msat_IntVec_t * pLits );
extern bool Msat_SolverSimplifyDB( Msat_Solver_t * p );
extern bool Msat_SolverSolve( Msat_Solver_t * p, Msat_IntVec_t * pVecAssumps, int nBackTrackLimit, int nTimeLimit );
......
......@@ -46,6 +46,7 @@ void Msat_SolverVarBumpActivity( Msat_Solver_t * p, Msat_Lit_t Lit )
return;
Var = MSAT_LIT2VAR(Lit);
if ( (p->pdActivity[Var] += p->dVarInc) > 1e100 )
// if ( (p->pdActivity[Var] += p->dVarInc * (1.0 + 0.005*p->pLevel[Var])) > 1e100 )
Msat_SolverVarRescaleActivity( p );
Msat_OrderUpdate( p->pOrder, Var );
}
......
......@@ -119,6 +119,7 @@ struct Msat_Solver_t_
double dClaDecay; // INVERSE decay factor for clause activity: stores 1/decay.
double * pdActivity; // A heuristic measurement of the activity of a variable.
int * pLevels; // the levels of the variables
double dVarInc; // Amount to bump next variable with.
double dVarDecay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
Msat_Order_t * pOrder; // Keeps track of the decision variable order.
......
......@@ -174,8 +174,12 @@ Msat_Solver_t * Msat_SolverAlloc( int nVarsAlloc,
p->dVarDecay = dVarDecay;
p->pdActivity = ALLOC( double, p->nVarsAlloc );
p->pLevels = ALLOC( int, p->nVarsAlloc );
for ( i = 0; i < p->nVarsAlloc; i++ )
{
p->pdActivity[i] = 0;
p->pLevels = 0;
}
p->pAssigns = ALLOC( int, p->nVarsAlloc );
p->pModel = ALLOC( int, p->nVarsAlloc );
......@@ -239,6 +243,7 @@ void Msat_SolverResize( Msat_Solver_t * p, int nVarsAlloc )
p->nVarsAlloc = nVarsAlloc;
p->pdActivity = REALLOC( double, p->pdActivity, p->nVarsAlloc );
p->pLevels = REALLOC( int, p->pLevels, p->nVarsAlloc );
for ( i = nVarsAllocOld; i < p->nVarsAlloc; i++ )
p->pdActivity[i] = 0;
......@@ -394,6 +399,7 @@ void Msat_SolverFree( Msat_Solver_t * p )
Msat_ClauseVecFree( p->vLearned );
FREE( p->pdActivity );
FREE( p->pLevels );
Msat_OrderFree( p->pOrder );
for ( i = 0; i < 2 * p->nVarsAlloc; i++ )
......
......@@ -39,10 +39,11 @@
SeeAlso []
***********************************************************************/
bool Msat_SolverAddVar( Msat_Solver_t * p )
bool Msat_SolverAddVar( Msat_Solver_t * p, int Level )
{
if ( p->nVars == p->nVarsAlloc )
Msat_SolverResize( p, 2 * p->nVarsAlloc );
p->pLevel[p->nVars] = Level;
p->nVars++;
return 1;
}
......
......@@ -51,11 +51,15 @@ struct Dec_Node_t_
Dec_Edge_t eEdge1; // the right child of the node
// other info
void * pFunc; // the function of the node (BDD or AIG)
unsigned Level : 16; // the level of this node in the global AIG
unsigned Level : 14; // the level of this node in the global AIG
// printing info
unsigned fNodeOr : 1; // marks the original OR node
unsigned fCompl0 : 1; // marks the original complemented edge
unsigned fCompl1 : 1; // marks the original complemented edge
// latch info
unsigned nLat0 : 5; // the number of latches on the first edge
unsigned nLat1 : 5; // the number of latches on the second edge
unsigned nLat2 : 5; // the number of latches on the output edge
};
typedef struct Dec_Graph_t_ Dec_Graph_t;
......
......@@ -80,6 +80,8 @@ struct Ivy_Obj_t_ // 24 bytes (32-bit) or 32 bytes (64-bit)
int nRefs; // reference counter
Ivy_Obj_t * pFanin0; // fanin
Ivy_Obj_t * pFanin1; // fanin
Ivy_Obj_t * pFanout; // fanout
Ivy_Obj_t * pEquiv; // equivalent node
};
// the AIG manager
......@@ -136,6 +138,9 @@ struct Ivy_Store_t_
Ivy_Cut_t pCuts[IVY_CUT_LIMIT]; // storage for cuts
};
#define IVY_LEAF_MASK 255
#define IVY_LEAF_BITS 8
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -170,9 +175,9 @@ static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { ret
static inline Ivy_Edge_t Ivy_EdgeFromNode( Ivy_Obj_t * pNode ) { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) ); }
static inline Ivy_Obj_t * Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); }
static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; }
static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; }
static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; }
static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << IVY_LEAF_BITS) | Lat; }
static inline int Ivy_LeafId( int Leaf ) { return Leaf >> IVY_LEAF_BITS; }
static inline int Ivy_LeafLat( int Leaf ) { return Leaf & IVY_LEAF_MASK; }
static inline int Ivy_ManPiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PI]; }
static inline int Ivy_ManPoNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PO]; }
......@@ -261,12 +266,16 @@ static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout
static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init )
{
Ivy_Obj_t * pGhost, * pTemp;
assert( Type != IVY_AND || !Ivy_ObjIsConst1(Ivy_Regular(p0)) );
assert( p1 == NULL || !Ivy_ObjIsConst1(Ivy_Regular(p1)) );
assert( Type == IVY_PI || Ivy_Regular(p0) != Ivy_Regular(p1) );
assert( Type != IVY_LATCH || !Ivy_IsComplement(p0) );
// assert( p1 == NULL || (!Ivy_ObjIsLatch(Ivy_Regular(p0)) || !Ivy_ObjIsLatch(Ivy_Regular(p1))) );
pGhost = Ivy_ManGhost(p);
pGhost->Type = Type;
pGhost->Init = Init;
pGhost->pFanin0 = p0;
pGhost->pFanin1 = p1;
assert( Type == IVY_PI || Ivy_ObjFanin0(pGhost) != Ivy_ObjFanin1(pGhost) );
if ( p1 && Ivy_ObjFaninId0(pGhost) > Ivy_ObjFaninId1(pGhost) )
pTemp = pGhost->pFanin0, pGhost->pFanin0 = pGhost->pFanin1, pGhost->pFanin1 = pTemp;
return pGhost;
......@@ -384,6 +393,7 @@ extern Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches );
extern void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone );
extern Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p );
extern Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p );
extern int Ivy_ManIsAcyclic( Ivy_Man_t * p );
/*=== ivyDsd.c ==========================================================*/
extern int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree );
extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree );
......@@ -400,11 +410,14 @@ extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, V
extern Ivy_Obj_t * Ivy_ObjReadOneFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj );
/*=== ivyIsop.c ==========================================================*/
extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover );
extern void Ivy_TruthManStop();
/*=== ivyMan.c ==========================================================*/
extern Ivy_Man_t * Ivy_ManStart();
extern void Ivy_ManStop( Ivy_Man_t * p );
extern int Ivy_ManCleanup( Ivy_Man_t * p );
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p );
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel );
extern void Ivy_ManPrintStats( Ivy_Man_t * p );
extern void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits );
/*=== ivyMem.c ==========================================================*/
......@@ -425,8 +438,8 @@ extern void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew );
extern void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop );
extern void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop );
extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop );
extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode );
extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel );
extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel );
/*=== ivyOper.c =========================================================*/
extern Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type );
extern Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
......@@ -442,6 +455,8 @@ extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel, int fVerbo
extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
extern int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
extern int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose );
/*=== ivySeq.c =========================================================*/
extern int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose );
/*=== ivyTable.c ========================================================*/
extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj );
......@@ -456,6 +471,7 @@ extern unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_In
extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p );
extern int Ivy_ManLevels( Ivy_Man_t * p );
extern void Ivy_ManResetLevels( Ivy_Man_t * p );
extern int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew );
extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj );
......
......@@ -107,8 +107,8 @@ int Ivy_ManCheck( Ivy_Man_t * p )
printf( "Ivy_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id );
return 0;
}
// if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) )
// printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) );
if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) )
printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) );
pObj2 = Ivy_TableLookup( p, pObj );
if ( pObj2 != pObj )
printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id );
......@@ -124,6 +124,8 @@ int Ivy_ManCheck( Ivy_Man_t * p )
printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
return 0;
}
if ( !Ivy_ManIsAcyclic(p) )
return 0;
return 1;
}
......
......@@ -24,6 +24,8 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Ivy_NodeCutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -580,6 +582,88 @@ static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew )
/**Function*************************************************************
Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Ivy_NodeCutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 )
{
int i;
if ( pCut->nSize < pCut->nSizeMax )
return 1;
for ( i = 0; i < pCut->nSize; i++ )
if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Derives new cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Ivy_NodeCutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
{
unsigned uHash = 0;
int i, k;
assert( pCut->nSize > 0 );
assert( IdNew0 < IdNew1 );
for ( i = k = 0; i < pCut->nSize; i++ )
{
if ( pCut->pArray[i] == IdOld )
continue;
if ( IdNew0 <= pCut->pArray[i] )
{
if ( IdNew0 < pCut->pArray[i] )
{
pCutNew->pArray[ k++ ] = IdNew0;
uHash |= Ivy_NodeCutHashValue( IdNew0 );
}
IdNew0 = 0x7FFFFFFF;
}
if ( IdNew1 <= pCut->pArray[i] )
{
if ( IdNew1 < pCut->pArray[i] )
{
pCutNew->pArray[ k++ ] = IdNew1;
uHash |= Ivy_NodeCutHashValue( IdNew1 );
}
IdNew1 = 0x7FFFFFFF;
}
pCutNew->pArray[ k++ ] = pCut->pArray[i];
uHash |= Ivy_NodeCutHashValue( pCut->pArray[i] );
}
if ( IdNew0 < 0x7FFFFFFF )
{
pCutNew->pArray[ k++ ] = IdNew0;
uHash |= Ivy_NodeCutHashValue( IdNew0 );
}
if ( IdNew1 < 0x7FFFFFFF )
{
pCutNew->pArray[ k++ ] = IdNew1;
uHash |= Ivy_NodeCutHashValue( IdNew1 );
}
pCutNew->nSize = k;
pCutNew->uHash = uHash;
assert( pCutNew->nSize <= pCut->nSizeMax );
// for ( i = 1; i < pCutNew->nSize; i++ )
// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
return 1;
}
/**Function*************************************************************
Synopsis [Check if the cut exists.]
Description [Returns 1 if the cut exists.]
......@@ -789,7 +873,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
Ivy_Man_t * pMan = p;
Ivy_Obj_t * pLeaf;
int i, k;
int i, k, iLeaf0, iLeaf1;
assert( nLeaves <= IVY_CUT_INPUT );
......@@ -818,6 +902,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
pLeaf = Ivy_ManObj( p, pCut->pArray[k] );
if ( Ivy_ObjIsCi(pLeaf) )
continue;
/*
*pCutNew = *pCut;
Ivy_NodeCutShrink( pCutNew, pLeaf->Id );
if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) )
......@@ -825,6 +910,12 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) )
continue;
Ivy_NodeCutHash( pCutNew );
*/
iLeaf0 = Ivy_ObjFaninId0(pLeaf);
iLeaf1 = Ivy_ObjFaninId1(pLeaf);
if ( !Ivy_NodeCutPrescreen( pCut, iLeaf0, iLeaf1 ) )
continue;
Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 );
Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew );
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
break;
......
......@@ -250,6 +250,105 @@ Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p )
return vLevelsR;
}
/**Function*************************************************************
Synopsis [Recursively detects combinational loops.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_ManIsAcyclic_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode )
{
if ( Ivy_ObjIsCi(pNode) || Ivy_ObjIsConst1(pNode) )
return 1;
assert( Ivy_ObjIsNode( pNode ) );
// make sure the node is not visited
assert( !Ivy_ObjIsTravIdPrevious(p, pNode) );
// check if the node is part of the combinational loop
if ( Ivy_ObjIsTravIdCurrent(p, pNode) )
{
fprintf( stdout, "Manager contains combinational loop!\n" );
fprintf( stdout, "Node \"%d\" is encountered twice on the following path:\n", Ivy_ObjId(pNode) );
fprintf( stdout, " %d", Ivy_ObjId(pNode) );
return 0;
}
// mark this node as a node on the current path
Ivy_ObjSetTravIdCurrent( p, pNode );
// check if the fanin is visited
if ( !Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin0(pNode)) )
{
// traverse the fanin's cone searching for the loop
if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pNode)) )
{
// return as soon as the loop is detected
fprintf( stdout, " <-- %d", Ivy_ObjId(Ivy_ObjFanin0(pNode)) );
return 0;
}
}
// check if the fanin is visited
if ( !Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin1(pNode)) )
{
// traverse the fanin's cone searching for the loop
if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin1(pNode)) )
{
// return as soon as the loop is detected
fprintf( stdout, " <-- %d", Ivy_ObjId(Ivy_ObjFanin1(pNode)) );
return 0;
}
}
// mark this node as a visited node
Ivy_ObjSetTravIdPrevious( p, pNode );
return 1;
}
/**Function*************************************************************
Synopsis [Detects combinational loops.]
Description [This procedure is based on the idea suggested by Donald Chai.
As we traverse the network and visit the nodes, we need to distinquish
three types of nodes: (1) those that are visited for the first time,
(2) those that have been visited in this traversal but are currently not
on the traversal path, (3) those that have been visited and are currently
on the travesal path. When the node of type (3) is encountered, it means
that there is a combinational loop. To mark the three types of nodes,
two new values of the traversal IDs are used.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_ManIsAcyclic( Ivy_Man_t * p )
{
Ivy_Obj_t * pNode;
int fAcyclic, i;
// set the traversal ID for this DFS ordering
Ivy_ManIncrementTravId( p );
Ivy_ManIncrementTravId( p );
// pNode->TravId == pNet->nTravIds means "pNode is on the path"
// pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
// pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
// traverse the network to detect cycles
fAcyclic = 1;
Ivy_ManForEachCo( p, pNode, i )
{
if ( Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin0(pNode)) )
continue;
// traverse the output logic cone
if ( fAcyclic = Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pNode)) )
continue;
// stop as soon as the first loop is detected
fprintf( stdout, " (cone of CO \"%d\")\n", Ivy_ObjFaninId0(pNode) );
break;
}
return fAcyclic;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -153,6 +153,7 @@ void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout )
assert( *ppSpot == pFanout );
*ppSpot = NULL;
}
// printf( " %d", Ivy_ObjFanoutNum(p, pObj) );
}
/**Function*************************************************************
......
......@@ -109,9 +109,10 @@ int Ivy_ManCleanup( Ivy_Man_t * p )
Ivy_Obj_t * pNode;
int i, nNodesOld;
nNodesOld = Ivy_ManNodeNum(p);
Ivy_ManForEachNode( p, pNode, i )
if ( Ivy_ObjRefs(pNode) == 0 )
Ivy_ObjDelete_rec( p, pNode, 1 );
Ivy_ManForEachObj( p, pNode, i )
if ( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
if ( Ivy_ObjRefs(pNode) == 0 )
Ivy_ObjDelete_rec( p, pNode, 1 );
return nNodesOld - Ivy_ManNodeNum(p);
}
......@@ -126,7 +127,7 @@ int Ivy_ManCleanup( Ivy_Man_t * p )
SeeAlso []
***********************************************************************/
int Ivy_ManPropagateBuffers( Ivy_Man_t * p )
int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel )
{
Ivy_Obj_t * pNode;
int nSteps;
......@@ -135,7 +136,7 @@ int Ivy_ManPropagateBuffers( Ivy_Man_t * p )
pNode = Vec_PtrEntryLast(p->vBufs);
while ( Ivy_ObjIsBuf(pNode) )
pNode = Ivy_ObjReadFirstFanout( p, pNode );
Ivy_NodeFixBufferFanins( p, pNode );
Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel );
}
// printf( "Number of steps = %d\n", nSteps );
return nSteps;
......@@ -200,6 +201,9 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
pObj = Ivy_ManPo( p, Ivy_ManPoNum(p) - nLatches + i );
pLatch = Ivy_Latch( p, Ivy_ObjChild0(pObj), Init );
Ivy_ObjDisconnect( p, pObj );
// recycle the old PO object
Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
Ivy_ManRecycleMemory( p, pObj );
// convert the corresponding PI to a buffer and connect it to the latch
pObj = Ivy_ManPi( p, Ivy_ManPiNum(p) - nLatches + i );
pObj->Type = IVY_BUF;
......@@ -215,8 +219,21 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
p->nObjs[IVY_PO] -= nLatches;
p->nObjs[IVY_BUF] += nLatches;
p->nDeleted -= 2 * nLatches;
// remove dangling nodes
Ivy_ManCleanup(p);
/*
// check for dangling nodes
Ivy_ManForEachObj( p, pObj, i )
if ( !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsConst1(pObj) )
{
assert( Ivy_ObjRefs(pObj) > 0 );
assert( Ivy_ObjRefs(pObj) == Ivy_ObjFanoutNum(p, pObj) );
}
*/
// perform hashing by propagating the buffers
Ivy_ManPropagateBuffers( p );
Ivy_ManPropagateBuffers( p, 0 );
// fix the levels
Ivy_ManResetLevels( p );
// check the resulting network
if ( !Ivy_ManCheck(p) )
printf( "Ivy_ManMakeSeq(): The check has failed.\n" );
......
......@@ -300,7 +300,7 @@ void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
SeeAlso []
***********************************************************************/
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop )
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel )
{
int nRefsOld;
// the object to be replaced cannot be complemented
......@@ -315,26 +315,32 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) );
assert( !Ivy_IsComplement(pObjNew) );
// if the new node's arrival time is different, recursively update arrival time of the fanouts
if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
if ( fUpdateLevel )
{
assert( Ivy_ObjIsNode(pObjOld) );
pObjOld->Level = pObjNew->Level;
Ivy_ObjUpdateLevel_rec( p, pObjOld );
}
// if the new node's required time has changed, recursively update required time of the fanins
if ( p->vRequired )
{
int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
// if the new node's arrival time is different, recursively update arrival time of the fanouts
if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
{
assert( Ivy_ObjIsNode(pObjOld) );
pObjOld->Level = pObjNew->Level;
Ivy_ObjUpdateLevel_rec( p, pObjOld );
}
// if the new node's required time has changed, recursively update required time of the fanins
if ( p->vRequired )
{
Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
{
Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
}
}
}
// delete the old object
if ( fDeleteOld )
Ivy_ObjDelete_rec( p, pObjOld, fFreeTop );
// make sure object is pointing to itself
assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) );
assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) );
// transfer the old object
assert( Ivy_ObjRefs(pObjNew) == 0 );
nRefsOld = pObjOld->nRefs;
......@@ -370,7 +376,7 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
SeeAlso []
***********************************************************************/
void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode )
void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel )
{
Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult;
if ( Ivy_ObjIsPo(pNode) )
......@@ -394,7 +400,7 @@ void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode )
else
assert( 0 );
// perform the replacement
Ivy_ObjReplace( p, pNode, pResult, 1, 0 );
Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel );
}
////////////////////////////////////////////////////////////////////////
......
......@@ -80,7 +80,7 @@ int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
// the case of constant 0 cone
if ( RetValue == -1 )
{
Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0 );
Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0, 1 );
continue;
}
assert( Vec_PtrSize(vLeaves) > 2 );
......@@ -94,7 +94,7 @@ int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 )
Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++;
else
Ivy_ObjReplace( pObj, pResult, 1, 0 ), CountUsed++;
Ivy_ObjReplace( pObj, pResult, 1, 0, 1 ), CountUsed++;
}
printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo );
Vec_PtrFree( vFront );
......
......@@ -27,9 +27,8 @@
////////////////////////////////////////////////////////////////////////
static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums );
static int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj );
static int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost );
static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut,
static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot,
Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth );
static int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
......@@ -74,7 +73,7 @@ int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fV
Ivy_ManForEachNode( p, pNode, i )
{
// fix the fanin buffer problem
Ivy_NodeFixBufferFanins( p, pNode );
Ivy_NodeFixBufferFanins( p, pNode, 1 );
if ( Ivy_ObjIsBuf(pNode) )
continue;
// stop if all nodes have been tried once
......@@ -120,8 +119,8 @@ Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
// fix the levels
if ( fUpdateLevel )
Vec_IntFree( p->vRequired ), p->vRequired = NULL;
// else
// Ivy_ManResetLevels( p );
else
Ivy_ManResetLevels( p );
// check
if ( i = Ivy_ManCleanup(p) )
printf( "Cleanup after rewriting removed %d dangling nodes.\n", i );
......@@ -182,7 +181,11 @@ clk = clock();
if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, pCut->pArray[i]) ) )
break;
if ( i != pCut->nSize )
{
p->nCutsBad++;
continue;
}
p->nCutsGood++;
// get the fanin permutation
clk2 = clock();
uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize ); // truth table
......@@ -211,7 +214,7 @@ clk2 = clock();
Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
// label MFFC with current ID
Ivy_ManIncrementTravId( pMan );
nNodesSaved = Ivy_NodeMffcLabel( pMan, pNode );
nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode );
// unmark the fanin boundary
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
......@@ -219,7 +222,7 @@ p->timeMffc += clock() - clk2;
// evaluate the cut
clk2 = clock();
pGraph = Rwt_CutEvaluate( pMan, p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
pGraph = Rwt_CutEvaluate( pMan, p, pNode, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
p->timeEval += clock() - clk2;
// check if the cut is better than the current best one
......@@ -289,75 +292,6 @@ p->timeRes += clock() - clk;
return GainBest;
}
/**Function*************************************************************
Synopsis [References/references the node and returns MFFC size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_NodeRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel )
{
Ivy_Obj_t * pNode0, * pNode1;
int Counter;
// label visited nodes
if ( fLabel )
Ivy_ObjSetTravIdCurrent( p, pNode );
// skip the CI
if ( Ivy_ObjIsCi(pNode) )
return 0;
assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) );
// process the internal node
pNode0 = Ivy_ObjFanin0(pNode);
pNode1 = Ivy_ObjFanin1(pNode);
Counter = Ivy_ObjIsNode(pNode);
if ( fReference )
{
if ( pNode0->nRefs++ == 0 )
Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel );
if ( pNode1 && pNode1->nRefs++ == 0 )
Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel );
}
else
{
assert( pNode0->nRefs > 0 );
assert( pNode1 == NULL || pNode1->nRefs > 0 );
if ( --pNode0->nRefs == 0 )
Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel );
if ( pNode1 && --pNode1->nRefs == 0 )
Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Computes the size of MFFC and labels nodes with the current TravId.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode )
{
int nConeSize1, nConeSize2;
assert( !Ivy_IsComplement( pNode ) );
assert( Ivy_ObjIsNode( pNode ) );
nConeSize1 = Ivy_NodeRefDeref( p, pNode, 0, 1 ); // dereference
nConeSize2 = Ivy_NodeRefDeref( p, pNode, 1, 0 ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return nConeSize1;
}
/**Function*************************************************************
Synopsis [Computes the truth table.]
......@@ -418,7 +352,7 @@ unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums )
SeeAlso []
***********************************************************************/
Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
{
Vec_Ptr_t * vSubgraphs;
Dec_Graph_t * pGraphBest, * pGraphCur;
......@@ -596,12 +530,12 @@ void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGr
printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) );
printf( " " );
*/
Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0 );
Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 1 );
// compare the gains
nNodesNew = Ivy_ManNodeNum(p);
assert( nGain <= nNodesOld - nNodesNew );
// propagate the buffer
Ivy_ManPropagateBuffers( p );
Ivy_ManPropagateBuffers( p, 1 );
}
/**Function*************************************************************
......@@ -649,7 +583,7 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG
printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) );
printf( " " );
*/
Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0 );
Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0, 1 );
//printf( "Replace = %d. ", Ivy_ManNodeNum(p) );
// delete remaining dangling nodes
......
......@@ -74,8 +74,8 @@ Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj )
return NULL;
assert( Ivy_ObjIsLatch(pObj) || Ivy_ObjFaninId0(pObj) > 0 );
assert( Ivy_ObjFaninId1(pObj) == 0 || Ivy_ObjFaninId0(pObj) < Ivy_ObjFaninId1(pObj) );
// if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (!Ivy_ObjIsLatch(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) )
// return NULL;
if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (Ivy_ObjChild1(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) )
return NULL;
for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
{
pEntry = Ivy_ManObj( p, p->pTable[i] );
......
......@@ -265,7 +265,7 @@ int Ivy_ManLevels( Ivy_Man_t * p )
***********************************************************************/
int Ivy_ManResetLevels_rec( Ivy_Obj_t * pObj )
{
if ( pObj->Level || Ivy_ObjIsCi(pObj) )
if ( pObj->Level || Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) )
return pObj->Level;
if ( Ivy_ObjIsBuf(pObj) )
return pObj->Level = Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
......@@ -292,12 +292,81 @@ void Ivy_ManResetLevels( Ivy_Man_t * p )
int i;
Ivy_ManForEachObj( p, pObj, i )
pObj->Level = 0;
Ivy_ManForEachPo( p, pObj, i )
Ivy_ManForEachCo( p, pObj, i )
Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
}
/**Function*************************************************************
Synopsis [References/references the node and returns MFFC size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_ObjRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel )
{
Ivy_Obj_t * pNode0, * pNode1;
int Counter;
// label visited nodes
if ( fLabel )
Ivy_ObjSetTravIdCurrent( p, pNode );
// skip the CI
if ( Ivy_ObjIsPi(pNode) )
return 0;
assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) || Ivy_ObjIsLatch(pNode) );
// process the internal node
pNode0 = Ivy_ObjFanin0(pNode);
pNode1 = Ivy_ObjFanin1(pNode);
Counter = Ivy_ObjIsNode(pNode);
if ( fReference )
{
if ( pNode0->nRefs++ == 0 )
Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel );
if ( pNode1 && pNode1->nRefs++ == 0 )
Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel );
}
else
{
assert( pNode0->nRefs > 0 );
assert( pNode1 == NULL || pNode1->nRefs > 0 );
if ( --pNode0->nRefs == 0 )
Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel );
if ( pNode1 && --pNode1->nRefs == 0 )
Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Labels MFFC with the current label.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode )
{
int nConeSize1, nConeSize2;
assert( !Ivy_IsComplement( pNode ) );
assert( Ivy_ObjIsNode( pNode ) );
nConeSize1 = Ivy_ObjRefDeref( p, pNode, 0, 1 ); // dereference
nConeSize2 = Ivy_ObjRefDeref( p, pNode, 1, 0 ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return nConeSize1;
}
/**Function*************************************************************
Synopsis [Recursively updates fanout levels.]
Description []
......
......@@ -5,6 +5,7 @@ SRC += src/temp/ivy/ivyBalance.c \
src/temp/ivy/ivyDfs.c \
src/temp/ivy/ivyDsd.c \
src/temp/ivy/ivyFanout.c \
src/temp/ivy/ivyIsop.c \
src/temp/ivy/ivyMan.c \
src/temp/ivy/ivyMem.c \
src/temp/ivy/ivyMulti.c \
......
......@@ -302,7 +302,7 @@ Mem_Flex_t * Mem_FlexStart()
p->pCurrent = NULL;
p->pEnd = NULL;
p->nChunkSize = (1 << 12);
p->nChunkSize = (1 << 14);
p->nChunksAlloc = 64;
p->nChunks = 0;
p->pChunks = ALLOC( char *, p->nChunksAlloc );
......@@ -390,6 +390,34 @@ char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes )
Synopsis []
Description [Relocates all the memory except the first chunk.]
SideEffects []
SeeAlso []
***********************************************************************/
void Mem_FlexRestart( Mem_Flex_t * p )
{
int i;
if ( p->nChunks == 0 )
return;
// deallocate all chunks except the first one
for ( i = 1; i < p->nChunks; i++ )
free( p->pChunks[i] );
p->nChunks = 1;
p->nMemoryAlloc = p->nChunkSize;
// transform these entries into a linked list
p->pCurrent = p->pChunks[0];
p->pEnd = p->pCurrent + p->nChunkSize;
p->nEntriesUsed = 0;
p->nMemoryUsed = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
......@@ -399,7 +427,7 @@ char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes )
***********************************************************************/
int Mem_FlexReadMemUsage( Mem_Flex_t * p )
{
return p->nMemoryAlloc;
return p->nMemoryUsed;
}
......
......@@ -49,6 +49,7 @@ extern int Mem_FixedReadMemUsage( Mem_Fixed_t * p );
extern Mem_Flex_t * Mem_FlexStart();
extern void Mem_FlexStop( Mem_Flex_t * p, int fVerbose );
extern char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes );
extern void Mem_FlexRestart( Mem_Flex_t * p );
extern int Mem_FlexReadMemUsage( Mem_Flex_t * p );
// hierarchical memory manager
extern Mem_Step_t * Mem_StepStart( int nSteps );
......
SRC += src/temp/player/playerToAbc.c \
src/temp/player/playerFast.c \
src/temp/player/playerCore.c \
src/temp/player/playerMan.c \
src/temp/player/playerUtil.c
......@@ -86,9 +86,13 @@ static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) {
////////////////////////////////////////////////////////////////////////
/*=== playerToAbc.c ==============================================================*/
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nFaninMax, int fVerbose );
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose );
/*=== playerCore.c =============================================================*/
extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
/*=== playerFast.c =============================================================*/
extern void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit );
extern void Pla_ManFastLutMapStop( Ivy_Man_t * pAig );
extern void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves );
/*=== playerMan.c ==============================================================*/
extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax );
extern void Pla_ManFree( Pla_Man_t * p );
......
......@@ -45,7 +45,7 @@ static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
SeeAlso []
***********************************************************************/
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose )
{
int fUseRewriting = 1;
Ivy_Man_t * pMan, * pManExt;
......
......@@ -70,7 +70,9 @@ struct Rwt_Man_t_
int nClasses; // the number of NN classes
// the result of resynthesis
int fCompl; // indicates if the output of FF should be complemented
void * pCut; // the decomposition tree (temporary)
void * pGraph; // the decomposition tree (temporary)
char * pPerm; // permutation used for the best cut
Vec_Ptr_t * vFanins; // the fanins array (temporary)
Vec_Ptr_t * vFaninsCur; // the fanins array (temporary)
Vec_Int_t * vLevNums; // the array of levels (temporary)
......
......@@ -200,7 +200,7 @@ void Rwt_ManPrintStats( Rwt_Man_t * p )
PRT( "Update ", p->timeUpdate );
PRT( "TOTAL ", p->timeTotal );
/*
printf( "The scores are:\n" );
for ( i = 0; i < 222; i++ )
if ( p->nScores[i] > 0 )
......@@ -210,7 +210,7 @@ void Rwt_ManPrintStats( Rwt_Man_t * p )
Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) );
}
printf( "\n" );
*/
}
/**Function*************************************************************
......
SRC += src/temp/xyz/xyzBuild.c \
src/temp/xyz/xyzCore.c \
src/temp/xyz/xyzMan.c \
src/temp/xyz/xyzMinEsop.c \
src/temp/xyz/xyzMinMan.c \
src/temp/xyz/xyzMinSop.c \
src/temp/xyz/xyzMinUtil.c \
src/temp/xyz/xyzTest.c
/**CFile****************************************************************
FileName [xyz.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: xyz.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __XYZ_H__
#define __XYZ_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "abc.h"
#include "xyzInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Xyz_Man_t_ Xyz_Man_t;
typedef struct Xyz_Obj_t_ Xyz_Obj_t;
// storage for node information
struct Xyz_Obj_t_
{
Min_Cube_t * pCover[3]; // pos/neg/esop
Vec_Int_t * vSupp; // computed support (all nodes except CIs)
};
// storage for additional information
struct Xyz_Man_t_
{
// general characteristics
int nFaninMax; // the number of vars
int nCubesMax; // the limit on the number of cubes in the intermediate covers
int nWords; // the number of words
Vec_Int_t * vFanCounts; // fanout counts
Vec_Ptr_t * vObjStrs; // object structures
void * pMemory; // memory for the internal data strctures
Min_Man_t * pManMin; // the cub manager
int fUseEsop; // enables ESOPs
int fUseSop; // enables SOPs
// arrays to map local variables
Vec_Int_t * vComTo0; // mapping of common variables into first fanin
Vec_Int_t * vComTo1; // mapping of common variables into second fanin
Vec_Int_t * vPairs0; // the first var in each pair of common vars
Vec_Int_t * vPairs1; // the second var in each pair of common vars
Vec_Int_t * vTriv0; // trival support of the first node
Vec_Int_t * vTriv1; // trival support of the second node
// statistics
int nSupps; // supports created
int nSuppsMax; // the maximum number of supports
int nBoundary; // the boundary size
int nNodes; // the number of nodes processed
};
static inline Xyz_Obj_t * Abc_ObjGetStr( Abc_Obj_t * pObj ) { return Vec_PtrEntry(((Xyz_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); }
static inline void Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec ) { Abc_ObjGetStr(pObj)->vSupp = vVec; }
static inline Vec_Int_t * Abc_ObjGetSupp( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->vSupp; }
static inline void Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; }
static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->pCover[2]; }
static inline void Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; }
static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol ) { return Abc_ObjGetStr(pObj)->pCover[Pol]; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/*=== xyzBuild.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk );
/*=== xyzCore.c ===========================================================*/
extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
/*=== xyzMan.c ============================================================*/
extern Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax );
extern void Xyz_ManFree( Xyz_Man_t * p );
extern void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj );
/*=== xyzTest.c ===========================================================*/
extern Abc_Ntk_t * Abc_NtkXyzTestSop( Abc_Ntk_t * pNtk );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [xyzMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [Decomposition manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: xyzMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "xyz.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax )
{
Xyz_Man_t * pMan;
Xyz_Obj_t * pMem;
Abc_Obj_t * pObj;
int i;
assert( pNtk->pManCut == NULL );
// start the manager
pMan = ALLOC( Xyz_Man_t, 1 );
memset( pMan, 0, sizeof(Xyz_Man_t) );
pMan->nFaninMax = nFaninMax;
pMan->nCubesMax = 2 * pMan->nFaninMax;
pMan->nWords = Abc_BitWordNum( nFaninMax * 2 );
// get the cubes
pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax );
pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax );
pMan->vPairs0 = Vec_IntAlloc( nFaninMax );
pMan->vPairs1 = Vec_IntAlloc( nFaninMax );
pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
// allocate memory for object structures
pMan->pMemory = pMem = ALLOC( Xyz_Obj_t, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) );
memset( pMem, 0, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) );
// allocate storage for the pointers to the memory
pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) );
Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL );
Abc_NtkForEachObj( pNtk, pObj, i )
Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i );
// create the cube manager
pMan->pManMin = Min_ManAlloc( nFaninMax );
return pMan;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Xyz_ManFree( Xyz_Man_t * p )
{
Vec_Int_t * vSupp;
int i;
for ( i = 0; i < p->vObjStrs->nSize; i++ )
{
vSupp = ((Xyz_Obj_t *)p->vObjStrs->pArray[i])->vSupp;
if ( vSupp ) Vec_IntFree( vSupp );
}
Min_ManFree( p->pManMin );
Vec_PtrFree( p->vObjStrs );
Vec_IntFree( p->vFanCounts );
Vec_IntFree( p->vTriv0 );
Vec_IntFree( p->vTriv1 );
Vec_IntFree( p->vComTo0 );
Vec_IntFree( p->vComTo1 );
Vec_IntFree( p->vPairs0 );
Vec_IntFree( p->vPairs1 );
free( p->pMemory );
free( p );
}
/**Function*************************************************************
Synopsis [Drop the covers at the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj )
{
int nFanouts;
assert( p->vFanCounts );
nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id );
assert( nFanouts > 0 );
if ( --nFanouts == 0 )
{
Vec_IntFree( Abc_ObjGetSupp(pObj) );
Abc_ObjSetSupp( pObj, NULL );
Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) );
Abc_ObjSetCover2( pObj, NULL );
p->nSupps--;
}
Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [xyzMinEsop.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [ESOP manipulation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: xyzMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "xyzInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Min_EsopRewrite( Min_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_EsopMinimize( Min_Man_t * p )
{
int nCubesInit, nCubesOld, nIter;
if ( p->nCubes < 3 )
return;
nIter = 0;
nCubesInit = p->nCubes;
do {
nCubesOld = p->nCubes;
Min_EsopRewrite( p );
nIter++;
}
while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
}
/**Function*************************************************************
Synopsis [Performs one round of rewriting using distance 2 cubes.]
Description [The weakness of this procedure is that it tries each cube
with only one distance-2 cube. If this pair does not lead to improvement
the cube is inserted into the cover anyhow, and we try another pair.
A possible improvement would be to try this cube with all distance-2
cubes, until an improvement is found, or until all such cubes are tried.]
SideEffects []
SeeAlso []
***********************************************************************/
void Min_EsopRewrite( Min_Man_t * p )
{
Min_Cube_t * pCube, ** ppPrev;
Min_Cube_t * pThis, ** ppPrevT;
int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld;
int nPairs = 0;
// insert the bubble before the first cube
p->pBubble->pNext = p->ppStore[0];
p->ppStore[0] = p->pBubble;
p->pBubble->nLits = 0;
// go through the cubes
while ( 1 )
{
// get the index of the bubble
Index = p->pBubble->nLits;
// find the bubble
Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
if ( pCube == p->pBubble )
break;
assert( pCube == p->pBubble );
// remove the bubble, get the next cube after the bubble
*ppPrev = p->pBubble->pNext;
pCube = p->pBubble->pNext;
if ( pCube == NULL )
for ( Index++; Index <= p->nVars; Index++ )
if ( p->ppStore[Index] )
{
ppPrev = &(p->ppStore[Index]);
pCube = p->ppStore[Index];
break;
}
// stop if there is no more cubes
if ( pCube == NULL )
break;
// find the first dist2 cube
Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
if ( pThis == NULL && Index < p->nVars )
Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
if ( pThis == NULL && Index < p->nVars - 1 )
Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT )
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
// continue if there is no dist2 cube
if ( pThis == NULL )
{
// insert the bubble after the cube
p->pBubble->pNext = pCube->pNext;
pCube->pNext = p->pBubble;
p->pBubble->nLits = pCube->nLits;
continue;
}
nPairs++;
// remove the cubes, insert the bubble instead of pCube
*ppPrevT = pThis->pNext;
*ppPrev = p->pBubble;
p->pBubble->pNext = pCube->pNext;
p->pBubble->nLits = pCube->nLits;
p->nCubes -= 2;
// Exorlink-2:
// A{v00} B{v01} + A{v10} B{v11} =
// A{v00+v10} B{v01} + A{v10} B{v01+v11} =
// A{v00} B{v01+v11} + A{v00+v10} B{v11}
// save the dist2 parameters
v00 = Min_CubeGetVar( pCube, Var0 );
v01 = Min_CubeGetVar( pCube, Var1 );
v10 = Min_CubeGetVar( pThis, Var0 );
v11 = Min_CubeGetVar( pThis, Var1 );
//printf( "\n" );
//Min_CubeWrite( stdout, pCube );
//Min_CubeWrite( stdout, pThis );
// derive the first pair of resulting cubes
Min_CubeXorVar( pCube, Var0, v10 );
pCube->nLits -= (v00 != 3);
pCube->nLits += ((v00 ^ v10) != 3);
Min_CubeXorVar( pThis, Var1, v01 );
pThis->nLits -= (v11 != 3);
pThis->nLits += ((v01 ^ v11) != 3);
// add the cubes
nCubesOld = p->nCubes;
Min_EsopAddCube( p, pCube );
Min_EsopAddCube( p, pThis );
// check if the cubes were absorbed
if ( p->nCubes < nCubesOld + 2 )
continue;
// pull out both cubes
assert( pThis == p->ppStore[pThis->nLits] );
p->ppStore[pThis->nLits] = pThis->pNext;
assert( pCube == p->ppStore[pCube->nLits] );
p->ppStore[pCube->nLits] = pCube->pNext;
p->nCubes -= 2;
// derive the second pair of resulting cubes
Min_CubeXorVar( pCube, Var0, v10 );
pCube->nLits -= ((v00 ^ v10) != 3);
pCube->nLits += (v00 != 3);
Min_CubeXorVar( pCube, Var1, v11 );
pCube->nLits -= (v01 != 3);
pCube->nLits += ((v01 ^ v11) != 3);
Min_CubeXorVar( pThis, Var0, v00 );
pThis->nLits -= (v10 != 3);
pThis->nLits += ((v00 ^ v10) != 3);
Min_CubeXorVar( pThis, Var1, v01 );
pThis->nLits -= ((v01 ^ v11) != 3);
pThis->nLits += (v11 != 3);
// add them anyhow
Min_EsopAddCube( p, pCube );
Min_EsopAddCube( p, pThis );
}
// printf( "Pairs = %d ", nPairs );
}
/**Function*************************************************************
Synopsis [Adds the cube to storage.]
Description [Returns 0 if the cube is added or removed. Returns 1
if the cube is glued with some other cube and has to be added again.
Do not forget to clean the storage!]
SideEffects []
SeeAlso []
***********************************************************************/
int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube )
{
Min_Cube_t * pThis, ** ppPrev;
// try to find the identical cube
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
{
if ( Min_CubesAreEqual( pCube, pThis ) )
{
*ppPrev = pThis->pNext;
Min_CubeRecycle( p, pCube );
Min_CubeRecycle( p, pThis );
p->nCubes--;
return 0;
}
}
// find a distance-1 cube if it exists
if ( pCube->nLits < pCube->nVars )
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
{
if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
Min_CubesTransform( pCube, pThis, p->pTemp );
pCube->nLits++;
Min_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
{
if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
Min_CubesTransform( pCube, pThis, p->pTemp );
pCube->nLits--;
Min_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
if ( pCube->nLits > 0 )
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
{
if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
Min_CubesTransform( pCube, pThis, p->pTemp );
Min_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
// add the cube
pCube->pNext = p->ppStore[pCube->nLits];
p->ppStore[pCube->nLits] = pCube;
p->nCubes++;
return 0;
}
/**Function*************************************************************
Synopsis [Adds the cube to storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube )
{
assert( pCube != p->pBubble );
assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
while ( Min_EsopAddCubeInt( p, pCube ) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [xyzMinMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [SOP manipulation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: xyzMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "xyzInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the minimization manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Min_Man_t * Min_ManAlloc( int nVars )
{
Min_Man_t * pMan;
// start the manager
pMan = ALLOC( Min_Man_t, 1 );
memset( pMan, 0, sizeof(Min_Man_t) );
pMan->nVars = nVars;
pMan->nWords = Abc_BitWordNum( nVars * 2 );
pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) );
// allocate storage for the temporary cover
pMan->ppStore = ALLOC( Min_Cube_t *, pMan->nVars + 1 );
// create tautology cubes
Min_ManClean( pMan, nVars );
pMan->pOne0 = Min_CubeAlloc( pMan );
pMan->pOne1 = Min_CubeAlloc( pMan );
pMan->pTemp = Min_CubeAlloc( pMan );
pMan->pBubble = Min_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0;
// create trivial cubes
Min_ManClean( pMan, 1 );
pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 );
pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 );
pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 );
pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 );
Min_ManClean( pMan, nVars );
return pMan;
}
/**Function*************************************************************
Synopsis [Cleans the minimization manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_ManClean( Min_Man_t * p, int nSupp )
{
// set the size of the cube manager
p->nVars = nSupp;
p->nWords = Abc_BitWordNum(2*nSupp);
// clean the storage
memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) );
p->nCubes = 0;
}
/**Function*************************************************************
Synopsis [Stops the minimization manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_ManFree( Min_Man_t * p )
{
Extra_MmFixedStop ( p->pMemMan, 0 );
free( p->ppStore );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [xyzMinUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [Utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: xyzMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "xyzInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube )
{
int i;
assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
for ( i = 0; i < (int)pCube->nVars; i++ )
if ( Min_CubeHasBit(pCube, i*2) )
{
if ( Min_CubeHasBit(pCube, i*2+1) )
fprintf( pFile, "-" );
else
fprintf( pFile, "0" );
}
else
{
if ( Min_CubeHasBit(pCube, i*2+1) )
fprintf( pFile, "1" );
else
fprintf( pFile, "?" );
}
fprintf( pFile, " 1\n" );
// fprintf( pFile, " %d\n", pCube->nLits );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover )
{
Min_Cube_t * pCube;
Min_CoverForEachCube( pCover, pCube )
Min_CubeWrite( pFile, pCube );
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p )
{
Min_Cube_t * pCube;
int i;
for ( i = 0; i <= p->nVars; i++ )
{
Min_CoverForEachCube( p->ppStore[i], pCube )
{
printf( "%2d : ", i );
if ( pCube == p->pBubble )
{
printf( "Bubble\n" );
continue;
}
Min_CubeWrite( pFile, pCube );
}
}
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop )
{
char Buffer[1000];
Min_Cube_t * pCube;
FILE * pFile;
int i;
sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" );
for ( i = strlen(Buffer) - 1; i >= 0; i-- )
if ( Buffer[i] == '<' || Buffer[i] == '>' )
Buffer[i] = '_';
pFile = fopen( Buffer, "w" );
fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() );
fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
fprintf( pFile, ".o %d\n", 1 );
fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) );
if ( fEsop ) fprintf( pFile, ".type esop\n" );
Min_CoverForEachCube( pCover, pCube )
Min_CubeWrite( pFile, pCube );
fprintf( pFile, ".e\n" );
fclose( pFile );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_CoverCheck( Min_Man_t * p )
{
Min_Cube_t * pCube;
int i;
for ( i = 0; i <= p->nVars; i++ )
Min_CoverForEachCube( p->ppStore[i], pCube )
assert( i == (int)pCube->nLits );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Min_CubeCheck( Min_Cube_t * pCube )
{
int i;
for ( i = 0; i < (int)pCube->nVars; i++ )
if ( Min_CubeGetVar( pCube, i ) == 0 )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Converts the cover from the sorted structure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize )
{
Min_Cube_t * pCov = NULL, ** ppTail = &pCov;
Min_Cube_t * pCube, * pCube2;
int i;
for ( i = 0; i <= nSuppSize; i++ )
{
Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
{
assert( i == (int)pCube->nLits );
*ppTail = pCube;
ppTail = &pCube->pNext;
assert( pCube->uData[0] ); // not a bubble
}
}
*ppTail = NULL;
return pCov;
}
/**Function*************************************************************
Synopsis [Sorts the cover in the increasing number of literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover )
{
Min_Cube_t * pCube, * pCube2;
Min_ManClean( p, p->nVars );
Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
{
pCube->pNext = p->ppStore[pCube->nLits];
p->ppStore[pCube->nLits] = pCube;
p->nCubes++;
}
}
/**Function*************************************************************
Synopsis [Sorts the cover in the increasing number of literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover )
{
Min_Cube_t * pCube;
int i, Counter;
if ( pCover == NULL )
return 0;
// clean the cube
for ( i = 0; i < (int)pCover->nWords; i++ )
p->pTemp->uData[i] = ~((unsigned)0);
// add the bit data
Min_CoverForEachCube( pCover, pCube )
for ( i = 0; i < (int)pCover->nWords; i++ )
p->pTemp->uData[i] &= pCube->uData[i];
// count the vars
Counter = 0;
for ( i = 0; i < (int)pCover->nVars; i++ )
Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 );
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -47,3 +47,10 @@ Other great projects:
Other:
- completely silent mode
High-priority changes:
- add a new mode to "fpga" to differentiate latch-to-latch and pad-to-latch paths
- support asynchronous set/reset in retiming and retiming/mapping
- port "mfs" into ABC
- reduce the latch count in the new version of "retime" and "spfga"
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment