summaryrefslogtreecommitdiffstats
path: root/src/aig/saig/saigRetMin.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-04-20 20:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2008-04-20 20:01:00 -0700
commit7ec48bc20de6209f311715f4b1479cb2e0a4d906 (patch)
tree00ee497c28001a646f98407115f5541fb49adf83 /src/aig/saig/saigRetMin.c
parent7ff4c2b2719a78ba7d1ddcfdf9356affa291e876 (diff)
downloadabc-7ec48bc20de6209f311715f4b1479cb2e0a4d906.tar.gz
abc-7ec48bc20de6209f311715f4b1479cb2e0a4d906.tar.bz2
abc-7ec48bc20de6209f311715f4b1479cb2e0a4d906.zip
Version abc80420_2
Diffstat (limited to 'src/aig/saig/saigRetMin.c')
-rw-r--r--src/aig/saig/saigRetMin.c269
1 files changed, 245 insertions, 24 deletions
diff --git a/src/aig/saig/saigRetMin.c b/src/aig/saig/saigRetMin.c
index 92d39ab6..3adb76c6 100644
--- a/src/aig/saig/saigRetMin.c
+++ b/src/aig/saig/saigRetMin.c
@@ -19,6 +19,8 @@
***********************************************************************/
#include "saig.h"
+#include "satSolver.h"
+#include "cnf.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -54,7 +56,7 @@ void Saig_ManMarkCone_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
/**Function*************************************************************
- Synopsis [Marks the TFI cones with the current traversal ID.]
+ Synopsis [Counts the number of nodes to get registers after retiming.]
Description []
@@ -63,18 +65,44 @@ void Saig_ManMarkCone_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-void Saig_ManMarkCones( Aig_Man_t * p, Vec_Ptr_t * vNodes )
+int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut )
{
- Aig_Obj_t * pObj;
- int i;
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pObj, * pFanin;
+ int i, RetValue;
+ // mark the cones
Aig_ManIncrementTravId( p );
- Vec_PtrForEachEntry( vNodes, pObj, i )
+ Vec_PtrForEachEntry( vCut, pObj, i )
Saig_ManMarkCone_rec( p, pObj );
+ // collect the new cut
+ vNodes = Vec_PtrAlloc( 1000 );
+ Aig_ManForEachObj( p, pObj, i )
+ {
+ if ( Aig_ObjIsTravIdCurrent(p, pObj) )
+ continue;
+ pFanin = Aig_ObjFanin0( pObj );
+ if ( pFanin && !pFanin->fMarkA && Aig_ObjIsTravIdCurrent(p, pFanin) )
+ {
+ Vec_PtrPush( vNodes, pFanin );
+ pFanin->fMarkA = 1;
+ }
+ pFanin = Aig_ObjFanin1( pObj );
+ if ( pFanin && !pFanin->fMarkA && Aig_ObjIsTravIdCurrent(p, pFanin) )
+ {
+ Vec_PtrPush( vNodes, pFanin );
+ pFanin->fMarkA = 1;
+ }
+ }
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ pObj->fMarkA = 0;
+ RetValue = Vec_PtrSize( vNodes );
+ Vec_PtrFree( vNodes );
+ return RetValue;
}
/**Function*************************************************************
- Synopsis [Counts the number of nodes to get registers after retiming.]
+ Synopsis [Computes the new cut after excluding the nodes in the set.]
Description []
@@ -83,12 +111,18 @@ void Saig_ManMarkCones( Aig_Man_t * p, Vec_Ptr_t * vNodes )
SeeAlso []
***********************************************************************/
-int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut )
+Vec_Ptr_t * Saig_ManRetimeExtendCut( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Ptr_t * vToExclude )
{
Vec_Ptr_t * vNodes;
Aig_Obj_t * pObj, * pFanin;
- int i, RetValue;
- Saig_ManMarkCones( p, vCut );
+ int i;
+ // mark the cones
+ Aig_ManIncrementTravId( p );
+ Vec_PtrForEachEntry( vCut, pObj, i )
+ Saig_ManMarkCone_rec( p, pObj );
+ Vec_PtrForEachEntry( vToExclude, pObj, i )
+ Saig_ManMarkCone_rec( p, pObj );
+ // collect the new cut
vNodes = Vec_PtrAlloc( 1000 );
Aig_ManForEachObj( p, pObj, i )
{
@@ -107,16 +141,14 @@ int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut )
pFanin->fMarkA = 1;
}
}
- RetValue = Vec_PtrSize( vNodes );
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->fMarkA = 0;
- Vec_PtrFree( vNodes );
- return RetValue;
+ return vNodes;
}
/**Function*************************************************************
- Synopsis [Duplicates the AIG while retiming the registers to the cut.]
+ Synopsis [Duplicates the AIG recursively.]
Description []
@@ -125,13 +157,13 @@ int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut )
SeeAlso []
***********************************************************************/
-void Saig_ManRetimeDupForward_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj )
+void Saig_ManRetimeDup_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj )
{
if ( pObj->pData )
return;
assert( Aig_ObjIsNode(pObj) );
- Saig_ManRetimeDupForward_rec( pNew, Aig_ObjFanin0(pObj) );
- Saig_ManRetimeDupForward_rec( pNew, Aig_ObjFanin1(pObj) );
+ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) );
+ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin1(pObj) );
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
}
@@ -168,9 +200,9 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut )
// create the registers
Vec_PtrForEachEntry( vCut, pObj, i )
pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), pObj->fPhase );
- // duplicate the logic above the cut
+ // duplicate logic above the cut
Aig_ManForEachPo( p, pObj, i )
- Saig_ManRetimeDupForward_rec( pNew, Aig_ObjFanin0(pObj) );
+ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) );
// create the true POs
Saig_ManForEachPo( p, pObj, i )
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
@@ -182,12 +214,12 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut )
pObjLo->pData = pObjLi->pData;
// erase the data values on the internal nodes of the cut
Vec_PtrForEachEntry( vCut, pObj, i )
- if ( !Aig_ObjIsPi(pObj) )
+ if ( Aig_ObjIsNode(pObj) )
pObj->pData = NULL;
- // duplicate the logic below the cut
+ // duplicate logic below the cut
Vec_PtrForEachEntry( vCut, pObj, i )
{
- Saig_ManRetimeDupForward_rec( pNew, pObj );
+ Saig_ManRetimeDup_rec( pNew, pObj );
Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, pObj->fPhase) );
}
return pNew;
@@ -195,7 +227,7 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut )
/**Function*************************************************************
- Synopsis [Duplicates the AIG while retiming the registers to the cut.]
+ Synopsis [Derives AIG for the initial state computation.]
Description []
@@ -204,10 +236,199 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut )
SeeAlso []
***********************************************************************/
-Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut )
+Aig_Man_t * Saig_ManRetimeDupInitState( Aig_Man_t * p, Vec_Ptr_t * vCut )
{
Aig_Man_t * pNew;
- pNew = Aig_ManDup( p );
+ Aig_Obj_t * pObj;
+ int i;
+ // mark the cones under the cut
+// assert( Vec_PtrSize(vCut) == Saig_ManRetimeCountCut(p, vCut) );
+ // create the new manager
+ pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
+ // create the true PIs
+ Aig_ManCleanData( p );
+ Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
+ // create the registers
+ Vec_PtrForEachEntry( vCut, pObj, i )
+ pObj->pData = Aig_ObjCreatePi(pNew);
+ // duplicate logic above the cut and create POs
+ Saig_ManForEachLi( p, pObj, i )
+ {
+ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) );
+ Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ }
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the initial state after backward retiming.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManRetimeFindInitState( Aig_Man_t * p )
+{
+ int nConfLimit = 1000000;
+ Vec_Int_t * vCiIds, * vInit = NULL;
+ Cnf_Dat_t * pCnf;
+ sat_solver * pSat;
+ Aig_Obj_t * pObj;
+ int i, RetValue, * pAssumps, * pModel;
+ // solve the SAT problem
+ pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) );
+ pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ pAssumps = ALLOC( int, Aig_ManPoNum(p) );
+ Aig_ManForEachPo( p, pObj, i )
+ pAssumps[i] = toLitCond( pCnf->pVarNums[pObj->Id], 1 );
+ RetValue = sat_solver_solve( pSat, pAssumps, pAssumps+Aig_ManPoNum(p), (sint64)nConfLimit, (sint64)0, (sint64)0, (sint64)0 );
+ free( pAssumps );
+ if ( RetValue == l_True )
+ {
+ // accumulate SAT variables of the CIs
+ vCiIds = Vec_IntAlloc( Aig_ManPiNum(p) );
+ Aig_ManForEachPi( p, pObj, i )
+ Vec_IntPush( vCiIds, pCnf->pVarNums[pObj->Id] );
+ // create the model
+ pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize );
+ vInit = Vec_IntAllocArray( pModel, Aig_ManPiNum(p) );
+ Vec_IntFree( vCiIds );
+ }
+ sat_solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ return vInit;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of bad registers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Saig_ManGetRegistersToExclude( Aig_Man_t * p )
+{
+ Vec_Ptr_t * vNodes = NULL;
+ Aig_Obj_t * pObj, * pFanin;
+ int i, Diffs;
+ assert( Saig_ManRegNum(p) > 0 );
+ Saig_ManForEachLi( p, pObj, i )
+ {
+ pFanin = Aig_ObjFanin0(pObj);
+ if ( !Aig_ObjFaninC0(pObj) )
+ pFanin->fMarkA = 1;
+ else
+ pFanin->fMarkB = 1;
+ }
+ Diffs = 0;
+ Saig_ManForEachLi( p, pObj, i )
+ {
+ pFanin = Aig_ObjFanin0(pObj);
+ Diffs += pFanin->fMarkA && pFanin->fMarkB;
+ }
+ if ( Diffs > 0 )
+ vNodes = Vec_PtrAlloc( Diffs );
+ Saig_ManForEachLi( p, pObj, i )
+ {
+ pFanin = Aig_ObjFanin0(pObj);
+ if ( vNodes && pFanin->fMarkA && pFanin->fMarkB )
+ Vec_PtrPush( vNodes, pFanin );
+ pFanin->fMarkA = pFanin->fMarkB = 0;
+ }
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG while retiming the registers to the cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCutInit )
+{
+ Vec_Ptr_t * vToExclude, * vCut;
+ Vec_Int_t * vInit = NULL;
+ Aig_Man_t * pNew, * pInit;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i;
+ // check if there are bad registers
+ vToExclude = Saig_ManGetRegistersToExclude( p );
+ if ( vToExclude )
+ {
+ vCut = Saig_ManRetimeExtendCut( p, vCutInit, vToExclude );
+ printf( "Bad registers = %d. Extended cut from %d to %d nodes.\n",
+ Vec_PtrSize(vToExclude), Vec_PtrSize(vCutInit), Vec_PtrSize(vCut) );
+ Vec_PtrFree( vToExclude );
+ }
+ else
+ vCut = Vec_PtrDup( vCutInit );
+ // mark the cones under the cut
+// assert( Vec_PtrSize(vCut) == Saig_ManRetimeCountCut(p, vCut) );
+ // count if there are registers to disable
+ // derive the initial state
+ pInit = Saig_ManRetimeDupInitState( p, vCut );
+ vInit = Saig_ManRetimeFindInitState( pInit );
+ if ( vInit == NULL )
+ printf( "Initial state computation has failed.\n" );
+ Aig_ManStop( pInit );
+ // create the new manager
+ pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ pNew->pSpec = Aig_UtilStrsav( p->pSpec );
+ pNew->nRegs = Vec_PtrSize(vCut);
+ pNew->nTruePis = p->nTruePis;
+ pNew->nTruePos = p->nTruePos;
+ // create the true PIs
+ Aig_ManCleanData( p );
+ Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
+ Saig_ManForEachPi( p, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( pNew );
+ // create the registers
+ Vec_PtrForEachEntry( vCut, pObj, i )
+ pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), vInit?Vec_IntEntry(vInit,i):0 );
+ // duplicate logic above the cut and remember values
+ Saig_ManForEachLi( p, pObj, i )
+ {
+ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) );
+ pObj->pData = Aig_ObjChild0Copy(pObj);
+ }
+ // transfer values from the LIs to the LOs
+ Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
+ pObjLo->pData = pObjLi->pData;
+ // erase the data values on the internal nodes of the cut
+ Vec_PtrForEachEntry( vCut, pObj, i )
+ if ( Aig_ObjIsNode(pObj) )
+ pObj->pData = NULL;
+ // replicate the data on the primary inputs
+ Saig_ManForEachPi( p, pObj, i )
+ pObj->pData = Aig_ManPi( pNew, i );
+ // duplicate logic below the cut
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) );
+ Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ }
+ Vec_PtrForEachEntry( vCut, pObj, i )
+ {
+ Saig_ManRetimeDup_rec( pNew, pObj );
+ Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, vInit?Vec_IntEntry(vInit,i):0) );
+ }
+ if ( vInit )
+ Vec_IntFree( vInit );
+ Vec_PtrFree( vCut );
return pNew;
}