blob: 3ba22bec72e67a8a486d82a43710a8f43a4850f0 [file] [log] [blame]
/**CFile****************************************************************
FileName [saigTempor.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential AIG package.]
Synopsis [Temporal decomposition.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: saigTempor.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "saig.h"
#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates initialized timeframes for temporal decomposition.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManTemporFrames( Aig_Man_t * pAig, int nFrames )
{
Aig_Man_t * pFrames;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i, f;
// start the frames package
Aig_ManCleanData( pAig );
pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * nFrames );
pFrames->pName = Abc_UtilStrsav( pAig->pName );
// initiliaze the flops
Saig_ManForEachLo( pAig, pObj, i )
pObj->pData = Aig_ManConst0(pFrames);
// for each timeframe
for ( f = 0; f < nFrames; f++ )
{
Aig_ManConst1(pAig)->pData = Aig_ManConst1(pFrames);
Saig_ManForEachPi( pAig, pObj, i )
pObj->pData = Aig_ObjCreateCi(pFrames);
Aig_ManForEachNode( pAig, pObj, i )
pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
Aig_ManForEachCo( pAig, pObj, i )
pObj->pData = Aig_ObjChild0Copy(pObj);
Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
pObjLo->pData = pObjLi->pData;
}
// create POs for the flop inputs
Saig_ManForEachLi( pAig, pObj, i )
Aig_ObjCreateCo( pFrames, (Aig_Obj_t *)pObj->pData );
Aig_ManCleanup( pFrames );
return pFrames;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManTemporDecompose( Aig_Man_t * pAig, int nFrames )
{
Aig_Man_t * pAigNew, * pFrames;
Aig_Obj_t * pObj, * pReset;
int i;
if ( pAig->nConstrs > 0 )
{
printf( "The AIG manager should have no constraints.\n" );
return NULL;
}
// create initialized timeframes
pFrames = Saig_ManTemporFrames( pAig, nFrames );
assert( Aig_ManCoNum(pFrames) == Aig_ManRegNum(pAig) );
// start the new manager
Aig_ManCleanData( pAig );
pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
pAigNew->pName = Abc_UtilStrsav( pAig->pName );
// map the constant node and primary inputs
Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
Saig_ManForEachPi( pAig, pObj, i )
pObj->pData = Aig_ObjCreateCi( pAigNew );
// insert initialization logic
Aig_ManConst1(pFrames)->pData = Aig_ManConst1( pAigNew );
Aig_ManForEachCi( pFrames, pObj, i )
pObj->pData = Aig_ObjCreateCi( pAigNew );
Aig_ManForEachNode( pFrames, pObj, i )
pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
Aig_ManForEachCo( pFrames, pObj, i )
pObj->pData = Aig_ObjChild0Copy(pObj);
// create reset latch (the first one among the latches)
pReset = Aig_ObjCreateCi( pAigNew );
// create flop output values
Saig_ManForEachLo( pAig, pObj, i )
pObj->pData = Aig_Mux( pAigNew, pReset, Aig_ObjCreateCi(pAigNew), (Aig_Obj_t *)Aig_ManCo(pFrames, i)->pData );
Aig_ManStop( pFrames );
// add internal nodes of this frame
Aig_ManForEachNode( pAig, pObj, i )
pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// create primary outputs
Saig_ManForEachPo( pAig, pObj, i )
Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
// create reset latch (the first one among the latches)
Aig_ObjCreateCo( pAigNew, Aig_ManConst1(pAigNew) );
// create latch inputs
Saig_ManForEachLi( pAig, pObj, i )
Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
// finalize
Aig_ManCleanup( pAigNew );
Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig)+1 ); // + reset latch (011111...)
return pAigNew;
}
/**Function*************************************************************
Synopsis [Find index of first non-zero entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Vec_IntLastNonZeroBeforeLimit( Vec_Int_t * vTemp, int Limit )
{
int Entry, i;
if ( vTemp == NULL )
return -1;
Vec_IntForEachEntryReverse( vTemp, Entry, i )
{
if ( i >= Limit )
continue;
if ( Entry )
return i;
}
return -1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManTempor( Aig_Man_t * pAig, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fUseTransSigs, int fVerbose, int fVeryVerbose )
{
extern int Saig_ManPhasePrefixLength( Aig_Man_t * p, int fVerbose, int fVeryVerbose, Vec_Int_t ** pvTrans );
Vec_Int_t * vTransSigs = NULL;
int RetValue, nFramesFinished = -1;
assert( nFrames >= 0 );
if ( nFrames == 0 )
{
nFrames = Saig_ManPhasePrefixLength( pAig, fVerbose, fVeryVerbose, &vTransSigs );
if ( nFrames == 0 )
{
Vec_IntFreeP( &vTransSigs );
printf( "The leading sequence has length 0. Temporal decomposition is not performed.\n" );
return NULL;
}
if ( nFrames == 1 )
{
Vec_IntFreeP( &vTransSigs );
printf( "The leading sequence has length 1. Temporal decomposition is not performed.\n" );
return NULL;
}
if ( fUseTransSigs )
{
int Entry, i, iLast = -1;
Vec_IntForEachEntry( vTransSigs, Entry, i )
iLast = Entry ? i :iLast;
if ( iLast > 0 && iLast < nFrames )
{
Abc_Print( 1, "Reducing frame count from %d to %d to fit the last transient.\n", nFrames, iLast );
nFrames = iLast;
}
}
Abc_Print( 1, "Using computed frame number (%d).\n", nFrames );
}
else
Abc_Print( 1, "Using user-given frame number (%d).\n", nFrames );
// run BMC2
if ( fUseBmc )
{
RetValue = Saig_BmcPerform( pAig, 0, nFrames, 2000, TimeOut, nConfLimit, 0, fVerbose, 0, &nFramesFinished, 0, 0 );
if ( RetValue == 0 )
{
Vec_IntFreeP( &vTransSigs );
printf( "A cex found in the first %d frames.\n", nFrames );
return NULL;
}
if ( nFramesFinished + 1 < nFrames )
{
int iLastBefore = Vec_IntLastNonZeroBeforeLimit( vTransSigs, nFramesFinished );
if ( iLastBefore < 1 || !fUseTransSigs )
{
Vec_IntFreeP( &vTransSigs );
printf( "BMC for %d frames could not be completed. A cex may exist!\n", nFrames );
return NULL;
}
assert( iLastBefore < nFramesFinished );
printf( "BMC succeeded to frame %d. Adjusting frame count to be (%d) based on the last transient signal.\n", nFramesFinished, iLastBefore );
nFrames = iLastBefore;
}
}
Vec_IntFreeP( &vTransSigs );
return Saig_ManTemporDecompose( pAig, nFrames );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END