mirror of https://github.com/YosysHQ/abc.git
Version abc70828
This commit is contained in:
parent
2846782381
commit
ddc6d1c168
8
abc.dsp
8
abc.dsp
|
|
@ -2586,6 +2586,10 @@ SOURCE=.\src\aig\fra\fraInd.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fra\fraLcr.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fra\fraMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2794,6 +2798,10 @@ SOURCE=.\src\aig\aig\aigRet.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\aig\aigScl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\aig\aigSeq.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ struct Aig_Man_t_
|
|||
int fCatchExor; // enables EXOR nodes
|
||||
int fAddStrash; // performs additional strashing
|
||||
Aig_Obj_t ** pObjCopies; // mapping of AIG nodes into FRAIG nodes
|
||||
void (*pImpFunc) (void*, void*); // implication checking precedure
|
||||
void * pImpData; // implication checking data
|
||||
// timing statistics
|
||||
int time1;
|
||||
int time2;
|
||||
|
|
@ -298,6 +300,9 @@ static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry )
|
|||
// iterator over the primary outputs
|
||||
#define Aig_ManForEachPo( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPos, pObj, i )
|
||||
// iterator over the assertions
|
||||
#define Aig_ManForEachAssert( p, pObj, i ) \
|
||||
Vec_PtrForEachEntryStart( p->vPos, pObj, i, Aig_ManPoNum(p)-p->nAsserts )
|
||||
// iterator over all objects, including those currently not used
|
||||
#define Aig_ManForEachObj( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else
|
||||
|
|
@ -373,15 +378,12 @@ extern void Aig_ManFanoutStop( Aig_Man_t * p );
|
|||
/*=== aigMan.c ==========================================================*/
|
||||
extern Aig_Man_t * Aig_ManStart( int nNodesMax );
|
||||
extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p );
|
||||
extern Aig_Obj_t * Aig_ManDup_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
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 );
|
||||
|
|
@ -436,6 +438,11 @@ 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_ManRetime( Aig_Man_t * p, int fForward, int nStepsMax, int fVerbose );
|
||||
/*=== aigScl.c ==========================================================*/
|
||||
extern Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap );
|
||||
extern int Aig_ManSeqCleanup( Aig_Man_t * p );
|
||||
extern int Aig_ManCountMergeRegs( Aig_Man_t * p );
|
||||
extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose );
|
||||
/*=== aigSeq.c ========================================================*/
|
||||
extern int Aig_ManSeqStrash( Aig_Man_t * p, int nLatches, int * pInits );
|
||||
/*=== aigShow.c ========================================================*/
|
||||
|
|
|
|||
|
|
@ -170,54 +170,6 @@ Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Remaps the manager.]
|
||||
|
||||
Description [Map in the array specifies for each CI nodes the node that
|
||||
should be used after remapping.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjMapped;
|
||||
int i;
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Aig_ManObjIdMax(p) + 1 );
|
||||
pNew->nRegs = p->nRegs;
|
||||
pNew->nAsserts = p->nAsserts;
|
||||
// create the PIs
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
// implement the mapping
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
pObjMapped = Vec_PtrEntry( vMap, i );
|
||||
pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) );
|
||||
}
|
||||
// duplicate internal nodes
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
if ( Aig_ObjIsBuf(pObj) )
|
||||
pObj->pData = Aig_ObjChild0Copy(pObj);
|
||||
else if ( Aig_ObjIsNode(pObj) )
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
// add the POs
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
assert( Aig_ManNodeNum(p) >= Aig_ManNodeNum(pNew) );
|
||||
// check the resulting network
|
||||
if ( !Aig_ManCheck(pNew) )
|
||||
printf( "Aig_ManDup(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Extracts the miter composed of XOR of the two nodes.]
|
||||
|
|
@ -295,110 +247,6 @@ void Aig_ManStop( Aig_Man_t * p )
|
|||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManSeqCleanup_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent(p, pObj);
|
||||
// collect latch input corresponding to unmarked PI (latch output)
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
{
|
||||
Vec_PtrPush( vNodes, pObj->pNext );
|
||||
return;
|
||||
}
|
||||
if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
|
||||
return;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
|
||||
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin1(pObj), vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManSeqCleanup( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNodes, * vCis, * vCos;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
|
||||
int i, nTruePis, nTruePos;
|
||||
assert( Aig_ManBufNum(p) == 0 );
|
||||
|
||||
// mark the PIs
|
||||
Aig_ManIncrementTravId( p );
|
||||
Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
|
||||
Aig_ManForEachPiSeq( p, pObj, i )
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
|
||||
// prepare to collect nodes reachable from POs
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Aig_ManForEachPoSeq( p, pObj, i )
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
|
||||
// remember latch inputs in latch outputs
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
pObjLo->pNext = pObjLi;
|
||||
// mark the nodes reachable from these nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Aig_ManSeqCleanup_rec( p, pObj, vNodes );
|
||||
assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) );
|
||||
// clean latch output pointers
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
pObjLo->pNext = NULL;
|
||||
|
||||
// if some latches are removed, update PIs/POs
|
||||
if ( Vec_PtrSize(vNodes) < Aig_ManPoNum(p) )
|
||||
{
|
||||
// collect new CIs/COs
|
||||
vCis = Vec_PtrAlloc( Aig_ManPiNum(p) );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
Vec_PtrPush( vCis, pObj );
|
||||
vCos = Vec_PtrAlloc( Aig_ManPoNum(p) );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
Vec_PtrPush( vCos, pObj );
|
||||
else
|
||||
Aig_ObjDisconnect( p, pObj );
|
||||
// remember the number of true PIs/POs
|
||||
nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p);
|
||||
nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p);
|
||||
// set the new number of registers
|
||||
p->nRegs -= Aig_ManPoNum(p) - Vec_PtrSize(vNodes);
|
||||
// create new PIs/POs
|
||||
assert( Vec_PtrSize(vCis) == nTruePis + p->nRegs );
|
||||
assert( Vec_PtrSize(vCos) == nTruePos + p->nRegs );
|
||||
Vec_PtrFree( p->vPis ); p->vPis = vCis;
|
||||
Vec_PtrFree( p->vPos ); p->vPos = vCos;
|
||||
p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis );
|
||||
p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// remove dangling nodes
|
||||
return Aig_ManCleanup( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
|
@ -428,42 +276,6 @@ int Aig_ManCleanup( Aig_Man_t * p )
|
|||
return nNodesOld - Aig_ManNodeNum(p);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManCountMergeRegs( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pFanin;
|
||||
int i, Counter = 0, Const0 = 0, Const1 = 0;
|
||||
Aig_ManIncrementTravId( p );
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
if ( Aig_ObjIsConst1(pFanin) )
|
||||
{
|
||||
if ( Aig_ObjFaninC0(pObj) )
|
||||
Const0++;
|
||||
else
|
||||
Const1++;
|
||||
}
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pFanin) )
|
||||
continue;
|
||||
Aig_ObjSetTravIdCurrent(p, pFanin);
|
||||
Counter++;
|
||||
}
|
||||
printf( "Regs = %d. Fanins = %d. Const0 = %d. Const1 = %d.\n",
|
||||
Aig_ManRegNum(p), Counter, Const0, Const1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the AIG manager.]
|
||||
|
|
@ -491,149 +303,6 @@ void Aig_ManPrintStats( Aig_Man_t * p )
|
|||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks how many latches can be reduced.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManReduceLachesCount( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pFanin;
|
||||
int i, Counter = 0;
|
||||
assert( Aig_ManRegNum(p) > 0 );
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
if ( Aig_ObjFaninC0(pObj) )
|
||||
{
|
||||
if ( pFanin->fMarkB )
|
||||
Counter++;
|
||||
else
|
||||
pFanin->fMarkB = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pFanin->fMarkA )
|
||||
Counter++;
|
||||
else
|
||||
pFanin->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
pFanin->fMarkA = pFanin->fMarkB = 0;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reduces the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Aig_ManReduceLachesOnce( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vMap;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pFanin;
|
||||
int * pMapping, i;
|
||||
// start mapping by adding the true PIs
|
||||
vMap = Vec_PtrAlloc( Aig_ManPiNum(p) );
|
||||
Aig_ManForEachPiSeq( p, pObj, i )
|
||||
Vec_PtrPush( vMap, pObj );
|
||||
// create mapping of fanin nodes into the corresponding latch outputs
|
||||
pMapping = ALLOC( int, 2 * (Aig_ManObjIdMax(p) + 1) );
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObjLi);
|
||||
if ( Aig_ObjFaninC0(pObjLi) )
|
||||
{
|
||||
if ( pFanin->fMarkB )
|
||||
{
|
||||
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id + 1]) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pFanin->fMarkB = 1;
|
||||
pMapping[2*pFanin->Id + 1] = i;
|
||||
Vec_PtrPush( vMap, pObjLo );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pFanin->fMarkA )
|
||||
{
|
||||
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id]) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pFanin->fMarkA = 1;
|
||||
pMapping[2*pFanin->Id] = i;
|
||||
Vec_PtrPush( vMap, pObjLo );
|
||||
}
|
||||
}
|
||||
}
|
||||
free( pMapping );
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
pFanin->fMarkA = pFanin->fMarkB = 0;
|
||||
}
|
||||
return vMap;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reduces the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose )
|
||||
{
|
||||
Aig_Man_t * pTemp;
|
||||
Vec_Ptr_t * vMap;
|
||||
int nSaved, nCur;
|
||||
for ( nSaved = 0; nCur = Aig_ManReduceLachesCount(p); nSaved += nCur )
|
||||
{
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Saved = %5d. ", nCur );
|
||||
printf( "RBeg = %5d. NBeg = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
|
||||
}
|
||||
vMap = Aig_ManReduceLachesOnce( p );
|
||||
p = Aig_ManRemap( pTemp = p, vMap );
|
||||
Aig_ManStop( pTemp );
|
||||
Vec_PtrFree( vMap );
|
||||
Aig_ManSeqCleanup( p );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "REnd = %5d. NEnd = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan )
|
|||
}
|
||||
assert( 0 );
|
||||
}
|
||||
printf( "Memory usage = %d Mb.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) );
|
||||
//printf( "Memory usage = %d Mb.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) );
|
||||
Part_ManStop( p );
|
||||
// sort supports by size
|
||||
Vec_VecSort( vSupps, 1 );
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ Aig_Obj_t * Aig_ManDupRepr_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pOb
|
|||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p )
|
||||
{
|
||||
int fOrdered = 1;
|
||||
int fOrdered = 0;
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,370 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigScl.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [AIG package.]
|
||||
|
||||
Synopsis [Sequential cleanup.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - April 28, 2007.]
|
||||
|
||||
Revision [$Id: aigScl.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Remaps the manager.]
|
||||
|
||||
Description [Map in the array specifies for each CI nodes the node that
|
||||
should be used after remapping.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjMapped;
|
||||
int i;
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Aig_ManObjIdMax(p) + 1 );
|
||||
pNew->nRegs = p->nRegs;
|
||||
pNew->nAsserts = p->nAsserts;
|
||||
// create the PIs
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
// implement the mapping
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
pObjMapped = Vec_PtrEntry( vMap, i );
|
||||
pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) );
|
||||
}
|
||||
// duplicate internal nodes
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
if ( Aig_ObjIsBuf(pObj) )
|
||||
pObj->pData = Aig_ObjChild0Copy(pObj);
|
||||
else if ( Aig_ObjIsNode(pObj) )
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
// add the POs
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
assert( Aig_ManNodeNum(p) >= Aig_ManNodeNum(pNew) );
|
||||
// check the resulting network
|
||||
if ( !Aig_ManCheck(pNew) )
|
||||
printf( "Aig_ManDup(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManSeqCleanup_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent(p, pObj);
|
||||
// collect latch input corresponding to unmarked PI (latch output)
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
{
|
||||
Vec_PtrPush( vNodes, pObj->pNext );
|
||||
return;
|
||||
}
|
||||
if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
|
||||
return;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
|
||||
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin1(pObj), vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManSeqCleanup( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNodes, * vCis, * vCos;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
|
||||
int i, nTruePis, nTruePos;
|
||||
assert( Aig_ManBufNum(p) == 0 );
|
||||
|
||||
// mark the PIs
|
||||
Aig_ManIncrementTravId( p );
|
||||
Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
|
||||
Aig_ManForEachPiSeq( p, pObj, i )
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
|
||||
// prepare to collect nodes reachable from POs
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Aig_ManForEachPoSeq( p, pObj, i )
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
|
||||
// remember latch inputs in latch outputs
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
pObjLo->pNext = pObjLi;
|
||||
// mark the nodes reachable from these nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Aig_ManSeqCleanup_rec( p, pObj, vNodes );
|
||||
assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) );
|
||||
// clean latch output pointers
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
pObjLo->pNext = NULL;
|
||||
|
||||
// if some latches are removed, update PIs/POs
|
||||
if ( Vec_PtrSize(vNodes) < Aig_ManPoNum(p) )
|
||||
{
|
||||
// collect new CIs/COs
|
||||
vCis = Vec_PtrAlloc( Aig_ManPiNum(p) );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
Vec_PtrPush( vCis, pObj );
|
||||
vCos = Vec_PtrAlloc( Aig_ManPoNum(p) );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
Vec_PtrPush( vCos, pObj );
|
||||
else
|
||||
Aig_ObjDisconnect( p, pObj );
|
||||
// remember the number of true PIs/POs
|
||||
nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p);
|
||||
nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p);
|
||||
// set the new number of registers
|
||||
p->nRegs -= Aig_ManPoNum(p) - Vec_PtrSize(vNodes);
|
||||
// create new PIs/POs
|
||||
assert( Vec_PtrSize(vCis) == nTruePis + p->nRegs );
|
||||
assert( Vec_PtrSize(vCos) == nTruePos + p->nRegs );
|
||||
Vec_PtrFree( p->vPis ); p->vPis = vCis;
|
||||
Vec_PtrFree( p->vPos ); p->vPos = vCos;
|
||||
p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis );
|
||||
p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// remove dangling nodes
|
||||
return Aig_ManCleanup( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManCountMergeRegs( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pFanin;
|
||||
int i, Counter = 0, Const0 = 0, Const1 = 0;
|
||||
Aig_ManIncrementTravId( p );
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
if ( Aig_ObjIsConst1(pFanin) )
|
||||
{
|
||||
if ( Aig_ObjFaninC0(pObj) )
|
||||
Const0++;
|
||||
else
|
||||
Const1++;
|
||||
}
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pFanin) )
|
||||
continue;
|
||||
Aig_ObjSetTravIdCurrent(p, pFanin);
|
||||
Counter++;
|
||||
}
|
||||
printf( "Regs = %d. Fanins = %d. Const0 = %d. Const1 = %d.\n",
|
||||
Aig_ManRegNum(p), Counter, Const0, Const1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks how many latches can be reduced.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManReduceLachesCount( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pFanin;
|
||||
int i, Counter = 0, Diffs = 0;
|
||||
assert( Aig_ManRegNum(p) > 0 );
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
if ( Aig_ObjFaninC0(pObj) )
|
||||
{
|
||||
if ( pFanin->fMarkB )
|
||||
Counter++;
|
||||
else
|
||||
pFanin->fMarkB = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pFanin->fMarkA )
|
||||
Counter++;
|
||||
else
|
||||
pFanin->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
// count fanins that have both attributes
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
Diffs += pFanin->fMarkA && pFanin->fMarkB;
|
||||
pFanin->fMarkA = pFanin->fMarkB = 0;
|
||||
}
|
||||
// printf( "Diffs = %d.\n", Diffs );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reduces the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Aig_ManReduceLachesOnce( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vMap;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pFanin;
|
||||
int * pMapping, i;
|
||||
// start mapping by adding the true PIs
|
||||
vMap = Vec_PtrAlloc( Aig_ManPiNum(p) );
|
||||
Aig_ManForEachPiSeq( p, pObj, i )
|
||||
Vec_PtrPush( vMap, pObj );
|
||||
// create mapping of fanin nodes into the corresponding latch outputs
|
||||
pMapping = ALLOC( int, 2 * (Aig_ManObjIdMax(p) + 1) );
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObjLi);
|
||||
if ( Aig_ObjFaninC0(pObjLi) )
|
||||
{
|
||||
if ( pFanin->fMarkB )
|
||||
{
|
||||
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id + 1]) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pFanin->fMarkB = 1;
|
||||
pMapping[2*pFanin->Id + 1] = i;
|
||||
Vec_PtrPush( vMap, pObjLo );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pFanin->fMarkA )
|
||||
{
|
||||
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id]) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pFanin->fMarkA = 1;
|
||||
pMapping[2*pFanin->Id] = i;
|
||||
Vec_PtrPush( vMap, pObjLo );
|
||||
}
|
||||
}
|
||||
}
|
||||
free( pMapping );
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
pFanin->fMarkA = pFanin->fMarkB = 0;
|
||||
}
|
||||
return vMap;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reduces the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose )
|
||||
{
|
||||
Aig_Man_t * pTemp;
|
||||
Vec_Ptr_t * vMap;
|
||||
int nSaved, nCur;
|
||||
for ( nSaved = 0; nCur = Aig_ManReduceLachesCount(p); nSaved += nCur )
|
||||
{
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Saved = %5d. ", nCur );
|
||||
printf( "RBeg = %5d. NBeg = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
|
||||
}
|
||||
vMap = Aig_ManReduceLachesOnce( p );
|
||||
p = Aig_ManRemap( pTemp = p, vMap );
|
||||
Aig_ManStop( pTemp );
|
||||
Vec_PtrFree( vMap );
|
||||
Aig_ManSeqCleanup( p );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "REnd = %5d. NEnd = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TSI_MAX_ROUNDS 10000
|
||||
#define TSI_MAX_ROUNDS 1000
|
||||
|
||||
#define AIG_XVS0 1
|
||||
#define AIG_XVS1 2
|
||||
|
|
@ -340,7 +340,7 @@ Vec_Ptr_t * Aig_ManTernarySimulate( Aig_Man_t * p, int fVerbose )
|
|||
}
|
||||
if ( f == TSI_MAX_ROUNDS )
|
||||
{
|
||||
printf( "Aig_ManTernarySimulate(): Did not reach a fixed point after %d iterations.\n", TSI_MAX_ROUNDS );
|
||||
printf( "Aig_ManTernarySimulate(): Did not reach a fixed point after %d iterations (not a bug).\n", TSI_MAX_ROUNDS );
|
||||
Aig_TsiStop( pTsi );
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -662,7 +662,7 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
|
|||
{
|
||||
FILE * pFile;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj, * pConst1 = NULL;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pConst1 = NULL;
|
||||
int i, nDigits, Counter = 0;
|
||||
if ( Aig_ManPoNum(p) == 0 )
|
||||
{
|
||||
|
|
@ -687,14 +687,22 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
|
|||
fprintf( pFile, ".model test\n" );
|
||||
// write PIs
|
||||
fprintf( pFile, ".inputs" );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
Aig_ManForEachPiSeq( p, pObj, i )
|
||||
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
|
||||
fprintf( pFile, "\n" );
|
||||
// write POs
|
||||
fprintf( pFile, ".outputs" );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Aig_ManForEachPoSeq( p, pObj, i )
|
||||
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
|
||||
fprintf( pFile, "\n" );
|
||||
// write latches
|
||||
if ( Aig_ManRegNum(p) )
|
||||
{
|
||||
fprintf( pFile, "\n" );
|
||||
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
|
||||
fprintf( pFile, ".latch n%0*d n%0*d 0\n", nDigits, (int)pObjLi->pData, nDigits, (int)pObjLo->pData );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
// write nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ SRC += src/aig/aig/aigCheck.c \
|
|||
src/aig/aig/aigOrder.c \
|
||||
src/aig/aig/aigPart.c \
|
||||
src/aig/aig/aigRepr.c \
|
||||
src/aig/aig/aigRet.c \
|
||||
src/aig/aig/aigScl.c \
|
||||
src/aig/aig/aigSeq.c \
|
||||
src/aig/aig/aigTable.c \
|
||||
src/aig/aig/aigTiming.c \
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ struct Fra_Par_t_
|
|||
int fRewrite; // use rewriting for constraint reduction
|
||||
int fLatchCorr; // computes latch correspondence only
|
||||
int fUseImps; // use implications
|
||||
int fWriteImps; // record implications
|
||||
};
|
||||
|
||||
// FRAIG equivalence classes
|
||||
|
|
@ -148,7 +149,6 @@ struct Fra_Man_t_
|
|||
// statistics
|
||||
int nSimRounds;
|
||||
int nNodesMiter;
|
||||
int nLitsZero;
|
||||
int nLitsBeg;
|
||||
int nLitsEnd;
|
||||
int nNodesBeg;
|
||||
|
|
@ -202,6 +202,10 @@ static inline void Fra_ClassObjSetRepr( Aig_Obj_t * pObj, Aig_Obj_t * pN
|
|||
static inline Aig_Obj_t * Fra_ObjChild0Fra( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Fra_ObjFraig(Aig_ObjFanin0(pObj),i), Aig_ObjFaninC0(pObj)) : NULL; }
|
||||
static inline Aig_Obj_t * Fra_ObjChild1Fra( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Fra_ObjFraig(Aig_ObjFanin1(pObj),i), Aig_ObjFaninC1(pObj)) : NULL; }
|
||||
|
||||
static inline int Fra_ImpLeft( int Imp ) { return Imp & 0xFFFF; }
|
||||
static inline int Fra_ImpRight( int Imp ) { return Imp >> 16; }
|
||||
static inline int Fra_ImpCreate( int Left, int Right ) { return (Right << 16) | Left; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -222,7 +226,7 @@ extern void Fra_ClassesCopyReprs( Fra_Cla_t * p, Vec_Ptr_t * vFai
|
|||
extern void Fra_ClassesPrint( Fra_Cla_t * p, int fVeryVerbose );
|
||||
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_ClassesRefine1( Fra_Cla_t * p, int fRefineNewClass, int * pSkipped );
|
||||
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 );
|
||||
|
|
@ -233,18 +237,24 @@ extern Aig_Man_t * Fra_ClassesDeriveAig( Fra_Cla_t * p, int nFramesK );
|
|||
/*=== fraCnf.c ========================================================*/
|
||||
extern void Fra_CnfNodeAddToSolver( 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 );
|
||||
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 Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax );
|
||||
/*=== fraImp.c ========================================================*/
|
||||
extern Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr );
|
||||
extern void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums );
|
||||
extern int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, int Pos );
|
||||
extern int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps );
|
||||
extern void Fra_ImpCompactArray( Vec_Int_t * vImps );
|
||||
extern double Fra_ImpComputeStateSpaceRatio( Fra_Man_t * p );
|
||||
extern int Fra_ImpVerifyUsingSimulation( Fra_Man_t * p );
|
||||
extern void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew );
|
||||
/*=== fraInd.c ========================================================*/
|
||||
extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose, int * pnIter );
|
||||
extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose, int * pnIter );
|
||||
/*=== fraLcr.c ========================================================*/
|
||||
extern Aig_Man_t * Fra_FraigLatchCorrespondence( Aig_Man_t * pAig, int nFramesP, int nConfMax, int fVerbose, int * pnIter );
|
||||
/*=== fraMan.c ========================================================*/
|
||||
extern void Fra_ParamsDefault( Fra_Par_t * pParams );
|
||||
extern void Fra_ParamsDefaultSeq( Fra_Par_t * pParams );
|
||||
|
|
@ -259,7 +269,7 @@ extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, A
|
|||
extern int Fra_NodesAreImp( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR );
|
||||
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 );
|
||||
extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose );
|
||||
/*=== fraSim.c ========================================================*/
|
||||
extern int Fra_SmlNodeHash( Aig_Obj_t * pObj, int nTableSize );
|
||||
extern int Fra_SmlNodeIsConst( Aig_Obj_t * pObj );
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ struct Fra_Bmc_t_
|
|||
int nPref; // the size of the prefix
|
||||
int nDepth; // the depth of the frames
|
||||
int nFramesAll; // the total number of timeframes
|
||||
// implications to be filtered
|
||||
Vec_Int_t * vImps;
|
||||
// AIG managers
|
||||
Aig_Man_t * pAig; // the original AIG manager
|
||||
Aig_Man_t * pAigFrames; // initialized timeframes
|
||||
|
|
@ -67,7 +69,6 @@ static inline Aig_Obj_t * Bmc_ObjChild1Frames( Aig_Obj_t * pObj, int i ) { asse
|
|||
int Fra_BmcNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
|
||||
{
|
||||
Fra_Man_t * p = pObj0->pData;
|
||||
// Aig_Obj_t ** ppNodes = p->pBmc->pObjToFraig;
|
||||
Aig_Obj_t * pObjFrames0, * pObjFrames1;
|
||||
Aig_Obj_t * pObjFraig0, * pObjFraig1;
|
||||
int i;
|
||||
|
|
@ -102,6 +103,69 @@ int Fra_BmcNodeIsConst( Aig_Obj_t * pObj )
|
|||
return Fra_BmcNodesAreEqual( pObj, Aig_ManConst1(p->pManAig) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Refines implications using BMC.]
|
||||
|
||||
Description [The input is the combinational FRAIG manager,
|
||||
which is used to FRAIG the timeframes. ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_BmcFilterImplications( Fra_Man_t * p, Fra_Bmc_t * pBmc )
|
||||
{
|
||||
Aig_Obj_t * pLeft, * pRight;
|
||||
Aig_Obj_t * pLeftT, * pRightT;
|
||||
Aig_Obj_t * pLeftF, * pRightF;
|
||||
int i, f, Imp, Left, Right;
|
||||
int fComplL, fComplR;
|
||||
assert( p->nFramesAll == 1 );
|
||||
assert( p->pManAig == pBmc->pAigFrames );
|
||||
Vec_IntForEachEntry( pBmc->vImps, Imp, i )
|
||||
{
|
||||
if ( Imp == 0 )
|
||||
continue;
|
||||
Left = Fra_ImpLeft(Imp);
|
||||
Right = Fra_ImpRight(Imp);
|
||||
// get the corresponding nodes
|
||||
pLeft = Aig_ManObj( pBmc->pAig, Left );
|
||||
pRight = Aig_ManObj( pBmc->pAig, Right );
|
||||
// iterate through the timeframes
|
||||
for ( f = pBmc->nPref; f < pBmc->nFramesAll; f++ )
|
||||
{
|
||||
// get timeframes nodes
|
||||
pLeftT = Bmc_ObjFrames( pLeft, f );
|
||||
pRightT = Bmc_ObjFrames( pRight, f );
|
||||
// get the corresponding FRAIG nodes
|
||||
pLeftF = Fra_ObjFraig( Aig_Regular(pLeftT), 0 );
|
||||
pRightF = Fra_ObjFraig( Aig_Regular(pRightT), 0 );
|
||||
// get the complemented attributes
|
||||
fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF) ^ Aig_IsComplement(pLeftT);
|
||||
fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF) ^ Aig_IsComplement(pRightT);
|
||||
// check equality
|
||||
if ( Aig_Regular(pLeftF) == Aig_Regular(pRightF) )
|
||||
{
|
||||
if ( fComplL != fComplR )
|
||||
Vec_IntWriteEntry( pBmc->vImps, i, 0 );
|
||||
break;
|
||||
}
|
||||
// check the implication
|
||||
// - if true, a clause is added
|
||||
// - if false, a cex is simulated
|
||||
// make sure the implication is refined
|
||||
if ( Fra_NodesAreImp( p, Aig_Regular(pLeftF), Aig_Regular(pRightF), fComplL, fComplR ) != 1 )
|
||||
{
|
||||
Vec_IntWriteEntry( pBmc->vImps, i, 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Fra_ImpCompactArray( pBmc->vImps );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -125,8 +189,6 @@ Fra_Bmc_t * Fra_BmcStart( Aig_Man_t * pAig, int nPref, int nDepth )
|
|||
p->nFramesAll = nPref + nDepth;
|
||||
p->pObjToFrames = ALLOC( Aig_Obj_t *, p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
|
||||
memset( p->pObjToFrames, 0, sizeof(Aig_Obj_t *) * p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
|
||||
// p->pObjToFraig = ALLOC( Aig_Obj_t *, p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
|
||||
// memset( p->pObjToFraig, 0, sizeof(Aig_Obj_t *) * p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -213,34 +275,6 @@ Aig_Man_t * Fra_BmcFrames( Fra_Bmc_t * p )
|
|||
return pAigFrames;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs FRAIG manager for the initialized timeframes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Fra_BmcFraig( Fra_Bmc_t * p )
|
||||
{
|
||||
Aig_Man_t * pFraig;
|
||||
Fra_Par_t Pars, * pPars = &Pars;
|
||||
Fra_ParamsDefault( pPars );
|
||||
pPars->nBTLimitNode = 100000;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fProve = 0;
|
||||
pPars->fDoSparse = 1;
|
||||
pPars->fSpeculate = 0;
|
||||
pPars->fChoicing = 0;
|
||||
pFraig = Fra_FraigPerform( p->pAigFrames, pPars );
|
||||
p->pObjToFraig = p->pAigFrames->pObjCopies;
|
||||
p->pAigFrames->pObjCopies = NULL;
|
||||
return pFraig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BMC for the given AIG.]
|
||||
|
|
@ -255,12 +289,22 @@ Aig_Man_t * Fra_BmcFraig( Fra_Bmc_t * p )
|
|||
void Fra_BmcPerform( Fra_Man_t * p, int nPref, int nDepth )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, clk = clock();
|
||||
int i, nImpsOld, clk = clock();
|
||||
assert( p->pBmc == NULL );
|
||||
// derive and fraig the frames
|
||||
p->pBmc = Fra_BmcStart( p->pManAig, nPref, nDepth );
|
||||
p->pBmc->pAigFrames = Fra_BmcFrames( p->pBmc );
|
||||
p->pBmc->pAigFraig = Fra_BmcFraig( p->pBmc );
|
||||
// if implications are present, configure the AIG manager to check them
|
||||
if ( p->pCla->vImps )
|
||||
{
|
||||
p->pBmc->pAigFrames->pImpFunc = Fra_BmcFilterImplications;
|
||||
p->pBmc->pAigFrames->pImpData = p->pBmc;
|
||||
p->pBmc->vImps = p->pCla->vImps;
|
||||
nImpsOld = Vec_IntSize(p->pCla->vImps);
|
||||
}
|
||||
p->pBmc->pAigFraig = Fra_FraigEquivence( p->pBmc->pAigFrames, 1000000 );
|
||||
p->pBmc->pObjToFraig = p->pBmc->pAigFrames->pObjCopies;
|
||||
p->pBmc->pAigFrames->pObjCopies = NULL;
|
||||
// annotate frames nodes with pointers to the manager
|
||||
Aig_ManForEachObj( p->pBmc->pAigFrames, pObj, i )
|
||||
pObj->pData = p;
|
||||
|
|
@ -271,19 +315,31 @@ void Fra_BmcPerform( Fra_Man_t * p, int nPref, int nDepth )
|
|||
Aig_ManNodeNum(p->pBmc->pAig), p->pBmc->nFramesAll,
|
||||
Aig_ManNodeNum(p->pBmc->pAigFrames), Aig_ManNodeNum(p->pBmc->pAigFraig) );
|
||||
PRT( "Time", clock() - clk );
|
||||
printf( "Before BMC: " ); Fra_ClassesPrint( p->pCla, 0 );
|
||||
printf( "Before BMC: " );
|
||||
// Fra_ClassesPrint( p->pCla, 0 );
|
||||
printf( "Const = %5d. Class = %5d. Lit = %5d. ",
|
||||
Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) );
|
||||
if ( p->pCla->vImps && Vec_IntSize(p->pCla->vImps) > 0 )
|
||||
printf( "Imp = %5d. ", nImpsOld );
|
||||
printf( "\n" );
|
||||
}
|
||||
// refine the classes
|
||||
p->pCla->pFuncNodeIsConst = Fra_BmcNodeIsConst;
|
||||
p->pCla->pFuncNodesAreEqual = Fra_BmcNodesAreEqual;
|
||||
Fra_ClassesRefine( p->pCla );
|
||||
Fra_ClassesRefine1( p->pCla );
|
||||
Fra_ClassesRefine1( p->pCla, 1, NULL );
|
||||
p->pCla->pFuncNodeIsConst = Fra_SmlNodeIsConst;
|
||||
p->pCla->pFuncNodesAreEqual = Fra_SmlNodesAreEqual;
|
||||
// report the results
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
printf( "After BMC: " ); Fra_ClassesPrint( p->pCla, 0 );
|
||||
printf( "After BMC: " );
|
||||
// Fra_ClassesPrint( p->pCla, 0 );
|
||||
printf( "Const = %5d. Class = %5d. Lit = %5d. ",
|
||||
Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) );
|
||||
if ( p->pCla->vImps && Vec_IntSize(p->pCla->vImps) > 0 )
|
||||
printf( "Imp = %5d. ", Vec_IntSize(p->pCla->vImps) );
|
||||
printf( "\n" );
|
||||
}
|
||||
// free the BMC manager
|
||||
Fra_BmcStop( p->pBmc );
|
||||
|
|
|
|||
|
|
@ -520,10 +520,10 @@ int Fra_ClassesRefine( Fra_Cla_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fra_ClassesRefine1( Fra_Cla_t * p )
|
||||
int Fra_ClassesRefine1( Fra_Cla_t * p, int fRefineNewClass, int * pSkipped )
|
||||
{
|
||||
Aig_Obj_t * pObj, ** ppClass;
|
||||
int i, k, nRefis;
|
||||
int i, k, nRefis = 1;
|
||||
// check if there is anything to refine
|
||||
if ( Vec_PtrSize(p->vClasses1) == 0 )
|
||||
return 0;
|
||||
|
|
@ -565,7 +565,10 @@ int Fra_ClassesRefine1( Fra_Cla_t * p )
|
|||
assert( ppClass[0] != NULL );
|
||||
Vec_PtrPush( p->vClasses, ppClass );
|
||||
// iteratively refine this class
|
||||
nRefis = 1 + Fra_RefineClassLastIter( p, p->vClasses );
|
||||
if ( fRefineNewClass )
|
||||
nRefis += Fra_RefineClassLastIter( p, p->vClasses );
|
||||
else if ( pSkipped )
|
||||
(*pSkipped)++;
|
||||
return nRefis;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj )
|
|||
Vec_PtrPush( p->vTimeouts, pObj );
|
||||
// verify that the counter-example satisfies all the constraints
|
||||
// if ( p->vCex )
|
||||
// Fra_FraigVerifyCounterEx( p, p->vCex );
|
||||
// Fra_FraigVerifyCounterEx( p, p->vCex );
|
||||
// simulate the counter-example and return the Fraig node
|
||||
Fra_SmlResimulate( p );
|
||||
if ( !p->pPars->nFramesK && Fra_ClassObjRepr(pObj) == pObjRepr )
|
||||
|
|
@ -334,12 +334,15 @@ clk = clock();
|
|||
if ( p->pPars->fChoicing )
|
||||
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->nNodesBeg = Aig_ManNodeNum(pManAig);
|
||||
p->nRegsBeg = Aig_ManRegNum(pManAig);
|
||||
// perform fraig sweep
|
||||
Fra_FraigSweep( p );
|
||||
// call back the procedure to check implications
|
||||
if ( pManAig->pImpFunc )
|
||||
pManAig->pImpFunc( p, pManAig->pImpData );
|
||||
// finalize the fraiged manager
|
||||
Fra_ManFinalizeComb( p );
|
||||
if ( p->pPars->fChoicing )
|
||||
{
|
||||
|
|
@ -397,6 +400,32 @@ Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig )
|
|||
pPars->fChoicing = 1;
|
||||
return Fra_FraigPerform( pManAig, pPars );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax )
|
||||
{
|
||||
Aig_Man_t * pFraig;
|
||||
Fra_Par_t Pars, * pPars = &Pars;
|
||||
Fra_ParamsDefault( pPars );
|
||||
pPars->nBTLimitNode = nConfMax;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fProve = 0;
|
||||
pPars->fDoSparse = 1;
|
||||
pPars->fSpeculate = 0;
|
||||
pPars->fChoicing = 0;
|
||||
pFraig = Fra_FraigPerform( pManAig, pPars );
|
||||
return pFraig;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -24,14 +24,31 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Sml_ImpLeft( int Imp ) { return Imp & 0xFFFF; }
|
||||
static inline int Sml_ImpRight( int Imp ) { return Imp >> 16; }
|
||||
static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16) | Left; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of 1s in each siminfo of each node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fra_SmlCountOnesOne( Fra_Sml_t * p, int Node )
|
||||
{
|
||||
unsigned * pSim;
|
||||
int k, Counter = 0;
|
||||
pSim = Fra_ObjSim( p, Node );
|
||||
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
|
||||
Counter += Aig_WordCountOnes( pSim[k] );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of 1s in each siminfo of each node.]
|
||||
|
|
@ -46,16 +63,11 @@ static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16)
|
|||
static inline int * Fra_SmlCountOnes( Fra_Sml_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
unsigned * pSim;
|
||||
int i, k, * pnBits;
|
||||
int i, * pnBits;
|
||||
pnBits = ALLOC( int, Aig_ManObjIdMax(p->pAig) + 1 );
|
||||
memset( pnBits, 0, sizeof(int) * (Aig_ManObjIdMax(p->pAig) + 1) );
|
||||
Aig_ManForEachObj( p->pAig, pObj, i )
|
||||
{
|
||||
pSim = Fra_ObjSim( p, i );
|
||||
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
|
||||
pnBits[i] += Aig_WordCountOnes( pSim[k] );
|
||||
}
|
||||
pnBits[i] = Fra_SmlCountOnesOne( p, i );
|
||||
return pnBits;
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +116,27 @@ static inline int Sml_NodeNotImpWeight( Fra_Sml_t * p, int Left, int Right )
|
|||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of 1s in the reverse implication.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Sml_NodeSaveNotImpPatterns( Fra_Sml_t * p, int Left, int Right, unsigned * pResult )
|
||||
{
|
||||
unsigned * pSimL, * pSimR;
|
||||
int k;
|
||||
pSimL = Fra_ObjSim( p, Left );
|
||||
pSimR = Fra_ObjSim( p, Right );
|
||||
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
|
||||
pResult[k] |= pSimL[k] & ~pSimR[k];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of nodes sorted by the number of 1s.]
|
||||
|
|
@ -284,7 +317,6 @@ int Sml_CompareMaxId( unsigned short * pImp1, unsigned short * pImp2 )
|
|||
***********************************************************************/
|
||||
Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr )
|
||||
{
|
||||
// Aig_Obj_t * pObj;
|
||||
int nSimWords = 64;
|
||||
Fra_Sml_t * pSeq, * pComb;
|
||||
Vec_Int_t * vImps, * vTemp;
|
||||
|
|
@ -293,21 +325,13 @@ Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, in
|
|||
int nImpsTotal = 0, nImpsTried = 0, nImpsNonSeq = 0, nImpsComb = 0, nImpsCollected = 0;
|
||||
int CostMin = AIG_INFINITY, CostMax = 0;
|
||||
int i, k, Imp, CostRange, clk = clock();
|
||||
assert( Aig_ManObjIdMax(p->pManAig) + 1 < (1 << 15) );
|
||||
assert( nImpMaxLimit > 0 && nImpUseLimit > 0 && nImpUseLimit <= nImpMaxLimit );
|
||||
// normalize both managers
|
||||
pComb = Fra_SmlSimulateComb( p->pManAig, nSimWords );
|
||||
pSeq = Fra_SmlSimulateSeq( p->pManAig, p->pPars->nFramesP, nSimWords, 1 );
|
||||
// get the nodes sorted by the number of 1s
|
||||
vNodes = Fra_SmlSortUsingOnes( pSeq, fLatchCorr );
|
||||
/*
|
||||
Aig_ManForEachObj( p->pManAig, pObj, i )
|
||||
{
|
||||
printf( "%6s", Aig_ObjIsPi(pObj)? "pi" : (Aig_ObjIsNode(pObj)? "node" : "other" ) );
|
||||
printf( "%d (%d) :\n", i, pObj->fPhase );
|
||||
Extra_PrintBinary( stdout, Fra_ObjSim( pComb, i ), 64 ); printf( "\n" );
|
||||
Extra_PrintBinary( stdout, Fra_ObjSim( pSeq, i ), 64 ); printf( "\n" );
|
||||
}
|
||||
*/
|
||||
// count the total number of implications
|
||||
for ( k = nSimWords * 32; k > 0; k-- )
|
||||
for ( i = k - 1; i > 0; i-- )
|
||||
|
|
@ -335,10 +359,8 @@ Aig_ManForEachObj( p->pManAig, pObj, i )
|
|||
nImpsComb++;
|
||||
continue;
|
||||
}
|
||||
// printf( "d=%d c=%d ", k-i, Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK) );
|
||||
|
||||
nImpsCollected++;
|
||||
Imp = Sml_ImpCreate( *pNodesI, *pNodesK );
|
||||
Imp = Fra_ImpCreate( *pNodesI, *pNodesK );
|
||||
pImpCosts[ Vec_IntSize(vImps) ] = Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK);
|
||||
CostMin = AIG_MIN( CostMin, pImpCosts[ Vec_IntSize(vImps) ] );
|
||||
CostMax = AIG_MAX( CostMax, pImpCosts[ Vec_IntSize(vImps) ] );
|
||||
|
|
@ -368,13 +390,16 @@ finish:
|
|||
(int (*)(const void *, const void *)) Sml_CompareMaxId );
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
printf( "Tot = %d. Try = %d. NonS = %d. C = %d. Found = %d. Cost = [%d < %d < %d] ",
|
||||
nImpsTotal, nImpsTried, nImpsNonSeq, nImpsComb, nImpsCollected, CostMin, CostRange, CostMax );
|
||||
printf( "Implications: All = %d. Try = %d. NonSeq = %d. Comb = %d. Res = %d.\n",
|
||||
nImpsTotal, nImpsTried, nImpsNonSeq, nImpsComb, nImpsCollected );
|
||||
printf( "Implication weight: Min = %d. Pivot = %d. Max = %d. ",
|
||||
CostMin, CostRange, CostMax );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
return vImps;
|
||||
}
|
||||
|
||||
|
||||
// the following three procedures are called to
|
||||
// - add implications to the SAT solver
|
||||
// - check implications using the SAT solver
|
||||
|
|
@ -401,8 +426,8 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums )
|
|||
Vec_IntForEachEntry( vImps, Imp, i )
|
||||
{
|
||||
// get the corresponding nodes
|
||||
pLeft = Aig_ManObj( p->pManAig, Sml_ImpLeft(Imp) );
|
||||
pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) );
|
||||
pLeft = Aig_ManObj( p->pManAig, Fra_ImpLeft(Imp) );
|
||||
pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) );
|
||||
// check if all the nodes are present
|
||||
for ( f = 0; f < p->pPars->nFramesK; f++ )
|
||||
{
|
||||
|
|
@ -431,7 +456,7 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums )
|
|||
// get the complemented attributes
|
||||
fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF);
|
||||
fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF);
|
||||
// get the constaint
|
||||
// get the constraint
|
||||
// L => R L' v R (complement = L & R')
|
||||
pLits[0] = 2 * Left + !fComplL;
|
||||
pLits[1] = 2 * Right + fComplR;
|
||||
|
|
@ -476,8 +501,8 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
|
|||
{
|
||||
if ( Imp == 0 )
|
||||
continue;
|
||||
Left = Sml_ImpLeft(Imp);
|
||||
Right = Sml_ImpRight(Imp);
|
||||
Left = Fra_ImpLeft(Imp);
|
||||
Right = Fra_ImpRight(Imp);
|
||||
Max = AIG_MAX( Left, Right );
|
||||
assert( Max >= pNode->Id );
|
||||
if ( Max > pNode->Id )
|
||||
|
|
@ -494,9 +519,6 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
|
|||
// check equality
|
||||
if ( Aig_Regular(pLeftF) == Aig_Regular(pRightF) )
|
||||
{
|
||||
// assert( fComplL == fComplR );
|
||||
// if ( fComplL != fComplR )
|
||||
// printf( "Fra_ImpCheckForNode(): Unexpected situation!\n" );
|
||||
if ( fComplL != fComplR )
|
||||
Vec_IntWriteEntry( vImps, i, 0 );
|
||||
continue;
|
||||
|
|
@ -507,6 +529,7 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
|
|||
// make sure the implication is refined
|
||||
if ( Fra_NodesAreImp( p, Aig_Regular(pLeftF), Aig_Regular(pRightF), fComplL, fComplR ) == 0 )
|
||||
{
|
||||
p->pCla->fRefinement = 1;
|
||||
Fra_SmlResimulate( p );
|
||||
if ( Vec_IntEntry(vImps, i) != 0 )
|
||||
printf( "Fra_ImpCheckForNode(): Implication is not refined!\n" );
|
||||
|
|
@ -536,8 +559,8 @@ int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps )
|
|||
if ( Imp == 0 )
|
||||
continue;
|
||||
// get the corresponding nodes
|
||||
pLeft = Aig_ManObj( p->pManAig, Sml_ImpLeft(Imp) );
|
||||
pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) );
|
||||
pLeft = Aig_ManObj( p->pManAig, Fra_ImpLeft(Imp) );
|
||||
pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) );
|
||||
// check if implication holds using this simulation info
|
||||
if ( !Sml_NodeCheckImp(p->pSml, pLeft->Id, pRight->Id) )
|
||||
{
|
||||
|
|
@ -569,6 +592,113 @@ void Fra_ImpCompactArray( Vec_Int_t * vImps )
|
|||
Vec_IntShrink( vImps, k );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Determines the ratio of the state space by computed implications.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
double Fra_ImpComputeStateSpaceRatio( Fra_Man_t * p )
|
||||
{
|
||||
int nSimWords = 64;
|
||||
Fra_Sml_t * pComb;
|
||||
unsigned * pResult;
|
||||
double Ratio = 0.0;
|
||||
int Left, Right, Imp, i;
|
||||
if ( p->pCla->vImps == NULL || Vec_IntSize(p->pCla->vImps) == 0 )
|
||||
return Ratio;
|
||||
// simulate the AIG manager with combinational patterns
|
||||
pComb = Fra_SmlSimulateComb( p->pManAig, nSimWords );
|
||||
// go through the implications and collect where they do not hold
|
||||
pResult = Fra_ObjSim( pComb, 0 );
|
||||
assert( pResult[0] == 0 );
|
||||
Vec_IntForEachEntry( p->pCla->vImps, Imp, i )
|
||||
{
|
||||
Left = Fra_ImpLeft(Imp);
|
||||
Right = Fra_ImpRight(Imp);
|
||||
Sml_NodeSaveNotImpPatterns( pComb, Left, Right, pResult );
|
||||
}
|
||||
// count the number of ones in this area
|
||||
Ratio = 100.0 * Fra_SmlCountOnesOne( pComb, 0 ) / (32*(pComb->nWordsTotal-pComb->nWordsPref));
|
||||
Fra_SmlStop( pComb );
|
||||
return Ratio;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of failed implications.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fra_ImpVerifyUsingSimulation( Fra_Man_t * p )
|
||||
{
|
||||
int nSimWords = 2000;
|
||||
Fra_Sml_t * pSeq;
|
||||
char * pfFails;
|
||||
int Left, Right, Imp, i, Counter;
|
||||
if ( p->pCla->vImps == NULL || Vec_IntSize(p->pCla->vImps) == 0 )
|
||||
return 0;
|
||||
// simulate the AIG manager with combinational patterns
|
||||
pSeq = Fra_SmlSimulateSeq( p->pManAig, p->pPars->nFramesP, nSimWords, 4 );
|
||||
// go through the implications and check how many of them do not hold
|
||||
pfFails = ALLOC( char, Vec_IntSize(p->pCla->vImps) );
|
||||
memset( pfFails, 0, sizeof(char) * Vec_IntSize(p->pCla->vImps) );
|
||||
Vec_IntForEachEntry( p->pCla->vImps, Imp, i )
|
||||
{
|
||||
Left = Fra_ImpLeft(Imp);
|
||||
Right = Fra_ImpRight(Imp);
|
||||
pfFails[i] = !Sml_NodeCheckImp( pSeq, Left, Right );
|
||||
}
|
||||
// count how many has failed
|
||||
Counter = 0;
|
||||
for ( i = 0; i < Vec_IntSize(p->pCla->vImps); i++ )
|
||||
Counter += pfFails[i];
|
||||
free( pfFails );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Record proven implications in the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew )
|
||||
{
|
||||
Aig_Obj_t * pLeft, * pRight, * pMiter;
|
||||
int nPosOld, Imp, i;
|
||||
if ( p->pCla->vImps == NULL || Vec_IntSize(p->pCla->vImps) == 0 )
|
||||
return;
|
||||
// go through the implication
|
||||
nPosOld = Aig_ManPoNum(pNew);
|
||||
Vec_IntForEachEntry( p->pCla->vImps, Imp, i )
|
||||
{
|
||||
pLeft = Aig_ManObj( p->pManAig, Fra_ImpLeft(Imp) );
|
||||
pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) );
|
||||
// record the implication: L' + R
|
||||
pMiter = Aig_Or( pNew,
|
||||
Aig_NotCond(pLeft->pData, !pLeft->fPhase),
|
||||
Aig_NotCond(pRight->pData, pRight->fPhase) );
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
pNew->nAsserts = Aig_ManPoNum(pNew) - nPosOld;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -175,6 +175,61 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p )
|
|||
return pManFraig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the inductive case with speculative reduction.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_FramesAddMore( Aig_Man_t * p, int nFrames )
|
||||
{
|
||||
Aig_Obj_t * pObj, ** pLatches;
|
||||
int i, k, f, nNodesOld;
|
||||
// set copy pointer of each object to point to itself
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
pObj->pData = pObj;
|
||||
// iterate and add objects
|
||||
nNodesOld = Aig_ManObjIdMax(p);
|
||||
pLatches = ALLOC( Aig_Obj_t *, Aig_ManRegNum(p) );
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
{
|
||||
// clean latch inputs and outputs
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
Aig_ManForEachLoSeq( p, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
// save the latch input values
|
||||
k = 0;
|
||||
Aig_ManForEachLiSeq( p, pObj, i )
|
||||
{
|
||||
if ( Aig_ObjFanin0(pObj)->pData )
|
||||
pLatches[k++] = Aig_ObjChild0Copy(pObj);
|
||||
else
|
||||
pLatches[k++] = NULL;
|
||||
}
|
||||
// insert them as the latch output values
|
||||
k = 0;
|
||||
Aig_ManForEachLoSeq( p, pObj, i )
|
||||
pObj->pData = pLatches[k++];
|
||||
// create the next time frame of nodes
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
if ( i > nNodesOld )
|
||||
break;
|
||||
if ( Aig_ObjFanin0(pObj)->pData && Aig_ObjFanin1(pObj)->pData )
|
||||
pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
else
|
||||
pObj->pData = NULL;
|
||||
}
|
||||
}
|
||||
free( pLatches );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs choicing of the AIG.]
|
||||
|
|
@ -186,7 +241,7 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose, int * pnIter )
|
||||
Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose, int * pnIter )
|
||||
{
|
||||
int fUseSimpleCnf = 0;
|
||||
int fUseOldSimulation = 0;
|
||||
|
|
@ -201,8 +256,9 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK,
|
|||
Aig_Obj_t * pObj;
|
||||
Cnf_Dat_t * pCnf;
|
||||
Aig_Man_t * pManAigNew;
|
||||
// Vec_Int_t * vImps;
|
||||
int nNodesBeg, nRegsBeg, Temp;
|
||||
int nIter, i, clk = clock(), clk2;
|
||||
|
||||
if ( Aig_ManNodeNum(pManAig) == 0 )
|
||||
{
|
||||
if ( pnIter ) *pnIter = 0;
|
||||
|
|
@ -212,6 +268,12 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK,
|
|||
assert( Aig_ManRegNum(pManAig) > 0 );
|
||||
assert( nFramesK > 0 );
|
||||
//Aig_ManShow( pManAig, 0, NULL );
|
||||
|
||||
nNodesBeg = Aig_ManNodeNum(pManAig);
|
||||
nRegsBeg = Aig_ManRegNum(pManAig);
|
||||
|
||||
// enhance the AIG by adding timeframes
|
||||
// Fra_FramesAddMore( pManAig, 3 );
|
||||
|
||||
// get parameters
|
||||
Fra_ParamsDefaultSeq( pPars );
|
||||
|
|
@ -222,6 +284,7 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK,
|
|||
pPars->fRewrite = fRewrite;
|
||||
pPars->fLatchCorr = fLatchCorr;
|
||||
pPars->fUseImps = fUseImps;
|
||||
pPars->fWriteImps = fWriteImps;
|
||||
|
||||
// start the fraig manager for this run
|
||||
p = Fra_ManStart( pManAig, pPars );
|
||||
|
|
@ -255,19 +318,19 @@ PRT( "Time", clock() - clk );
|
|||
p->pSml = Fra_SmlStart( pManAig, 0, pPars->nFramesK + 1, pPars->nSimWords );
|
||||
}
|
||||
|
||||
// perform BMC (for the min number of frames)
|
||||
Fra_BmcPerform( p, pPars->nFramesP, pPars->nFramesK );
|
||||
//Fra_ClassesPrint( p->pCla, 1 );
|
||||
// p->vCex = Vec_IntAlloc( 1000 );
|
||||
|
||||
// select the most expressive implications
|
||||
if ( pPars->fUseImps )
|
||||
p->pCla->vImps = Fra_ImpDerive( p, 5000000, pPars->nMaxImps, pPars->fLatchCorr );
|
||||
|
||||
p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 );
|
||||
|
||||
// perform BMC (for the min number of frames)
|
||||
Fra_BmcPerform( p, pPars->nFramesP, pPars->nFramesK+1 ); // +1 is needed to prevent non-refinement
|
||||
//Fra_ClassesPrint( p->pCla, 1 );
|
||||
// if ( p->vCex == NULL )
|
||||
// p->vCex = Vec_IntAlloc( 1000 );
|
||||
|
||||
p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
|
||||
p->nNodesBeg = Aig_ManNodeNum(pManAig);
|
||||
p->nRegsBeg = Aig_ManRegNum(pManAig);
|
||||
p->nNodesBeg = nNodesBeg; // Aig_ManNodeNum(pManAig);
|
||||
p->nRegsBeg = nRegsBeg; // Aig_ManRegNum(pManAig);
|
||||
|
||||
// dump AIG of the timeframes
|
||||
// pManAigNew = Fra_ClassesDeriveAig( p->pCla, pPars->nFramesK );
|
||||
|
|
@ -279,6 +342,8 @@ PRT( "Time", clock() - clk );
|
|||
p->pCla->fRefinement = 1;
|
||||
for ( nIter = 0; p->pCla->fRefinement; nIter++ )
|
||||
{
|
||||
int nLitsOld = Fra_ClassesCountLits(p->pCla);
|
||||
int nImpsOld = p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0;
|
||||
// mark the classes as non-refined
|
||||
p->pCla->fRefinement = 0;
|
||||
// derive non-init K-timeframes while implementing e-classes
|
||||
|
|
@ -325,13 +390,13 @@ PRT( "Time", clock() - clk );
|
|||
// report the intermediate results
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "%3d : Const = %6d. Class = %6d. L = %6d. LR = %6d. %s = %6d. NR = %6d.\n",
|
||||
printf( "%3d : Const = %6d. Class = %6d. L = %6d. LR = %6d. ",
|
||||
nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses),
|
||||
Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts,
|
||||
p->pCla->vImps? "I" : "N",
|
||||
p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : Aig_ManNodeNum(p->pManAig),
|
||||
Aig_ManNodeNum(p->pManFraig) );
|
||||
}
|
||||
Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts );
|
||||
if ( p->pCla->vImps )
|
||||
printf( "I = %6d. ", Vec_IntSize(p->pCla->vImps) );
|
||||
printf( "NR = %6d.\n", Aig_ManNodeNum(p->pManFraig) );
|
||||
}
|
||||
|
||||
// perform sweeping
|
||||
p->nSatCallsRecent = 0;
|
||||
|
|
@ -341,18 +406,40 @@ PRT( "Time", clock() - clk );
|
|||
assert( p->vTimeouts == NULL );
|
||||
if ( p->vTimeouts )
|
||||
printf( "Fra_FraigInduction(): SAT solver timed out!\n" );
|
||||
|
||||
// cleanup
|
||||
Fra_ManClean( p );
|
||||
// if ( nIter == 3 )
|
||||
// break;
|
||||
// check if refinement has happened
|
||||
// p->pCla->fRefinement = (int)(nLitsOld != Fra_ClassesCountLits(p->pCla));
|
||||
if ( p->pCla->fRefinement &&
|
||||
nLitsOld == Fra_ClassesCountLits(p->pCla) &&
|
||||
nImpsOld == (p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0) )
|
||||
{
|
||||
printf( "Fra_FraigInduction(): Internal error. The result may not verify.\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Fra_ClassesPrint( p->pCla, 1 );
|
||||
// Fra_ClassesSelectRepr( p->pCla );
|
||||
// check implications using simulation
|
||||
if ( p->pCla->vImps && Vec_IntSize(p->pCla->vImps) )
|
||||
{
|
||||
int clk = clock();
|
||||
if ( Temp = Fra_ImpVerifyUsingSimulation( p ) )
|
||||
printf( "Implications failing the simulation test = %d (out of %d). ", Temp, Vec_IntSize(p->pCla->vImps) );
|
||||
else
|
||||
printf( "All %d implications have passed the simulation test. ", Vec_IntSize(p->pCla->vImps) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
|
||||
// move the classes into representatives and reduce AIG
|
||||
clk2 = clock();
|
||||
// Fra_ClassesPrint( p->pCla, 1 );
|
||||
Fra_ClassesSelectRepr( p->pCla );
|
||||
Fra_ClassesCopyReprs( p->pCla, p->vTimeouts );
|
||||
pManAigNew = Aig_ManDupRepr( pManAig );
|
||||
// add implications to the manager
|
||||
if ( fWriteImps && p->pCla->vImps && Vec_IntSize(p->pCla->vImps) )
|
||||
Fra_ImpRecordInManager( p, pManAigNew );
|
||||
// cleanup the new manager
|
||||
Aig_ManSeqCleanup( pManAigNew );
|
||||
// Aig_ManCountMergeRegs( pManAigNew );
|
||||
p->timeTrav += clock() - clk2;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,644 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fraLcorr.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [New FRAIG package.]
|
||||
|
||||
Synopsis [Latch correspondence computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 30, 2007.]
|
||||
|
||||
Revision [$Id: fraLcorr.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Fra_Lcr_t_ Fra_Lcr_t;
|
||||
struct Fra_Lcr_t_
|
||||
{
|
||||
// original AIG
|
||||
Aig_Man_t * pAig;
|
||||
// equivalence class representation
|
||||
Fra_Cla_t * pCla;
|
||||
// partitioning information
|
||||
Vec_Ptr_t * vParts; // output partitions
|
||||
int * pInToOutPart; // mapping of PI num into PO partition num
|
||||
int * pInToOutNum; // mapping of PI num into the num of this PO in the partition
|
||||
// AIGs for the partitions
|
||||
Vec_Ptr_t * vFraigs;
|
||||
// other variables
|
||||
int fRefining;
|
||||
// parameters
|
||||
int nFramesP;
|
||||
int fVerbose;
|
||||
// statistics
|
||||
int nIters;
|
||||
int nLitsBeg;
|
||||
int nLitsEnd;
|
||||
int nNodesBeg;
|
||||
int nNodesEnd;
|
||||
int nRegsBeg;
|
||||
int nRegsEnd;
|
||||
// runtime
|
||||
int timeSim;
|
||||
int timePart;
|
||||
int timeTrav;
|
||||
int timeFraig;
|
||||
int timeUpdate;
|
||||
int timeTotal;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates the retiming manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fra_Lcr_t * Lcr_ManAlloc( Aig_Man_t * pAig )
|
||||
{
|
||||
Fra_Lcr_t * p;
|
||||
p = ALLOC( Fra_Lcr_t, 1 );
|
||||
memset( p, 0, sizeof(Fra_Lcr_t) );
|
||||
p->pAig = pAig;
|
||||
p->pInToOutPart = ALLOC( int, Aig_ManPiNum(pAig) );
|
||||
memset( p->pInToOutPart, 0, sizeof(int) * Aig_ManPiNum(pAig) );
|
||||
p->pInToOutNum = ALLOC( int, Aig_ManPiNum(pAig) );
|
||||
memset( p->pInToOutNum, 0, sizeof(int) * Aig_ManPiNum(pAig) );
|
||||
p->vFraigs = Vec_PtrAlloc( 1000 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints stats for the fraiging manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Lcr_ManPrint( Fra_Lcr_t * p )
|
||||
{
|
||||
printf( "Iterations = %d. LitBeg = %d. LitEnd = %d. (%6.2f %%).\n",
|
||||
p->nIters, p->nLitsBeg, p->nLitsEnd, 100.0*p->nLitsEnd/p->nLitsBeg );
|
||||
printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
|
||||
p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg,
|
||||
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/p->nRegsBeg );
|
||||
PRT( "AIG simulation ", p->timeSim );
|
||||
PRT( "AIG partitioning", p->timePart );
|
||||
PRT( "AIG rebuiding ", p->timeTrav );
|
||||
PRT( "FRAIGing ", p->timeFraig );
|
||||
PRT( "AIG updating ", p->timeUpdate );
|
||||
PRT( "TOTAL RUNTIME ", p->timeTotal );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the retiming manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Lcr_ManFree( Fra_Lcr_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
if ( p->fVerbose )
|
||||
Lcr_ManPrint( p );
|
||||
Aig_ManForEachPi( p->pAig, pObj, i )
|
||||
pObj->pNext = NULL;
|
||||
Vec_PtrFree( p->vFraigs );
|
||||
if ( p->pCla ) Fra_ClassesStop( p->pCla );
|
||||
if ( p->vParts ) Vec_VecFree( (Vec_Vec_t *)p->vParts );
|
||||
free( p->pInToOutPart );
|
||||
free( p->pInToOutNum );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepare the AIG for class computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fra_Man_t * Fra_LcrAigPrepare( Aig_Man_t * pAig )
|
||||
{
|
||||
Fra_Man_t * p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
p = ALLOC( Fra_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Fra_Man_t) );
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
pObj->pData = p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepare the AIG for class computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_LcrAigPrepareTwo( Aig_Man_t * pAig, Fra_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
pObj->pData = p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares two nodes for equivalence after partitioned fraiging.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fra_LcrNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
|
||||
{
|
||||
Fra_Man_t * pTemp = pObj0->pData;
|
||||
Fra_Lcr_t * pLcr = (Fra_Lcr_t *)pTemp->pBmc;
|
||||
Aig_Man_t * pFraig;
|
||||
Aig_Obj_t * pOut0, * pOut1;
|
||||
int nPart0, nPart1;
|
||||
assert( Aig_ObjIsPi(pObj0) );
|
||||
assert( Aig_ObjIsPi(pObj1) );
|
||||
// find the partition to which these nodes belong
|
||||
nPart0 = pLcr->pInToOutPart[(int)pObj0->pNext];
|
||||
nPart1 = pLcr->pInToOutPart[(int)pObj1->pNext];
|
||||
// if this is the result of refinement of the class created const-1 nodes
|
||||
// the nodes may end up in different partions - we assume them equivalent
|
||||
if ( nPart0 != nPart1 )
|
||||
{
|
||||
assert( 0 );
|
||||
return 1;
|
||||
}
|
||||
assert( nPart0 == nPart1 );
|
||||
pFraig = Vec_PtrEntry( pLcr->vFraigs, nPart0 );
|
||||
// get the fraig outputs
|
||||
pOut0 = Aig_ManPo( pFraig, pLcr->pInToOutNum[(int)pObj0->pNext] );
|
||||
pOut1 = Aig_ManPo( pFraig, pLcr->pInToOutNum[(int)pObj1->pNext] );
|
||||
return Aig_ObjFanin0(pOut0) == Aig_ObjFanin0(pOut1);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the node with a constant after partioned fraiging.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fra_LcrNodeIsConst( Aig_Obj_t * pObj )
|
||||
{
|
||||
Fra_Man_t * pTemp = pObj->pData;
|
||||
Fra_Lcr_t * pLcr = (Fra_Lcr_t *)pTemp->pBmc;
|
||||
Aig_Man_t * pFraig;
|
||||
Aig_Obj_t * pOut;
|
||||
int nPart;
|
||||
assert( Aig_ObjIsPi(pObj) );
|
||||
// find the partition to which these nodes belong
|
||||
nPart = pLcr->pInToOutPart[(int)pObj->pNext];
|
||||
pFraig = Vec_PtrEntry( pLcr->vFraigs, nPart );
|
||||
// get the fraig outputs
|
||||
pOut = Aig_ManPo( pFraig, pLcr->pInToOutNum[(int)pObj->pNext] );
|
||||
return Aig_ObjFanin0(pOut) == Aig_ManConst1(pFraig);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Give the AIG and classes, reduces AIG for partitioning.]
|
||||
|
||||
Description [Ignores registers that are not in the classes.
|
||||
Places candidate equivalent classes of registers into single outputs
|
||||
(for ease of partitioning). The resulting combinational AIG contains
|
||||
outputs in the same order as equivalence classes of registers,
|
||||
followed by constant-1 registers. Preserves the set of all inputs.
|
||||
Complemented attributes of the outputs do not matter because we need
|
||||
then only for collecting the structural info.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Fra_LcrDeriveAigForPartitioning( Fra_Lcr_t * pLcr )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjPo, * pObjNew, ** ppClass, * pMiter;
|
||||
int i, c, Offset;
|
||||
// remember the numbers of the inputs of the original AIG
|
||||
Aig_ManForEachPi( pLcr->pAig, pObj, i )
|
||||
{
|
||||
pObj->pData = pLcr;
|
||||
pObj->pNext = (Aig_Obj_t *)i;
|
||||
}
|
||||
// compute the LO/LI offset
|
||||
Offset = Aig_ManPoNum(pLcr->pAig) - Aig_ManPiNum(pLcr->pAig);
|
||||
// create the PIs
|
||||
Aig_ManCleanData( pLcr->pAig );
|
||||
pNew = Aig_ManStartFrom( pLcr->pAig );
|
||||
// go over the equivalence classes
|
||||
Vec_PtrForEachEntry( pLcr->pCla->vClasses, ppClass, i )
|
||||
{
|
||||
pMiter = Aig_ManConst0(pNew);
|
||||
for ( c = 0; ppClass[c]; c++ )
|
||||
{
|
||||
assert( Aig_ObjIsPi(ppClass[c]) );
|
||||
pObjPo = Aig_ManPo( pLcr->pAig, Offset+(int)ppClass[c]->pNext );
|
||||
pObjNew = Aig_ManDup_rec( pNew, pLcr->pAig, Aig_ObjFanin0(pObjPo) );
|
||||
pMiter = Aig_Exor( pNew, pMiter, pObjNew );
|
||||
}
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
// go over the constant candidates
|
||||
Vec_PtrForEachEntry( pLcr->pCla->vClasses1, pObj, i )
|
||||
{
|
||||
assert( Aig_ObjIsPi(pObj) );
|
||||
pObjPo = Aig_ManPo( pLcr->pAig, Offset+(int)pObj->pNext );
|
||||
pMiter = Aig_ManDup_rec( pNew, pLcr->pAig, Aig_ObjFanin0(pObjPo) );
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Remaps partitions into the inputs of original AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_LcrRemapPartitions( Vec_Ptr_t * vParts, Fra_Cla_t * pCla, int * pInToOutPart, int * pInToOutNum )
|
||||
{
|
||||
Vec_Int_t * vOne, * vOneNew;
|
||||
Aig_Obj_t ** ppClass, * pObjPi;
|
||||
int Out, Offset, i, k, c;
|
||||
// compute the LO/LI offset
|
||||
Offset = Aig_ManPoNum(pCla->pAig) - Aig_ManPiNum(pCla->pAig);
|
||||
Vec_PtrForEachEntry( vParts, vOne, i )
|
||||
{
|
||||
vOneNew = Vec_IntAlloc( Vec_IntSize(vOne) );
|
||||
Vec_IntForEachEntry( vOne, Out, k )
|
||||
{
|
||||
if ( Out < Vec_PtrSize(pCla->vClasses) )
|
||||
{
|
||||
ppClass = Vec_PtrEntry( pCla->vClasses, Out );
|
||||
for ( c = 0; ppClass[c]; c++ )
|
||||
{
|
||||
pInToOutPart[(int)ppClass[c]->pNext] = i;
|
||||
pInToOutNum[(int)ppClass[c]->pNext] = Vec_IntSize(vOneNew);
|
||||
Vec_IntPush( vOneNew, Offset+(int)ppClass[c]->pNext );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pObjPi = Vec_PtrEntry( pCla->vClasses1, Out - Vec_PtrSize(pCla->vClasses) );
|
||||
pInToOutPart[(int)pObjPi->pNext] = i;
|
||||
pInToOutNum[(int)pObjPi->pNext] = Vec_IntSize(vOneNew);
|
||||
Vec_IntPush( vOneNew, Offset+(int)pObjPi->pNext );
|
||||
}
|
||||
}
|
||||
// replace the class
|
||||
Vec_PtrWriteEntry( vParts, i, vOneNew );
|
||||
Vec_IntFree( vOne );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates AIG of one partition with speculative reduction.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Fra_LcrCreatePart_rec( Fra_Cla_t * pCla, Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
return pObj->pData;
|
||||
Aig_ObjSetTravIdCurrent(p, pObj);
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
{
|
||||
// Aig_Obj_t * pRepr = Fra_ClassObjRepr(pObj);
|
||||
Aig_Obj_t * pRepr = pCla->pMemRepr[pObj->Id];
|
||||
if ( pRepr == NULL )
|
||||
pObj->pData = Aig_ObjCreatePi( pNew );
|
||||
else
|
||||
{
|
||||
pObj->pData = Fra_LcrCreatePart_rec( pCla, pNew, p, pRepr );
|
||||
pObj->pData = Aig_NotCond( pObj->pData, pRepr->fPhase ^ pObj->fPhase );
|
||||
}
|
||||
return pObj->pData;
|
||||
}
|
||||
Fra_LcrCreatePart_rec( pCla, pNew, p, Aig_ObjFanin0(pObj) );
|
||||
Fra_LcrCreatePart_rec( pCla, pNew, p, Aig_ObjFanin1(pObj) );
|
||||
return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates AIG of one partition with speculative reduction.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Fra_LcrCreatePart( Fra_Lcr_t * p, Vec_Int_t * vPart )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjNew;
|
||||
int Out, i;
|
||||
// create new AIG for this partition
|
||||
pNew = Aig_ManStartFrom( p->pAig );
|
||||
Aig_ManIncrementTravId( p->pAig );
|
||||
Aig_ObjSetTravIdCurrent( p->pAig, Aig_ManConst1(p->pAig) );
|
||||
Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew);
|
||||
Vec_IntForEachEntry( vPart, Out, i )
|
||||
{
|
||||
pObj = Aig_ManPo( p->pAig, Out );
|
||||
if ( pObj->fMarkA )
|
||||
{
|
||||
pObjNew = Fra_LcrCreatePart_rec( p->pCla, pNew, p->pAig, Aig_ObjFanin0(pObj) );
|
||||
pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) );
|
||||
}
|
||||
else
|
||||
pObjNew = Aig_ManConst1( pNew );
|
||||
Aig_ObjCreatePo( pNew, pObjNew );
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks the nodes belonging to the equivalence classes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_ClassNodesMark( Fra_Lcr_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, ** ppClass;
|
||||
int i, c, Offset;
|
||||
// compute the LO/LI offset
|
||||
Offset = Aig_ManPoNum(p->pCla->pAig) - Aig_ManPiNum(p->pCla->pAig);
|
||||
// mark the nodes remaining in the classes
|
||||
Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i )
|
||||
{
|
||||
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)pObj->pNext );
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i )
|
||||
{
|
||||
for ( c = 0; ppClass[c]; c++ )
|
||||
{
|
||||
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)ppClass[c]->pNext );
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Unmarks the nodes belonging to the equivalence classes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fra_ClassNodesUnmark( Fra_Lcr_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, ** ppClass;
|
||||
int i, c, Offset;
|
||||
// compute the LO/LI offset
|
||||
Offset = Aig_ManPoNum(p->pCla->pAig) - Aig_ManPiNum(p->pCla->pAig);
|
||||
// mark the nodes remaining in the classes
|
||||
Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i )
|
||||
{
|
||||
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)pObj->pNext );
|
||||
pObj->fMarkA = 0;
|
||||
}
|
||||
Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i )
|
||||
{
|
||||
for ( c = 0; ppClass[c]; c++ )
|
||||
{
|
||||
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)ppClass[c]->pNext );
|
||||
pObj->fMarkA = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs choicing of the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Fra_FraigLatchCorrespondence( Aig_Man_t * pAig, int nFramesP, int nConfMax, int fVerbose, int * pnIter )
|
||||
{
|
||||
int nPartSize = 200;
|
||||
int fReprSelect = 0;
|
||||
|
||||
Fra_Lcr_t * p;
|
||||
Fra_Man_t * pTemp;
|
||||
Aig_Man_t * pAigPart, * pAigNew = NULL;
|
||||
Vec_Int_t * vPart;
|
||||
Aig_Obj_t * pObj = Aig_ManObj(pAig, 2078);
|
||||
int i, nIter, clk = clock(), clk2, clk3;
|
||||
if ( Aig_ManNodeNum(pAig) == 0 )
|
||||
{
|
||||
if ( pnIter ) *pnIter = 0;
|
||||
return Aig_ManDup(pAig, 1);
|
||||
}
|
||||
assert( Aig_ManLatchNum(pAig) == 0 );
|
||||
assert( Aig_ManRegNum(pAig) > 0 );
|
||||
|
||||
// start the manager
|
||||
p = Lcr_ManAlloc( pAig );
|
||||
p->nFramesP = nFramesP;
|
||||
p->fVerbose = fVerbose;
|
||||
|
||||
// simulate the AIG
|
||||
clk2 = clock();
|
||||
if ( fVerbose )
|
||||
printf( "Simulating AIG with %d nodes for %d cycles ... ", Aig_ManNodeNum(pAig), nFramesP + 32 );
|
||||
pTemp = Fra_LcrAigPrepare( p->pAig );
|
||||
pTemp->pBmc = (Fra_Bmc_t *)p;
|
||||
pTemp->pSml = Fra_SmlSimulateSeq( p->pAig, p->nFramesP, 32, 1 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
PRT( "Time", clock() - clk2 );
|
||||
p->timeSim += clock() - clk2;
|
||||
}
|
||||
// get preliminary info about equivalence classes
|
||||
pTemp->pCla = p->pCla = Fra_ClassesStart( p->pAig );
|
||||
Fra_ClassesPrepare( p->pCla, 1 );
|
||||
p->pCla->pFuncNodeIsConst = Fra_LcrNodeIsConst;
|
||||
p->pCla->pFuncNodesAreEqual = Fra_LcrNodesAreEqual;
|
||||
Fra_SmlStop( pTemp->pSml );
|
||||
|
||||
// partition the AIG for latch correspondence computation
|
||||
clk2 = clock();
|
||||
if ( fVerbose )
|
||||
printf( "Partitioning AIG ... " );
|
||||
pAigPart = Fra_LcrDeriveAigForPartitioning( p );
|
||||
p->vParts = (Vec_Ptr_t *)Aig_ManPartitionSmart( pAigPart, nPartSize, 0, NULL );
|
||||
Fra_LcrRemapPartitions( p->vParts, p->pCla, p->pInToOutPart, p->pInToOutNum );
|
||||
Aig_ManStop( pAigPart );
|
||||
if ( fVerbose )
|
||||
{
|
||||
PRT( "Time", clock() - clk2 );
|
||||
p->timePart += clock() - clk2;
|
||||
}
|
||||
|
||||
// get the initial stats
|
||||
p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
|
||||
p->nNodesBeg = Aig_ManNodeNum(p->pAig);
|
||||
p->nRegsBeg = Aig_ManRegNum(p->pAig);
|
||||
|
||||
// perforn interative reduction of the partitions
|
||||
p->fRefining = 1;
|
||||
for ( nIter = 0; p->fRefining; nIter++ )
|
||||
{
|
||||
p->fRefining = 0;
|
||||
clk3 = clock();
|
||||
// derive AIGs for each partition
|
||||
Fra_ClassNodesMark( p );
|
||||
Vec_PtrClear( p->vFraigs );
|
||||
Vec_PtrForEachEntry( p->vParts, vPart, i )
|
||||
{
|
||||
clk2 = clock();
|
||||
pAigPart = Fra_LcrCreatePart( p, vPart );
|
||||
p->timeTrav += clock() - clk2;
|
||||
clk2 = clock();
|
||||
pAigNew = Fra_FraigEquivence( pAigPart, nConfMax );
|
||||
p->timeFraig += clock() - clk2;
|
||||
Vec_PtrPush( p->vFraigs, pAigNew );
|
||||
Aig_ManStop( pAigPart );
|
||||
}
|
||||
Fra_ClassNodesUnmark( p );
|
||||
// report the intermediate results
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "%3d : Const = %6d. Class = %6d. L = %6d. Part = %3d. ",
|
||||
nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses),
|
||||
Fra_ClassesCountLits(p->pCla), Vec_PtrSize(p->vParts) );
|
||||
PRT( "T", clock() - clk3 );
|
||||
}
|
||||
// refine the classes
|
||||
Fra_LcrAigPrepareTwo( p->pAig, pTemp );
|
||||
if ( Fra_ClassesRefine( p->pCla ) )
|
||||
p->fRefining = 1;
|
||||
if ( Fra_ClassesRefine1( p->pCla, 0, NULL ) )
|
||||
p->fRefining = 1;
|
||||
// clean the fraigs
|
||||
Vec_PtrForEachEntry( p->vFraigs, pAigPart, i )
|
||||
Aig_ManStop( pAigPart );
|
||||
|
||||
// repartition if needed
|
||||
if ( 1 )
|
||||
{
|
||||
clk2 = clock();
|
||||
Vec_VecFree( (Vec_Vec_t *)p->vParts );
|
||||
pAigPart = Fra_LcrDeriveAigForPartitioning( p );
|
||||
p->vParts = (Vec_Ptr_t *)Aig_ManPartitionSmart( pAigPart, nPartSize, 0, NULL );
|
||||
Fra_LcrRemapPartitions( p->vParts, p->pCla, p->pInToOutPart, p->pInToOutNum );
|
||||
Aig_ManStop( pAigPart );
|
||||
p->timePart += clock() - clk2;
|
||||
}
|
||||
}
|
||||
free( pTemp );
|
||||
p->nIters = nIter;
|
||||
|
||||
// move the classes into representatives and reduce AIG
|
||||
clk2 = clock();
|
||||
// Fra_ClassesPrint( p->pCla, 1 );
|
||||
if ( fReprSelect )
|
||||
Fra_ClassesSelectRepr( p->pCla );
|
||||
Fra_ClassesCopyReprs( p->pCla, NULL );
|
||||
pAigNew = Aig_ManDupRepr( p->pAig );
|
||||
Aig_ManSeqCleanup( pAigNew );
|
||||
// Aig_ManCountMergeRegs( pAigNew );
|
||||
p->timeUpdate += clock() - clk2;
|
||||
p->timeTotal = clock() - clk;
|
||||
// get the final stats
|
||||
p->nLitsEnd = Fra_ClassesCountLits( p->pCla );
|
||||
p->nNodesEnd = Aig_ManNodeNum(pAigNew);
|
||||
p->nRegsEnd = Aig_ManRegNum(pAigNew);
|
||||
Lcr_ManFree( p );
|
||||
if ( pnIter ) *pnIter = nIter;
|
||||
return pAigNew;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -181,6 +181,8 @@ Aig_Man_t * Fra_ManPrepareComb( Fra_Man_t * p )
|
|||
assert( p->pManFraig == NULL );
|
||||
// start the fraig package
|
||||
pManFraig = Aig_ManStart( Aig_ManObjIdMax(p->pManAig) + 1 );
|
||||
pManFraig->nRegs = p->pManAig->nRegs;
|
||||
pManFraig->nAsserts = p->pManAig->nAsserts;
|
||||
// set the pointers to the available fraig nodes
|
||||
Fra_ObjSetFraig( Aig_ManConst1(p->pManAig), 0, Aig_ManConst1(pManFraig) );
|
||||
Aig_ManForEachPi( p->pManAig, pObj, i )
|
||||
|
|
@ -271,9 +273,9 @@ void Fra_ManPrint( Fra_Man_t * p )
|
|||
{
|
||||
double nMemory = 1.0*Aig_ManObjIdMax(p->pManAig)*(p->pSml->nWordsTotal*sizeof(unsigned)+6*sizeof(void*))/(1<<20);
|
||||
printf( "SimWord = %d. Round = %d. Mem = %0.2f Mb. LitBeg = %d. LitEnd = %d. (%6.2f %%).\n",
|
||||
p->pPars->nSimWords, p->pSml->nSimRounds, nMemory, p->nLitsBeg, p->nLitsEnd, 100.0*p->nLitsEnd/p->nLitsBeg );
|
||||
printf( "Proof = %d. Cex = %d. Fail = %d. FailReal = %d. Zero = %d. C-lim = %d. Vars = %d.\n",
|
||||
p->nSatProof, p->nSatCallsSat, p->nSatFails, p->nSatFailsReal, p->nLitsZero, p->pPars->nBTLimitNode, p->nSatVars );
|
||||
p->pPars->nSimWords, p->pSml->nSimRounds, nMemory, p->nLitsBeg, p->nLitsEnd, 100.0*p->nLitsEnd/(p->nLitsBeg?p->nLitsBeg:1) );
|
||||
printf( "Proof = %d. Cex = %d. Fail = %d. FailReal = %d. C-lim = %d. ImpRatio = %6.2f %%\n",
|
||||
p->nSatProof, p->nSatCallsSat, p->nSatFails, p->nSatFailsReal, p->pPars->nBTLimitNode, Fra_ImpComputeStateSpaceRatio(p) );
|
||||
printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
|
||||
p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg,
|
||||
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/p->nRegsBeg );
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose )
|
||||
int Fra_FraigSec2( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
int nFrames, RetValue, nIter, clk, clkTotal = clock();
|
||||
|
|
@ -48,7 +48,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose
|
|||
{
|
||||
nFrames = nFramesFix;
|
||||
// perform seq sweeping for one frame number
|
||||
pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, fVeryVerbose, &nIter );
|
||||
pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -56,7 +56,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose
|
|||
for ( nFrames = 1; ; nFrames++ )
|
||||
{
|
||||
clk = clock();
|
||||
pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, fVeryVerbose, &nIter );
|
||||
pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter );
|
||||
RetValue = Fra_FraigMiterStatus( pNew );
|
||||
if ( fVerbose )
|
||||
{
|
||||
|
|
@ -89,6 +89,136 @@ PRT( "Time", clock() - clkTotal );
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fRetimeFirst, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
Aig_Man_t * pNew, * pTemp;
|
||||
int nFrames, RetValue, nIter, clk, clkTotal = clock();
|
||||
int fLatchCorr = 0;
|
||||
|
||||
pNew = Aig_ManDup( p, 1 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Original miter: Latches = %5d. Nodes = %6d.\n",
|
||||
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
}
|
||||
//Aig_ManDumpBlif( pNew, "after.blif" );
|
||||
|
||||
// perform sequential cleanup
|
||||
clk = clock();
|
||||
pNew = Aig_ManReduceLaches( pNew, 0 );
|
||||
pNew = Aig_ManConstReduce( pNew, 0 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Sequential cleanup: Latches = %5d. Nodes = %6d. ",
|
||||
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
// perform forward retiming
|
||||
if ( fRetimeFirst )
|
||||
{
|
||||
clk = clock();
|
||||
pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Forward retiming: Latches = %5d. Nodes = %6d. ",
|
||||
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
|
||||
// run latch correspondence
|
||||
clk = clock();
|
||||
pNew = Aig_ManDup( pTemp = pNew, 1 );
|
||||
Aig_ManStop( pTemp );
|
||||
pNew = Fra_FraigLatchCorrespondence( pTemp = pNew, 0, 100000, fVeryVerbose, &nIter );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Latch-corr (I=%3d): Latches = %5d. Nodes = %6d. ",
|
||||
nIter, Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
// perform fraiging
|
||||
clk = clock();
|
||||
pNew = Fra_FraigEquivence( pTemp = pNew, 1000 );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Fraiging: Latches = %5d. Nodes = %6d. ",
|
||||
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
// perform seq sweeping while increasing the number of frames
|
||||
RetValue = Fra_FraigMiterStatus( pNew );
|
||||
if ( RetValue == -1 )
|
||||
for ( nFrames = 1; ; nFrames *= 2 )
|
||||
{
|
||||
clk = clock();
|
||||
pNew = Fra_FraigInduction( pTemp = pNew, 0, nFrames, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter );
|
||||
Aig_ManStop( pTemp );
|
||||
RetValue = Fra_FraigMiterStatus( pNew );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "K-step (K=%2d,I=%3d): Latches = %5d. Nodes = %6d. ",
|
||||
nFrames, nIter, Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
if ( RetValue != -1 )
|
||||
break;
|
||||
// perform rewriting
|
||||
clk = clock();
|
||||
pNew = Aig_ManDup( pTemp = pNew, 1 );
|
||||
Aig_ManStop( pTemp );
|
||||
pNew = Dar_ManRewriteDefault( pTemp = pNew );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Rewriting: Latches = %5d. Nodes = %6d. ",
|
||||
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// perform retiming
|
||||
clk = clock();
|
||||
pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 );
|
||||
Aig_ManStop( pTemp );
|
||||
pNew = Aig_ManDup( pTemp = pNew, 1 );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Forward retiming: Latches = %5d. Nodes = %6d. ",
|
||||
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
// get the miter status
|
||||
RetValue = Fra_FraigMiterStatus( pNew );
|
||||
Aig_ManStop( pNew );
|
||||
|
||||
// report the miter
|
||||
if ( RetValue == 1 )
|
||||
printf( "Networks are equivalent. " );
|
||||
else if ( RetValue == 0 )
|
||||
printf( "Networks are NOT EQUIVALENT. " );
|
||||
else
|
||||
printf( "Networks are UNDECIDED. " );
|
||||
PRT( "Time", clock() - clkTotal );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ void Fra_SmlSavePattern( Fra_Man_t * p )
|
|||
Aig_ManForEachPi( p->pManFraig, pObj, i )
|
||||
if ( p->pSat->model.ptr[Fra_ObjSatNum(pObj)] == l_True )
|
||||
Aig_InfoSetBit( p->pPatWords, i );
|
||||
/*
|
||||
|
||||
if ( p->vCex )
|
||||
{
|
||||
Vec_IntClear( p->vCex );
|
||||
|
|
@ -208,7 +208,6 @@ void Fra_SmlSavePattern( Fra_Man_t * p )
|
|||
for ( i = Aig_ManPiNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); i < Aig_ManPiNum(p->pManFraig); i++ )
|
||||
Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
printf( "Pattern: " );
|
||||
|
|
@ -608,7 +607,7 @@ void Fra_SmlResimulate( Fra_Man_t * p )
|
|||
return;
|
||||
clk = clock();
|
||||
nChanges = Fra_ClassesRefine( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
|
||||
if ( p->pCla->vImps )
|
||||
nChanges += Fra_ImpRefineUsingCex( p, p->pCla->vImps );
|
||||
p->timeRef += clock() - clk;
|
||||
|
|
@ -652,7 +651,7 @@ printf( "Starting classes = %5d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses
|
|||
return;
|
||||
clk = clock();
|
||||
nChanges = Fra_ClassesRefine( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
|
||||
p->timeRef += clock() - clk;
|
||||
if ( fVerbose )
|
||||
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
|
||||
|
|
@ -663,7 +662,7 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(
|
|||
return;
|
||||
clk = clock();
|
||||
nChanges = Fra_ClassesRefine( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
|
||||
p->timeRef += clock() - clk;
|
||||
|
||||
if ( fVerbose )
|
||||
|
|
@ -677,7 +676,7 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(
|
|||
return;
|
||||
clk = clock();
|
||||
nChanges = Fra_ClassesRefine( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla );
|
||||
nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
|
||||
p->timeRef += clock() - clk;
|
||||
if ( fVerbose )
|
||||
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
|
||||
|
|
@ -704,7 +703,6 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(
|
|||
Fra_Sml_t * Fra_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame )
|
||||
{
|
||||
Fra_Sml_t * p;
|
||||
assert( Aig_ManObjIdMax(pAig) + 1 < (1 << 16) );
|
||||
p = (Fra_Sml_t *)malloc( sizeof(Fra_Sml_t) + sizeof(unsigned) * (Aig_ManObjIdMax(pAig) + 1) * (nPref + nFrames) * nWordsFrame );
|
||||
memset( p, 0, sizeof(Fra_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame );
|
||||
p->pAig = pAig;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ SRC += src/aig/fra/fraBmc.c \
|
|||
src/aig/fra/fraCore.c \
|
||||
src/aig/fra/fraImp.c \
|
||||
src/aig/fra/fraInd.c \
|
||||
src/aig/fra/fraLcr.c \
|
||||
src/aig/fra/fraMan.c \
|
||||
src/aig/fra/fraSat.c \
|
||||
src/aig/fra/fraSec.c \
|
||||
|
|
|
|||
|
|
@ -869,6 +869,7 @@ extern void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFree
|
|||
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk );
|
||||
|
|
|
|||
|
|
@ -146,6 +146,33 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
|
|||
return nCubes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the number of cubes of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i, nCubes, nCubePairs = 0;
|
||||
assert( Abc_NtkHasSop(pNtk) );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
assert( pNode->pData );
|
||||
nCubes = Abc_SopGetCubeNum( pNode->pData );
|
||||
nCubePairs += nCubes * (nCubes - 1) / 2;
|
||||
}
|
||||
return nCubePairs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the number of literals in the SOPs of the nodes.]
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandDFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandCSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandDProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -166,6 +167,7 @@ static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandSeqFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandSeqMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandSeqSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandLcorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandSeqCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandCycle ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandXsim ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -326,12 +328,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "zero", Abc_CommandZero, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "lcorr", Abc_CommandLcorr, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "scleanup", Abc_CommandSeqCleanup, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "cycle", Abc_CommandCycle, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "xsim", Abc_CommandXsim, 0 );
|
||||
|
|
@ -339,6 +340,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Verification", "dsec", Abc_CommandDSec, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Verification", "dprove", Abc_CommandDProve, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
|
||||
|
|
@ -2588,22 +2590,34 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
p = ALLOC( Fxu_Data_t, 1 );
|
||||
memset( p, 0, sizeof(Fxu_Data_t) );
|
||||
// set the defaults
|
||||
p->nPairsMax = 30000;
|
||||
p->nNodesExt = 10000;
|
||||
p->fOnlyS = 0;
|
||||
p->fOnlyD = 0;
|
||||
p->fUse0 = 0;
|
||||
p->fUseCompl = 1;
|
||||
p->fVerbose = 0;
|
||||
p->nSingleMax = 20000;
|
||||
p->nPairsMax = 30000;
|
||||
p->nNodesExt = 10000;
|
||||
p->fOnlyS = 0;
|
||||
p->fOnlyD = 0;
|
||||
p->fUse0 = 0;
|
||||
p->fUseCompl = 1;
|
||||
p->fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "LNsdzcvh")) != EOF )
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "SDNsdzcvh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'L':
|
||||
case 'S':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" );
|
||||
fprintf( pErr, "Command line switch \"-S\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
p->nSingleMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( p->nSingleMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'D':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-D\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
p->nPairsMax = atoi(argv[globalUtilOptind]);
|
||||
|
|
@ -2643,7 +2657,7 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
|
|
@ -2673,10 +2687,11 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: fx [-N num] [-L num] [-sdzcvh]\n");
|
||||
fprintf( pErr, "usage: fx [-S num] [-D num] [-N num] [-sdzcvh]\n");
|
||||
fprintf( pErr, "\t performs unate fast extract on the current network\n");
|
||||
fprintf( pErr, "\t-S num : max number of single-cube divisors to consider [default = %d]\n", p->nSingleMax );
|
||||
fprintf( pErr, "\t-D num : max number of double-cube divisors to consider [default = %d]\n", p->nPairsMax );
|
||||
fprintf( pErr, "\t-N num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt );
|
||||
fprintf( pErr, "\t-L num : the maximum number of cube pairs to consider [default = %d]\n", p->nPairsMax );
|
||||
fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" );
|
||||
fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" );
|
||||
fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" );
|
||||
|
|
@ -6175,7 +6190,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nLevels = 128;
|
||||
nLevels = 1000;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
|
||||
{
|
||||
|
|
@ -6293,7 +6308,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
// pNtkRes = Abc_NtkDar( pNtk );
|
||||
pNtkRes = Abc_NtkDarRetime( pNtk, 1000, 1 );
|
||||
pNtkRes = Abc_NtkDarRetime( pNtk, nLevels, 1 );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
|
|
@ -8674,7 +8689,7 @@ int Abc_CommandFraigDress( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fVerbose = 1;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
|
|
@ -10975,12 +10990,12 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int nFramesP;
|
||||
int nFramesK;
|
||||
int nMaxImps;
|
||||
int fExdc;
|
||||
int fUseImps;
|
||||
int fRewrite;
|
||||
int fLatchCorr;
|
||||
int fWriteImps;
|
||||
int fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFrames, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFrames, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -10990,13 +11005,13 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
nFramesP = 0;
|
||||
nFramesK = 1;
|
||||
nMaxImps = 5000;
|
||||
fExdc = 1;
|
||||
fUseImps = 0;
|
||||
fRewrite = 0;
|
||||
fLatchCorr = 0;
|
||||
fWriteImps = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "PFIeirlvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "PFIirlevh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -11033,9 +11048,6 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nMaxImps <= 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'e':
|
||||
fExdc ^= 1;
|
||||
break;
|
||||
case 'i':
|
||||
fUseImps ^= 1;
|
||||
break;
|
||||
|
|
@ -11045,6 +11057,9 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'l':
|
||||
fLatchCorr ^= 1;
|
||||
break;
|
||||
case 'e':
|
||||
fWriteImps ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -11069,12 +11084,12 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Sequential sweep works only for structurally hashed networks (run \"strash\").\n" );
|
||||
return 1;
|
||||
printf( "This command works only for structrally hashed networks. Run \"st\".\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkDarSeqSweep( pNtk, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fVerbose );
|
||||
pNtkRes = Abc_NtkDarSeqSweep( pNtk, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fWriteImps, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Sequential sweeping has failed.\n" );
|
||||
|
|
@ -11085,15 +11100,120 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: ssweep [-P num] [-F num] [-I num] [-ilrvh]\n" );
|
||||
fprintf( pErr, "usage: ssweep [-P num] [-F num] [-I num] [-ilrevh]\n" );
|
||||
fprintf( pErr, "\t performs sequential sweep using K-step induction\n" );
|
||||
fprintf( pErr, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP );
|
||||
fprintf( pErr, "\t-F num : number of time frames for induction (1=simple) [default = %d]\n", nFramesK );
|
||||
fprintf( pErr, "\t-I num : max number of implications to consider [default = %d]\n", nMaxImps );
|
||||
// fprintf( pErr, "\t-e : toggle writing EXDC network [default = %s]\n", fExdc? "yes": "no" );
|
||||
fprintf( pErr, "\t-i : toggle using implications [default = %s]\n", fUseImps? "yes": "no" );
|
||||
fprintf( pErr, "\t-l : toggle latch correspondence only [default = %s]\n", fLatchCorr? "yes": "no" );
|
||||
fprintf( pErr, "\t-r : toggle AIG rewriting [default = %s]\n", fRewrite? "yes": "no" );
|
||||
fprintf( pErr, "\t-e : toggle writing implications as assertions [default = %s]\n", fWriteImps? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c;
|
||||
int nFramesP;
|
||||
int nConfMax;
|
||||
int fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nFramesP = 0;
|
||||
nConfMax = 10000;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "PCvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'P':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nFramesP = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nFramesP < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'C':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nConfMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nConfMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( Abc_NtkIsComb(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
printf( "This command works only for structrally hashed networks. Run \"st\".\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkDarLcorr( pNtk, nFramesP, nConfMax, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Sequential sweeping has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: lcorr [-P num] [-C num] [-vh]\n" );
|
||||
fprintf( pErr, "\t computes latch correspondence using 1-step induction\n" );
|
||||
fprintf( pErr, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP );
|
||||
fprintf( pErr, "\t-C num : max conflict number when proving latch equivalence [default = %d]\n", nConfMax );
|
||||
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -11113,12 +11233,12 @@ usage:
|
|||
int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes, * pTemp;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c;
|
||||
int fLatchSweep;
|
||||
int fAutoSweep;
|
||||
int fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fLatchSweep, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -11153,23 +11273,13 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsLogic(pNtk) )
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for logic networks.\n" );
|
||||
fprintf( pErr, "Only works for structrally hashed networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
// modify the current network
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkDup( pNtk );
|
||||
Abc_NtkCleanupSeq( pNtkRes, 0, fAutoSweep, fVerbose );
|
||||
if ( fLatchSweep )
|
||||
{
|
||||
pNtkRes = Abc_NtkStrash( pTemp = pNtkRes, 0, 0, 0 );
|
||||
Abc_NtkDelete( pTemp );
|
||||
pNtkRes = Abc_NtkDarLatchSweep( pTemp = pNtkRes, fVerbose );
|
||||
Abc_NtkDelete( pTemp );
|
||||
}
|
||||
pNtkRes = Abc_NtkDarLatchSweep( pNtk, fLatchSweep, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Sequential cleanup has failed.\n" );
|
||||
|
|
@ -11180,14 +11290,14 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: scleanup [-lavh]\n" );
|
||||
fprintf( pErr, "usage: scleanup [-lvh]\n" );
|
||||
fprintf( pErr, "\t performs sequential cleanup\n" );
|
||||
fprintf( pErr, "\t - removes nodes/latches that do not feed into POs\n" );
|
||||
fprintf( pErr, "\t - removes stuck-at and identical latches (latch sweep)\n" );
|
||||
fprintf( pErr, "\t - replaces autonomous logic by free PI variables\n" );
|
||||
// fprintf( pErr, "\t - replaces autonomous logic by free PI variables\n" );
|
||||
fprintf( pErr, "\t (the latter may change sequential behaviour)\n" );
|
||||
fprintf( pErr, "\t-l : toggle sweeping latches [default = %s]\n", fLatchSweep? "yes": "no" );
|
||||
fprintf( pErr, "\t-a : toggle removing autonomous logic [default = %s]\n", fAutoSweep? "yes": "no" );
|
||||
// fprintf( pErr, "\t-a : toggle removing autonomous logic [default = %s]\n", fAutoSweep? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -11291,9 +11401,10 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int nFrames;
|
||||
int fInputs;
|
||||
int fXInputs;
|
||||
int fXState;
|
||||
int fVerbose;
|
||||
extern void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose );
|
||||
extern void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fXInputs, int fXState, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -11301,10 +11412,11 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
// set defaults
|
||||
nFrames = 10;
|
||||
fInputs = 0;
|
||||
fXInputs = 0;
|
||||
fXState = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Fivh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Fisvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -11320,7 +11432,10 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
goto usage;
|
||||
break;
|
||||
case 'i':
|
||||
fInputs ^= 1;
|
||||
fXInputs ^= 1;
|
||||
break;
|
||||
case 's':
|
||||
fXState ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
|
|
@ -11343,14 +11458,15 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
Abc_NtkXValueSimulate( pNtk, nFrames, fInputs, fVerbose );
|
||||
Abc_NtkXValueSimulate( pNtk, nFrames, fXInputs, fXState, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: xsim [-F num] [-ivh]\n" );
|
||||
fprintf( pErr, "usage: xsim [-F num] [-isvh]\n" );
|
||||
fprintf( pErr, "\t performs X-valued simulation of the AIG\n" );
|
||||
fprintf( pErr, "\t-F num : the number of frames to simulate [default = %d]\n", nFrames );
|
||||
fprintf( pErr, "\t-i : toggle X-valued state or X-valued inputs [default = %s]\n", fInputs? "inputs": "state" );
|
||||
fprintf( pErr, "\t-i : toggle X-valued representation of inputs [default = %s]\n", fXInputs? "yes": "no" );
|
||||
fprintf( pErr, "\t-s : toggle X-valued representation of state [default = %s]\n", fXState? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -11674,11 +11790,12 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
char ** pArgvNew;
|
||||
int nArgcNew;
|
||||
int c;
|
||||
int fRetimeFirst;
|
||||
int fVerbose;
|
||||
int fVeryVerbose;
|
||||
int nFrames;
|
||||
|
||||
extern int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbose, int fVeryVerbose );
|
||||
extern int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -11686,10 +11803,11 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
// set defaults
|
||||
nFrames = 0; // if 0, iterates through frames
|
||||
fVerbose = 1;
|
||||
fRetimeFirst = 1;
|
||||
fVerbose = 0;
|
||||
fVeryVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Fwvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Frwvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -11704,6 +11822,9 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nFrames <= 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'r':
|
||||
fRetimeFirst ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
fVeryVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -11727,18 +11848,19 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
// perform verification
|
||||
Abc_NtkDarSec( pNtk1, pNtk2, nFrames, fVerbose, fVeryVerbose );
|
||||
Abc_NtkDarSec( pNtk1, pNtk2, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
|
||||
|
||||
if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
|
||||
if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: dsec [-F num] [-wvh] <file1> <file2>\n" );
|
||||
fprintf( pErr, "usage: dsec [-F num] [-rwvh] <file1> <file2>\n" );
|
||||
fprintf( pErr, "\t performs inductive sequential equivalence checking\n" );
|
||||
fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames );
|
||||
fprintf( pErr, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-r : toggles forward retiming at the beginning [default = %s]\n", fRetimeFirst? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
|
||||
fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
|
||||
|
|
@ -11746,6 +11868,95 @@ usage:
|
|||
fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandDProve( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int fRetimeFirst;
|
||||
int fVerbose;
|
||||
int fVeryVerbose;
|
||||
int nFrames;
|
||||
|
||||
extern int Abc_NtkDarProve( Abc_Ntk_t * pNtk, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nFrames = 0; // if 0, iterates through frames
|
||||
fRetimeFirst = 1;
|
||||
fVerbose = 0;
|
||||
fVeryVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Frwvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'F':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nFrames = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nFrames <= 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'r':
|
||||
fRetimeFirst ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Abc_NtkLatchNum(pNtk) == 0 )
|
||||
{
|
||||
printf( "The network has no latches. Used combinational command \"iprove\".\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
printf( "This command works only for structrally hashed networks. Run \"st\".\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// perform verification
|
||||
Abc_NtkDarProve( pNtk, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: dprove [-F num] [-rwvh]\n" );
|
||||
fprintf( pErr, "\t performs SEC on the sequential miter\n" );
|
||||
fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames );
|
||||
fprintf( pErr, "\t-r : toggles forward retiming at the beginning [default = %s]\n", fRetimeFirst? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
|
|||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObjNew;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Aig_ManRegNum(pMan) == Abc_NtkLatchNum(pNtkOld) );
|
||||
|
|
@ -141,7 +142,19 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
|
|||
Vec_PtrFree( vNodes );
|
||||
// connect the PO nodes
|
||||
Aig_ManForEachPo( pMan, pObj, i )
|
||||
{
|
||||
if ( pMan->nAsserts && i == Aig_ManPoNum(pMan) - pMan->nAsserts )
|
||||
break;
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
// if there are assertions, add them
|
||||
if ( pMan->nAsserts > 0 )
|
||||
Aig_ManForEachAssert( pMan, pObj, i )
|
||||
{
|
||||
pObjNew = Abc_NtkCreateAssert(pNtkNew);
|
||||
Abc_ObjAssignName( pObjNew, "assert_", Abc_ObjName(pObjNew) );
|
||||
Abc_ObjAddFanin( pObjNew, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" );
|
||||
return pNtkNew;
|
||||
|
|
@ -194,7 +207,19 @@ Abc_Ntk_t * Abc_NtkFromDarSeqSweep( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
|
|||
Vec_PtrFree( vNodes );
|
||||
// connect the PO nodes
|
||||
Aig_ManForEachPo( pMan, pObj, i )
|
||||
{
|
||||
if ( pMan->nAsserts && i == Aig_ManPoNum(pMan) - pMan->nAsserts )
|
||||
break;
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
// if there are assertions, add them
|
||||
if ( pMan->nAsserts > 0 )
|
||||
Aig_ManForEachAssert( pMan, pObj, i )
|
||||
{
|
||||
pObjNew = Abc_NtkCreateAssert(pNtkNew);
|
||||
Abc_ObjAssignName( pObjNew, "assert_", Abc_ObjName(pObjNew) );
|
||||
Abc_ObjAddFanin( pObjNew, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" );
|
||||
return pNtkNew;
|
||||
|
|
@ -892,7 +917,7 @@ int Abc_NtkDSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVer
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose )
|
||||
{
|
||||
Fraig_Params_t Params;
|
||||
Abc_Ntk_t * pNtkAig, * pNtkFraig;
|
||||
|
|
@ -916,7 +941,7 @@ PRT( "Initial fraiging time", clock() - clk );
|
|||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
|
||||
pMan = Fra_FraigInduction( pTemp = pMan, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fVerbose, NULL );
|
||||
pMan = Fra_FraigInduction( pTemp = pMan, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fWriteImps, fVerbose, NULL );
|
||||
Aig_ManStop( pTemp );
|
||||
|
||||
if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) )
|
||||
|
|
@ -927,6 +952,34 @@ PRT( "Initial fraiging time", clock() - clk );
|
|||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes latch correspondence.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose )
|
||||
{
|
||||
Aig_Man_t * pMan, * pTemp;
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
pMan = Abc_NtkToDar( pNtk, 1 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
pMan = Fra_FraigLatchCorrespondence( pTemp = pMan, nFramesP, nConfMax, fVerbose, NULL );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) )
|
||||
pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan );
|
||||
else
|
||||
pNtkAig = Abc_NtkFromDar( pNtk, pMan );
|
||||
Aig_ManStop( pMan );
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
|
@ -938,11 +991,40 @@ PRT( "Initial fraiging time", clock() - clk );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbose, int fVeryVerbose )
|
||||
int Abc_NtkDarProve( Abc_Ntk_t * pNtk, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
Fraig_Params_t Params;
|
||||
Aig_Man_t * pMan;
|
||||
Abc_Ntk_t * pMiter, * pTemp;
|
||||
int RetValue;
|
||||
// derive the AIG manager
|
||||
pMan = Abc_NtkToDar( pNtk, 1 );
|
||||
if ( pMan == NULL )
|
||||
{
|
||||
printf( "Converting miter into AIG has failed.\n" );
|
||||
return -1;
|
||||
}
|
||||
assert( pMan->nRegs > 0 );
|
||||
// perform verification
|
||||
RetValue = Fra_FraigSec( pMan, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
|
||||
Aig_ManStop( pMan );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
// Fraig_Params_t Params;
|
||||
Aig_Man_t * pMan;
|
||||
Abc_Ntk_t * pMiter;//, * pTemp;
|
||||
int RetValue;
|
||||
|
||||
// get the miter of the two networks
|
||||
|
|
@ -971,6 +1053,8 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
|
|||
return 1;
|
||||
}
|
||||
|
||||
// commented out because something became non-inductive
|
||||
/*
|
||||
// preprocess the miter by fraiging it
|
||||
// (note that for each functional class, fraiging leaves one representative;
|
||||
// so fraiging does not reduce the number of functions represented by nodes
|
||||
|
|
@ -978,7 +1062,25 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
|
|||
Params.nBTLimit = 100000;
|
||||
pMiter = Abc_NtkFraig( pTemp = pMiter, &Params, 0, 0 );
|
||||
Abc_NtkDelete( pTemp );
|
||||
|
||||
RetValue = Abc_NtkMiterIsConstant( pMiter );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
extern void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel, int nFrames );
|
||||
printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
|
||||
// report the error
|
||||
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, nFrames );
|
||||
Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pMiter->pModel, nFrames );
|
||||
FREE( pMiter->pModel );
|
||||
Abc_NtkDelete( pMiter );
|
||||
return 0;
|
||||
}
|
||||
if ( RetValue == 1 )
|
||||
{
|
||||
Abc_NtkDelete( pMiter );
|
||||
printf( "Networks are equivalent after structural hashing.\n" );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
// derive the AIG manager
|
||||
pMan = Abc_NtkToDar( pMiter, 1 );
|
||||
Abc_NtkDelete( pMiter );
|
||||
|
|
@ -990,7 +1092,7 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
|
|||
assert( pMan->nRegs > 0 );
|
||||
|
||||
// perform verification
|
||||
RetValue = Fra_FraigSec( pMan, nFrames, fVerbose, fVeryVerbose );
|
||||
RetValue = Fra_FraigSec( pMan, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
|
||||
Aig_ManStop( pMan );
|
||||
return RetValue;
|
||||
}
|
||||
|
|
@ -1006,15 +1108,19 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fLatchSweep, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Aig_Man_t * pMan;
|
||||
pMan = Abc_NtkToDar( pNtk, 1 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
pMan = Aig_ManReduceLaches( pMan, fVerbose );
|
||||
pMan = Aig_ManConstReduce( pMan, fVerbose );
|
||||
Aig_ManSeqCleanup( pMan );
|
||||
if ( fLatchSweep )
|
||||
{
|
||||
pMan = Aig_ManReduceLaches( pMan, fVerbose );
|
||||
pMan = Aig_ManConstReduce( pMan, fVerbose );
|
||||
}
|
||||
pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan );
|
||||
Aig_ManStop( pMan );
|
||||
return pNtkAig;
|
||||
|
|
@ -1038,6 +1144,8 @@ Abc_Ntk_t * Abc_NtkDarRetime( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose )
|
|||
pMan = Abc_NtkToDar( pNtk, 1 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
// Aig_ManReduceLachesCount( pMan );
|
||||
|
||||
pMan = Rtm_ManRetime( pTemp = pMan, 1, nStepsMax, 0 );
|
||||
Aig_ManStop( pTemp );
|
||||
|
||||
|
|
|
|||
|
|
@ -213,6 +213,9 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n",
|
||||
s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges );
|
||||
*/
|
||||
|
||||
// if ( Abc_NtkHasSop(pNtk) )
|
||||
// printf( "The total number of cube pairs = %d.\n", Abc_NtkGetCubePairNum(pNtk) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
|
|||
// perform strashing
|
||||
nNewCis = 0;
|
||||
Abc_NtkCleanCopy( pNtk2 );
|
||||
Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1);
|
||||
if ( Abc_NtkIsStrash(pNtk2) )
|
||||
Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1);
|
||||
Abc_NtkForEachCi( pNtk2, pObj, i )
|
||||
{
|
||||
pName = Abc_ObjName(pObj);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ static inline void Abc_XsimPrint( FILE * pFile, int Value )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose )
|
||||
void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fXInputs, int fXState, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, f;
|
||||
|
|
@ -111,20 +111,26 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer
|
|||
srand( 0x12341234 );
|
||||
// start simulation
|
||||
Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 );
|
||||
if ( fInputs )
|
||||
if ( fXInputs )
|
||||
{
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, XVSX );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
|
||||
}
|
||||
if ( fXState )
|
||||
{
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), XVSX );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) );
|
||||
}
|
||||
// simulate and print the result
|
||||
fprintf( stdout, "Frame : Inputs : Latches : Outputs\n" );
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
|
|
@ -147,14 +153,24 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer
|
|||
fprintf( stdout, " : " );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
|
||||
if ( Abc_NtkAssertNum(pNtk) )
|
||||
{
|
||||
fprintf( stdout, " : " );
|
||||
Abc_NtkForEachAssert( pNtk, pObj, i )
|
||||
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
|
||||
}
|
||||
fprintf( stdout, "\n" );
|
||||
// assign input values
|
||||
if ( fInputs )
|
||||
if ( fXInputs )
|
||||
{
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, XVSX );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
|
||||
}
|
||||
// transfer the latch values
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) );
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
|
|||
Fxu_Single * pSingle;
|
||||
Fxu_Double * pDouble;
|
||||
int Weight1, Weight2, Weight3;
|
||||
int Counter = 0;
|
||||
|
||||
s_MemoryTotal = 0;
|
||||
s_MemoryPeak = 0;
|
||||
|
|
@ -77,7 +78,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
|
|||
{
|
||||
Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best single = %3d.\n", Weight1 );
|
||||
printf( "Div %5d : Best single = %5d.\r", Counter++, Weight1 );
|
||||
if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 )
|
||||
Fxu_UpdateSingle( p );
|
||||
else
|
||||
|
|
@ -92,7 +93,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
|
|||
{
|
||||
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best double = %3d.\n", Weight2 );
|
||||
printf( "Div %5d : Best double = %5d.\r", Counter++, Weight2 );
|
||||
if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 )
|
||||
Fxu_UpdateDouble( p );
|
||||
else
|
||||
|
|
@ -109,7 +110,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
|
|||
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
|
||||
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best double = %3d. Best single = %3d.\n", Weight2, Weight1 );
|
||||
printf( "Div %5d : Best double = %5d. Best single = %5d.\r", Counter++, Weight2, Weight1 );
|
||||
//Fxu_Select( p, &pSingle, &pDouble );
|
||||
|
||||
if ( Weight1 >= Weight2 )
|
||||
|
|
@ -140,8 +141,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
|
|||
// select the best single and double
|
||||
Weight3 = Fxu_Select( p, &pSingle, &pDouble );
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best double = %3d. Best single = %3d. Best complement = %3d.\n",
|
||||
Weight2, Weight1, Weight3 );
|
||||
printf( "Div %5d : Best double = %5d. Best single = %5d. Best complement = %5d.\r",
|
||||
Counter++, Weight2, Weight1, Weight3 );
|
||||
|
||||
if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 )
|
||||
Fxu_Update( p, pSingle, pDouble );
|
||||
|
|
@ -152,7 +153,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
|
|||
}
|
||||
|
||||
if ( pData->fVerbose )
|
||||
printf( "Total single = %3d. Total double = %3d. Total compl = %3d.\n", p->nDivs1, p->nDivs2, p->nDivs3 );
|
||||
printf( "Total single = %3d. Total double = %3d. Total compl = %3d. \n",
|
||||
p->nDivs1, p->nDivs2, p->nDivs3 );
|
||||
|
||||
// create the new covers
|
||||
if ( pData->nNodesNew )
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ struct FxuDataStruct
|
|||
bool fUseCompl; // set to 1 to have complement taken into account
|
||||
bool fVerbose; // set to 1 to have verbose output
|
||||
int nNodesExt; // the number of divisors to extract
|
||||
int nPairsMax; // the maximum number of cube pairs to consider
|
||||
int nSingleMax; // the max number of single-cube divisors to consider
|
||||
int nPairsMax; // the max number of double-cube divisors to consider
|
||||
// the input information
|
||||
Vec_Ptr_t * vSops; // the SOPs for each node in the network
|
||||
Vec_Ptr_t * vFanins; // the fanins of each node in the network
|
||||
|
|
|
|||
|
|
@ -178,12 +178,26 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
|
|||
|
||||
// consider the case when cube pairs should be preprocessed
|
||||
// before adding them to the set of divisors
|
||||
// if ( pData->fVerbose )
|
||||
// printf( "The total number of cube pairs is %d.\n", nPairsTotal );
|
||||
if ( nPairsTotal > 10000000 )
|
||||
{
|
||||
printf( "The total number of cube pairs of the network is more than 10,000,000.\n" );
|
||||
printf( "Command \"fx\" takes a long time to run in such cases. It is suggested\n" );
|
||||
printf( "that the user changes the network by reducing the size of logic node and\n" );
|
||||
printf( "consequently the number of cube pairs to be processed by this command.\n" );
|
||||
printf( "One way to achieve this is to run the commands \"st; multi -m -F <num>\"\n" );
|
||||
printf( "as a proprocessing step, while selecting <num> as approapriate.\n" );
|
||||
return NULL;
|
||||
}
|
||||
if ( nPairsTotal > pData->nPairsMax )
|
||||
if ( !Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ) )
|
||||
return NULL;
|
||||
// if ( pData->fVerbose )
|
||||
// printf( "Only %d best cube pairs will be used by the fast extract command.\n", pData->nPairsMax );
|
||||
|
||||
// add the var pairs to the heap
|
||||
Fxu_MatrixComputeSingles( p );
|
||||
Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax );
|
||||
|
||||
// print stats
|
||||
if ( pData->fVerbose )
|
||||
|
|
@ -194,9 +208,8 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
|
|||
p->lVars.nItems, p->lCubes.nItems );
|
||||
fprintf( stdout, "Lits = %d Density = %.5f%%\n",
|
||||
p->nEntries, Density );
|
||||
fprintf( stdout, "1-cube divisors = %6d. ", p->lSingles.nItems );
|
||||
fprintf( stdout, "2-cube divisors = %6d. ", p->nDivsTotal );
|
||||
fprintf( stdout, "Cube pairs = %6d.", nPairsTotal );
|
||||
fprintf( stdout, "1-cube divs = %6d. (Total = %6d) ", p->lSingles.nItems, p->nSingleTotal );
|
||||
fprintf( stdout, "2-cube divs = %6d. (Total = %6d)", p->nDivsTotal, nPairsTotal );
|
||||
fprintf( stdout, "\n" );
|
||||
}
|
||||
// Fxu_MatrixPrint( stdout, p );
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ struct FxuMatrix // ~ 30 words
|
|||
// the single cube divisors
|
||||
Fxu_ListSingle lSingles; // the linked list of single cube divisors
|
||||
Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix
|
||||
int nWeightLimit;// the limit on weight of single cube divisors collected
|
||||
int nSingleTotal;// the total number of single cube divisors
|
||||
// storage for cube pairs
|
||||
Fxu_Pair *** pppPairs;
|
||||
Fxu_Pair ** ppPairs;
|
||||
|
|
@ -459,7 +461,7 @@ extern void Fxu_PairClearStorage( Fxu_Cube * pCube );
|
|||
extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 );
|
||||
extern void Fxu_PairAdd( Fxu_Pair * pPair );
|
||||
/*===== fxuSingle.c ====================================================*/
|
||||
extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p );
|
||||
extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax );
|
||||
extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar );
|
||||
extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 );
|
||||
/*===== fxuMatrix.c ====================================================*/
|
||||
|
|
|
|||
|
|
@ -17,11 +17,14 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
#include "vec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -38,12 +41,70 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixComputeSingles( Fxu_Matrix * p )
|
||||
void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
// iterate through the columns in the matrix
|
||||
Vec_Ptr_t * vSingles;
|
||||
int i, k;
|
||||
// set the weight limit
|
||||
p->nWeightLimit = 1 - fUse0;
|
||||
// iterate through columns in the matrix and collect single-cube divisors
|
||||
vSingles = Vec_PtrAlloc( 10000 );
|
||||
Fxu_MatrixForEachVariable( p, pVar )
|
||||
Fxu_MatrixComputeSinglesOne( p, pVar );
|
||||
Fxu_MatrixComputeSinglesOneCollect( p, pVar, vSingles );
|
||||
p->nSingleTotal = Vec_PtrSize(vSingles) / 3;
|
||||
// check if divisors should be filtered
|
||||
if ( Vec_PtrSize(vSingles) > nSingleMax )
|
||||
{
|
||||
int * pWeigtCounts, nDivCount, Weight, i, c;;
|
||||
assert( Vec_PtrSize(vSingles) % 3 == 0 );
|
||||
// count how many divisors have the given weight
|
||||
pWeigtCounts = ALLOC( int, 1000 );
|
||||
memset( pWeigtCounts, 0, sizeof(int) * 1000 );
|
||||
for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 )
|
||||
{
|
||||
Weight = (int)Vec_PtrEntry(vSingles, i);
|
||||
if ( Weight >= 999 )
|
||||
pWeigtCounts[999]++;
|
||||
else
|
||||
pWeigtCounts[Weight]++;
|
||||
}
|
||||
// select the bound on the weight (above this bound, singles will be included)
|
||||
nDivCount = 0;
|
||||
for ( c = 999; c >= 0; c-- )
|
||||
{
|
||||
nDivCount += pWeigtCounts[c];
|
||||
if ( nDivCount >= nSingleMax )
|
||||
break;
|
||||
}
|
||||
free( pWeigtCounts );
|
||||
// collect singles with the given costs
|
||||
k = 0;
|
||||
for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 )
|
||||
{
|
||||
Weight = (int)Vec_PtrEntry(vSingles, i);
|
||||
if ( Weight < c )
|
||||
continue;
|
||||
Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-2) );
|
||||
Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-1) );
|
||||
Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i) );
|
||||
if ( k/3 == nSingleMax )
|
||||
break;
|
||||
}
|
||||
Vec_PtrShrink( vSingles, k );
|
||||
// adjust the weight limit
|
||||
p->nWeightLimit = c;
|
||||
}
|
||||
// collect the selected divisors
|
||||
assert( Vec_PtrSize(vSingles) % 3 == 0 );
|
||||
for ( i = 0; i < Vec_PtrSize(vSingles); i += 3 )
|
||||
{
|
||||
Fxu_MatrixAddSingle( p,
|
||||
Vec_PtrEntry(vSingles,i),
|
||||
Vec_PtrEntry(vSingles,i+1),
|
||||
(int)Vec_PtrEntry(vSingles,i+2) );
|
||||
}
|
||||
Vec_PtrFree( vSingles );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -57,14 +118,11 @@ void Fxu_MatrixComputeSingles( Fxu_Matrix * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
|
||||
void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles )
|
||||
{
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
Fxu_Lit * pLitV, * pLitH;
|
||||
Fxu_Var * pVar2;
|
||||
int Coin;
|
||||
// int CounterAll;
|
||||
// int CounterTest;
|
||||
int WeightCur;
|
||||
|
||||
// start collecting the affected vars
|
||||
|
|
@ -76,7 +134,6 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
|
|||
{
|
||||
// get another variable
|
||||
pVar2 = pLitH->pVar;
|
||||
// CounterAll++;
|
||||
// skip the var if it is already used
|
||||
if ( pVar2->pOrder )
|
||||
continue;
|
||||
|
|
@ -92,20 +149,81 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
|
|||
// iterate through the selected vars
|
||||
Fxu_MatrixForEachVarInRing( p, pVar2 )
|
||||
{
|
||||
// CounterTest++;
|
||||
// count the coincidence
|
||||
Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar );
|
||||
assert( Coin > 0 );
|
||||
// get the new weight
|
||||
WeightCur = Coin - 2;
|
||||
if ( WeightCur >= 0 )
|
||||
Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
|
||||
// peformance fix (August 24, 2007)
|
||||
if ( WeightCur >= p->nWeightLimit )
|
||||
{
|
||||
Vec_PtrPush( vSingles, pVar2 );
|
||||
Vec_PtrPush( vSingles, pVar );
|
||||
Vec_PtrPush( vSingles, (void *)WeightCur );
|
||||
}
|
||||
}
|
||||
|
||||
// unmark the vars
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the single-cube divisors associated with a new column.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
|
||||
{
|
||||
Fxu_Lit * pLitV, * pLitH;
|
||||
Fxu_Var * pVar2;
|
||||
int Coin;
|
||||
int WeightCur;
|
||||
|
||||
// start collecting the affected vars
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
// go through all the literals of this variable
|
||||
for ( pLitV = pVar->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
|
||||
// for this literal, go through all the horizontal literals
|
||||
for ( pLitH = pLitV->pHPrev; pLitH; pLitH = pLitH->pHPrev )
|
||||
{
|
||||
// get another variable
|
||||
pVar2 = pLitH->pVar;
|
||||
// skip the var if it is already used
|
||||
if ( pVar2->pOrder )
|
||||
continue;
|
||||
// skip the var if it belongs to the same node
|
||||
// if ( pValue2Node[pVar->iVar] == pValue2Node[pVar2->iVar] )
|
||||
// continue;
|
||||
// collect the var
|
||||
Fxu_MatrixRingVarsAdd( p, pVar2 );
|
||||
}
|
||||
// stop collecting the selected vars
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// iterate through the selected vars
|
||||
Fxu_MatrixForEachVarInRing( p, pVar2 )
|
||||
{
|
||||
// count the coincidence
|
||||
Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar );
|
||||
assert( Coin > 0 );
|
||||
// get the new weight
|
||||
WeightCur = Coin - 2;
|
||||
// peformance fix (August 24, 2007)
|
||||
// if ( WeightCur >= 0 )
|
||||
// Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
|
||||
if ( WeightCur >= p->nWeightLimit )
|
||||
Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
|
||||
}
|
||||
// unmark the vars
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the coincidence count of two columns.]
|
||||
|
|
|
|||
|
|
@ -757,12 +757,14 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
|
|||
{
|
||||
Fxu_Single * pSingle, * pSingle2;
|
||||
int WeightNew;
|
||||
int Counter = 0;
|
||||
|
||||
Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
|
||||
{
|
||||
// if at least one of the variables is marked, recalculate
|
||||
if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder )
|
||||
{
|
||||
Counter++;
|
||||
// get the new weight
|
||||
WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 );
|
||||
if ( WeightNew >= 0 )
|
||||
|
|
@ -778,6 +780,7 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
|
|||
}
|
||||
}
|
||||
}
|
||||
// printf( "Called procedure %d times.\n", Counter );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
Loading…
Reference in New Issue