Commit 9e4213e2 by Alan Mishchenko

Version abc70817

parent 29c9b0c0
......@@ -2558,6 +2558,10 @@ SOURCE=.\src\aig\fra\fra.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraCec.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraClass.c
# End Source File
# Begin Source File
......@@ -2570,6 +2574,10 @@ SOURCE=.\src\aig\fra\fraCore.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraImp.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraInd.c
# End Source File
# Begin Source File
......@@ -2578,10 +2586,18 @@ SOURCE=.\src\aig\fra\fraMan.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraPart.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraSat.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraSec.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraSim.c
# End Source File
# End Group
......@@ -2770,6 +2786,10 @@ SOURCE=.\src\aig\aig\aigRepr.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigRet.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigSeq.c
# End Source File
# Begin Source File
......
......@@ -126,6 +126,7 @@ struct Aig_Man_t_
void * pData; // the temporary data
int nTravIds; // the current traversal ID
int fCatchExor; // enables EXOR nodes
int fAddStrash; // performs additional strashing
// timing statistics
int time1;
int time2;
......@@ -149,7 +150,16 @@ static inline int Aig_TruthWordNum( int nVars ) { return nVars
static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
static inline unsigned Aig_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); }
static inline unsigned Aig_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); }
static inline int Aig_WordCountOnes( unsigned uWord )
{
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333);
uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F);
uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
return (uWord & 0x0000FFFF) + (uWord>>16);
}
static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) & ~01); }
static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) ^ 01); }
......@@ -328,6 +338,10 @@ static inline int Aig_ObjFanoutNext( Aig_Man_t * p, int iFan ) { assert(iF
// iterator over the latch inputs
#define Aig_ManForEachLiSeq( p, pObj, i ) \
Vec_PtrForEachEntryStart( p->vPos, pObj, i, Aig_ManPoNum(p)-Aig_ManRegNum(p) )
// iterator over the latch input and outputs
#define Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, k ) \
for ( k = 0; (k < Aig_ManRegNum(p)) && (((pObjLi) = Aig_ManLi(p, k)), 1) \
&& (((pObjLo)=Aig_ManLo(p, k)), 1); k++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
......@@ -358,10 +372,14 @@ extern void Aig_ManFanoutStop( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManStart( int nNodesMax );
extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered );
extern Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap );
extern Aig_Man_t * Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 );
extern void Aig_ManStop( Aig_Man_t * p );
extern int Aig_ManCleanup( Aig_Man_t * p );
extern int Aig_ManCountMergeRegs( Aig_Man_t * p );
extern int Aig_ManSeqCleanup( Aig_Man_t * p );
extern void Aig_ManPrintStats( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose );
/*=== aigMem.c ==========================================================*/
extern void Aig_ManStartMemory( Aig_Man_t * p );
extern void Aig_ManStopMemory( Aig_Man_t * p );
......@@ -414,8 +432,11 @@ extern void Aig_ManTransferRepr( Aig_Man_t * pNew, Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManRehash( Aig_Man_t * p );
extern void Aig_ManCreateChoices( Aig_Man_t * p );
/*=== aigRet.c ========================================================*/
extern Aig_Man_t * Rtm_ManRetimeFwd( Aig_Man_t * p, int nStepsMax, int fVerbose );
/*=== aigSeq.c ========================================================*/
extern int Aig_ManSeqStrash( Aig_Man_t * p, int nLatches, int * pInits );
extern Aig_Man_t * Aig_ManConstReduce( Aig_Man_t * p, int fVerbose );
/*=== aigShow.c ========================================================*/
extern void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold );
/*=== aigTable.c ========================================================*/
......
......@@ -148,6 +148,89 @@ Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
return p0 == p->pConst1 ? p1 : Aig_Not(p->pConst1);
if ( Aig_Regular(p1) == p->pConst1 )
return p1 == p->pConst1 ? p0 : Aig_Not(p->pConst1);
// check not so trivial cases
if ( p->fAddStrash && (Aig_ObjIsNode(Aig_Regular(p0)) || Aig_ObjIsNode(Aig_Regular(p1))) )
{ // http://fmv.jku.at/papers/BrummayerBiere-MEMICS06.pdf
Aig_Obj_t * pFanA, * pFanB, * pFanC, * pFanD;
pFanA = Aig_ObjChild0(Aig_Regular(p0));
pFanB = Aig_ObjChild1(Aig_Regular(p0));
pFanC = Aig_ObjChild0(Aig_Regular(p1));
pFanD = Aig_ObjChild1(Aig_Regular(p1));
if ( Aig_IsComplement(p0) )
{
if ( pFanA == Aig_Not(p1) || pFanB == Aig_Not(p1) )
return p1;
if ( pFanB == p1 )
return Aig_And( p, Aig_Not(pFanA), pFanB );
if ( pFanA == p1 )
return Aig_And( p, Aig_Not(pFanB), pFanA );
}
else
{
if ( pFanA == Aig_Not(p1) || pFanB == Aig_Not(p1) )
return Aig_Not(p->pConst1);
if ( pFanA == p1 || pFanB == p1 )
return p0;
}
if ( Aig_IsComplement(p1) )
{
if ( pFanC == Aig_Not(p0) || pFanD == Aig_Not(p0) )
return p0;
if ( pFanD == p0 )
return Aig_And( p, Aig_Not(pFanC), pFanD );
if ( pFanC == p0 )
return Aig_And( p, Aig_Not(pFanD), pFanC );
}
else
{
if ( pFanC == Aig_Not(p0) || pFanD == Aig_Not(p0) )
return Aig_Not(p->pConst1);
if ( pFanC == p0 || pFanD == p0 )
return p1;
}
if ( !Aig_IsComplement(p0) && !Aig_IsComplement(p1) )
{
if ( pFanA == Aig_Not(pFanC) || pFanA == Aig_Not(pFanD) || pFanB == Aig_Not(pFanC) || pFanB == Aig_Not(pFanD) )
return Aig_Not(p->pConst1);
if ( pFanA == pFanC || pFanB == pFanC )
return Aig_And( p, p0, pFanD );
if ( pFanB == pFanC || pFanB == pFanD )
return Aig_And( p, pFanA, p1 );
if ( pFanA == pFanD || pFanB == pFanD )
return Aig_And( p, p0, pFanC );
if ( pFanA == pFanC || pFanA == pFanD )
return Aig_And( p, pFanB, p1 );
}
else if ( Aig_IsComplement(p0) && !Aig_IsComplement(p1) )
{
if ( pFanA == Aig_Not(pFanC) || pFanA == Aig_Not(pFanD) || pFanB == Aig_Not(pFanC) || pFanB == Aig_Not(pFanD) )
return p1;
if ( pFanB == pFanC || pFanB == pFanD )
return Aig_And( p, Aig_Not(pFanA), p1 );
if ( pFanA == pFanC || pFanA == pFanD )
return Aig_And( p, Aig_Not(pFanB), p1 );
}
else if ( !Aig_IsComplement(p0) && Aig_IsComplement(p1) )
{
if ( pFanC == Aig_Not(pFanA) || pFanC == Aig_Not(pFanB) || pFanD == Aig_Not(pFanA) || pFanD == Aig_Not(pFanB) )
return p0;
if ( pFanD == pFanA || pFanD == pFanB )
return Aig_And( p, Aig_Not(pFanC), p0 );
if ( pFanC == pFanA || pFanC == pFanB )
return Aig_And( p, Aig_Not(pFanD), p0 );
}
else // if ( Aig_IsComplement(p0) && Aig_IsComplement(p1) )
{
if ( pFanA == pFanD && pFanB == Aig_Not(pFanC) )
return Aig_Not(pFanA);
if ( pFanB == pFanC && pFanA == Aig_Not(pFanD) )
return Aig_Not(pFanB);
if ( pFanA == pFanC && pFanB == Aig_Not(pFanD) )
return Aig_Not(pFanA);
if ( pFanB == pFanD && pFanA == Aig_Not(pFanC) )
return Aig_Not(pFanB);
}
}
// check if it can be an EXOR gate
// if ( Aig_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
// return Aig_Exor( p, pFan0, pFan1 );
......
......@@ -24,6 +24,70 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define AIG_XVS0 1
#define AIG_XVS1 2
#define AIG_XVSX 3
static inline void Aig_ObjSetXsim( Aig_Obj_t * pObj, int Value ) { pObj->nCuts = Value; }
static inline int Aig_ObjGetXsim( Aig_Obj_t * pObj ) { return pObj->nCuts; }
static inline int Aig_XsimInv( int Value )
{
if ( Value == AIG_XVS0 )
return AIG_XVS1;
if ( Value == AIG_XVS1 )
return AIG_XVS0;
assert( Value == AIG_XVSX );
return AIG_XVSX;
}
static inline int Aig_XsimAnd( int Value0, int Value1 )
{
if ( Value0 == AIG_XVS0 || Value1 == AIG_XVS0 )
return AIG_XVS0;
if ( Value0 == AIG_XVSX || Value1 == AIG_XVSX )
return AIG_XVSX;
assert( Value0 == AIG_XVS1 && Value1 == AIG_XVS1 );
return AIG_XVS1;
}
static inline int Aig_XsimRand2()
{
return (rand() & 1) ? AIG_XVS1 : AIG_XVS0;
}
static inline int Aig_XsimRand3()
{
int RetValue;
do {
RetValue = rand() & 3;
} while ( RetValue == 0 );
return RetValue;
}
static inline int Aig_ObjGetXsimFanin0( Aig_Obj_t * pObj )
{
int RetValue;
RetValue = Aig_ObjGetXsim(Aig_ObjFanin0(pObj));
return Aig_ObjFaninC0(pObj)? Aig_XsimInv(RetValue) : RetValue;
}
static inline int Aig_ObjGetXsimFanin1( Aig_Obj_t * pObj )
{
int RetValue;
RetValue = Aig_ObjGetXsim(Aig_ObjFanin1(pObj));
return Aig_ObjFaninC1(pObj)? Aig_XsimInv(RetValue) : RetValue;
}
static inline void Aig_XsimPrint( FILE * pFile, int Value )
{
if ( Value == AIG_XVS0 )
{
fprintf( pFile, "0" );
return;
}
if ( Value == AIG_XVS1 )
{
fprintf( pFile, "1" );
return;
}
assert( Value == AIG_XVSX );
fprintf( pFile, "x" );
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -493,6 +557,163 @@ int Aig_ManSeqStrash( Aig_Man_t * p, int nLatches, int * pInits )
}
/**Function*************************************************************
Synopsis [Cycles the circuit to create a new initial state.]
Description [Simulates the circuit with random input for the given
number of timeframes to get a better initial state.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Aig_ManTernarySimulate( Aig_Man_t * p, int fVerbose )
{
int nRounds = 1000; // limit on the number of ternary simulation rounds
Vec_Ptr_t * vMap;
Vec_Ptr_t * vStates;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
unsigned * pState, * pPrev;
int i, k, f, fConstants, Value, nWords, nCounter;
// allocate storage for states
nWords = Aig_BitWordNum( 2*Aig_ManRegNum(p) );
vStates = Vec_PtrAllocSimInfo( nRounds, nWords );
// initialize the values
Aig_ObjSetXsim( Aig_ManConst1(p), AIG_XVS1 );
Aig_ManForEachPiSeq( p, pObj, i )
Aig_ObjSetXsim( pObj, AIG_XVSX );
Aig_ManForEachLoSeq( p, pObj, i )
Aig_ObjSetXsim( pObj, AIG_XVS0 );
// simulate for the given number of timeframes
for ( f = 0; f < nRounds; f++ )
{
// collect this state
pState = Vec_PtrEntry( vStates, f );
memset( pState, 0, sizeof(unsigned) * nWords );
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
{
Value = Aig_ObjGetXsim(pObjLo);
if ( Value & 1 )
Aig_InfoSetBit( pState, 2 * i );
if ( Value & 2 )
Aig_InfoSetBit( pState, 2 * i + 1 );
// Aig_XsimPrint( stdout, Value );
}
// printf( "\n" );
// check if this state exists
for ( i = f - 1; i >= 0; i-- )
{
pPrev = Vec_PtrEntry( vStates, i );
if ( !memcmp( pPrev, pState, sizeof(unsigned) * nWords ) )
break;
}
if ( i >= 0 )
break;
// simulate internal nodes
Aig_ManForEachNode( p, pObj, i )
Aig_ObjSetXsim( pObj, Aig_XsimAnd(Aig_ObjGetXsimFanin0(pObj), Aig_ObjGetXsimFanin1(pObj)) );
// transfer the latch values
Aig_ManForEachLiSeq( p, pObj, i )
Aig_ObjSetXsim( pObj, Aig_ObjGetXsimFanin0(pObj) );
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
Aig_ObjSetXsim( pObjLo, Aig_ObjGetXsim(pObjLi) );
}
if ( f == nRounds )
{
printf( "Aig_ManTernarySimulate(): Did not reach a fixed point.\n" );
Vec_PtrFree( vStates );
return NULL;
}
// OR all the states
pState = Vec_PtrEntry( vStates, 0 );
for ( i = 1; i <= f; i++ )
{
pPrev = Vec_PtrEntry( vStates, i );
for ( k = 0; k < nWords; k++ )
pState[k] |= pPrev[k];
}
// check if there are constants
fConstants = 0;
if ( 2*Aig_ManRegNum(p) == 32*nWords )
{
for ( i = 0; i < nWords; i++ )
if ( pState[i] != ~0 )
fConstants = 1;
}
else
{
for ( i = 0; i < nWords - 1; i++ )
if ( pState[i] != ~0 )
fConstants = 1;
if ( pState[i] != Aig_InfoMask( 2*Aig_ManRegNum(p) - 32*(nWords-1) ) )
fConstants = 1;
}
if ( fConstants == 0 )
{
Vec_PtrFree( vStates );
return NULL;
}
// start mapping by adding the true PIs
vMap = Vec_PtrAlloc( Aig_ManPiNum(p) );
Aig_ManForEachPiSeq( p, pObj, i )
Vec_PtrPush( vMap, pObj );
// find constant registers
nCounter = 0;
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
{
Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i );
nCounter += (Value == 1 || Value == 2);
if ( Value == 1 )
Vec_PtrPush( vMap, Aig_ManConst0(p) );
else if ( Value == 2 )
Vec_PtrPush( vMap, Aig_ManConst1(p) );
else if ( Value == 3 )
Vec_PtrPush( vMap, pObjLo );
else
assert( 0 );
// Aig_XsimPrint( stdout, Value );
}
// printf( "\n" );
Vec_PtrFree( vStates );
if ( fVerbose )
printf( "Detected %d constants after %d iterations.\n", nCounter, f );
return vMap;
}
/**Function*************************************************************
Synopsis [Reduces the circuit using ternary simulation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManConstReduce( Aig_Man_t * p, int fVerbose )
{
Aig_Man_t * pTemp;
Vec_Ptr_t * vMap;
while ( vMap = Aig_ManTernarySimulate( p, fVerbose ) )
{
if ( fVerbose )
printf( "RBeg = %5d. NBeg = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
p = Aig_ManRemap( pTemp = p, vMap );
Aig_ManStop( pTemp );
Vec_PtrFree( vMap );
Aig_ManSeqCleanup( p );
if ( fVerbose )
printf( "REnd = %5d. NEnd = %6d. \n", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
}
return p;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -13,5 +13,5 @@ SRC += src/aig/aig/aigCheck.c \
src/aig/aig/aigTable.c \
src/aig/aig/aigTiming.c \
src/aig/aig/aigTruth.c \
src/aig/aig/aigUtil.c \
src/aig/aig/aigWin.c
src/aig/aig/aigUtil.c \
src/aig/aig/aigWin.c
\ No newline at end of file
......@@ -76,7 +76,6 @@ struct Bdc_Isf_t_
unsigned * puOff; // off-set
};
typedef struct Bdc_Man_t_ Bdc_Man_t;
struct Bdc_Man_t_
{
// external parameters
......
......@@ -71,6 +71,7 @@ struct Fra_Par_t_
int nBTLimitMiter; // conflict limit at an output
int nFramesK; // the number of timeframes to unroll
int fRewrite; // use rewriting for constraint reduction
int fLatchCorr; // computes latch correspondence only
};
// FRAIG equivalence classes
......@@ -101,6 +102,7 @@ struct Fra_Man_t_
int nFramesAll; // the number of timeframes used
Aig_Obj_t ** pMemFraig; // memory allocated for points to the fraig nodes
// simulation info
void * pSim; // the simulation manager
unsigned * pSimWords; // memory for simulation information
int nSimWords; // the number of simulation words
// counter example storage
......@@ -187,21 +189,23 @@ extern Fra_Cla_t * Fra_ClassesStart( Aig_Man_t * pAig );
extern void Fra_ClassesStop( Fra_Cla_t * p );
extern void Fra_ClassesCopyReprs( Fra_Cla_t * p, Vec_Ptr_t * vFailed );
extern void Fra_ClassesPrint( Fra_Cla_t * p, int fVeryVerbose );
extern void Fra_ClassesPrepare( Fra_Cla_t * p );
extern void Fra_ClassesPrepare( Fra_Cla_t * p, int fLatchCorr );
extern int Fra_ClassesRefine( Fra_Cla_t * p );
extern int Fra_ClassesRefine1( Fra_Cla_t * p );
extern int Fra_ClassesCountLits( Fra_Cla_t * p );
extern int Fra_ClassesCountPairs( Fra_Cla_t * p );
extern void Fra_ClassesTest( Fra_Cla_t * p, int Id1, int Id2 );
extern void Fra_ClassesLatchCorr( Fra_Man_t * p );
/*=== fraCnf.c ========================================================*/
extern void Fra_NodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
/*=== fraCore.c ========================================================*/
extern Aig_Man_t * Fra_FraigPerform( Aig_Man_t * pManAig, Fra_Par_t * pPars );
extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig );
extern void Fra_FraigSweep( Fra_Man_t * pManAig );
extern int Fra_FraigMiterStatus( Aig_Man_t * p );
/*=== fraDfs.c ========================================================*/
/*=== fraInd.c ========================================================*/
extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesK, int fRewrite, int fVerbose );
extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesK, int fRewrite, int fLatchCorr, int fVerbose, int * pnIter );
/*=== fraMan.c ========================================================*/
extern void Fra_ParamsDefault( Fra_Par_t * pParams );
extern void Fra_ParamsDefaultSeq( Fra_Par_t * pParams );
......@@ -214,6 +218,8 @@ extern void Fra_ManPrint( Fra_Man_t * p );
/*=== fraSat.c ========================================================*/
extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
extern int Fra_NodeIsConst( Fra_Man_t * p, Aig_Obj_t * pNew );
/*=== fraSec.c ========================================================*/
extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fVerbose, int fVeryVerbose );
/*=== fraSim.c ========================================================*/
extern int Fra_NodeHasZeroSim( Aig_Obj_t * pObj );
extern int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
......
/**CFile****************************************************************
FileName [fraCec.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [New FRAIG package.]
Synopsis [CEC engined based on fraiging.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 30, 2007.]
Revision [$Id: fraCec.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fra.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -250,7 +250,7 @@ void Fra_ClassesPrint( Fra_Cla_t * p, int fVeryVerbose )
SeeAlso []
***********************************************************************/
void Fra_ClassesPrepare( Fra_Cla_t * p )
void Fra_ClassesPrepare( Fra_Cla_t * p, int fLatchCorr )
{
Aig_Obj_t ** ppTable, ** ppNexts;
Aig_Obj_t * pObj, * pTemp;
......@@ -266,8 +266,16 @@ void Fra_ClassesPrepare( Fra_Cla_t * p )
Vec_PtrClear( p->vClasses1 );
Aig_ManForEachObj( p->pAig, pObj, i )
{
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
continue;
if ( fLatchCorr )
{
if ( !Aig_ObjIsPi(pObj) )
continue;
}
else
{
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
continue;
}
//printf( "%3d : ", pObj->Id );
//Extra_PrintBinary( stdout, Fra_ObjSim(pObj), 32 );
//printf( "\n" );
......@@ -312,7 +320,7 @@ void Fra_ClassesPrepare( Fra_Cla_t * p )
// allocate room for classes
p->pMemClasses = ALLOC( Aig_Obj_t *, 2*(nEntries + Vec_PtrSize(p->vClasses1)) );
p->pMemClassesFree = p->pMemClasses + 2*nEntries;
// copy the entries into storage in the topological order
Vec_PtrClear( p->vClasses );
nEntries = 0;
......@@ -563,6 +571,32 @@ void Fra_ClassesTest( Fra_Cla_t * p, int Id1, int Id2 )
Vec_PtrPush( p->vClasses, pClass );
}
/**Function*************************************************************
Synopsis [Creates latch correspondence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_ClassesLatchCorr( Fra_Man_t * p )
{
Aig_Obj_t * pObj;
int i, nEntries = 0;
Vec_PtrClear( p->pCla->vClasses1 );
Aig_ManForEachLoSeq( p->pManAig, pObj, i )
{
Vec_PtrPush( p->pCla->vClasses1, pObj );
Fra_ClassObjSetRepr( pObj, Aig_ManConst1(p->pManAig) );
}
// allocate room for classes
p->pCla->pMemClasses = ALLOC( Aig_Obj_t *, 2*(nEntries + Vec_PtrSize(p->pCla->vClasses1)) );
p->pCla->pMemClassesFree = p->pCla->pMemClasses + 2*nEntries;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -30,6 +30,63 @@
/**Function*************************************************************
Synopsis [Reports the status of the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_FraigMiterStatus( Aig_Man_t * p )
{
Aig_Obj_t * pObj, * pObjNew;
int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0;
if ( p->pData )
return 0;
Aig_ManForEachPoSeq( p, pObj, i )
{
pObjNew = Aig_ObjChild0(pObj);
// check if the output is constant 0
if ( pObjNew == Aig_ManConst0(p) )
{
CountConst0++;
continue;
}
// check if the output is constant 1
if ( pObjNew == Aig_ManConst1(p) )
{
CountNonConst0++;
continue;
}
// check if the output can be constant 0
if ( Aig_Regular(pObjNew)->fPhase != (unsigned)Aig_IsComplement(pObjNew) )
{
CountNonConst0++;
continue;
}
CountUndecided++;
}
/*
if ( p->pParams->fVerbose )
{
printf( "Miter has %d outputs. ", Aig_ManPoNum(p->pManAig) );
printf( "Const0 = %d. ", CountConst0 );
printf( "NonConst0 = %d. ", CountNonConst0 );
printf( "Undecided = %d. ", CountUndecided );
printf( "\n" );
}
*/
if ( CountNonConst0 )
return 0;
if ( CountUndecided )
return -1;
return 1;
}
/**Function*************************************************************
Synopsis [Write speculative miter for one node.]
Description []
......@@ -121,9 +178,9 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj )
Vec_PtrPush( p->vTimeouts, pObj );
// simulate the counter-example and return the Fraig node
Fra_Resimulate( p );
assert( Fra_ClassObjRepr(pObj) != pObjRepr );
if ( Fra_ClassObjRepr(pObj) == pObjRepr )
printf( "Fra_FraigNode(): Error in class refinement!\n" );
assert( Fra_ClassObjRepr(pObj) != pObjRepr );
}
/**Function*************************************************************
......@@ -196,7 +253,7 @@ clk = clock();
Aig_ManReprStart( p->pManFraig, Aig_ManObjIdMax(p->pManAig)+1 );
// collect initial states
p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 );
p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
p->nNodesBeg = Aig_ManNodeNum(pManAig);
p->nRegsBeg = Aig_ManRegNum(pManAig);
// perform fraig sweep
......@@ -228,7 +285,7 @@ p->timeTrav += clock() - clk2;
}
p->timeTotal = clock() - clk;
// collect final stats
p->nLitsEnd = Fra_ClassesCountLits( p->pCla );
p->nLitsEnd = Fra_ClassesCountLits( p->pCla );
p->nNodesEnd = Aig_ManNodeNum(pManAigNew);
p->nRegsEnd = Aig_ManRegNum(pManAigNew);
Fra_ManStop( p );
......
......@@ -198,7 +198,7 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p )
SeeAlso []
***********************************************************************/
Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, int fVerbose )
Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, int fLatchCorr, int fVerbose, int * pnIter )
{
Fra_Man_t * p;
Fra_Par_t Pars, * pPars = &Pars;
......@@ -208,7 +208,10 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
int nIter, i, clk = clock(), clk2;
if ( Aig_ManNodeNum(pManAig) == 0 )
{
if ( pnIter ) *pnIter = 0;
return Aig_ManDup(pManAig, 1);
}
assert( Aig_ManLatchNum(pManAig) == 0 );
assert( Aig_ManRegNum(pManAig) > 0 );
assert( nFramesK > 0 );
......@@ -216,14 +219,18 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
// get parameters
Fra_ParamsDefaultSeq( pPars );
pPars->nFramesK = nFramesK;
pPars->fVerbose = fVerbose;
pPars->fRewrite = fRewrite;
pPars->nFramesK = nFramesK;
pPars->fVerbose = fVerbose;
pPars->fRewrite = fRewrite;
pPars->fLatchCorr = fLatchCorr;
// start the fraig manager for this run
p = Fra_ManStart( pManAig, pPars );
// derive and refine e-classes using K initialized frames
Fra_Simulate( p, 1 );
// if ( fLatchCorr )
// Fra_ClassesLatchCorr( p );
// else
Fra_Simulate( p, 1 );
// refine e-classes using sequential simulation?
p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 );
......@@ -239,6 +246,8 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
p->pCla->fRefinement = 0;
// derive non-init K-timeframes while implementing e-classes
p->pManFraig = Fra_FramesWithClasses( p );
//Aig_ManDumpBlif( p->pManFraig, "testaig.blif" );
// perform AIG rewriting
if ( p->pPars->fRewrite )
Fra_FraigInductionRewrite( p );
......@@ -252,8 +261,8 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
}
// convert the manager to SAT solver (the last nLatches outputs are inputs)
pCnf = Cnf_Derive( p->pManFraig, Aig_ManRegNum(p->pManFraig) );
// pCnf = Cnf_DeriveSimple( p->pManFraig, Aig_ManRegNum(p->pManFraig) );
// pCnf = Cnf_Derive( p->pManFraig, Aig_ManRegNum(p->pManFraig) );
pCnf = Cnf_DeriveSimple( p->pManFraig, Aig_ManRegNum(p->pManFraig) );
//Cnf_DataWriteIntoFile( pCnf, "temp.cnf", 1 );
p->pSat = Cnf_DataWriteIntoSolver( pCnf );
......@@ -278,7 +287,7 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
Fra_ObjSetFaninVec( pObj, (void *)1 );
}
Cnf_DataFree( pCnf );
/*
/*
Aig_ManForEachObj( p->pManFraig, pObj, i )
{
Fra_ObjSetSatNum( pObj, pCnf->pVarNums[pObj->Id] );
......@@ -300,6 +309,8 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
clk2 = clock();
Fra_ClassesCopyReprs( p->pCla, p->vTimeouts );
pManAigNew = Aig_ManDupRepr( pManAig );
Aig_ManSeqCleanup( pManAigNew );
// Aig_ManCountMergeRegs( pManAigNew );
p->timeTrav += clock() - clk2;
p->timeTotal = clock() - clk;
// get the final stats
......@@ -309,9 +320,10 @@ p->timeTotal = clock() - clk;
// free the manager
Fra_ManStop( p );
// check the output
if ( Aig_ManPoNum(pManAigNew) - Aig_ManRegNum(pManAigNew) == 1 )
if ( Aig_ObjChild0( Aig_ManPo(pManAigNew,0) ) == Aig_ManConst0(pManAigNew) )
printf( "Proved output constant 0.\n" );
// if ( Aig_ManPoNum(pManAigNew) - Aig_ManRegNum(pManAigNew) == 1 )
// if ( Aig_ObjChild0( Aig_ManPo(pManAigNew,0) ) == Aig_ManConst0(pManAigNew) )
// printf( "Proved output constant 0.\n" );
if ( pnIter ) *pnIter = nIter;
return pManAigNew;
}
......
......@@ -86,6 +86,7 @@ void Fra_ParamsDefaultSeq( Fra_Par_t * pPars )
pPars->nFramesK = 1; // the number of timeframes to unroll
pPars->fConeBias = 0;
pPars->fRewrite = 0;
pPars->fLatchCorr = 0;
}
/**Function*************************************************************
......
/**CFile****************************************************************
FileName [fraPart.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [New FRAIG package.]
Synopsis [Partitioning for induction.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 30, 2007.]
Revision [$Id: fraPart.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fra.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_ManPartitionTest( Aig_Man_t * p, int nComLim )
{
ProgressBar * pProgress;
Vec_Vec_t * vSupps, * vSuppsIn;
Vec_Ptr_t * vSuppsNew;
Vec_Int_t * vSupNew, * vSup, * vSup2, * vTemp;//, * vSupIn;
Vec_Int_t * vOverNew, * vQuantNew;
Aig_Obj_t * pObj;
int i, k, nCommon, CountOver, CountQuant;
int nTotalSupp, nTotalSupp2, Entry, Largest;//, iVar;
double Ratio, R;
int clk;
nTotalSupp = 0;
nTotalSupp2 = 0;
Ratio = 0.0;
// compute supports
clk = clock();
vSupps = Aig_ManSupports( p );
PRT( "Supports", clock() - clk );
// remove last entry
Aig_ManForEachPo( p, pObj, i )
{
vSup = Vec_VecEntry( vSupps, i );
Vec_IntPop( vSup );
// remember support
// pObj->pNext = (Aig_Obj_t *)vSup;
}
// create reverse supports
clk = clock();
vSuppsIn = Vec_VecStart( Aig_ManPiNum(p) );
Aig_ManForEachPo( p, pObj, i )
{
vSup = Vec_VecEntry( vSupps, i );
Vec_IntForEachEntry( vSup, Entry, k )
Vec_VecPush( vSuppsIn, Entry, (void *)i );
}
PRT( "Inverse ", clock() - clk );
clk = clock();
// compute extended supports
Largest = 0;
vSuppsNew = Vec_PtrAlloc( Aig_ManPoNum(p) );
vOverNew = Vec_IntAlloc( Aig_ManPoNum(p) );
vQuantNew = Vec_IntAlloc( Aig_ManPoNum(p) );
pProgress = Extra_ProgressBarStart( stdout, Aig_ManPoNum(p) );
Aig_ManForEachPo( p, pObj, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// get old supports
vSup = Vec_VecEntry( vSupps, i );
if ( Vec_IntSize(vSup) < 2 )
continue;
// compute new supports
CountOver = CountQuant = 0;
vSupNew = Vec_IntDup( vSup );
// go through the nodes where the first var appears
Aig_ManForEachPo( p, pObj, k )
// iVar = Vec_IntEntry( vSup, 0 );
// vSupIn = Vec_VecEntry( vSuppsIn, iVar );
// Vec_IntForEachEntry( vSupIn, Entry, k )
{
// pObj = Aig_ManObj( p, Entry );
// get support of this output
// vSup2 = (Vec_Int_t *)pObj->pNext;
vSup2 = Vec_VecEntry( vSupps, k );
// count the number of common vars
nCommon = Vec_IntTwoCountCommon(vSup, vSup2);
if ( nCommon < 2 )
continue;
if ( nCommon > nComLim )
{
vSupNew = Vec_IntTwoMerge( vTemp = vSupNew, vSup2 );
Vec_IntFree( vTemp );
CountOver++;
}
else
CountQuant++;
}
// save the results
Vec_PtrPush( vSuppsNew, vSupNew );
Vec_IntPush( vOverNew, CountOver );
Vec_IntPush( vQuantNew, CountQuant );
if ( Largest < Vec_IntSize(vSupNew) )
Largest = Vec_IntSize(vSupNew);
nTotalSupp += Vec_IntSize(vSup);
nTotalSupp2 += Vec_IntSize(vSupNew);
if ( Vec_IntSize(vSup) )
R = Vec_IntSize(vSupNew) / Vec_IntSize(vSup);
else
R = 0;
Ratio += R;
if ( R < 5.0 )
continue;
printf( "%6d : ", i );
printf( "S = %5d. ", Vec_IntSize(vSup) );
printf( "SNew = %5d. ", Vec_IntSize(vSupNew) );
printf( "R = %7.2f. ", R );
printf( "Over = %5d. ", CountOver );
printf( "Quant = %5d. ", CountQuant );
printf( "\n" );
/*
Vec_IntForEachEntry( vSupNew, Entry, k )
printf( "%d ", Entry );
printf( "\n" );
*/
}
Extra_ProgressBarStop( pProgress );
PRT( "Scanning", clock() - clk );
// print cumulative statistics
printf( "PIs = %6d. POs = %6d. Lim = %3d. AveS = %3d. SN = %3d. R = %4.2f Max = %5d.\n",
Aig_ManPiNum(p), Aig_ManPoNum(p), nComLim,
nTotalSupp/Aig_ManPoNum(p), nTotalSupp2/Aig_ManPoNum(p),
Ratio/Aig_ManPoNum(p), Largest );
Vec_VecFree( vSupps );
Vec_VecFree( vSuppsIn );
Vec_VecFree( (Vec_Vec_t *)vSuppsNew );
Vec_IntFree( vOverNew );
Vec_IntFree( vQuantNew );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [fraSec.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [New FRAIG package.]
Synopsis [Performs SEC based on seq sweeping.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 30, 2007.]
Revision [$Id: fraSec.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fra.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose )
{
Aig_Man_t * pNew;
int nFrames, RetValue, nIter, clk, clkTotal = clock();
if ( nFramesFix )
{
nFrames = nFramesFix;
// perform seq sweeping for one frame number
pNew = Fra_FraigInduction( p, nFrames, 0, 0, fVeryVerbose, &nIter );
}
else
{
// perform seq sweeping while increasing the number of frames
for ( nFrames = 1; ; nFrames++ )
{
clk = clock();
pNew = Fra_FraigInduction( p, nFrames, 0, 0, fVeryVerbose, &nIter );
RetValue = Fra_FraigMiterStatus( pNew );
if ( fVerbose )
{
printf( "FRAMES %3d : Iters = %3d. ", nFrames, nIter );
if ( RetValue == 1 )
printf( "UNSAT " );
else
printf( "UNDECIDED " );
PRT( "Time", clock() - clk );
}
if ( RetValue != -1 )
break;
Aig_ManStop( pNew );
}
}
// get the miter status
RetValue = Fra_FraigMiterStatus( pNew );
Aig_ManStop( pNew );
// report the miter
if ( RetValue == 1 )
printf( "Networks are equivalent after seq sweeping with K=%d frames (%d iters). ", nFrames, nIter );
else if ( RetValue == 0 )
printf( "Networks are NOT EQUIVALENT. " );
else
printf( "Networks are UNDECIDED after seq sweeping with K=%d frames (%d iters). ", nFrames, nIter );
PRT( "Time", clock() - clkTotal );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -537,7 +537,7 @@ int Fra_SelectBestPat( Fra_Man_t * p )
***********************************************************************/
void Fra_SimulateOne( Fra_Man_t * p )
{
Aig_Obj_t * pObj;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int f, i, clk;
clk = clock();
for ( f = 0; f < p->nFramesAll; f++ )
......@@ -551,9 +551,10 @@ clk = clock();
Aig_ManForEachLiSeq( p->pManAig, pObj, i )
Fra_NodeCopyFanin( p, pObj, f );
// copy simulation info into the inputs
for ( i = 0; i < Aig_ManRegNum(p->pManAig); i++ )
Fra_NodeTransferNext( p, Aig_ManLi(p->pManAig, i), Aig_ManLo(p->pManAig, i), f );
// for ( i = 0; i < Aig_ManRegNum(p->pManAig); i++ )
// Fra_NodeTransferNext( p, Aig_ManLi(p->pManAig, i), Aig_ManLo(p->pManAig, i), f );
Aig_ManForEachLiLoSeq( p->pManAig, pObjLi, pObjLo, i )
Fra_NodeTransferNext( p, pObjLi, pObjLo, f );
}
p->timeSim += clock() - clk;
p->nSimRounds++;
......@@ -627,7 +628,7 @@ void Fra_Simulate( Fra_Man_t * p, int fInit )
// start the classes
Fra_AssignRandom( p, fInit );
Fra_SimulateOne( p );
Fra_ClassesPrepare( p->pCla );
Fra_ClassesPrepare( p->pCla, p->pPars->fLatchCorr );
// Fra_ClassesPrint( p->pCla, 0 );
//printf( "Starting classes = %5d. Pairs = %6d.\n", p->lClasses.nItems, Fra_CountPairsClasses(p) );
......
SRC += src/aig/fra/fraClass.c \
SRC += src/aig/fra/fraCec.c \
src/aig/fra/fraClass.c \
src/aig/fra/fraCnf.c \
src/aig/fra/fraCore.c \
src/aig/fra/fraImp.c \
src/aig/fra/fraInd.c \
src/aig/fra/fraMan.c \
src/aig/fra/fraSat.c \
src/aig/fra/fraSec.c \
src/aig/fra/fraSim.c
......@@ -1086,6 +1086,89 @@ void Abc_NtkMakeComb( Abc_Ntk_t * pNtk )
}
/**Function*************************************************************
Synopsis [Removes POs with suppsize less than 2 and PIs without fanout.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkTrim( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, k, m;
// filter POs
k = m = 0;
Abc_NtkForEachCo( pNtk, pObj, i )
{
if ( Abc_ObjIsPo(pObj) )
{
// remove constant nodes and PI pointers
if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 0 )
{
Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) );
if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 0 && !Abc_ObjIsPi(Abc_ObjFanin0(pObj)) )
Abc_NtkDeleteObj_rec( Abc_ObjFanin0(pObj), 1 );
pNtk->vObjs->pArray[pObj->Id] = NULL;
pObj->Id = (1<<26)-1;
pNtk->nObjCounts[pObj->Type]--;
pNtk->nObjs--;
Abc_ObjRecycle( pObj );
continue;
}
// remove buffers/inverters of PIs
if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 1 )
{
if ( Abc_ObjIsPi(Abc_ObjFanin0(Abc_ObjFanin0(pObj))) )
{
Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) );
if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 0 )
Abc_NtkDeleteObj_rec( Abc_ObjFanin0(pObj), 1 );
pNtk->vObjs->pArray[pObj->Id] = NULL;
pObj->Id = (1<<26)-1;
pNtk->nObjCounts[pObj->Type]--;
pNtk->nObjs--;
Abc_ObjRecycle( pObj );
continue;
}
}
Vec_PtrWriteEntry( pNtk->vPos, m++, pObj );
}
Vec_PtrWriteEntry( pNtk->vCos, k++, pObj );
}
Vec_PtrShrink( pNtk->vPos, m );
Vec_PtrShrink( pNtk->vCos, k );
// filter PIs
k = m = 0;
Abc_NtkForEachCi( pNtk, pObj, i )
{
if ( Abc_ObjIsPi(pObj) )
{
if ( Abc_ObjFanoutNum(pObj) == 0 )
{
pNtk->vObjs->pArray[pObj->Id] = NULL;
pObj->Id = (1<<26)-1;
pNtk->nObjCounts[pObj->Type]--;
pNtk->nObjs--;
Abc_ObjRecycle( pObj );
continue;
}
Vec_PtrWriteEntry( pNtk->vPis, m++, pObj );
}
Vec_PtrWriteEntry( pNtk->vCis, k++, pObj );
}
Vec_PtrShrink( pNtk->vPis, m );
Vec_PtrShrink( pNtk->vCis, k );
return Abc_NtkDup( pNtk );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -98,6 +98,7 @@ Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, in
Abc_NtkMiterAddOne( pNtk1, pNtkMiter );
Abc_NtkMiterAddOne( pNtk2, pNtkMiter );
Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize );
Abc_AigCleanup(pNtkMiter->pManFunc);
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtkMiter ) )
......
......@@ -322,7 +322,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
fprintf( pFile, "Latch = %6d. No = %4d. Zero = %4d. One = %4d. DC = %4d.\n",
Abc_NtkLatchNum(pNtk), InitNums[0], InitNums[1], InitNums[2], InitNums[3] );
fprintf( pFile, "Const fanin = %3d. DC init = %3d. Matching init = %3d. ", Counter0, Counter1, Counter2 );
fprintf( pFile, "Self-feed latches = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
fprintf( pFile, "Self-feed latches = %2d.\n", -1 ); //Abc_NtkCountSelfFeedLatches(pNtk) );
}
/**Function*************************************************************
......
......@@ -27,7 +27,7 @@
////////////////////////////////////////////////////////////////////////
static void Abc_NtkVerifyReportError( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel );
static void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel, int nFrames );
extern void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel, int nFrames );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......
......@@ -139,7 +139,11 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
fprintf( stdout, " : " );
Abc_NtkForEachLatch( pNtk, pObj, i )
{
// if ( Abc_ObjGetXsim(Abc_ObjFanout0(pObj)) != XVSX )
// printf( " %s=", Abc_ObjName(pObj) );
Abc_XsimPrint( stdout, Abc_ObjGetXsim(Abc_ObjFanout0(pObj)) );
}
fprintf( stdout, " : " );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
......
......@@ -121,8 +121,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
Abc_ObjAddFanin( pNode1, pObj );
Vec_PtrPush( vNodes, pNode1 );
// assign names to latch and its input
Abc_ObjAssignName( pObj, Abc_ObjNameDummy("_L", i, nDigits), NULL );
// Abc_ObjAssignName( pObj, Abc_ObjNameDummy("_L", i, nDigits), NULL );
// printf( "Creating latch %s with input %d and output %d.\n", Abc_ObjName(pObj), pNode0->Id, pNode1->Id );
}
......@@ -142,7 +141,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
uLit = ((i + 1 + nInputs + nLatches) << 1);
uLit1 = uLit - Io_ReadAigerDecode( &pCur );
uLit0 = uLit1 - Io_ReadAigerDecode( &pCur );
assert( uLit1 > uLit0 );
// assert( uLit1 > uLit0 );
pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
pNode1 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
assert( Vec_PtrSize(vNodes) == i + 1 + nInputs + nLatches );
......@@ -171,66 +170,84 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
Abc_ObjAddFanin( pObj, pNode0 );
}
// read the names if present
pCur = pSymbols;
while ( pCur < pContents + nFileSize && *pCur != 'c' )
if ( *pCur != 'c' )
{
// get the terminal type
pType = pCur;
if ( *pCur == 'i' )
vTerms = pNtkNew->vPis;
else if ( *pCur == 'l' )
vTerms = pNtkNew->vBoxes;
else if ( *pCur == 'o' )
vTerms = pNtkNew->vPos;
else
int Counter = 0;
while ( pCur < pContents + nFileSize && *pCur != 'c' )
{
// get the terminal type
pType = pCur;
if ( *pCur == 'i' )
vTerms = pNtkNew->vPis;
else if ( *pCur == 'l' )
vTerms = pNtkNew->vBoxes;
else if ( *pCur == 'o' )
vTerms = pNtkNew->vPos;
else
{
fprintf( stdout, "Wrong terminal type.\n" );
return NULL;
}
// get the terminal number
iTerm = atoi( ++pCur ); while ( *pCur++ != ' ' );
// get the node
if ( iTerm >= Vec_PtrSize(vTerms) )
{
fprintf( stdout, "The number of terminal is out of bound.\n" );
return NULL;
}
pObj = Vec_PtrEntry( vTerms, iTerm );
if ( *pType == 'l' )
pObj = Abc_ObjFanout0(pObj);
// assign the name
pName = pCur; while ( *pCur++ != '\n' );
// assign this name
*(pCur-1) = 0;
Abc_ObjAssignName( pObj, pName, NULL );
if ( *pType == 'l' )
{
Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjName(pObj), "L" );
Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "_in" );
}
// mark the node as named
pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
}
// assign the remaining names
Abc_NtkForEachPi( pNtkNew, pObj, i )
{
fprintf( stdout, "Wrong terminal type.\n" );
return NULL;
if ( pObj->pCopy ) continue;
Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
Counter++;
}
// get the terminal number
iTerm = atoi( ++pCur ); while ( *pCur++ != ' ' );
// get the node
if ( iTerm >= Vec_PtrSize(vTerms) )
Abc_NtkForEachLatchOutput( pNtkNew, pObj, i )
{
fprintf( stdout, "The number of terminal is out of bound.\n" );
return NULL;
if ( pObj->pCopy ) continue;
Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjName(pObj), "L" );
Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "_in" );
Counter++;
}
pObj = Vec_PtrEntry( vTerms, iTerm );
if ( *pType == 'l' )
pObj = Abc_ObjFanout0(pObj);
// assign the name
pName = pCur; while ( *pCur++ != '\n' );
// assign this name
*(pCur-1) = 0;
Abc_ObjAssignName( pObj, pName, NULL );
if ( *pType == 'l' )
Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "L" );
// mark the node as named
pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
}
// skipping the comments
free( pContents );
Vec_PtrFree( vNodes );
// assign the remaining names
Abc_NtkForEachPi( pNtkNew, pObj, i )
{
if ( pObj->pCopy ) continue;
Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
}
Abc_NtkForEachLatchOutput( pNtkNew, pObj, i )
{
if ( pObj->pCopy ) continue;
Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), NULL );
Abc_NtkForEachPo( pNtkNew, pObj, i )
{
if ( pObj->pCopy ) continue;
Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
Counter++;
}
if ( Counter )
printf( "Io_ReadAiger(): Added %d default names for nameless I/O/register objects.\n", Counter );
}
Abc_NtkForEachPo( pNtkNew, pObj, i )
else
{
if ( pObj->pCopy ) continue;
Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
// printf( "Io_ReadAiger(): I/O/register names are not given. Generating short names.\n" );
Abc_NtkShortNames( pNtkNew );
}
// skipping the comments
free( pContents );
Vec_PtrFree( vNodes );
// remove the extra nodes
Abc_AigCleanup( pNtkNew->pManFunc );
......
......@@ -163,6 +163,12 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols )
fprintf( stdout, "Io_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName );
return;
}
Abc_NtkForEachLatch( pNtk, pObj, i )
if ( !Abc_LatchIsInit0(pObj) )
{
fprintf( stdout, "Io_WriteAiger(): Cannot write AIGER format with non-0 latch init values. Run \"zero\".\n" );
return;
}
// set the node numbers to be used in the output file
nNodes = 0;
......
......@@ -41,7 +41,7 @@ int timeRetime = 0;
SeeAlso []
***********************************************************************/
int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fVerbose )
int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fOneStep, int fVerbose )
{
int nLatches = Abc_NtkLatchNum(pNtk);
int nLevels = Abc_NtkLevel(pNtk);
......@@ -62,26 +62,26 @@ int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOn
switch ( Mode )
{
case 1: // forward
RetValue = Abc_NtkRetimeIncremental( pNtk, 1, 0, fVerbose );
RetValue = Abc_NtkRetimeIncremental( pNtk, 1, 0, 0, fVerbose );
break;
case 2: // backward
RetValue = Abc_NtkRetimeIncremental( pNtk, 0, 0, fVerbose );
RetValue = Abc_NtkRetimeIncremental( pNtk, 0, 0, 0, fVerbose );
break;
case 3: // min-area
RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose );
break;
case 4: // min-delay
if ( !fBackwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fVerbose );
RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fOneStep, fVerbose );
if ( !fForwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fVerbose );
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fOneStep, fVerbose );
break;
case 5: // min-area + min-delay
RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose );
if ( !fBackwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fVerbose );
RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, 0, fVerbose );
if ( !fForwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fVerbose );
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, 0, fVerbose );
break;
case 6: // Pan's algorithm
RetValue = Abc_NtkRetimeLValue( pNtk, 500, fVerbose );
......@@ -121,7 +121,7 @@ int Abc_NtkRetimeDebug( Abc_Ntk_t * pNtk )
// fprintf( stdout, "Abc_NtkRetimeDebug(): Network check has failed.\n" );
// Io_WriteBlifLogic( pNtk, "debug_temp.blif", 1 );
pNtkRet = Abc_NtkDup( pNtk );
Abc_NtkRetime( pNtkRet, 3, 0, 1, 0 ); // debugging backward flow
Abc_NtkRetime( pNtkRet, 3, 0, 1, 0, 0 ); // debugging backward flow
return !Abc_NtkSecFraig( pNtk, pNtkRet, 10000, 3, 0 );
}
......
......@@ -63,7 +63,7 @@ int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimi
Synopsis [Returns the best delay and the number of best iteration.]
Description []
Description []
SideEffects []
......@@ -145,7 +145,7 @@ if ( fVerbose && !fInitial )
if ( fVerbose && !fInitial )
printf( "%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).\n",
fForward? "Forward " : "Backward", DelayStart, DelayBest, IterBest, nIterLimit );
*pIterBest = IterBest;
*pIterBest = (nIterLimit == 1) ? 1 : IterBest;
return DelayBest;
}
......
......@@ -41,7 +41,7 @@ static int Abc_NtkRetimeOneWay( Abc_Ntk_t * pNtk, int fForward, int fVerbose );
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fVerbose )
int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fOneStep, int fVerbose )
{
Abc_Ntk_t * pNtkCopy = NULL;
Vec_Ptr_t * vBoxes;
......@@ -55,7 +55,7 @@ int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int
Abc_NtkOrderCisCos( pNtk );
if ( fMinDelay )
{
nIterLimit = 2 * Abc_NtkLevel(pNtk);
nIterLimit = fOneStep? 1 : 2 * Abc_NtkLevel(pNtk);
pNtkCopy = Abc_NtkDup( pNtk );
tLatches = Abc_NtkRetimePrepareLatches( pNtkCopy );
st_free_table( tLatches );
......
......@@ -46,11 +46,11 @@
/*=== retArea.c ========================================================*/
extern int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fForwardOnly, int fBackwardOnly, int fVerbose );
/*=== retCore.c ========================================================*/
extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fVerbose );
extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fOneStep, int fVerbose );
/*=== retDelay.c ========================================================*/
extern int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimit, int fForward, int fVerbose );
/*=== retDirect.c ========================================================*/
extern int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fVerbose );
extern int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fOneStep, int fVerbose );
extern void Abc_NtkRetimeShareLatches( Abc_Ntk_t * pNtk, int fInitial );
extern int Abc_NtkRetimeNodeIsEnabled( Abc_Obj_t * pObj, int fForward );
extern void Abc_NtkRetimeNode( Abc_Obj_t * pObj, int fForward, int fInitial );
......
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