summaryrefslogtreecommitdiffstats
path: root/src/base/abci/abcQuant.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2007-10-01 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2007-10-01 08:01:00 -0700
commit4812c90424dfc40d26725244723887a2d16ddfd9 (patch)
treeb32ace96e7e2d84d586e09ba605463b6f49c3271 /src/base/abci/abcQuant.c
parente54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (diff)
downloadabc-4812c90424dfc40d26725244723887a2d16ddfd9.tar.gz
abc-4812c90424dfc40d26725244723887a2d16ddfd9.tar.bz2
abc-4812c90424dfc40d26725244723887a2d16ddfd9.zip
Version abc71001
Diffstat (limited to 'src/base/abci/abcQuant.c')
-rw-r--r--src/base/abci/abcQuant.c419
1 files changed, 419 insertions, 0 deletions
diff --git a/src/base/abci/abcQuant.c b/src/base/abci/abcQuant.c
new file mode 100644
index 00000000..0f2bd72f
--- /dev/null
+++ b/src/base/abci/abcQuant.c
@@ -0,0 +1,419 @@
+/**CFile****************************************************************
+
+ FileName [abcQuant.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [AIG-based variable quantification.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcQuant.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs fast synthesis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSynthesize( Abc_Ntk_t ** ppNtk, int fMoreEffort )
+{
+ Abc_Ntk_t * pNtk, * pNtkTemp;
+
+ pNtk = *ppNtk;
+
+ Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
+ Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
+ pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 );
+ Abc_NtkDelete( pNtkTemp );
+
+ if ( fMoreEffort )
+ {
+ Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
+ Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
+ pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 );
+ Abc_NtkDelete( pNtkTemp );
+ }
+
+ *ppNtk = pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Existentially quantifies one variable.]
+
+ Description []
+
+ SideEffects [This procedure creates dangling nodes in the AIG.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkQuantify( Abc_Ntk_t * pNtk, int fUniv, int iVar, int fVerbose )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pObj, * pNext, * pFanin;
+ int i;
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( iVar < Abc_NtkCiNum(pNtk) );
+
+ // collect the internal nodes
+ pObj = Abc_NtkCi( pNtk, iVar );
+ vNodes = Abc_NtkDfsReverseNodes( pNtk, &pObj, 1 );
+
+ // assign the cofactors of the CI node to be constants
+ pObj->pCopy = Abc_ObjNot( Abc_AigConst1(pNtk) );
+ pObj->pData = Abc_AigConst1(pNtk);
+
+ // quantify the nodes
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ for ( pNext = pObj? pObj->pCopy : pObj; pObj; pObj = pNext, pNext = pObj? pObj->pCopy : pObj )
+ {
+ pFanin = Abc_ObjFanin0(pObj);
+ if ( !Abc_NodeIsTravIdCurrent(pFanin) )
+ pFanin->pCopy = pFanin->pData = pFanin;
+ pFanin = Abc_ObjFanin1(pObj);
+ if ( !Abc_NodeIsTravIdCurrent(pFanin) )
+ pFanin->pCopy = pFanin->pData = pFanin;
+ pObj->pCopy = Abc_AigAnd( pNtk->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
+ pObj->pData = Abc_AigAnd( pNtk->pManFunc, Abc_ObjChild0Data(pObj), Abc_ObjChild1Data(pObj) );
+ }
+ }
+ Vec_PtrFree( vNodes );
+
+ // update the affected COs
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ if ( !Abc_NodeIsTravIdCurrent(pObj) )
+ continue;
+ pFanin = Abc_ObjFanin0(pObj);
+ // get the result of quantification
+ if ( fUniv )
+ pNext = Abc_AigAnd( pNtk->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild0Data(pObj) );
+ else
+ pNext = Abc_AigOr( pNtk->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild0Data(pObj) );
+ pNext = Abc_ObjNotCond( pNext, Abc_ObjFaninC0(pObj) );
+ if ( Abc_ObjRegular(pNext) == pFanin )
+ continue;
+ // update the fanins of the CO
+ Abc_ObjPatchFanin( pObj, pFanin, pNext );
+// if ( Abc_ObjFanoutNum(pFanin) == 0 )
+// Abc_AigDeleteNode( pNtk->pManFunc, pFanin );
+ }
+
+ // make sure the node has no fanouts
+// pObj = Abc_NtkCi( pNtk, iVar );
+// assert( Abc_ObjFanoutNum(pObj) == 0 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the transition relation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkTransRel( Abc_Ntk_t * pNtk, int fInputs, int fVerbose )
+{
+ char Buffer[1000];
+ Vec_Ptr_t * vPairs;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pMiter;
+ int i, nLatches;
+ int fSynthesis = 1;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( Abc_NtkLatchNum(pNtk) );
+ nLatches = Abc_NtkLatchNum(pNtk);
+ // start the network
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
+ // duplicate the name and the spec
+ sprintf( Buffer, "%s_TR", pNtk->pName );
+ pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
+// pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
+ Abc_NtkCleanCopy( pNtk );
+ // create current state variables
+ Abc_NtkForEachLatchOutput( pNtk, pObj, i )
+ {
+ pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
+ Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
+ }
+ // create next state variables
+ Abc_NtkForEachLatchInput( pNtk, pObj, i )
+ Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj), NULL );
+ // create PI variables
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkDupObj( pNtkNew, pObj, 1 );
+ // create the PO
+ Abc_NtkCreatePo( pNtkNew );
+ // restrash the nodes (assuming a topological order of the old network)
+ Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
+ // create the function of the primary output
+ assert( Abc_NtkBoxNum(pNtk) == Abc_NtkLatchNum(pNtk) );
+ vPairs = Vec_PtrAlloc( 2*nLatches );
+ Abc_NtkForEachLatchInput( pNtk, pObj, i )
+ {
+ Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pObj) );
+ Vec_PtrPush( vPairs, Abc_NtkPi(pNtkNew, i+nLatches) );
+ }
+ pMiter = Abc_AigMiter( pNtkNew->pManFunc, vPairs );
+ Vec_PtrFree( vPairs );
+ // add the primary output
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkNew,0), Abc_ObjNot(pMiter) );
+ Abc_ObjAssignName( Abc_NtkPo(pNtkNew,0), "rel", NULL );
+
+ // quantify inputs
+ if ( fInputs )
+ {
+ assert( Abc_NtkPiNum(pNtkNew) == Abc_NtkPiNum(pNtk) + 2*nLatches );
+ for ( i = Abc_NtkPiNum(pNtkNew) - 1; i >= 2*nLatches; i-- )
+// for ( i = 2*nLatches; i < Abc_NtkPiNum(pNtkNew); i++ )
+ {
+ Abc_NtkQuantify( pNtkNew, 0, i, fVerbose );
+// if ( fSynthesis && (i % 3 == 2) )
+ if ( fSynthesis )
+ {
+ Abc_NtkCleanData( pNtkNew );
+ Abc_AigCleanup( pNtkNew->pManFunc );
+ Abc_NtkSynthesize( &pNtkNew, 1 );
+ }
+// printf( "Var = %3d. Nodes = %6d. ", Abc_NtkPiNum(pNtkNew) - 1 - i, Abc_NtkNodeNum(pNtkNew) );
+// printf( "Var = %3d. Nodes = %6d. ", i - 2*nLatches, Abc_NtkNodeNum(pNtkNew) );
+ }
+// printf( "\n" );
+ Abc_NtkCleanData( pNtkNew );
+ Abc_AigCleanup( pNtkNew->pManFunc );
+ for ( i = Abc_NtkPiNum(pNtkNew) - 1; i >= 2*nLatches; i-- )
+ {
+ pObj = Abc_NtkPi( pNtkNew, i );
+ assert( Abc_ObjFanoutNum(pObj) == 0 );
+ Abc_NtkDeleteObj( pObj );
+ }
+ }
+
+ // check consistency of the network
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkTransRel: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs one image computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkInitialState( Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pMiter;
+ int i, nVars = Abc_NtkPiNum(pNtk)/2;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
+ // compute the all-zero state in terms of the CS variables
+ pMiter = Abc_AigConst1(pNtkNew);
+ for ( i = 0; i < nVars; i++ )
+ pMiter = Abc_AigAnd( pNtkNew->pManFunc, pMiter, Abc_ObjNot( Abc_NtkPi(pNtkNew, i) ) );
+ // add the PO
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkNew,0), pMiter );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Swaps current state and next state variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkSwapVariables( Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pMiter, * pObj, * pObj0, * pObj1;
+ int i, nVars = Abc_NtkPiNum(pNtk)/2;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
+ // update the PIs
+ for ( i = 0; i < nVars; i++ )
+ {
+ pObj0 = Abc_NtkPi( pNtk, i );
+ pObj1 = Abc_NtkPi( pNtk, i+nVars );
+ pMiter = pObj0->pCopy;
+ pObj0->pCopy = pObj1->pCopy;
+ pObj1->pCopy = pMiter;
+ }
+ // restrash
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
+ // add the PO
+ pMiter = Abc_ObjChild0Copy( Abc_NtkPo(pNtk,0) );
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkNew,0), pMiter );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs reachability analisys.]
+
+ Description [Assumes that the input is the transition relation.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkReachability( Abc_Ntk_t * pNtkRel, int nIters, int fVerbose )
+{
+ Abc_Obj_t * pObj;
+ Abc_Ntk_t * pNtkFront, * pNtkReached, * pNtkNext, * pNtkTemp;
+ int clk, i, v, nVars, nNodesOld, nNodesNew, nNodesPrev;
+ int fFixedPoint = 0;
+ int fSynthesis = 1;
+ int fMoreEffort = 1;
+
+ assert( Abc_NtkIsStrash(pNtkRel) );
+ assert( Abc_NtkLatchNum(pNtkRel) == 0 );
+ assert( Abc_NtkPiNum(pNtkRel) % 2 == 0 );
+
+ // compute the network composed of the initial states
+ pNtkFront = Abc_NtkInitialState( pNtkRel );
+ pNtkReached = Abc_NtkDup( pNtkFront );
+//Abc_NtkShow( pNtkReached, 0, 0, 0 );
+
+// if ( fVerbose )
+// printf( "Transition relation = %6d.\n", Abc_NtkNodeNum(pNtkRel) );
+
+ // perform iterations of reachability analysis
+ nNodesPrev = Abc_NtkNodeNum(pNtkFront);
+ nVars = Abc_NtkPiNum(pNtkRel)/2;
+ for ( i = 0; i < nIters; i++ )
+ {
+ clk = clock();
+ // get the set of next states
+ pNtkNext = Abc_NtkMiterAnd( pNtkRel, pNtkFront, 0, 0 );
+ Abc_NtkDelete( pNtkFront );
+ // quantify the current state variables
+ for ( v = 0; v < nVars; v++ )
+ {
+ Abc_NtkQuantify( pNtkNext, 0, v, fVerbose );
+ if ( fSynthesis && (v % 3 == 2) )
+ {
+ Abc_NtkCleanData( pNtkNext );
+ Abc_AigCleanup( pNtkNext->pManFunc );
+ Abc_NtkSynthesize( &pNtkNext, fMoreEffort );
+ }
+ }
+ Abc_NtkCleanData( pNtkNext );
+ Abc_AigCleanup( pNtkNext->pManFunc );
+ if ( fSynthesis )
+ Abc_NtkSynthesize( &pNtkNext, 1 );
+ // map the next states into the current states
+ pNtkNext = Abc_NtkSwapVariables( pNtkTemp = pNtkNext );
+ Abc_NtkDelete( pNtkTemp );
+ // check the termination condition
+ if ( Abc_ObjFanin0(Abc_NtkPo(pNtkNext,0)) == Abc_AigConst1(pNtkNext) )
+ {
+ fFixedPoint = 1;
+ printf( "Fixed point is reached!\n" );
+ Abc_NtkDelete( pNtkNext );
+ break;
+ }
+ // compute new front
+ pNtkFront = Abc_NtkMiterAnd( pNtkNext, pNtkReached, 0, 1 );
+ Abc_NtkDelete( pNtkNext );
+ // add the reached states
+ pNtkReached = Abc_NtkMiterAnd( pNtkTemp = pNtkReached, pNtkFront, 1, 0 );
+ Abc_NtkDelete( pNtkTemp );
+ // compress the size of Front
+ nNodesOld = Abc_NtkNodeNum(pNtkFront);
+ if ( fSynthesis )
+ {
+ Abc_NtkSynthesize( &pNtkFront, fMoreEffort );
+ Abc_NtkSynthesize( &pNtkReached, fMoreEffort );
+ }
+ nNodesNew = Abc_NtkNodeNum(pNtkFront);
+ // print statistics
+ if ( fVerbose )
+ {
+ printf( "I = %3d : Reach = %6d Fr = %6d FrM = %6d %7.2f %% ",
+ i + 1, Abc_NtkNodeNum(pNtkReached), nNodesOld, nNodesNew, 100.0*(nNodesNew-nNodesPrev)/nNodesPrev );
+ PRT( "T", clock() - clk );
+ }
+ nNodesPrev = Abc_NtkNodeNum(pNtkFront);
+ }
+ if ( !fFixedPoint )
+ fprintf( stdout, "Reachability analysis stopped after %d iterations.\n", nIters );
+
+ // complement the output to represent the set of unreachable states
+ Abc_ObjXorFaninC( Abc_NtkPo(pNtkReached,0), 0 );
+
+ // remove next state variables
+ for ( i = 2*nVars - 1; i >= nVars; i-- )
+ {
+ pObj = Abc_NtkPi( pNtkReached, i );
+ assert( Abc_ObjFanoutNum(pObj) == 0 );
+ Abc_NtkDeleteObj( pObj );
+ }
+
+ // check consistency of the network
+ if ( !Abc_NtkCheck( pNtkReached ) )
+ {
+ printf( "Abc_NtkReachability: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkReached );
+ return NULL;
+ }
+ return pNtkReached;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+