summaryrefslogtreecommitdiffstats
path: root/src/aig/llb/llb4Cluster.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2011-04-14 09:57:35 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2011-04-14 09:57:35 -0700
commit75e60ab2ee65993595e3d56ae73bad23332b879c (patch)
tree5df3c3ee116c7285ccff8d0c6f535f862fff65c0 /src/aig/llb/llb4Cluster.c
parentc0c9fc84f13d54b24b6f6e1d4895889d85ec8e65 (diff)
downloadabc-75e60ab2ee65993595e3d56ae73bad23332b879c.tar.gz
abc-75e60ab2ee65993595e3d56ae73bad23332b879c.tar.bz2
abc-75e60ab2ee65993595e3d56ae73bad23332b879c.zip
Experiments with reachability.
Diffstat (limited to 'src/aig/llb/llb4Cluster.c')
-rw-r--r--src/aig/llb/llb4Cluster.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/aig/llb/llb4Cluster.c b/src/aig/llb/llb4Cluster.c
new file mode 100644
index 00000000..71e044be
--- /dev/null
+++ b/src/aig/llb/llb4Cluster.c
@@ -0,0 +1,339 @@
+/**CFile****************************************************************
+
+ FileName [llb2Cluster.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: llb2Cluster.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "llbInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Llb_MnxBddVar( Vec_Int_t * vOrder, Aig_Obj_t * pObj ) { return Vec_IntEntry(vOrder, Aig_ObjId(pObj)); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Find good static variable ordering.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Llb_Nonlin4FindOrder_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_Nonlin4FindOrder_rec( pAig, pFanin0, vOrder, pCounter );
+ Llb_Nonlin4FindOrder_rec( pAig, pFanin1, vOrder, pCounter );
+ }
+ else
+ {
+ Llb_Nonlin4FindOrder_rec( pAig, pFanin1, vOrder, pCounter );
+ Llb_Nonlin4FindOrder_rec( pAig, pFanin0, vOrder, pCounter );
+ }
+ Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), (*pCounter)++ );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find good static variable ordering.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Llb_Nonlin4FindOrder( Aig_Man_t * pAig )
+{
+ Vec_Int_t * vNodes = NULL;
+ Vec_Int_t * vOrder;
+ Aig_Obj_t * pObj;
+ int i, Counter = 0;
+ // collect nodes in the order
+ vOrder = Vec_IntStartFull( Aig_ManObjNumMax(pAig) );
+ Aig_ManIncrementTravId( pAig );
+ Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) );
+ Aig_ManForEachPo( pAig, pObj, i )
+ {
+printf( "PO %d Var %d\n", i, Counter );
+ Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
+ Llb_Nonlin4FindOrder_rec( pAig, Aig_ObjFanin0(pObj), vOrder, &Counter );
+ }
+ Aig_ManForEachPi( pAig, pObj, i )
+ if ( Llb_MnxBddVar(vOrder, pObj) < 0 )
+ Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
+ Aig_ManCleanMarkA( pAig );
+ Vec_IntFreeP( &vNodes );
+ assert( Counter == Aig_ManObjNum(pAig) - 1 );
+ return vOrder;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives BDDs for the partitions.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Llb_Nonlin4FindPartitions( 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 );
+ }
+ Aig_ManForEachPo( 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 );
+ 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 );
+ }
+ // compute register output BDDs
+ Aig_ManForEachPo( 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 [Creates quantifiable varaibles for both types of traversal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Llb_Nonlin4FindVars2Q( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
+{
+ Vec_Int_t * vVars2Q;
+ Aig_Obj_t * pObj;
+ int i;
+ vVars2Q = Vec_IntAlloc( 0 );
+ Vec_IntFill( vVars2Q, Cudd_ReadSize(dd), 1 );
+ Saig_ManForEachLo( pAig, pObj, i )
+ Vec_IntWriteEntry( vVars2Q, Llb_MnxBddVar(vOrder, pObj), 0 );
+ Aig_ManForEachPo( pAig, pObj, i )
+ Vec_IntWriteEntry( vVars2Q, Llb_MnxBddVar(vOrder, pObj), 0 );
+ return vVars2Q;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates quantifiable varaibles for both types of traversal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Llb_Nonlin4CountTerms( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, DdNode * bFunc, int fCo, int fFlop )
+{
+ DdNode * bSupp;
+ Aig_Obj_t * pObj;
+ int i, Counter = 0;
+ bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bFunc );
+ if ( !fCo && !fFlop )
+ {
+ Saig_ManForEachPi( pAig, pObj, i )
+ Counter += Cudd_bddLeq( dd, bSupp, Cudd_bddIthVar(dd, Llb_MnxBddVar(vOrder, pObj)) );
+ }
+ else if ( fCo && !fFlop )
+ {
+ Saig_ManForEachPo( pAig, pObj, i )
+ Counter += Cudd_bddLeq( dd, bSupp, Cudd_bddIthVar(dd, Llb_MnxBddVar(vOrder, pObj)) );
+ }
+ else if ( !fCo && fFlop )
+ {
+ Saig_ManForEachLo( pAig, pObj, i )
+ Counter += Cudd_bddLeq( dd, bSupp, Cudd_bddIthVar(dd, Llb_MnxBddVar(vOrder, pObj)) );
+ }
+ else if ( fCo && fFlop )
+ {
+ Saig_ManForEachLi( pAig, pObj, i )
+ Counter += Cudd_bddLeq( dd, bSupp, Cudd_bddIthVar(dd, Llb_MnxBddVar(vOrder, pObj)) );
+ }
+ Cudd_RecursiveDeref( dd, bFunc );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates quantifiable varaibles for both types of traversal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Llb_Nonlin4PrintGroups( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, Vec_Ptr_t * vGroups )
+{
+ DdNode * bTemp;
+ int i, nSuppAll, nSuppPi, nSuppPo, nSuppLi, nSuppLo, nSuppAnd;
+ Vec_PtrForEachEntry( DdNode *, vGroups, bTemp, i )
+ {
+ nSuppAll = Cudd_SupportSize(dd,bTemp);
+ nSuppPi = Llb_Nonlin4CountTerms(dd, pAig, vOrder, bTemp, 0, 0);
+ nSuppPo = Llb_Nonlin4CountTerms(dd, pAig, vOrder, bTemp, 1, 0);
+ nSuppLi = Llb_Nonlin4CountTerms(dd, pAig, vOrder, bTemp, 0, 1);
+ nSuppLo = Llb_Nonlin4CountTerms(dd, pAig, vOrder, bTemp, 1, 1);
+ nSuppAnd = nSuppAll - (nSuppPi+nSuppPo+nSuppLi+nSuppLo);
+
+ printf( "%4d : bdd =%6d supp =%3d ", i, Cudd_DagSize(bTemp), nSuppAll );
+ printf( "pi =%3d ", nSuppPi );
+ printf( "po =%3d ", nSuppPo );
+ printf( "lo =%3d ", nSuppLo );
+ printf( "li =%3d ", nSuppLi );
+ printf( "and =%3d", nSuppAnd );
+ printf( "\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Llb_Nonlin4Cluster( Aig_Man_t * pAig )
+{
+ DdManager * dd;
+ Vec_Int_t * vOrder, * vVars2Q;
+ Vec_Ptr_t * vParts, * vGroups;
+ DdNode * bTemp;
+ int i;
+
+ // create the BDD manager
+ dd = Cudd_Init( Aig_ManObjNumMax(pAig), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+// Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT );
+ vOrder = Llb_Nonlin4FindOrder( pAig );
+ vVars2Q = Llb_Nonlin4FindVars2Q( dd, pAig, vOrder );
+ vParts = Llb_Nonlin4FindPartitions( dd, pAig, vOrder );
+
+ vGroups = Llb_Nonlin4Group( dd, vParts, vVars2Q, 500 );
+
+ Llb_Nonlin4PrintGroups( dd, pAig, vOrder, vGroups );
+
+ Vec_PtrForEachEntry( DdNode *, vGroups, bTemp, i )
+ Cudd_RecursiveDeref( dd, bTemp );
+
+ Vec_PtrForEachEntry( DdNode *, vParts, bTemp, i )
+ Cudd_RecursiveDeref( dd, bTemp );
+ Extra_StopManager( dd );
+// Cudd_Quit( dd );
+
+ Vec_IntFree( vOrder );
+ Vec_IntFree( vVars2Q );
+ Vec_PtrFree( vParts );
+ Vec_PtrFree( vGroups );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+