mirror of https://github.com/YosysHQ/abc.git
Enabled new BDD-based reachability engine 'reachy'.
This commit is contained in:
parent
8b22fd2856
commit
6e74c46bcf
60
abclib.dsp
60
abclib.dsp
|
|
@ -4163,6 +4163,18 @@ SOURCE=.\src\aig\llb\llb3Nonlin.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\llb\llb4Image.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\llb\llb4Map.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\llb\llb4Nonlin.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\llb\llbInt.h
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
@ -4305,6 +4317,54 @@ SOURCE=.\src\aig\au\auUtil.c
|
|||
# Begin Group "ssm"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmApi.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmClock.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmRandom.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmRead.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmReset.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmSchedule.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmSimple.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmSimulate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ssm\ssmWrite.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# End Group
|
||||
|
|
|
|||
|
|
@ -207,9 +207,9 @@ void Aig_ManDomPrint( Aig_Sto_t * pSto )
|
|||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Saig_ManForEachLo( pSto->pAig, pObj, i )
|
||||
Saig_ManForEachPi( pSto->pAig, pObj, i )
|
||||
{
|
||||
printf( "*** LO %4d %4d :\n", i, pObj->Id );
|
||||
printf( "*** PI %4d %4d :\n", i, pObj->Id );
|
||||
Aig_ObjDomVecPrint( pSto, (Vec_Ptr_t *)Vec_PtrEntry(pSto->vDoms, pObj->Id) );
|
||||
}
|
||||
}
|
||||
|
|
@ -647,6 +647,45 @@ Aig_Sto_t * Aig_ManComputeDomsFlops( Aig_Man_t * pAig, int Limit )
|
|||
return pSto;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes multi-node dominators.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Sto_t * Aig_ManComputeDomsPis( Aig_Man_t * pAig, int Limit )
|
||||
{
|
||||
Aig_Sto_t * pSto;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, clk = clock();
|
||||
pSto = Aig_ManDomStart( pAig, Limit );
|
||||
// initialize flop inputs
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
Aig_ObjAddTriv( pSto, pObj->Id, Vec_PtrAlloc(1) );
|
||||
// compute internal nodes
|
||||
vNodes = Aig_ManDfsReverse( pAig );
|
||||
Aig_ManMarkFlopTfi( pAig );
|
||||
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
|
||||
if ( Aig_ObjIsTravIdCurrent(pSto->pAig, pObj) )
|
||||
Aig_ObjDomCompute( pSto, pObj );
|
||||
Vec_PtrFree( vNodes );
|
||||
// compute combinational inputs
|
||||
Saig_ManForEachPi( pAig, pObj, i )
|
||||
Aig_ObjDomCompute( pSto, pObj );
|
||||
// print statistics
|
||||
printf( "Nodes =%4d. PIs =%4d. Doms =%9d. Ave =%8.2f. ",
|
||||
pSto->nDomNodes, Saig_ManPiNum(pSto->pAig), pSto->nDomsTotal,
|
||||
// pSto->nDomsFilter1, pSto->nDomsFilter2,
|
||||
1.0 * pSto->nDomsTotal / (pSto->nDomNodes + Saig_ManPiNum(pSto->pAig)) );
|
||||
Abc_PrintTime( 1, "Time", clock() - clk );
|
||||
return pSto;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -971,7 +1010,7 @@ void Aig_ObjDomFindGood( Aig_Sto_t * pSto )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManComputeDomsTest( Aig_Man_t * pAig, int Num )
|
||||
void Aig_ManComputeDomsTest2( Aig_Man_t * pAig, int Num )
|
||||
{
|
||||
Aig_Sto_t * pSto;
|
||||
// int i;
|
||||
|
|
@ -988,6 +1027,27 @@ void Aig_ManComputeDomsTest( Aig_Man_t * pAig, int Num )
|
|||
Aig_ManFanoutStop( pAig );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes multi-node dominators.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManComputeDomsTest( Aig_Man_t * pAig )
|
||||
{
|
||||
Aig_Sto_t * pSto;
|
||||
Aig_ManFanoutStart( pAig );
|
||||
pSto = Aig_ManComputeDomsPis( pAig, 1 );
|
||||
Aig_ManDomPrint( pSto );
|
||||
Aig_ManDomStop( pSto );
|
||||
Aig_ManFanoutStop( pAig );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -113,10 +113,10 @@ void Aig_ManPackPrintCare( Aig_ManPack_t * p )
|
|||
Aig_ManForEachPi( p->pAig, pObj, i )
|
||||
{
|
||||
Sign = Vec_WrdEntry( p->vPiCare, i );
|
||||
Extra_PrintBinary( stdout, (unsigned *)&Sign, 64 );
|
||||
printf( "\n" );
|
||||
// Extra_PrintBinary( stdout, (unsigned *)&Sign, 64 );
|
||||
// printf( "\n" );
|
||||
}
|
||||
printf( "\n" );
|
||||
// printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -316,6 +316,10 @@ static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) {
|
|||
static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; }
|
||||
static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); }
|
||||
|
||||
static inline int Gia_ManIdToCioId( Gia_Man_t * p, int Id ) { return Gia_ObjCioId( Gia_ManObj(p, Id) ); }
|
||||
static inline int Gia_ManCiIdToId( Gia_Man_t * p, int CiId ) { return Gia_ObjId( p, Gia_ManCi(p, CiId) ); }
|
||||
static inline int Gia_ManCoIdToId( Gia_Man_t * p, int CoId ) { return Gia_ObjId( p, Gia_ManCo(p, CoId) ); }
|
||||
|
||||
static inline int Gia_ObjIsPi( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCi(pObj) && Gia_ObjCioId(pObj) < Gia_ManPiNum(p); }
|
||||
static inline int Gia_ObjIsPo( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCo(pObj) && Gia_ObjCioId(pObj) < Gia_ManPoNum(p); }
|
||||
static inline int Gia_ObjIsRo( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCi(pObj) && Gia_ObjCioId(pObj) >= Gia_ManPiNum(p); }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,770 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [llb3Image.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [BDD based reachability.]
|
||||
|
||||
Synopsis [Computes image using partitioned structure.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: llb3Image.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "llbInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Llb_Var_t_ Llb_Var_t;
|
||||
struct Llb_Var_t_
|
||||
{
|
||||
int iVar; // variable number
|
||||
int nScore; // variable score
|
||||
Vec_Int_t * vParts; // partitions
|
||||
};
|
||||
|
||||
typedef struct Llb_Prt_t_ Llb_Prt_t;
|
||||
struct Llb_Prt_t_
|
||||
{
|
||||
int iPart; // partition number
|
||||
int nSize; // the number of BDD nodes
|
||||
DdNode * bFunc; // the partition
|
||||
Vec_Int_t * vVars; // support
|
||||
};
|
||||
|
||||
typedef struct Llb_Mgr_t_ Llb_Mgr_t;
|
||||
struct Llb_Mgr_t_
|
||||
{
|
||||
DdManager * dd; // working BDD manager
|
||||
Vec_Int_t * vVars2Q; // variables to quantify
|
||||
// internal
|
||||
Llb_Prt_t ** pParts; // partitions
|
||||
Llb_Var_t ** pVars; // variables
|
||||
int iPartFree; // next free partition
|
||||
int nVars; // the number of BDD variables
|
||||
int nSuppMax; // maximum support size
|
||||
// temporary
|
||||
int * pSupp; // temporary support storage
|
||||
};
|
||||
|
||||
static inline Llb_Var_t * Llb_MgrVar( Llb_Mgr_t * p, int i ) { return p->pVars[i]; }
|
||||
static inline Llb_Prt_t * Llb_MgrPart( Llb_Mgr_t * p, int i ) { return p->pParts[i]; }
|
||||
|
||||
// iterator over vars
|
||||
#define Llb_MgrForEachVar( p, pVar, i ) \
|
||||
for ( i = 0; (i < p->nVars) && (((pVar) = Llb_MgrVar(p, i)), 1); i++ ) if ( pVar == NULL ) {} else
|
||||
// iterator over parts
|
||||
#define Llb_MgrForEachPart( p, pPart, i ) \
|
||||
for ( i = 0; (i < p->iPartFree) && (((pPart) = Llb_MgrPart(p, i)), 1); i++ ) if ( pPart == NULL ) {} else
|
||||
|
||||
// iterator over vars of one partition
|
||||
#define Llb_PartForEachVar( p, pPart, pVar, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(pPart->vVars)) && (((pVar) = Llb_MgrVar(p, Vec_IntEntry(pPart->vVars,i))), 1); i++ )
|
||||
// iterator over parts of one variable
|
||||
#define Llb_VarForEachPart( p, pVar, pPart, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(pVar->vParts)) && (((pPart) = Llb_MgrPart(p, Vec_IntEntry(pVar->vParts,i))), 1); i++ )
|
||||
|
||||
// statistics
|
||||
//int timeBuild, timeAndEx, timeOther;
|
||||
//int nSuppMax;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes one variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4RemoveVar( Llb_Mgr_t * p, Llb_Var_t * pVar )
|
||||
{
|
||||
assert( p->pVars[pVar->iVar] == pVar );
|
||||
p->pVars[pVar->iVar] = NULL;
|
||||
Vec_IntFree( pVar->vParts );
|
||||
ABC_FREE( pVar );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes one partition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4RemovePart( Llb_Mgr_t * p, Llb_Prt_t * pPart )
|
||||
{
|
||||
assert( p->pParts[pPart->iPart] == pPart );
|
||||
p->pParts[pPart->iPart] = NULL;
|
||||
Vec_IntFree( pPart->vVars );
|
||||
Cudd_RecursiveDeref( p->dd, pPart->bFunc );
|
||||
ABC_FREE( pPart );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create cube with singleton variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Llb_Nonlin4CreateCube1( Llb_Mgr_t * p, Llb_Prt_t * pPart )
|
||||
{
|
||||
DdNode * bCube, * bTemp;
|
||||
Llb_Var_t * pVar;
|
||||
int i, TimeStop;
|
||||
TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0;
|
||||
bCube = Cudd_ReadOne(p->dd); Cudd_Ref( bCube );
|
||||
Llb_PartForEachVar( p, pPart, pVar, i )
|
||||
{
|
||||
assert( Vec_IntSize(pVar->vParts) > 0 );
|
||||
if ( Vec_IntSize(pVar->vParts) != 1 )
|
||||
continue;
|
||||
assert( Vec_IntEntry(pVar->vParts, 0) == pPart->iPart );
|
||||
bCube = Cudd_bddAnd( p->dd, bTemp = bCube, Cudd_bddIthVar(p->dd, pVar->iVar) ); Cudd_Ref( bCube );
|
||||
Cudd_RecursiveDeref( p->dd, bTemp );
|
||||
}
|
||||
Cudd_Deref( bCube );
|
||||
p->dd->TimeStop = TimeStop;
|
||||
return bCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create cube of variables appearing only in two partitions.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Llb_Nonlin4CreateCube2( Llb_Mgr_t * p, Llb_Prt_t * pPart1, Llb_Prt_t * pPart2 )
|
||||
{
|
||||
DdNode * bCube, * bTemp;
|
||||
Llb_Var_t * pVar;
|
||||
int i, TimeStop;
|
||||
TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0;
|
||||
bCube = Cudd_ReadOne(p->dd); Cudd_Ref( bCube );
|
||||
Llb_PartForEachVar( p, pPart1, pVar, i )
|
||||
{
|
||||
assert( Vec_IntSize(pVar->vParts) > 0 );
|
||||
if ( Vec_IntSize(pVar->vParts) != 2 )
|
||||
continue;
|
||||
if ( (Vec_IntEntry(pVar->vParts, 0) == pPart1->iPart && Vec_IntEntry(pVar->vParts, 1) == pPart2->iPart) ||
|
||||
(Vec_IntEntry(pVar->vParts, 0) == pPart2->iPart && Vec_IntEntry(pVar->vParts, 1) == pPart1->iPart) )
|
||||
{
|
||||
bCube = Cudd_bddAnd( p->dd, bTemp = bCube, Cudd_bddIthVar(p->dd, pVar->iVar) ); Cudd_Ref( bCube );
|
||||
Cudd_RecursiveDeref( p->dd, bTemp );
|
||||
}
|
||||
}
|
||||
Cudd_Deref( bCube );
|
||||
p->dd->TimeStop = TimeStop;
|
||||
return bCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if partition has singleton variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Llb_Nonlin4HasSingletonVars( Llb_Mgr_t * p, Llb_Prt_t * pPart )
|
||||
{
|
||||
Llb_Var_t * pVar;
|
||||
int i;
|
||||
Llb_PartForEachVar( p, pPart, pVar, i )
|
||||
if ( Vec_IntSize(pVar->vParts) == 1 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if partition has singleton variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4Print( Llb_Mgr_t * p )
|
||||
{
|
||||
Llb_Prt_t * pPart;
|
||||
Llb_Var_t * pVar;
|
||||
int i, k;
|
||||
printf( "\n" );
|
||||
Llb_MgrForEachVar( p, pVar, i )
|
||||
{
|
||||
printf( "Var %3d : ", i );
|
||||
Llb_VarForEachPart( p, pVar, pPart, k )
|
||||
printf( "%d ", pPart->iPart );
|
||||
printf( "\n" );
|
||||
}
|
||||
Llb_MgrForEachPart( p, pPart, i )
|
||||
{
|
||||
printf( "Part %3d : ", i );
|
||||
Llb_PartForEachVar( p, pPart, pVar, k )
|
||||
printf( "%d ", pVar->iVar );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Quantifies singles belonging to one partition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Llb_Nonlin4Quantify1( Llb_Mgr_t * p, Llb_Prt_t * pPart )
|
||||
{
|
||||
Llb_Var_t * pVar;
|
||||
Llb_Prt_t * pTemp;
|
||||
Vec_Ptr_t * vSingles;
|
||||
DdNode * bCube, * bTemp;
|
||||
int i, RetValue, nSizeNew;
|
||||
// create cube to be quantified
|
||||
bCube = Llb_Nonlin4CreateCube1( p, pPart ); Cudd_Ref( bCube );
|
||||
assert( !Cudd_IsConstant(bCube) );
|
||||
// derive new function
|
||||
pPart->bFunc = Cudd_bddExistAbstract( p->dd, bTemp = pPart->bFunc, bCube ); Cudd_Ref( pPart->bFunc );
|
||||
Cudd_RecursiveDeref( p->dd, bTemp );
|
||||
Cudd_RecursiveDeref( p->dd, bCube );
|
||||
// get support
|
||||
vSingles = Vec_PtrAlloc( 0 );
|
||||
nSizeNew = Cudd_DagSize(pPart->bFunc);
|
||||
Extra_SupportArray( p->dd, pPart->bFunc, p->pSupp );
|
||||
Llb_PartForEachVar( p, pPart, pVar, i )
|
||||
if ( p->pSupp[pVar->iVar] )
|
||||
{
|
||||
assert( Vec_IntSize(pVar->vParts) > 1 );
|
||||
pVar->nScore -= pPart->nSize - nSizeNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
RetValue = Vec_IntRemove( pVar->vParts, pPart->iPart );
|
||||
assert( RetValue );
|
||||
pVar->nScore -= pPart->nSize;
|
||||
if ( Vec_IntSize(pVar->vParts) == 0 )
|
||||
Llb_Nonlin4RemoveVar( p, pVar );
|
||||
else if ( Vec_IntSize(pVar->vParts) == 1 )
|
||||
Vec_PtrPushUnique( vSingles, Llb_MgrPart(p, Vec_IntEntry(pVar->vParts,0)) );
|
||||
}
|
||||
|
||||
// update partition
|
||||
pPart->nSize = nSizeNew;
|
||||
Vec_IntClear( pPart->vVars );
|
||||
for ( i = 0; i < p->nVars; i++ )
|
||||
if ( p->pSupp[i] && Vec_IntEntry(p->vVars2Q, i) )
|
||||
Vec_IntPush( pPart->vVars, i );
|
||||
// remove other variables
|
||||
Vec_PtrForEachEntry( Llb_Prt_t *, vSingles, pTemp, i )
|
||||
Llb_Nonlin4Quantify1( p, pTemp );
|
||||
Vec_PtrFree( vSingles );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Quantifies singles belonging to one partition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Llb_Nonlin4Quantify2( Llb_Mgr_t * p, Llb_Prt_t * pPart1, Llb_Prt_t * pPart2 )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
Llb_Var_t * pVar;
|
||||
Llb_Prt_t * pTemp;
|
||||
Vec_Ptr_t * vSingles;
|
||||
DdNode * bCube, * bFunc;
|
||||
int i, RetValue, nSuppSize;
|
||||
int iPart1 = pPart1->iPart;
|
||||
int iPart2 = pPart2->iPart;
|
||||
|
||||
// create cube to be quantified
|
||||
bCube = Llb_Nonlin4CreateCube2( p, pPart1, pPart2 ); Cudd_Ref( bCube );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
Llb_Nonlin4Print( p );
|
||||
printf( "Conjoining partitions %d and %d.\n", pPart1->iPart, pPart2->iPart );
|
||||
Extra_bddPrintSupport( p->dd, bCube ); printf( "\n" );
|
||||
}
|
||||
bFunc = Cudd_bddAndAbstract( p->dd, pPart1->bFunc, pPart2->bFunc, bCube );
|
||||
if ( bFunc == NULL )
|
||||
{
|
||||
Cudd_RecursiveDeref( p->dd, bCube );
|
||||
return 0;
|
||||
}
|
||||
Cudd_Ref( bFunc );
|
||||
Cudd_RecursiveDeref( p->dd, bCube );
|
||||
|
||||
// create new partition
|
||||
pTemp = p->pParts[p->iPartFree] = ABC_CALLOC( Llb_Prt_t, 1 );
|
||||
pTemp->iPart = p->iPartFree++;
|
||||
pTemp->nSize = Cudd_DagSize(bFunc);
|
||||
pTemp->bFunc = bFunc;
|
||||
pTemp->vVars = Vec_IntAlloc( 8 );
|
||||
// update variables
|
||||
Llb_PartForEachVar( p, pPart1, pVar, i )
|
||||
{
|
||||
RetValue = Vec_IntRemove( pVar->vParts, pPart1->iPart );
|
||||
assert( RetValue );
|
||||
pVar->nScore -= pPart1->nSize;
|
||||
}
|
||||
// update variables
|
||||
Llb_PartForEachVar( p, pPart2, pVar, i )
|
||||
{
|
||||
RetValue = Vec_IntRemove( pVar->vParts, pPart2->iPart );
|
||||
assert( RetValue );
|
||||
pVar->nScore -= pPart2->nSize;
|
||||
}
|
||||
// add variables to the new partition
|
||||
nSuppSize = 0;
|
||||
Extra_SupportArray( p->dd, bFunc, p->pSupp );
|
||||
for ( i = 0; i < p->nVars; i++ )
|
||||
{
|
||||
nSuppSize += p->pSupp[i];
|
||||
if ( p->pSupp[i] && Vec_IntEntry(p->vVars2Q, i) )
|
||||
{
|
||||
pVar = Llb_MgrVar( p, i );
|
||||
pVar->nScore += pTemp->nSize;
|
||||
Vec_IntPush( pVar->vParts, pTemp->iPart );
|
||||
Vec_IntPush( pTemp->vVars, i );
|
||||
}
|
||||
}
|
||||
p->nSuppMax = ABC_MAX( p->nSuppMax, nSuppSize );
|
||||
// remove variables and collect partitions with singleton variables
|
||||
vSingles = Vec_PtrAlloc( 0 );
|
||||
Llb_PartForEachVar( p, pPart1, pVar, i )
|
||||
{
|
||||
if ( Vec_IntSize(pVar->vParts) == 0 )
|
||||
Llb_Nonlin4RemoveVar( p, pVar );
|
||||
else if ( Vec_IntSize(pVar->vParts) == 1 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Adding partition %d because of var %d.\n",
|
||||
Llb_MgrPart(p, Vec_IntEntry(pVar->vParts,0))->iPart, pVar->iVar );
|
||||
Vec_PtrPushUnique( vSingles, Llb_MgrPart(p, Vec_IntEntry(pVar->vParts,0)) );
|
||||
}
|
||||
}
|
||||
Llb_PartForEachVar( p, pPart2, pVar, i )
|
||||
{
|
||||
if ( pVar == NULL )
|
||||
continue;
|
||||
if ( Vec_IntSize(pVar->vParts) == 0 )
|
||||
Llb_Nonlin4RemoveVar( p, pVar );
|
||||
else if ( Vec_IntSize(pVar->vParts) == 1 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Adding partition %d because of var %d.\n",
|
||||
Llb_MgrPart(p, Vec_IntEntry(pVar->vParts,0))->iPart, pVar->iVar );
|
||||
Vec_PtrPushUnique( vSingles, Llb_MgrPart(p, Vec_IntEntry(pVar->vParts,0)) );
|
||||
}
|
||||
}
|
||||
// remove partitions
|
||||
Llb_Nonlin4RemovePart( p, pPart1 );
|
||||
Llb_Nonlin4RemovePart( p, pPart2 );
|
||||
// remove other variables
|
||||
if ( fVerbose )
|
||||
Llb_Nonlin4Print( p );
|
||||
Vec_PtrForEachEntry( Llb_Prt_t *, vSingles, pTemp, i )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Updating partitiong %d with singlton vars.\n", pTemp->iPart );
|
||||
Llb_Nonlin4Quantify1( p, pTemp );
|
||||
}
|
||||
if ( fVerbose )
|
||||
Llb_Nonlin4Print( p );
|
||||
Vec_PtrFree( vSingles );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes volume of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4CutNodes_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent(p, pObj);
|
||||
if ( Saig_ObjIsLi(p, pObj) )
|
||||
{
|
||||
Llb_Nonlin4CutNodes_rec(p, Aig_ObjFanin0(pObj), vNodes);
|
||||
return;
|
||||
}
|
||||
if ( Aig_ObjIsConst1(pObj) )
|
||||
return;
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Llb_Nonlin4CutNodes_rec(p, Aig_ObjFanin0(pObj), vNodes);
|
||||
Llb_Nonlin4CutNodes_rec(p, Aig_ObjFanin1(pObj), vNodes);
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes volume of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Llb_Nonlin4CutNodes( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
// mark the lower cut with the traversal ID
|
||||
Aig_ManIncrementTravId(p);
|
||||
Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
// count the upper cut
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Vec_PtrForEachEntry( Aig_Obj_t *, vUpper, pObj, i )
|
||||
Llb_Nonlin4CutNodes_rec( p, pObj, vNodes );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts non-linear quantification scheduling.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4AddPair( Llb_Mgr_t * p, int iPart, int iVar )
|
||||
{
|
||||
if ( p->pVars[iVar] == NULL )
|
||||
{
|
||||
p->pVars[iVar] = ABC_CALLOC( Llb_Var_t, 1 );
|
||||
p->pVars[iVar]->iVar = iVar;
|
||||
p->pVars[iVar]->nScore = 0;
|
||||
p->pVars[iVar]->vParts = Vec_IntAlloc( 8 );
|
||||
}
|
||||
Vec_IntPush( p->pVars[iVar]->vParts, iPart );
|
||||
Vec_IntPush( p->pParts[iPart]->vVars, iVar );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts non-linear quantification scheduling.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4AddPartition( Llb_Mgr_t * p, int i, DdNode * bFunc )
|
||||
{
|
||||
int k, nSuppSize;
|
||||
assert( !Cudd_IsConstant(bFunc) );
|
||||
// create partition
|
||||
p->pParts[i] = ABC_CALLOC( Llb_Prt_t, 1 );
|
||||
p->pParts[i]->iPart = i;
|
||||
p->pParts[i]->bFunc = bFunc; Cudd_Ref( bFunc );
|
||||
p->pParts[i]->vVars = Vec_IntAlloc( 8 );
|
||||
// add support dependencies
|
||||
nSuppSize = 0;
|
||||
Extra_SupportArray( p->dd, bFunc, p->pSupp );
|
||||
for ( k = 0; k < p->nVars; k++ )
|
||||
{
|
||||
nSuppSize += p->pSupp[k];
|
||||
if ( p->pSupp[k] && Vec_IntEntry(p->vVars2Q, k) )
|
||||
Llb_Nonlin4AddPair( p, i, k );
|
||||
}
|
||||
p->nSuppMax = ABC_MAX( p->nSuppMax, nSuppSize );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks that each var appears in at least one partition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
**********************************************************************/
|
||||
void Llb_Nonlin4CheckVars( Llb_Mgr_t * p )
|
||||
{
|
||||
Llb_Var_t * pVar;
|
||||
int i;
|
||||
Llb_MgrForEachVar( p, pVar, i )
|
||||
assert( Vec_IntSize(pVar->vParts) > 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find next partition to quantify]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Llb_Nonlin4NextPartitions( Llb_Mgr_t * p, Llb_Prt_t ** ppPart1, Llb_Prt_t ** ppPart2 )
|
||||
{
|
||||
Llb_Var_t * pVar, * pVarBest = NULL;
|
||||
Llb_Prt_t * pPart, * pPart1Best = NULL, * pPart2Best = NULL;
|
||||
int i;
|
||||
Llb_Nonlin4CheckVars( p );
|
||||
// find variable with minimum score
|
||||
Llb_MgrForEachVar( p, pVar, i )
|
||||
if ( pVarBest == NULL || pVarBest->nScore > pVar->nScore )
|
||||
pVarBest = pVar;
|
||||
if ( pVarBest == NULL )
|
||||
return 0;
|
||||
// find two partitions with minimum size
|
||||
Llb_VarForEachPart( p, pVarBest, pPart, i )
|
||||
{
|
||||
if ( pPart1Best == NULL )
|
||||
pPart1Best = pPart;
|
||||
else if ( pPart2Best == NULL )
|
||||
pPart2Best = pPart;
|
||||
else if ( pPart1Best->nSize > pPart->nSize || pPart2Best->nSize > pPart->nSize )
|
||||
{
|
||||
if ( pPart1Best->nSize > pPart2Best->nSize )
|
||||
pPart1Best = pPart;
|
||||
else
|
||||
pPart2Best = pPart;
|
||||
}
|
||||
}
|
||||
*ppPart1 = pPart1Best;
|
||||
*ppPart2 = pPart2Best;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recomputes scores after variable reordering.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4RecomputeScores( Llb_Mgr_t * p )
|
||||
{
|
||||
Llb_Prt_t * pPart;
|
||||
Llb_Var_t * pVar;
|
||||
int i, k;
|
||||
Llb_MgrForEachPart( p, pPart, i )
|
||||
pPart->nSize = Cudd_DagSize(pPart->bFunc);
|
||||
Llb_MgrForEachVar( p, pVar, i )
|
||||
{
|
||||
pVar->nScore = 0;
|
||||
Llb_VarForEachPart( p, pVar, pPart, k )
|
||||
pVar->nScore += pPart->nSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recomputes scores after variable reordering.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4VerifyScores( Llb_Mgr_t * p )
|
||||
{
|
||||
Llb_Prt_t * pPart;
|
||||
Llb_Var_t * pVar;
|
||||
int i, k, nScore;
|
||||
Llb_MgrForEachPart( p, pPart, i )
|
||||
assert( pPart->nSize == Cudd_DagSize(pPart->bFunc) );
|
||||
Llb_MgrForEachVar( p, pVar, i )
|
||||
{
|
||||
nScore = 0;
|
||||
Llb_VarForEachPart( p, pVar, pPart, k )
|
||||
nScore += pPart->nSize;
|
||||
assert( nScore == pVar->nScore );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts non-linear quantification scheduling.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Llb_Mgr_t * Llb_Nonlin4Alloc( DdManager * dd, Vec_Ptr_t * vParts, DdNode * bCurrent, Vec_Int_t * vVars2Q )
|
||||
{
|
||||
Llb_Mgr_t * p;
|
||||
DdNode * bFunc;
|
||||
int i;
|
||||
p = ABC_CALLOC( Llb_Mgr_t, 1 );
|
||||
p->dd = dd;
|
||||
p->vVars2Q = vVars2Q;
|
||||
p->nVars = Cudd_ReadSize(dd);
|
||||
p->iPartFree = Vec_PtrSize(vParts);
|
||||
p->pVars = ABC_CALLOC( Llb_Var_t *, p->nVars );
|
||||
p->pParts = ABC_CALLOC( Llb_Prt_t *, 2 * p->iPartFree + 2 );
|
||||
p->pSupp = ABC_ALLOC( int, Cudd_ReadSize(dd) );
|
||||
// add pairs (refs are consumed inside)
|
||||
Vec_PtrForEachEntry( DdNode *, vParts, bFunc, i )
|
||||
Llb_Nonlin4AddPartition( p, i, bFunc );
|
||||
// add partition
|
||||
Llb_Nonlin4AddPartition( p, p->iPartFree++, bCurrent );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops non-linear quantification scheduling.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4Free( Llb_Mgr_t * p )
|
||||
{
|
||||
Llb_Prt_t * pPart;
|
||||
Llb_Var_t * pVar;
|
||||
int i;
|
||||
Llb_MgrForEachVar( p, pVar, i )
|
||||
Llb_Nonlin4RemoveVar( p, pVar );
|
||||
Llb_MgrForEachPart( p, pPart, i )
|
||||
Llb_Nonlin4RemovePart( p, pPart );
|
||||
ABC_FREE( p->pVars );
|
||||
ABC_FREE( p->pParts );
|
||||
ABC_FREE( p->pSupp );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs image computation.]
|
||||
|
||||
Description [Computes image of BDDs (vFuncs).]
|
||||
|
||||
SideEffects [BDDs in vFuncs are derefed inside. The result is refed.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Llb_Nonlin4Image( DdManager * dd, Vec_Ptr_t * vParts, DdNode * bCurrent, Vec_Int_t * vVars2Q )
|
||||
{
|
||||
Llb_Prt_t * pPart, * pPart1, * pPart2;
|
||||
Llb_Mgr_t * p;
|
||||
DdNode * bFunc, * bTemp;
|
||||
int i, nReorders;
|
||||
// start the manager
|
||||
p = Llb_Nonlin4Alloc( dd, vParts, bCurrent, vVars2Q );
|
||||
// remove singles
|
||||
Llb_MgrForEachPart( p, pPart, i )
|
||||
if ( Llb_Nonlin4HasSingletonVars(p, pPart) )
|
||||
Llb_Nonlin4Quantify1( p, pPart );
|
||||
// compute scores
|
||||
Llb_Nonlin4RecomputeScores( p );
|
||||
// iteratively quantify variables
|
||||
while ( Llb_Nonlin4NextPartitions(p, &pPart1, &pPart2) )
|
||||
{
|
||||
nReorders = Cudd_ReadReorderings(dd);
|
||||
if ( !Llb_Nonlin4Quantify2( p, pPart1, pPart2 ) )
|
||||
{
|
||||
Llb_Nonlin4Free( p );
|
||||
return NULL;
|
||||
}
|
||||
if ( nReorders < Cudd_ReadReorderings(dd) )
|
||||
Llb_Nonlin4RecomputeScores( p );
|
||||
else
|
||||
Llb_Nonlin4VerifyScores( p );
|
||||
}
|
||||
// load partitions
|
||||
bFunc = Cudd_ReadOne(p->dd); Cudd_Ref( bFunc );
|
||||
Llb_MgrForEachPart( p, pPart, i )
|
||||
{
|
||||
bFunc = Cudd_bddAnd( p->dd, bTemp = bFunc, pPart->bFunc ); Cudd_Ref( bFunc );
|
||||
Cudd_RecursiveDeref( p->dd, bTemp );
|
||||
}
|
||||
// nSuppMax = p->nSuppMax;
|
||||
Llb_Nonlin4Free( p );
|
||||
// return
|
||||
Cudd_Deref( bFunc );
|
||||
return bFunc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [llb2Map.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [BDD based reachability.]
|
||||
|
||||
Synopsis [Non-linear quantification scheduling.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: llb2Map.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "llbInt.h"
|
||||
#include "abc.h"
|
||||
#include "if.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns internal nodes used in the mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Llb_AigMap( Aig_Man_t * pAig, int nLutSize, int nLutMin )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
|
||||
extern If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
|
||||
extern void Gia_ManSetIfParsDefault( If_Par_t * pPars );
|
||||
If_Par_t Pars, * pPars = &Pars;
|
||||
If_Man_t * pIfMan;
|
||||
If_Obj_t * pAnd;
|
||||
Abc_Ntk_t * pNtk;
|
||||
Abc_Obj_t * pNode;
|
||||
Vec_Int_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
|
||||
// create ABC network
|
||||
pNtk = Abc_NtkFromAigPhase( pAig );
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
// derive mapping parameters
|
||||
Gia_ManSetIfParsDefault( pPars );
|
||||
pPars->nLutSize = nLutSize;
|
||||
|
||||
// get timing information
|
||||
pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk);
|
||||
pPars->pTimesReq = NULL;
|
||||
|
||||
// perform LUT mapping
|
||||
pIfMan = Abc_NtkToIf( pNtk, pPars );
|
||||
if ( pIfMan == NULL )
|
||||
{
|
||||
Abc_NtkDelete( pNtk );
|
||||
return NULL;
|
||||
}
|
||||
if ( !If_ManPerformMapping( pIfMan ) )
|
||||
{
|
||||
Abc_NtkDelete( pNtk );
|
||||
If_ManStop( pIfMan );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// mark nodes in the AIG used in the mapping
|
||||
Aig_ManCleanMarkA( pAig );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
{
|
||||
pNode = (Abc_Obj_t *)pObj->pData;
|
||||
if ( pNode == NULL )
|
||||
continue;
|
||||
pAnd = (If_Obj_t *)pNode->pCopy;
|
||||
if ( pAnd == NULL )
|
||||
continue;
|
||||
if ( pAnd->nRefs > 0 && (int)If_ObjCutBest(pAnd)->nLeaves >= nLutMin )
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
Abc_NtkDelete( pNtk );
|
||||
If_ManStop( pIfMan );
|
||||
|
||||
// unmark flop drivers
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
Aig_ObjFanin0(pObj)->fMarkA = 0;
|
||||
|
||||
// collect mapping
|
||||
vNodes = Vec_IntAlloc( 100 );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
if ( pObj->fMarkA )
|
||||
Vec_IntPush( vNodes, Aig_ObjId(pObj) );
|
||||
Aig_ManCleanMarkA( pAig );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,914 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [llb2Nonlin.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [BDD based reachability.]
|
||||
|
||||
Synopsis [Non-linear quantification scheduling.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: llb2Nonlin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "llbInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Llb_Mnx_t_ Llb_Mnx_t;
|
||||
struct Llb_Mnx_t_
|
||||
{
|
||||
// user info
|
||||
Aig_Man_t * pAig; // AIG manager
|
||||
Gia_ParLlb_t * pPars; // parameters
|
||||
|
||||
// intermediate BDDs
|
||||
DdManager * dd; // BDD manager
|
||||
DdNode * bBad; // bad states in terms of CIs
|
||||
DdNode * bReached; // reached states
|
||||
DdNode * bCurrent; // from states
|
||||
DdNode * bNext; // to states
|
||||
Vec_Ptr_t * vRings; // onion rings in ddR
|
||||
Vec_Ptr_t * vRoots; // BDDs for partitions
|
||||
|
||||
// structural info
|
||||
Vec_Int_t * vOrder; // for each object ID, its BDD variable number or -1
|
||||
Vec_Int_t * vVars2Q; // 1 if variable is quantifiable; 0 othervise
|
||||
|
||||
int timeImage;
|
||||
int timeRemap;
|
||||
int timeReo;
|
||||
int timeOther;
|
||||
int timeTotal;
|
||||
};
|
||||
|
||||
static inline int Llb_MnxBddVar( Vec_Int_t * vOrder, Aig_Obj_t * pObj ) { return Vec_IntEntry(vOrder, Aig_ObjId(pObj)); }
|
||||
|
||||
//extern int timeBuild, timeAndEx, timeOther;
|
||||
//extern int nSuppMax;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes bad in working manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Llb_Nonlin4ComputeBad( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
DdNode * bBdd, * bBdd0, * bBdd1, * bTemp, * bResult;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Aig_ManCleanData( pAig );
|
||||
// assign elementary variables
|
||||
Aig_ManConst1(pAig)->pData = Cudd_ReadOne(dd);
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
pObj->pData = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObj) );
|
||||
// compute internal nodes
|
||||
vNodes = Aig_ManDfsNodes( pAig, (Aig_Obj_t **)Vec_PtrArray(pAig->vPos), Saig_ManPoNum(pAig) );
|
||||
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsNode(pObj) )
|
||||
continue;
|
||||
bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
|
||||
bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) );
|
||||
bBdd = Cudd_bddAnd( dd, bBdd0, bBdd1 );
|
||||
if ( bBdd == NULL )
|
||||
{
|
||||
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
|
||||
if ( Aig_ObjIsNode(pObj) && pObj->pData != NULL )
|
||||
Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
|
||||
Vec_PtrFree( vNodes );
|
||||
return NULL;
|
||||
}
|
||||
Cudd_Ref( bBdd );
|
||||
pObj->pData = bBdd;
|
||||
}
|
||||
// quantify PIs of each PO
|
||||
bResult = Cudd_ReadLogicZero( dd ); Cudd_Ref( bResult );
|
||||
Saig_ManForEachPo( pAig, pObj, i )
|
||||
{
|
||||
bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
|
||||
bResult = Cudd_bddOr( dd, bTemp = bResult, bBdd0 );
|
||||
if ( bResult == NULL )
|
||||
{
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
break;
|
||||
}
|
||||
Cudd_Ref( bResult );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
// deref
|
||||
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
|
||||
if ( Aig_ObjIsNode(pObj) && pObj->pData != NULL )
|
||||
Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
|
||||
Vec_PtrFree( vNodes );
|
||||
if ( bResult )
|
||||
Cudd_Deref( bResult );
|
||||
//if ( bResult )
|
||||
//printf( "Bad state = %d.\n", Cudd_DagSize(bResult) );
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives BDDs for the partitions.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Llb_Nonlin4DerivePartitions( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
|
||||
{
|
||||
Vec_Ptr_t * vRoots;
|
||||
Aig_Obj_t * pObj;
|
||||
DdNode * bBdd, * bBdd0, * bBdd1, * bPart;
|
||||
int i;
|
||||
Aig_ManCleanData( pAig );
|
||||
// assign elementary variables
|
||||
Aig_ManConst1(pAig)->pData = Cudd_ReadOne(dd);
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
pObj->pData = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObj) );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
if ( Llb_MnxBddVar(vOrder, pObj) >= 0 )
|
||||
{
|
||||
pObj->pData = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObj) );
|
||||
Cudd_Ref( (DdNode *)pObj->pData );
|
||||
}
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
pObj->pData = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObj) );
|
||||
// compute intermediate BDDs
|
||||
vRoots = Vec_PtrAlloc( 100 );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
{
|
||||
bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
|
||||
bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) );
|
||||
bBdd = Cudd_bddAnd( dd, bBdd0, bBdd1 );
|
||||
if ( bBdd == NULL )
|
||||
goto finish;
|
||||
Cudd_Ref( bBdd );
|
||||
if ( pObj->pData == NULL )
|
||||
{
|
||||
pObj->pData = bBdd;
|
||||
continue;
|
||||
}
|
||||
// create new partition
|
||||
bPart = Cudd_bddXnor( dd, (DdNode *)pObj->pData, bBdd );
|
||||
if ( bPart == NULL )
|
||||
goto finish;
|
||||
Cudd_Ref( bPart );
|
||||
Cudd_RecursiveDeref( dd, bBdd );
|
||||
Vec_PtrPush( vRoots, bPart );
|
||||
//printf( "%d ", Cudd_DagSize(bPart) );
|
||||
}
|
||||
// compute register output BDDs
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
{
|
||||
bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
|
||||
bPart = Cudd_bddXnor( dd, (DdNode *)pObj->pData, bBdd0 );
|
||||
if ( bPart == NULL )
|
||||
goto finish;
|
||||
Cudd_Ref( bPart );
|
||||
Vec_PtrPush( vRoots, bPart );
|
||||
//printf( "%d ", Cudd_DagSize(bPart) );
|
||||
}
|
||||
//printf( "\n" );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
|
||||
return vRoots;
|
||||
// early termination
|
||||
finish:
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
if ( pObj->pData )
|
||||
Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
|
||||
Vec_PtrForEachEntry( DdNode *, vRoots, bPart, i )
|
||||
Cudd_RecursiveDeref( dd, bPart );
|
||||
Vec_PtrFree( vRoots );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find simple variable ordering.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Llb_Nonlin4CreateOrderSimple( Aig_Man_t * pAig )
|
||||
{
|
||||
Vec_Int_t * vOrder;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
vOrder = Vec_IntStartFull( Aig_ManObjNumMax(pAig) );
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
|
||||
return vOrder;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find good static variable ordering.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4CreateOrderSmart_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vOrder, int * pCounter )
|
||||
{
|
||||
Aig_Obj_t * pFanin0, * pFanin1;
|
||||
if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent( pAig, pObj );
|
||||
assert( Llb_MnxBddVar(vOrder, pObj) < 0 );
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
{
|
||||
Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), (*pCounter)++ );
|
||||
return;
|
||||
}
|
||||
// try fanins with higher level first
|
||||
pFanin0 = Aig_ObjFanin0(pObj);
|
||||
pFanin1 = Aig_ObjFanin1(pObj);
|
||||
// if ( pFanin0->Level > pFanin1->Level || (pFanin0->Level == pFanin1->Level && pFanin0->Id < pFanin1->Id) )
|
||||
if ( pFanin0->Level > pFanin1->Level )
|
||||
{
|
||||
Llb_Nonlin4CreateOrderSmart_rec( pAig, pFanin0, vOrder, pCounter );
|
||||
Llb_Nonlin4CreateOrderSmart_rec( pAig, pFanin1, vOrder, pCounter );
|
||||
}
|
||||
else
|
||||
{
|
||||
Llb_Nonlin4CreateOrderSmart_rec( pAig, pFanin1, vOrder, pCounter );
|
||||
Llb_Nonlin4CreateOrderSmart_rec( pAig, pFanin0, vOrder, pCounter );
|
||||
}
|
||||
if ( pObj->fMarkA )
|
||||
Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), (*pCounter)++ );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect nodes with the given fanout count.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Llb_Nonlin4CollectHighRefNodes( Aig_Man_t * pAig, int nFans )
|
||||
{
|
||||
Vec_Int_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Aig_ManCleanMarkA( pAig );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
if ( Aig_ObjRefs(pObj) >= nFans )
|
||||
pObj->fMarkA = 1;
|
||||
// unmark flop drivers
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
Aig_ObjFanin0(pObj)->fMarkA = 0;
|
||||
// collect mapping
|
||||
vNodes = Vec_IntAlloc( 100 );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
if ( pObj->fMarkA )
|
||||
Vec_IntPush( vNodes, Aig_ObjId(pObj) );
|
||||
Aig_ManCleanMarkA( pAig );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find good static variable ordering.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Llb_Nonlin4CreateOrderSmart( Aig_Man_t * pAig )
|
||||
{
|
||||
Vec_Int_t * vNodes = NULL;
|
||||
Vec_Int_t * vOrder;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
/*
|
||||
// mark internal nodes to be used
|
||||
Aig_ManCleanMarkA( pAig );
|
||||
vNodes = Llb_Nonlin4CollectHighRefNodes( pAig, 4 );
|
||||
Aig_ManForEachNodeVec( pAig, vNodes, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
printf( "Techmapping added %d pivots.\n", Vec_IntSize(vNodes) );
|
||||
*/
|
||||
|
||||
// collect nodes in the order
|
||||
vOrder = Vec_IntStartFull( Aig_ManObjNumMax(pAig) );
|
||||
Aig_ManIncrementTravId( pAig );
|
||||
Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) );
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
{
|
||||
Llb_Nonlin4CreateOrderSmart_rec( pAig, Aig_ObjFanin0(pObj), vOrder, &Counter );
|
||||
Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
|
||||
}
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
if ( Llb_MnxBddVar(vOrder, pObj) < 0 )
|
||||
Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
|
||||
assert( Counter <= Aig_ManPiNum(pAig) + Aig_ManRegNum(pAig) + (vNodes?Vec_IntSize(vNodes):0) );
|
||||
Aig_ManCleanMarkA( pAig );
|
||||
Vec_IntFreeP( &vNodes );
|
||||
return vOrder;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates quantifiable varaibles for both types of traversal.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Llb_Nonlin4CreateVars2Q( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, int fForward )
|
||||
{
|
||||
Vec_Int_t * vVars2Q;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
vVars2Q = Vec_IntAlloc( 0 );
|
||||
Vec_IntFill( vVars2Q, Cudd_ReadSize(dd), 1 );
|
||||
if ( fForward )
|
||||
{
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
Vec_IntWriteEntry( vVars2Q, Llb_MnxBddVar(vOrder, pObj), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
Vec_IntWriteEntry( vVars2Q, Llb_MnxBddVar(vOrder, pObj), 0 );
|
||||
}
|
||||
return vVars2Q;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute initial state in terms of current state variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4SetupVarMap( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
|
||||
{
|
||||
DdNode ** pVarsX, ** pVarsY;
|
||||
Aig_Obj_t * pObjLo, * pObjLi;
|
||||
int i;
|
||||
pVarsX = ABC_ALLOC( DdNode *, Cudd_ReadSize(dd) );
|
||||
pVarsY = ABC_ALLOC( DdNode *, Cudd_ReadSize(dd) );
|
||||
Saig_ManForEachLiLo( pAig, pObjLo, pObjLi, i )
|
||||
{
|
||||
pVarsX[i] = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObjLo) );
|
||||
pVarsY[i] = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObjLi) );
|
||||
}
|
||||
Cudd_SetVarMap( dd, pVarsX, pVarsY, Aig_ManRegNum(pAig) );
|
||||
ABC_FREE( pVarsX );
|
||||
ABC_FREE( pVarsY );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute initial state in terms of current state variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Llb_Nonlin4ComputeInitState( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
DdNode * bRes, * bVar, * bTemp;
|
||||
int i, TimeStop;
|
||||
TimeStop = dd->TimeStop; dd->TimeStop = 0;
|
||||
bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes );
|
||||
Saig_ManForEachLo( pAig, pObj, i )
|
||||
{
|
||||
bVar = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObj) );
|
||||
bRes = Cudd_bddAnd( dd, bTemp = bRes, Cudd_Not(bVar) ); Cudd_Ref( bRes );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
Cudd_Deref( bRes );
|
||||
dd->TimeStop = TimeStop;
|
||||
return bRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute initial state in terms of current state variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Llb_Nonlin4ComputeCube( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, char * pValues )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pObjLi;
|
||||
DdNode * bRes, * bVar, * bTemp;
|
||||
int i, TimeStop;
|
||||
TimeStop = dd->TimeStop; dd->TimeStop = 0;
|
||||
bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes );
|
||||
Saig_ManForEachLo( pAig, pObj, i )
|
||||
{
|
||||
if ( pValues[Llb_MnxBddVar(vOrder, pObj)] == 2 )
|
||||
continue;
|
||||
// get the correspoding flop input variable
|
||||
pObjLi = Saig_ObjLoToLi(pAig, pObj);
|
||||
bVar = Cudd_bddIthVar( dd, Llb_MnxBddVar(vOrder, pObjLi) );
|
||||
if ( pValues[Llb_MnxBddVar(vOrder, pObj)] == 0 )
|
||||
bVar = Cudd_Not(bVar);
|
||||
// create cube
|
||||
bRes = Cudd_bddAnd( dd, bTemp = bRes, bVar ); Cudd_Ref( bRes );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
Cudd_Deref( bRes );
|
||||
dd->TimeStop = TimeStop;
|
||||
return bRes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives counter-example by backward reachability.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Cex_t * Llb_Nonlin4DeriveCex( Llb_Mnx_t * p )
|
||||
{
|
||||
Abc_Cex_t * pCex;
|
||||
Aig_Obj_t * pObj;
|
||||
DdNode * bState, * bImage, * bOneCube, * bRing;
|
||||
int i, v, RetValue, nPiOffset;
|
||||
char * pValues = ABC_ALLOC( char, Cudd_ReadSize(p->dd) );
|
||||
assert( Vec_PtrSize(p->vRings) > 0 );
|
||||
// disable the timeout
|
||||
p->dd->TimeStop = 0;
|
||||
|
||||
// update quantifiable vars
|
||||
Vec_IntFreeP( &p->vVars2Q );
|
||||
p->vVars2Q = Llb_Nonlin4CreateVars2Q( p->dd, p->pAig, p->vOrder, 0 );
|
||||
|
||||
// allocate room for the counter-example
|
||||
pCex = Abc_CexAlloc( Saig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Vec_PtrSize(p->vRings) );
|
||||
pCex->iFrame = Vec_PtrSize(p->vRings) - 1;
|
||||
pCex->iPo = -1;
|
||||
|
||||
// get the last cube
|
||||
bOneCube = Cudd_bddIntersect( p->dd, (DdNode *)Vec_PtrEntryLast(p->vRings), p->bBad ); Cudd_Ref( bOneCube );
|
||||
RetValue = Cudd_bddPickOneCube( p->dd, bOneCube, pValues );
|
||||
Cudd_RecursiveDeref( p->dd, bOneCube );
|
||||
assert( RetValue );
|
||||
|
||||
// write PIs of counter-example
|
||||
nPiOffset = Saig_ManRegNum(p->pAig) + Saig_ManPiNum(p->pAig) * (Vec_PtrSize(p->vRings) - 1);
|
||||
Saig_ManForEachPi( p->pAig, pObj, i )
|
||||
if ( pValues[Llb_MnxBddVar(p->vOrder, pObj)] == 1 )
|
||||
Aig_InfoSetBit( pCex->pData, nPiOffset + i );
|
||||
|
||||
// write state in terms of NS variables
|
||||
if ( Vec_PtrSize(p->vRings) > 1 )
|
||||
{
|
||||
bState = Llb_Nonlin4ComputeCube( p->dd, p->pAig, p->vOrder, pValues ); Cudd_Ref( bState );
|
||||
}
|
||||
// perform backward analysis
|
||||
Vec_PtrForEachEntryReverse( DdNode *, p->vRings, bRing, v )
|
||||
{
|
||||
if ( v == Vec_PtrSize(p->vRings) - 1 )
|
||||
continue;
|
||||
// compute the next states
|
||||
bImage = Llb_Nonlin4Image( p->dd, p->vRoots, bState, p->vVars2Q );
|
||||
assert( bImage != NULL );
|
||||
Cudd_Ref( bImage );
|
||||
Cudd_RecursiveDeref( p->dd, bState );
|
||||
|
||||
// intersect with the previous set
|
||||
bOneCube = Cudd_bddIntersect( p->dd, bImage, bRing ); Cudd_Ref( bOneCube );
|
||||
Cudd_RecursiveDeref( p->dd, bImage );
|
||||
|
||||
// find any assignment of the BDD
|
||||
RetValue = Cudd_bddPickOneCube( p->dd, bOneCube, pValues );
|
||||
Cudd_RecursiveDeref( p->dd, bOneCube );
|
||||
assert( RetValue );
|
||||
|
||||
// write PIs of counter-example
|
||||
nPiOffset -= Saig_ManPiNum(p->pAig);
|
||||
Saig_ManForEachPi( p->pAig, pObj, i )
|
||||
if ( pValues[Llb_MnxBddVar(p->vOrder, pObj)] == 1 )
|
||||
Aig_InfoSetBit( pCex->pData, nPiOffset + i );
|
||||
|
||||
// check that we get the init state
|
||||
if ( v == 0 )
|
||||
{
|
||||
Saig_ManForEachLo( p->pAig, pObj, i )
|
||||
assert( pValues[Llb_MnxBddVar(p->vOrder, pObj)] == 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
// write state in terms of NS variables
|
||||
bState = Llb_Nonlin4ComputeCube( p->dd, p->pAig, p->vOrder, pValues ); Cudd_Ref( bState );
|
||||
}
|
||||
assert( nPiOffset == Saig_ManRegNum(p->pAig) );
|
||||
// update the output number
|
||||
//Abc_CexPrint( pCex );
|
||||
RetValue = Saig_ManFindFailedPoCex( p->pAig, pCex );
|
||||
assert( RetValue >= 0 && RetValue < Saig_ManPoNum(p->pAig) ); // invalid CEX!!!
|
||||
pCex->iPo = RetValue;
|
||||
// cleanup
|
||||
ABC_FREE( pValues );
|
||||
return pCex;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Perform reachability with hints.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Llb_Nonlin4Reachability( Llb_Mnx_t * p )
|
||||
{
|
||||
DdNode * bAux;
|
||||
int nIters, nBddSizeFr, nBddSizeTo, nBddSizeTo2;
|
||||
int clkTemp, clkIter, clk = clock();
|
||||
assert( Aig_ManRegNum(p->pAig) > 0 );
|
||||
|
||||
// compute time to stop
|
||||
if ( p->pPars->TimeLimit )
|
||||
p->pPars->TimeTarget = clock() + p->pPars->TimeLimit * CLOCKS_PER_SEC;
|
||||
else
|
||||
p->pPars->TimeTarget = 0;
|
||||
// set the stop time parameter
|
||||
p->dd->TimeStop = p->pPars->TimeTarget;
|
||||
|
||||
// create bad state in the ring manager
|
||||
if ( !p->pPars->fSkipOutCheck )
|
||||
{
|
||||
p->bBad = Llb_Nonlin4ComputeBad( p->dd, p->pAig, p->vOrder );
|
||||
if ( p->bBad == NULL )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached timeout (%d seconds) during constructing the bad states.\n", p->pPars->TimeLimit );
|
||||
p->pPars->iFrame = -1;
|
||||
return -1;
|
||||
}
|
||||
Cudd_Ref( p->bBad );
|
||||
}
|
||||
|
||||
// compute the starting set of states
|
||||
p->bCurrent = Llb_Nonlin4ComputeInitState( p->dd, p->pAig, p->vOrder ); Cudd_Ref( p->bCurrent );
|
||||
p->bReached = p->bCurrent; Cudd_Ref( p->bCurrent );
|
||||
for ( nIters = 0; nIters < p->pPars->nIterMax; nIters++ )
|
||||
{
|
||||
clkIter = clock();
|
||||
// check the runtime limit
|
||||
if ( p->pPars->TimeLimit && clock() >= p->pPars->TimeTarget )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached timeout (%d seconds) during image computation.\n", p->pPars->TimeLimit );
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// save the onion ring
|
||||
Vec_PtrPush( p->vRings, p->bCurrent ); Cudd_Ref( p->bCurrent );
|
||||
|
||||
// check it for bad states
|
||||
if ( !p->pPars->fSkipOutCheck && !Cudd_bddLeq( p->dd, p->bCurrent, Cudd_Not(p->bBad) ) )
|
||||
{
|
||||
assert( p->pAig->pSeqModel == NULL );
|
||||
if ( !p->pPars->fBackward )
|
||||
p->pAig->pSeqModel = Llb_Nonlin4DeriveCex( p );
|
||||
if ( !p->pPars->fSilent )
|
||||
{
|
||||
if ( !p->pPars->fBackward )
|
||||
printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", p->pAig->pSeqModel->iPo, nIters );
|
||||
else
|
||||
printf( "Output ??? was asserted in frame %d (counter-example is not produced). ", nIters );
|
||||
Abc_PrintTime( 1, "Time", clock() - clk );
|
||||
}
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// compute the next states
|
||||
clkTemp = clock();
|
||||
p->bNext = Llb_Nonlin4Image( p->dd, p->vRoots, p->bCurrent, p->vVars2Q );
|
||||
if ( p->bNext == NULL )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached timeout (%d seconds) during image computation in quantification.\n", p->pPars->TimeLimit );
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
return -1;
|
||||
}
|
||||
Cudd_Ref( p->bNext );
|
||||
p->timeImage += clock() - clkTemp;
|
||||
|
||||
// remap into current states
|
||||
clkTemp = clock();
|
||||
p->bNext = Cudd_bddVarMap( p->dd, bAux = p->bNext );
|
||||
if ( p->bNext == NULL )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached timeout (%d seconds) during remapping next states.\n", p->pPars->TimeLimit );
|
||||
Cudd_RecursiveDeref( p->dd, bAux );
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
return -1;
|
||||
}
|
||||
Cudd_Ref( p->bNext );
|
||||
Cudd_RecursiveDeref( p->dd, bAux );
|
||||
p->timeRemap += clock() - clkTemp;
|
||||
|
||||
// collect statistics
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
nBddSizeFr = Cudd_DagSize( p->bCurrent );
|
||||
nBddSizeTo = Cudd_DagSize( bAux );
|
||||
nBddSizeTo2 = Cudd_DagSize( p->bNext );
|
||||
}
|
||||
Cudd_RecursiveDeref( p->dd, p->bCurrent ); p->bCurrent = NULL;
|
||||
|
||||
// derive new states
|
||||
p->bCurrent = Cudd_bddAnd( p->dd, p->bNext, Cudd_Not(p->bReached) );
|
||||
if ( p->bCurrent == NULL )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit );
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
return -1;
|
||||
}
|
||||
Cudd_Ref( p->bCurrent );
|
||||
Cudd_RecursiveDeref( p->dd, p->bNext ); p->bNext = NULL;
|
||||
if ( Cudd_IsConstant(p->bCurrent) )
|
||||
break;
|
||||
|
||||
// add to the reached set
|
||||
p->bReached = Cudd_bddOr( p->dd, bAux = p->bReached, p->bCurrent );
|
||||
if ( p->bReached == NULL )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit );
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
Cudd_RecursiveDeref( p->dd, bAux );
|
||||
return -1;
|
||||
}
|
||||
Cudd_Ref( p->bReached );
|
||||
Cudd_RecursiveDeref( p->dd, bAux );
|
||||
|
||||
// report the results
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
printf( "I =%5d : ", nIters );
|
||||
printf( "Fr =%7d ", nBddSizeFr );
|
||||
printf( "ImNs =%7d ", nBddSizeTo );
|
||||
printf( "ImCs =%7d ", nBddSizeTo2 );
|
||||
printf( "Rea =%7d ", Cudd_DagSize(p->bReached) );
|
||||
printf( "(%4d %4d) ", Cudd_ReadReorderings(p->dd), Cudd_ReadGarbageCollections(p->dd) );
|
||||
Abc_PrintTime( 1, "T", clock() - clkIter );
|
||||
}
|
||||
/*
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
double nMints = Cudd_CountMinterm(p->dd, bReached, Saig_ManRegNum(p->pAig) );
|
||||
// Extra_bddPrint( p->dd, bReached );printf( "\n" );
|
||||
printf( "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p->pAig)) );
|
||||
fflush( stdout );
|
||||
}
|
||||
*/
|
||||
if ( nIters == p->pPars->nIterMax - 1 )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Reached limit on the number of timeframes (%d).\n", p->pPars->nIterMax );
|
||||
p->pPars->iFrame = nIters;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// report the stats
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
double nMints = Cudd_CountMinterm(p->dd, p->bReached, Saig_ManRegNum(p->pAig) );
|
||||
if ( p->bCurrent && Cudd_IsConstant(p->bCurrent) )
|
||||
printf( "Reachability analysis completed after %d frames.\n", nIters );
|
||||
else
|
||||
printf( "Reachability analysis is stopped after %d frames.\n", nIters );
|
||||
printf( "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p->pAig)) );
|
||||
fflush( stdout );
|
||||
}
|
||||
if ( p->bCurrent == NULL || !Cudd_IsConstant(p->bCurrent) )
|
||||
{
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "Verified only for states reachable in %d frames. ", nIters );
|
||||
p->pPars->iFrame = p->pPars->nIterMax;
|
||||
return -1; // undecided
|
||||
}
|
||||
// report
|
||||
if ( !p->pPars->fSilent )
|
||||
printf( "The miter is proved unreachable after %d iterations. ", nIters );
|
||||
p->pPars->iFrame = nIters - 1;
|
||||
Abc_PrintTime( 1, "Time", clock() - clk );
|
||||
return 1; // unreachable
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reorders BDDs in the working manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_Nonlin4Reorder( DdManager * dd, int fTwice, int fVerbose )
|
||||
{
|
||||
int clk = clock();
|
||||
if ( fVerbose )
|
||||
Abc_Print( 1, "Reordering... Before =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
|
||||
Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
|
||||
if ( fVerbose )
|
||||
Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
|
||||
if ( fTwice )
|
||||
{
|
||||
Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
|
||||
if ( fVerbose )
|
||||
Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
|
||||
}
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Time", clock() - clk );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Llb_Mnx_t * Llb_MnxStart( Aig_Man_t * pAig, Gia_ParLlb_t * pPars )
|
||||
{
|
||||
Llb_Mnx_t * p;
|
||||
p = ABC_CALLOC( Llb_Mnx_t, 1 );
|
||||
p->pAig = pAig;
|
||||
p->pPars = pPars;
|
||||
// p->vOrder = Llb_Nonlin4CreateOrderSimple( pAig );
|
||||
p->vOrder = Llb_Nonlin4CreateOrderSmart( pAig );
|
||||
p->dd = Cudd_Init( Vec_IntSize(p->vOrder), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
Llb_Nonlin4SetupVarMap( p->dd, pAig, p->vOrder );
|
||||
Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT );
|
||||
p->vVars2Q = Llb_Nonlin4CreateVars2Q( p->dd, pAig, p->vOrder, 1 );
|
||||
p->vRoots = Llb_Nonlin4DerivePartitions( p->dd, pAig, p->vOrder );
|
||||
p->vRings = Vec_PtrAlloc( 100 );
|
||||
if ( pPars->fReorder )
|
||||
Llb_Nonlin4Reorder( p->dd, 0, 1 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Llb_MnxStop( Llb_Mnx_t * p )
|
||||
{
|
||||
DdNode * bTemp;
|
||||
int i;
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
p->timeReo = Cudd_ReadReorderingTime(p->dd);
|
||||
p->timeOther = p->timeTotal - p->timeImage - p->timeRemap;
|
||||
ABC_PRTP( "Image ", p->timeImage, p->timeTotal );
|
||||
ABC_PRTP( "Remap ", p->timeRemap, p->timeTotal );
|
||||
ABC_PRTP( "Other ", p->timeOther, p->timeTotal );
|
||||
ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
|
||||
ABC_PRTP( " reo ", p->timeReo, p->timeTotal );
|
||||
}
|
||||
// remove BDDs
|
||||
if ( p->bBad )
|
||||
Cudd_RecursiveDeref( p->dd, p->bBad );
|
||||
if ( p->bReached )
|
||||
Cudd_RecursiveDeref( p->dd, p->bReached );
|
||||
if ( p->bCurrent )
|
||||
Cudd_RecursiveDeref( p->dd, p->bCurrent );
|
||||
if ( p->bNext )
|
||||
Cudd_RecursiveDeref( p->dd, p->bNext );
|
||||
Vec_PtrForEachEntry( DdNode *, p->vRings, bTemp, i )
|
||||
Cudd_RecursiveDeref( p->dd, bTemp );
|
||||
Vec_PtrForEachEntry( DdNode *, p->vRoots, bTemp, i )
|
||||
Cudd_RecursiveDeref( p->dd, bTemp );
|
||||
// remove arrays
|
||||
Vec_PtrFree( p->vRings );
|
||||
Vec_PtrFree( p->vRoots );
|
||||
Extra_StopManager( p->dd );
|
||||
Vec_IntFreeP( &p->vOrder );
|
||||
Vec_IntFreeP( &p->vVars2Q );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds balanced cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Llb_Nonlin4CoreReach( Aig_Man_t * pAig, Gia_ParLlb_t * pPars )
|
||||
{
|
||||
Llb_Mnx_t * pMnn;
|
||||
int RetValue = -1;
|
||||
if ( pPars->fVerbose )
|
||||
Aig_ManPrintStats( pAig );
|
||||
if ( !pPars->fSkipReach )
|
||||
{
|
||||
int clk = clock();
|
||||
pMnn = Llb_MnxStart( pAig, pPars );
|
||||
RetValue = Llb_Nonlin4Reachability( pMnn );
|
||||
pMnn->timeTotal = clock() - clk;
|
||||
Llb_MnxStop( pMnn );
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -176,12 +176,20 @@ extern DdManager * Llb_NonlinImageStart( Aig_Man_t * pAig, Vec_Ptr_t * vLeav
|
|||
extern DdNode * Llb_NonlinImageCompute( DdNode * bCurrent, int fReorder, int fDrop, int fVerbose, int * pOrder );
|
||||
extern void Llb_NonlinImageQuit();
|
||||
|
||||
/*=== llb3Image.c ======================================================*/
|
||||
/*=== llb3Image.c =======================================================*/
|
||||
extern DdNode * Llb_NonlinImage( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q,
|
||||
DdManager * dd, DdNode * bCurrent, int fReorder, int fVerbose, int * pOrder, int Limit, int TimeTarget );
|
||||
/*=== llb3Nonlin.c ======================================================*/
|
||||
extern DdNode * Llb_NonlinComputeInitState( Aig_Man_t * pAig, DdManager * dd );
|
||||
|
||||
/*=== llb4Image.c =======================================================*/
|
||||
extern DdNode * Llb_Nonlin4Image( DdManager * dd, Vec_Ptr_t * vParts, DdNode * bCurrent, Vec_Int_t * vVars2Q );
|
||||
/*=== llb4Map.c =========================================================*/
|
||||
//extern Vec_Int_t * Llb_AigMap( Aig_Man_t * pAig, int nLutSize, int nLutMin );
|
||||
/*=== llb4Nonlin.c ======================================================*/
|
||||
extern int Llb_Nonlin4CoreReach( Aig_Man_t * pAig, Gia_ParLlb_t * pPars );
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,4 +16,6 @@ SRC += src/aig/llb/llb.c \
|
|||
src/aig/llb/llb2Flow.c \
|
||||
src/aig/llb/llb2Image.c \
|
||||
src/aig/llb/llb3Image.c \
|
||||
src/aig/llb/llb3Nonlin.c
|
||||
src/aig/llb/llb3Nonlin.c \
|
||||
src/aig/llb/llb4Image.c \
|
||||
src/aig/llb/llb4Nonlin.c
|
||||
|
|
|
|||
|
|
@ -373,6 +373,7 @@ static int Abc_CommandAbc9Posplit ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9ReachM ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9ReachP ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9ReachN ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9ReachY ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Undo ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
|
|
@ -784,6 +785,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&reachm", Abc_CommandAbc9ReachM, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&reachp", Abc_CommandAbc9ReachP, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&reachn", Abc_CommandAbc9ReachN, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&reachy", Abc_CommandAbc9ReachY, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&undo", Abc_CommandAbc9Undo, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 );
|
||||
|
||||
|
|
@ -8528,6 +8530,12 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Aig_ManTerSimulate( pAig );
|
||||
Aig_ManStop( pAig );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
{
|
||||
extern void Ssm_ManExperiment( char * pFileIn, char * pFileOut );
|
||||
Ssm_ManExperiment( "m\\big1.ssim", "m\\big1_.ssim" );
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
usage:
|
||||
|
|
@ -27957,6 +27965,137 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9ReachY( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Gia_ParLlb_t Pars, * pPars = &Pars;
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
Aig_Man_t * pMan;
|
||||
char * pLogFileName = NULL;
|
||||
int c;
|
||||
extern int Llb_Nonlin4CoreReach( Aig_Man_t * pAig, Gia_ParLlb_t * pPars );
|
||||
|
||||
// set defaults
|
||||
Llb_ManSetDefaultParams( pPars );
|
||||
pPars->fReorder = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "BFTLryzvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'B':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-B\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nBddMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nBddMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'F':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nIterMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nIterMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'T':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->TimeLimit = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->TimeLimit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'L':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-L\" should be followed by a file name.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pLogFileName = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'r':
|
||||
pPars->fReorder ^= 1;
|
||||
break;
|
||||
case 'y':
|
||||
pPars->fSkipOutCheck ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
pPars->fSkipReach ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
pPars->fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9ReachN(): There is no AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Gia_ManRegNum(pAbc->pGia) == 0 )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9ReachN(): The current AIG has no latches.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ManObjNum(pAbc->pGia) >= (1<<16) )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9ReachN(): Currently cannot handle AIGs with more than %d objects.\n", (1<<16) );
|
||||
return 0;
|
||||
}
|
||||
pMan = Gia_ManToAigSimple( pAbc->pGia );
|
||||
pAbc->Status = Llb_Nonlin4CoreReach( pMan, pPars );
|
||||
pAbc->nFrames = pPars->iFrame;
|
||||
Abc_FrameReplaceCex( pAbc, &pMan->pSeqModel );
|
||||
if ( pLogFileName )
|
||||
Abc_NtkWriteLogFile( pLogFileName, pAbc->pCex, pAbc->Status, pAbc->nFrames, "&reachn" );
|
||||
Aig_ManStop( pMan );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &reachy [-BFT num] [-L file] [-ryzvh]\n" );
|
||||
Abc_Print( -2, "\t model checking via BDD-based reachability (non-linear-QS-based)\n" );
|
||||
Abc_Print( -2, "\t-B num : the BDD node increase when hints kick in [default = %d]\n", pPars->nBddMax );
|
||||
Abc_Print( -2, "\t-F num : max number of reachability iterations [default = %d]\n", pPars->nIterMax );
|
||||
Abc_Print( -2, "\t-T num : approximate time limit in seconds (0=infinite) [default = %d]\n", pPars->TimeLimit );
|
||||
Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" );
|
||||
Abc_Print( -2, "\t-r : enable additional BDD var reordering before image [default = %s]\n", pPars->fReorder? "yes": "no" );
|
||||
Abc_Print( -2, "\t-y : skip checking property outputs [default = %s]\n", pPars->fSkipOutCheck? "yes": "no" );
|
||||
Abc_Print( -2, "\t-z : skip reachability (run preparation phase only) [default = %s]\n", pPars->fSkipReach? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
// Abc_Print( -2, "\t-w : prints additional information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
|
||||
extern If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
|
||||
static Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk );
|
||||
extern Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vCover );
|
||||
static Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj );
|
||||
|
|
|
|||
|
|
@ -1251,6 +1251,9 @@ cuddBddVarMapRecur(
|
|||
return(Cudd_NotCond(res,F != f));
|
||||
}
|
||||
|
||||
if ( manager->TimeStop && manager->TimeStop < clock() )
|
||||
return NULL;
|
||||
|
||||
/* Split and recur on children of this node. */
|
||||
T = cuddBddVarMapRecur(manager,cuddT(F));
|
||||
if (T == NULL) return(NULL);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ struct Vec_Vec_t_
|
|||
for ( i = Vec_VecSize(vGlob)-1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
#define Vec_VecForEachLevelReverseStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart-1; (i >= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
#define Vec_VecForEachLevelTwo( vGlob1, vGlob2, vVec1, vVec2, i ) \
|
||||
for ( i = 0; (i < Vec_VecSize(vGlob1)) && (((vVec1) = (Vec_Ptr_t*)Vec_VecEntry(vGlob1, i)), 1) && (((vVec2) = (Vec_Ptr_t*)Vec_VecEntry(vGlob2, i)), 1); i++ )
|
||||
|
||||
// iterators through levels
|
||||
#define Vec_VecForEachLevelInt( vGlob, vVec, i ) \
|
||||
|
|
@ -78,6 +80,8 @@ struct Vec_Vec_t_
|
|||
for ( i = Vec_VecSize(vGlob)-1; (i >= 0) && (((vVec) = (Vec_Int_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
#define Vec_VecForEachLevelIntReverseStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart-1; (i >= LevelStop) && (((vVec) = (Vec_Int_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
#define Vec_VecForEachLevelIntTwo( vGlob1, vGlob2, vVec1, vVec2, i ) \
|
||||
for ( i = 0; (i < Vec_VecSize(vGlob1)) && (((vVec1) = (Vec_Int_t*)Vec_VecEntry(vGlob1, i)), 1) && (((vVec2) = (Vec_Int_t*)Vec_VecEntry(vGlob2, i)), 1); i++ )
|
||||
|
||||
// iteratores through entries
|
||||
#define Vec_VecForEachEntry( Type, vGlob, pEntry, i, k ) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue