summaryrefslogtreecommitdiffstats
path: root/src/aig
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig')
-rw-r--r--src/aig/bbl/bblif.c1511
-rw-r--r--src/aig/bbl/bblif.h273
-rw-r--r--src/aig/bbl/module.make1
-rw-r--r--src/aig/cec/cec.h44
-rw-r--r--src/aig/cec/cecCec.c241
-rw-r--r--src/aig/cec/cecClass.c887
-rw-r--r--src/aig/cec/cecCore.c285
-rw-r--r--src/aig/cec/cecInt.h67
-rw-r--r--src/aig/cec/cecIso.c370
-rw-r--r--src/aig/cec/cecMan.c174
-rw-r--r--src/aig/cec/cecPat.c6
-rw-r--r--src/aig/cec/cecSim.c48
-rw-r--r--src/aig/cec/cecSolve.c97
-rw-r--r--src/aig/cec/cecSweep.c294
-rw-r--r--src/aig/cec/module.make8
-rw-r--r--src/aig/dar/darRefact.c2
-rw-r--r--src/aig/gia/gia.h165
-rw-r--r--src/aig/gia/giaAig.c6
-rw-r--r--src/aig/gia/giaAiger.c309
-rw-r--r--src/aig/gia/giaCof.c8
-rw-r--r--src/aig/gia/giaDup.c214
-rw-r--r--src/aig/gia/giaEmbed.c460
-rw-r--r--src/aig/gia/giaEnable.c210
-rw-r--r--src/aig/gia/giaEquiv.c618
-rw-r--r--src/aig/gia/giaForce.c1117
-rw-r--r--src/aig/gia/giaMan.c11
-rw-r--r--src/aig/gia/giaMap.c305
-rw-r--r--src/aig/gia/giaScl.c52
-rw-r--r--src/aig/gia/giaSort.c13
-rw-r--r--src/aig/gia/giaUtil.c67
-rw-r--r--src/aig/gia/module.make3
-rw-r--r--src/aig/ioa/ioaReadAig.c12
-rw-r--r--src/aig/ioa/ioaWriteAig.c6
-rw-r--r--src/aig/saig/saigMiter.c6
-rw-r--r--src/aig/ssw/sswCore.c3
35 files changed, 6679 insertions, 1214 deletions
diff --git a/src/aig/bbl/bblif.c b/src/aig/bbl/bblif.c
new file mode 100644
index 00000000..adc10b28
--- /dev/null
+++ b/src/aig/bbl/bblif.c
@@ -0,0 +1,1511 @@
+/**CFile****************************************************************
+
+ FileName [bblif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Binary BLIF representation for logic networks.]
+
+ Synopsis [Main implementation module.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 28, 2009.]
+
+ Revision [$Id: bblif.c,v 1.00 2009/02/28 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#include "bblif.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// vector of integers
+typedef struct Vec_Int_t_ Vec_Int_t;
+struct Vec_Int_t_
+{
+ int nCap;
+ int nSize;
+ int * pArray;
+};
+
+// vector of characters
+typedef struct Vec_Str_t_ Vec_Str_t;
+struct Vec_Str_t_
+{
+ int nCap;
+ int nSize;
+ char * pArray;
+};
+
+// network object
+struct Bbl_Obj_t_
+{
+ int Id; // user ID
+ int Fnc; // functionality
+ unsigned fCi : 1; // combinational input
+ unsigned fCo : 1; // combinational output
+ unsigned fBox : 1; // subcircuit
+ unsigned fMark : 1; // temporary mark
+ unsigned nFanins : 28; // fanin number
+ int pFanins[0]; // fanin array
+};
+
+// object function
+typedef struct Bbl_Fnc_t_ Bbl_Fnc_t;
+struct Bbl_Fnc_t_
+{
+ int nWords; // word number
+ int pWords[0]; // word array
+};
+
+// object function
+typedef struct Bbl_Ent_t_ Bbl_Ent_t;
+struct Bbl_Ent_t_
+{
+ int iFunc; // function handle
+ int iNext; // next entry handle
+};
+
+// data manager
+struct Bbl_Man_t_
+{
+ // data pool
+ Vec_Str_t * pName; // design name
+ Vec_Str_t * pObjs; // vector of objects
+ Vec_Str_t * pFncs; // vector of functions
+ // construction
+ Vec_Int_t * vId2Obj; // mapping user IDs into objects
+ Vec_Int_t * vObj2Id; // mapping objects into user IDs
+ Vec_Int_t * vFaninNums; // mapping user IDs into fanin number
+ // file contents
+ int nFileSize; // file size
+ char * pFileData; // file contents
+ // other data
+ Vec_Str_t * pEnts; // vector of entries
+ int SopMap[17][17]; // mapping vars x cubes into entry handles
+};
+
+static inline int Bbl_ObjIsCi( Bbl_Obj_t * pObj ) { return pObj->fCi; }
+static inline int Bbl_ObjIsCo( Bbl_Obj_t * pObj ) { return pObj->fCo; }
+static inline int Bbl_ObjIsNode( Bbl_Obj_t * pObj ) { return!pObj->fCi && !pObj->fCo; }
+
+static inline int Bbl_ObjFaninNum( Bbl_Obj_t * pObj ) { return pObj->nFanins; }
+static inline Bbl_Obj_t * Bbl_ObjFanin( Bbl_Obj_t * pObj, int i ) { return (Bbl_Obj_t *)(((char *)pObj) - pObj->pFanins[i]); }
+
+static inline int Bbl_ObjSize( Bbl_Obj_t * pObj ) { return sizeof(Bbl_Obj_t) + sizeof(int) * pObj->nFanins; }
+static inline int Bbl_FncSize( Bbl_Fnc_t * pFnc ) { return sizeof(Bbl_Fnc_t) + sizeof(int) * pFnc->nWords; }
+
+static inline Bbl_Obj_t * Bbl_VecObj( Vec_Str_t * p, int h ) { return (Bbl_Obj_t *)(p->pArray + h); }
+static inline Bbl_Fnc_t * Bbl_VecFnc( Vec_Str_t * p, int h ) { return (Bbl_Fnc_t *)(p->pArray + h); }
+static inline Bbl_Ent_t * Bbl_VecEnt( Vec_Str_t * p, int h ) { return (Bbl_Ent_t *)(p->pArray + h); }
+
+static inline char * Bbl_ManSop( Bbl_Man_t * p, int h ) { return (char *)Bbl_VecFnc(p->pFncs, h)->pWords; }
+static inline Bbl_Obj_t * Bbl_ManObj( Bbl_Man_t * p, int Id ) { return Bbl_VecObj(p->pObjs, p->vId2Obj->pArray[Id]); }
+
+#define Bbl_ManForEachObj_int( p, pObj, h ) \
+ for ( h = 0; (h < p->nSize) && (pObj = Bbl_VecObj(p,h)); h += Bbl_ObjSize(pObj) )
+#define Bbl_ManForEachFnc_int( p, pObj, h ) \
+ for ( h = 0; (h < p->nSize) && (pObj = Bbl_VecFnc(p,h)); h += Bbl_FncSize(pObj) )
+#define Bbl_ObjForEachFanin_int( pObj, pFanin, i ) \
+ for ( i = 0; (i < (int)pObj->nFanins) && (pFanin = Bbl_ObjFanin(pObj,i)); i++ )
+
+#define BBLIF_ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
+#define BBLIF_CALLOC(type, num) ((type *) calloc((num), sizeof(type)))
+#define BBLIF_FALLOC(type, num) ((type *) memset(malloc(sizeof(type) * (num)), 0xff, sizeof(type) * (num)))
+#define BBLIF_FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
+#define BBLIF_REALLOC(type, obj, num) \
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAlloc( int nCap )
+{
+ Vec_Int_t * p;
+ p = BBLIF_ALLOC( Vec_Int_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? BBLIF_ALLOC( int, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntStart( int nSize )
+{
+ Vec_Int_t * p;
+ p = Vec_IntAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(int) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntStartNatural( int nSize )
+{
+ Vec_Int_t * p;
+ int i;
+ p = Vec_IntAlloc( nSize );
+ p->nSize = nSize;
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = i;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize )
+{
+ Vec_Int_t * p;
+ p = BBLIF_ALLOC( Vec_Int_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFree( Vec_Int_t * p )
+{
+ BBLIF_FREE( p->pArray );
+ BBLIF_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSize( Vec_Int_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntEntry( Vec_Int_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] += Addition;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntEntryLast( Vec_Int_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = BBLIF_REALLOC( int, p->pArray, nCapMin );
+ assert( p->pArray );
+ p->nCap = nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Fill )
+{
+ int i;
+ Vec_IntGrow( p, nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Fill;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill )
+{
+ int i;
+ if ( p->nSize >= nSize )
+ return;
+ if ( nSize < 2 * p->nSize )
+ nSize = 2 * p->nSize;
+ Vec_IntGrow( p, nSize );
+ for ( i = p->nSize; i < nSize; i++ )
+ p->pArray[i] = Fill;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the entry even if the place not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntGetEntry( Vec_Int_t * p, int i )
+{
+ Vec_IntFillExtra( p, i + 1, 0 );
+ return Vec_IntEntry( p, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts the entry even if the place does not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSetEntry( Vec_Int_t * p, int i, int Entry )
+{
+ Vec_IntFillExtra( p, i + 1, 0 );
+ Vec_IntWriteEntry( p, i, Entry );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntClear( Vec_Int_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAlloc( int nCap )
+{
+ Vec_Str_t * p;
+ p = BBLIF_ALLOC( Vec_Str_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? BBLIF_ALLOC( char, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
+{
+ Vec_Str_t * p;
+ p = BBLIF_ALLOC( Vec_Str_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns a piece of memory.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Vec_StrFetch( Vec_Str_t * p, int nBytes )
+{
+ while ( p->nSize + nBytes > p->nCap )
+ {
+ p->pArray = BBLIF_REALLOC( char, p->pArray, 3 * p->nCap );
+ p->nCap *= 3;
+ }
+ p->nSize += nBytes;
+ return p->pArray + p->nSize - nBytes;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Write vector into file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vec_StrWrite( FILE * pFile, Vec_Str_t * p )
+{
+ fwrite( &p->nSize, sizeof(int), 1, pFile );
+ fwrite( p->pArray, sizeof(char), p->nSize, pFile );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Write vector into file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Vec_StrRead( char ** ppStr )
+{
+ Vec_Str_t * p;
+ char * pStr = *ppStr;
+ p = Vec_StrAlloc( 0 );
+ p->nSize = *(int *)pStr;
+ p->pArray = pStr + sizeof(int);
+ *ppStr = pStr + sizeof(int) + p->nSize * sizeof(char);
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSize( Vec_Str_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrFree( Vec_Str_t * p )
+{
+ BBLIF_FREE( p->pArray );
+ BBLIF_FREE( p );
+}
+
+
+
+
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the file size.]
+
+ Description [The file should be closed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ManFileSize( char * pFileName )
+{
+ FILE * pFile;
+ int nFileSize;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Bbl_ManFileSize(): The file is unavailable (absent or open).\n" );
+ return 0;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ fclose( pFile );
+ return nFileSize;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Read data from file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Bbl_ManFileRead( char * pFileName )
+{
+ FILE * pFile;
+ char * pContents;
+ int nFileSize;
+ nFileSize = Bbl_ManFileSize( pFileName );
+ pFile = fopen( pFileName, "rb" );
+ pContents = BBLIF_ALLOC( char, nFileSize );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+ return pContents;
+}
+
+
+
+/**Fnction*************************************************************
+
+ Synopsis [Writes data into file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName )
+{
+ FILE * pFile;
+ pFile = fopen( pFileName, "wb" );
+ Vec_StrWrite( pFile, p->pName );
+ Vec_StrWrite( pFile, p->pObjs );
+ Vec_StrWrite( pFile, p->pFncs );
+ fclose( pFile );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Creates manager after reading.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName )
+{
+ Bbl_Man_t * p;
+ Bbl_Obj_t * pObj;
+ char * pBuffer;
+ int h;
+ p = BBLIF_ALLOC( Bbl_Man_t, 1 );
+ memset( p, 0, sizeof(Bbl_Man_t) );
+ p->nFileSize = Bbl_ManFileSize( pFileName );
+ p->pFileData = Bbl_ManFileRead( pFileName );
+ // extract three managers
+ pBuffer = p->pFileData;
+ p->pName = Vec_StrRead( &pBuffer );
+ p->pObjs = Vec_StrRead( &pBuffer );
+ p->pFncs = Vec_StrRead( &pBuffer );
+ assert( pBuffer - p->pFileData == p->nFileSize );
+ // remember original IDs in the objects
+ p->vObj2Id = Vec_IntAlloc( 1000 );
+ Bbl_ManForEachObj_int( p->pObjs, pObj, h )
+ {
+ Vec_IntPush( p->vObj2Id, pObj->Id );
+ pObj->Id = Vec_IntSize(p->vObj2Id) - 1;
+ }
+ return p;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Prints stats of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManPrintStats( Bbl_Man_t * p )
+{
+ Bbl_Obj_t * pObj;
+ Bbl_Fnc_t * pFnc;
+ int h, nFuncs = 0, nNodes = 0, nObjs = 0;
+ Bbl_ManForEachObj_int( p->pObjs, pObj, h )
+ nObjs++, nNodes += Bbl_ObjIsNode(pObj);
+ Bbl_ManForEachFnc_int( p->pFncs, pFnc, h )
+ nFuncs++;
+ printf( "Total objects = %7d. Total nodes = %7d. Unique functions = %7d.\n", nObjs, nNodes, nFuncs );
+ printf( "Name manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pName)/(1 << 20) );
+ printf( "Objs manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pObjs)/(1 << 20) );
+ printf( "Fncs manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pFncs)/(1 << 20) );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Deletes the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManStop( Bbl_Man_t * p )
+{
+ if ( p->vId2Obj ) Vec_IntFree( p->vId2Obj );
+ if ( p->vObj2Id ) Vec_IntFree( p->vObj2Id );
+ if ( p->vFaninNums ) Vec_IntFree( p->vFaninNums );
+ if ( p->pFileData )
+ {
+ BBLIF_FREE( p->pFileData );
+ p->pName->pArray = NULL;
+ p->pObjs->pArray = NULL;
+ p->pFncs->pArray = NULL;
+ }
+ if ( p->pEnts )
+ Vec_StrFree( p->pEnts );
+ Vec_StrFree( p->pName );
+ Vec_StrFree( p->pObjs );
+ Vec_StrFree( p->pFncs );
+ BBLIF_FREE( p );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Creates manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Man_t * Bbl_ManStart( char * pName )
+{
+ Bbl_Man_t * p;
+ int nLength;
+ p = BBLIF_ALLOC( Bbl_Man_t, 1 );
+ memset( p, 0, sizeof(Bbl_Man_t) );
+ nLength = pName? 4 * ((strlen(pName) + 1) / 4 + 1) : 0;
+ p->pName = Vec_StrAlloc( nLength );
+ p->pName->nSize = p->pName->nCap;
+ if ( pName )
+ strcpy( p->pName->pArray, pName );
+ p->pObjs = Vec_StrAlloc( 1 << 16 );
+ p->pFncs = Vec_StrAlloc( 1 << 16 );
+ p->pEnts = Vec_StrAlloc( 1 << 16 ); p->pEnts->nSize = 1;
+ p->vId2Obj = Vec_IntStart( 1 << 10 );
+ p->vFaninNums = Vec_IntStart( 1 << 10 );
+ return p;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs selection sort on the array of cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManSortCubes( char ** pCubes, int nCubes, int nVars )
+{
+ char * pTemp;
+ int i, j, best_i;
+ for ( i = 0; i < nCubes-1; i++ )
+ {
+ best_i = i;
+ for (j = i+1; j < nCubes; j++)
+ if ( memcmp( pCubes[j], pCubes[best_i], nVars ) < 0 )
+ best_i = j;
+ pTemp = pCubes[i]; pCubes[i] = pCubes[best_i]; pCubes[best_i] = pTemp;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the cubes in the SOP to uniqify them to some extent.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Bbl_ManSortSop( char * pSop, int nVars )
+{
+ char ** pCubes, * pSopNew;
+ int c, Length, nCubes;
+ Length = strlen(pSop);
+ assert( Length % (nVars + 3) == 0 );
+ nCubes = Length / (nVars + 3);
+ if ( nCubes < 2 )
+ {
+ pSopNew = BBLIF_ALLOC( char, Length + 1 );
+ memcpy( pSopNew, pSop, Length + 1 );
+ return pSopNew;
+ }
+ pCubes = BBLIF_ALLOC( char *, nCubes );
+ for ( c = 0; c < nCubes; c++ )
+ pCubes[c] = pSop + c * (nVars + 3);
+ if ( nCubes < 300 )
+ Bbl_ManSortCubes( pCubes, nCubes, nVars );
+ pSopNew = BBLIF_ALLOC( char, Length + 1 );
+ for ( c = 0; c < nCubes; c++ )
+ memcpy( pSopNew + c * (nVars + 3), pCubes[c], nVars + 3 );
+ BBLIF_FREE( pCubes );
+ pSopNew[nCubes * (nVars + 3)] = 0;
+ return pSopNew;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Saves one entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ManCreateEntry( Bbl_Man_t * p, int iFunc, int iNext )
+{
+ Bbl_Ent_t * pEnt;
+ pEnt = (Bbl_Ent_t *)Vec_StrFetch( p->pEnts, 2 * sizeof(int) );
+ pEnt->iFunc = iFunc;
+ pEnt->iNext = iNext;
+ return (char *)pEnt - p->pEnts->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the cubes in the SOP to uniqify them to some extent.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ManSopCheckUnique( Bbl_Man_t * p, char * pSop, int nVars, int nCubes, int iFunc )
+{
+ Bbl_Fnc_t * pFnc;
+ Bbl_Ent_t * pEnt;
+ int h, Length = strlen(pSop) + 1;
+ int nWords = (Length / 4 + (Length % 4 > 0));
+ if ( nVars > 16 ) nVars = 16;
+ if ( nCubes > 16 ) nCubes = 16;
+// if ( nVars == 16 && nCubes == 16 )
+// return iFunc;
+ for ( h = p->SopMap[nVars][nCubes]; h; h = pEnt->iNext )
+ {
+ pEnt = Bbl_VecEnt( p->pEnts, h );
+ pFnc = Bbl_VecFnc( p->pFncs, pEnt->iFunc );
+ assert( nVars == 16 || nCubes == 16 || pFnc->nWords == nWords );
+ if ( pFnc->nWords == nWords && memcmp( pFnc->pWords, pSop, Length ) == 0 )
+ return pEnt->iFunc;
+ }
+ p->SopMap[nVars][nCubes] = Bbl_ManCreateEntry( p, iFunc, p->SopMap[nVars][nCubes] );
+ return iFunc;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Saves one SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ManSaveSop( Bbl_Man_t * p, char * pSop, int nVars )
+{
+ Bbl_Fnc_t * pFnc;
+ char * pSopNew;
+ int iFunc, Length = strlen(pSop) + 1;
+ int nWords = Length / 4 + (Length % 4 > 0);
+ // reorder cubes to semi-canicize SOPs
+ pSopNew = Bbl_ManSortSop( pSop, nVars );
+ // get the candidate location
+ iFunc = Bbl_ManSopCheckUnique( p, pSopNew, nVars, Length / (nVars + 3), Vec_StrSize(p->pFncs) );
+// iFunc = Vec_StrSize(p->pFncs);
+ if ( iFunc == Vec_StrSize(p->pFncs) )
+ { // store this SOP
+ pFnc = (Bbl_Fnc_t *)Vec_StrFetch( p->pFncs, sizeof(Bbl_Fnc_t) + nWords * sizeof(int) );
+ pFnc->pWords[nWords-1] = 0;
+ pFnc->nWords = nWords;
+ strcpy( (char *)pFnc->pWords, pSopNew );
+ assert( iFunc == (char *)pFnc - p->pFncs->pArray );
+ }
+ BBLIF_FREE( pSopNew );
+ return iFunc;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Adds one object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop )
+{
+ Bbl_Obj_t * pObj;
+ if ( Type == BBL_OBJ_CI && nFanins != 0 )
+ {
+ printf( "Attempting to create a combinational input with %d fanins (should be 0).\n", nFanins );
+ return;
+ }
+ if ( Type == BBL_OBJ_CO && nFanins != 1 )
+ {
+ printf( "Attempting to create a combinational output with %d fanins (should be 1).\n", nFanins );
+ return;
+ }
+ pObj = (Bbl_Obj_t *)Vec_StrFetch( p->pObjs, sizeof(Bbl_Obj_t) + nFanins * sizeof(int) );
+ memset( pObj, 0, sizeof(Bbl_Obj_t) );
+ Vec_IntSetEntry( p->vId2Obj, ObjId, (char *)pObj - p->pObjs->pArray );
+ Vec_IntSetEntry( p->vFaninNums, ObjId, 0 );
+ pObj->fCi = (Type == BBL_OBJ_CI);
+ pObj->fCo = (Type == BBL_OBJ_CO);
+ pObj->Id = ObjId;
+ pObj->Fnc = pSop? Bbl_ManSaveSop(p, pSop, nFanins) : -1;
+ pObj->nFanins = nFanins;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Creates fanin/fanout relationship between two objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId )
+{
+ Bbl_Obj_t * pObj, * pFanin;
+ int iFanin;
+ pObj = Bbl_ManObj( p, ObjId );
+ if ( Bbl_ObjIsCi(pObj) )
+ {
+ printf( "Bbl_ManAddFanin(): Cannot add fanin of the combinational input (Id = %d).\n", ObjId );
+ return;
+ }
+ pFanin = Bbl_ManObj( p, FaninId );
+ if ( Bbl_ObjIsCo(pFanin) )
+ {
+ printf( "Bbl_ManAddFanin(): Cannot add fanout of the combinational output (Id = %d).\n", FaninId );
+ return;
+ }
+ iFanin = Vec_IntEntry( p->vFaninNums, ObjId );
+ if ( iFanin >= (int)pObj->nFanins )
+ {
+ printf( "Bbl_ManAddFanin(): Trying to add more fanins to object (Id = %d) than declared (%d).\n", ObjId, pObj->nFanins );
+ return;
+ }
+ assert( iFanin < (int)pObj->nFanins );
+ Vec_IntWriteEntry( p->vFaninNums, ObjId, iFanin+1 );
+ pObj->pFanins[iFanin] = (char *)pObj - (char *)pFanin;
+}
+
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns 1 if the manager was created correctly.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ManCheck( Bbl_Man_t * p )
+{
+ Bbl_Obj_t * pObj;
+ int h, RetValue = 1;
+ Bbl_ManForEachObj_int( p->pObjs, pObj, h )
+ {
+ if ( Bbl_ObjIsNode(pObj) && pObj->Fnc == -1 )
+ RetValue = 0, printf( "Bbl_ManCheck(): Node %d does not have function specified.\n", pObj->Id );
+ if ( Bbl_ObjIsCi(pObj) && pObj->Fnc != -1 )
+ RetValue = 0, printf( "Bbl_ManCheck(): CI with %d has function specified.\n", pObj->Id );
+ if ( Bbl_ObjIsCo(pObj) && pObj->Fnc != -1 )
+ RetValue = 0, printf( "Bbl_ManCheck(): CO with %d has function specified.\n", pObj->Id );
+ if ( Vec_IntEntry(p->vFaninNums, pObj->Id) != (int)pObj->nFanins )
+ RetValue = 0, printf( "Bbl_ManCheck(): Object %d has less fanins (%d) than declared (%d).\n",
+ pObj->Id, Vec_IntEntry(p->vFaninNums, pObj->Id), pObj->nFanins );
+ }
+ return RetValue;
+}
+
+
+/**Fnction*************************************************************
+
+ Synopsis [Misc APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ObjIsInput( Bbl_Obj_t * p ) { return Bbl_ObjIsCi(p); }
+int Bbl_ObjIsOutput( Bbl_Obj_t * p ) { return Bbl_ObjIsCo(p); }
+int Bbl_ObjIsLut( Bbl_Obj_t * p ) { return Bbl_ObjIsNode(p); }
+int Bbl_ObjId( Bbl_Obj_t * p ) { return p->Id; }
+int Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p ) { assert(0); return Vec_IntEntry(pMan->vObj2Id, p->Id); }
+int Bbl_ObjFaninNumber( Bbl_Obj_t * p ) { return Bbl_ObjFaninNum(p); }
+char * Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p ) { return Bbl_ManSop(pMan, p->Fnc); }
+int Bbl_ObjIsMarked( Bbl_Obj_t * p ) { return p->fMark; }
+void Bbl_ObjMark( Bbl_Obj_t * p ) { p->fMark = 1; }
+int Bbl_ObjFncHandle( Bbl_Obj_t * p ) { return p->Fnc; }
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the name of the design.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Bbl_ManName( Bbl_Man_t * p )
+{
+ return p->pName->pArray;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the maximum handle of the SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bbl_ManFncSize( Bbl_Man_t * p )
+{
+ return p->pFncs->nSize;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the first object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p )
+{
+ return Bbl_VecObj( p->pObjs, 0 );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the next object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj )
+{
+ char * pNext = (char *)pObj + Bbl_ObjSize(pObj);
+ char * pEdge = p->pObjs->pArray + p->pObjs->nSize;
+ return (Bbl_Obj_t *)(pNext < pEdge ? pNext : NULL);
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the first fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p )
+{
+ return Bbl_ObjFaninNum(p) ? Bbl_ObjFanin( p, 0 ) : NULL;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Returns the next fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev )
+{
+ Bbl_Obj_t * pFanin;
+ int i;
+ Bbl_ObjForEachFanin_int( p, pFanin, i )
+ if ( pFanin == pPrev )
+ break;
+ return i < Bbl_ObjFaninNum(p) - 1 ? Bbl_ObjFanin( p, i+1 ) : NULL;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Drives text BLIF file for debugging.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName )
+{
+ FILE * pFile;
+ Bbl_Obj_t * pObj, * pFanin;
+ pFile = fopen( pFileName, "w" );
+ fprintf( pFile, "# Test file written by Bbl_ManDumpBlif() in ABC.\n" );
+ fprintf( pFile, ".model %s\n", Bbl_ManName(p) );
+ // write objects
+ Bbl_ManForEachObj( p, pObj )
+ {
+ if ( Bbl_ObjIsInput(pObj) )
+ fprintf( pFile, ".inputs %d\n", Bbl_ObjId(pObj) );
+ else if ( Bbl_ObjIsOutput(pObj) )
+ fprintf( pFile, ".outputs %d\n", Bbl_ObjId(pObj) );
+ else if ( Bbl_ObjIsLut(pObj) )
+ {
+ fprintf( pFile, ".names" );
+ Bbl_ObjForEachFanin( pObj, pFanin )
+ fprintf( pFile, " %d", Bbl_ObjId(pFanin) );
+ fprintf( pFile, " %d\n", Bbl_ObjId(pObj) );
+ fprintf( pFile, "%s", Bbl_ObjSop(p, pObj) );
+ }
+ else assert( 0 );
+ }
+ // write output drivers
+ Bbl_ManForEachObj( p, pObj )
+ {
+ if ( !Bbl_ObjIsOutput(pObj) )
+ continue;
+ fprintf( pFile, ".names" );
+ Bbl_ObjForEachFanin( pObj, pFanin )
+ fprintf( pFile, " %d", Bbl_ObjId(pFanin) );
+ fprintf( pFile, " %d\n", Bbl_ObjId(pObj) );
+ fprintf( pFile, "1 1\n" );
+ }
+ fprintf( pFile, ".end\n" );
+ fclose( pFile );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Converting truth table into an SOP.]
+
+ Description [The truth table is given as a bit-string pTruth
+ composed of 2^nVars bits. The result is an SOP derived by
+ collecting minterms appearing in the truth table. The SOP is
+ represented as a C-string, as documented in file "bblif.h".
+ It is recommended to limit the use of this procedure to Boolean
+ functions up to 6 inputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Bbl_ManTruthToSop( unsigned * pTruth, int nVars )
+{
+ char * pResult, * pTemp;
+ int nMints, nOnes, b, v;
+ assert( nVars >= 0 && nVars <= 16 );
+ nMints = (1 << nVars);
+ // count the number of ones
+ nOnes = 0;
+ for ( b = 0; b < nMints; b++ )
+ nOnes += ((pTruth[b>>5] >> (b&31)) & 1);
+ // handle constants
+ if ( nOnes == 0 || nOnes == nMints )
+ {
+ pResult = pTemp = BBLIF_ALLOC( char, nVars + 4 );
+ for ( v = 0; v < nVars; v++ )
+ *pTemp++ = '-';
+ *pTemp++ = ' ';
+ *pTemp++ = nOnes? '1' : '0';
+ *pTemp++ = '\n';
+ *pTemp++ = 0;
+ assert( pTemp - pResult == nVars + 4 );
+ return pResult;
+ }
+ pResult = pTemp = BBLIF_ALLOC( char, nOnes * (nVars + 3) + 1 );
+ for ( b = 0; b < nMints; b++ )
+ {
+ if ( ((pTruth[b>>5] >> (b&31)) & 1) == 0 )
+ continue;
+ for ( v = 0; v < nVars; v++ )
+ *pTemp++ = ((b >> v) & 1)? '1' : '0';
+ *pTemp++ = ' ';
+ *pTemp++ = '1';
+ *pTemp++ = '\n';
+ }
+ *pTemp++ = 0;
+ assert( pTemp - pResult == nOnes * (nVars + 3) + 1 );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the array of truth tables for the given number of vars.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Bbl_ManSopToTruthElem( int nVars, unsigned ** pVars )
+{
+ unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
+ int i, k, nWords;
+ nWords = (nVars <= 5 ? 1 : (1 << (nVars - 5)));
+ for ( i = 0; i < nVars; i++ )
+ {
+ if ( i < 5 )
+ {
+ for ( k = 0; k < nWords; k++ )
+ pVars[i][k] = Masks[i];
+ }
+ else
+ {
+ for ( k = 0; k < nWords; k++ )
+ if ( k & (1 << (i-5)) )
+ pVars[i][k] = ~(unsigned)0;
+ else
+ pVars[i][k] = 0;
+ }
+ }
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Converting SOP into a truth table.]
+
+ Description [The SOP is represented as a C-string, as documented in
+ file "bblif.h". The truth table is returned as a bit-string composed
+ of 2^nVars bits. For functions of less than 6 variables, the full
+ machine word is returned. (The truth table looks as if the function
+ had 5 variables.) The use of this procedure should be limited to
+ Boolean functions with no more than 16 inputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Bbl_ManSopToTruth( char * pSop, int nVars )
+{
+ unsigned * pTruth, * pCube, * pVars[16];
+ int nWords = nVars <= 5 ? 1 : (1 << (nVars - 5));
+ int v, c, w, nCubes, fCompl = 0;
+ if ( pSop == NULL )
+ return NULL;
+ if ( strlen(pSop) % (nVars + 3) != 0 )
+ {
+ printf( "Bbl_ManSopToTruth(): SOP is represented incorrectly.\n" );
+ return NULL;
+ }
+ // create storage for TTs of the result, elementary variables and the temp cube
+ pTruth = BBLIF_ALLOC( unsigned, nWords );
+ pVars[0] = BBLIF_ALLOC( unsigned, nWords * (nVars+1) );
+ for ( v = 1; v < nVars; v++ )
+ pVars[v] = pVars[v-1] + nWords;
+ pCube = pVars[v-1] + nWords;
+ Bbl_ManSopToTruthElem( nVars, pVars );
+ // iterate through the cubes
+ memset( pTruth, 0, sizeof(unsigned) * nWords );
+ nCubes = strlen(pSop) / (nVars + 3);
+ for ( c = 0; c < nCubes; c++ )
+ {
+ fCompl = (pSop[nVars+1] == '0');
+ memset( pCube, 0xff, sizeof(unsigned) * nWords );
+ // iterate through the literals of the cube
+ for ( v = 0; v < nVars; v++ )
+ if ( pSop[v] == '1' )
+ for ( w = 0; w < nWords; w++ )
+ pCube[w] &= pVars[v][w];
+ else if ( pSop[v] == '0' )
+ for ( w = 0; w < nWords; w++ )
+ pCube[w] &= ~pVars[v][w];
+ // add cube to storage
+ for ( w = 0; w < nWords; w++ )
+ pTruth[w] |= pCube[w];
+ // go to the next cube
+ pSop += (nVars + 3);
+ }
+ BBLIF_FREE( pVars[0] );
+ if ( fCompl )
+ for ( w = 0; w < nWords; w++ )
+ pTruth[w] = ~pTruth[w];
+ return pTruth;
+}
+
+
+/**Fnction*************************************************************
+
+ Synopsis [Checks the truth table computation.]
+
+ Description [We construct the logic network for the half-adder represnted
+ using the BLIF file below]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManTestTruth( char * pSop, int nVars )
+{
+ unsigned * pTruth;
+ char * pSopNew;
+ pTruth = Bbl_ManSopToTruth( pSop, nVars );
+ pSopNew = Bbl_ManTruthToSop( pTruth, nVars );
+ printf( "Old SOP:\n%s\n", pSop );
+ printf( "New SOP:\n%s\n", pSopNew );
+ BBLIF_FREE( pSopNew );
+ BBLIF_FREE( pTruth );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [This demo shows using the internal to construct a half-adder.]
+
+ Description [We construct the logic network for the half-adder represnted
+ using the BLIF file below]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManSimpleDemo()
+{
+/*
+ # There are contents of a BLIF file representing a half-adder:
+ .model hadder
+ .inputs a // ID = 1
+ .inputs b // ID = 2
+ .inputs cin // ID = 3
+ .outputs s // ID = 4
+ .outputs cout // ID = 5
+ .names a b cin s_driver // ID = 6
+ 100 1
+ 010 1
+ 001 1
+ 111 1
+ .names a b cin cout_driver // ID = 7
+ -11 1
+ 1-1 1
+ 11- 1
+ .names s_driver s
+ 1 1
+ .names cout_driver cout
+ 1 1
+ .end
+*/
+ Bbl_Man_t * p;
+ // start the data manager
+ p = Bbl_ManStart( "hadder" );
+ // create CIs
+ Bbl_ManCreateObject( p, BBL_OBJ_CI, 1, 0, NULL ); // a
+ Bbl_ManCreateObject( p, BBL_OBJ_CI, 2, 0, NULL ); // b
+ Bbl_ManCreateObject( p, BBL_OBJ_CI, 3, 0, NULL ); // cin
+ // create COs
+ Bbl_ManCreateObject( p, BBL_OBJ_CO, 4, 1, NULL ); // s
+ Bbl_ManCreateObject( p, BBL_OBJ_CO, 5, 1, NULL ); // cout
+ // create internal nodes
+ Bbl_ManCreateObject( p, BBL_OBJ_NODE, 6, 3, "100 1\n010 1\n001 1\n111 1\n" ); // s_driver
+ Bbl_ManCreateObject( p, BBL_OBJ_NODE, 7, 3, "-11 1\n1-1 1\n11- 1\n" ); // cout_driver
+ // add fanins of node 6
+ Bbl_ManAddFanin( p, 6, 1 ); // s_driver <- a
+ Bbl_ManAddFanin( p, 6, 2 ); // s_driver <- b
+ Bbl_ManAddFanin( p, 6, 3 ); // s_driver <- cin
+ // add fanins of node 7
+ Bbl_ManAddFanin( p, 7, 1 ); // cout_driver <- a
+ Bbl_ManAddFanin( p, 7, 2 ); // cout_driver <- b
+ Bbl_ManAddFanin( p, 7, 3 ); // cout_driver <- cin
+ // add fanins of COs
+ Bbl_ManAddFanin( p, 4, 6 ); // s <- s_driver
+ Bbl_ManAddFanin( p, 5, 7 ); // cout <- cout_driver
+ // sanity check
+ Bbl_ManCheck( p );
+ // write BLIF file as a sanity check
+ Bbl_ManDumpBlif( p, "hadder.blif" );
+ // write binary BLIF file
+ Bbl_ManDumpBinaryBlif( p, "hadder.bblif" );
+ // remove the manager
+ Bbl_ManStop( p );
+
+
+// Bbl_ManTestTruth( "100 1\n010 1\n001 1\n111 1\n", 3 );
+// Bbl_ManTestTruth( "-11 0\n1-1 0\n11- 0\n", 3 );
+// Bbl_ManTestTruth( "--- 1\n", 3 );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/bbl/bblif.h b/src/aig/bbl/bblif.h
new file mode 100644
index 00000000..db3eb2f5
--- /dev/null
+++ b/src/aig/bbl/bblif.h
@@ -0,0 +1,273 @@
+/**CFile****************************************************************
+
+ FileName [bblif.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Binary BLIF representation for logic networks.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 28, 2009.]
+
+ Revision [$Id: bblif.h,v 1.00 2009/02/28 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __BBLIF_H__
+#define __BBLIF_H__
+
+/*
+ This file (taken together with "bblif.c") implements a stand-alone
+ interface between ABC and an application that uses ABC.
+
+ The interface is designed to pass a combinational logic network
+ from the calling application to ABC using a binary BLIF format (BBLIF)
+ and return the network after synthesis/mapping/verification in ABC
+ back to the caller.
+
+ The interface can do the following:
+ (1) accept a combinational logic network via a set of APIs
+ (2) write the logic network into a binary BLIF file readable by ABC
+ (3) read a binary BLIF file with a mapped network produced by ABC
+ (4) return the mapped network to the caller through a set of APIs
+
+ Here these steps are described in more detail:
+
+ (1) The BBLIF manager is allocated by calling Bbl_ManStart() and
+ deallocated by calling Bbl_ManStop().
+
+ The combinational network is composed of three types of objects:
+ (a) combinational inputs (CIs), (b) combinational outputs (COs),
+ (c) internal logic nodes represented using Sum-of-Products (SOPs)
+ similar to the way logic nodes are represented in SIS. Sequential
+ elements (flops) are currently not supported. A CI has no fanins.
+ A CO has exactly one fanin and no fanouts. Internal nodes can
+ have any number of fanins and fanouts. Only an internal node can
+ have a logic function.
+
+ Before constructing the BBLIF manager, each object should be
+ assigned a unique non-negative (0-based) integer ID. The sequence
+ of ID numbers may have gaps in it (for example, 0, 1, 2, 5, 6, etc)
+ but care should be taken that the ID numbers do not grow too large
+ because internally they are used to index the objects. So if
+ the largest given ID has value N, an array of 4*N bytes will be
+ allocated internally by the BBLIF manager. Obviously if N = 1M,
+ the array will use 4Mb, but if N = 100M, it will use 0.4Gb.
+
+ This object ID (called also "the original ID of the object") is
+ given to Bbl_ManCreateObject(), which construct the BBLIF objects
+ and to the procedure Bbl_ManAddFanin(), which creates fanin/fanout
+ relations between two objects. The exact number of fanins of an
+ object should be declared when calling Bbl_ManCreateObject().
+ Later on, each node should be assigned as many fanins using
+ Bbl_ManAddFanin(). The order/number of fanins corresponds to the
+ order/number of variables in the SOP of the logic function of the
+ node. The declared and actual number of fanins should be the same.
+ otherwise the interface will not function correctly. This is checked
+ by the procedure Bbl_ManCheck(), which should be called when
+ constructing all objects and their fanins is finished.
+
+ The SOP representation of the logic function should be given to
+ every internal node. It is given as a C-string, showing the SOP
+ as it would appear in a BLIF or PLA file. Each cube is composed
+ of characters '0', '1', and '-', and ended by a seqence of three
+ characters: space ' ', followed by '0' or '1' (depending on whether
+ on- or off-set is used), followed by the new line character '\n'.
+ For example, a two-input OR has the following SOP representation:
+ "1- 1\n-1 1\n", or equivalently, "00 0\n". The SOP for a constant
+ function with no fanins is represented as " 0\n" (constant 0) and
+ " 1\n" (constant 1). SOP for a constant node with some fanins
+ may also be represented. For example, constant 0 node with three
+ fanins will have SOP representation as follows: "--- 0\n".
+
+ The objects can be added to the BBLIF manager in any order, but
+ by the time the fanin/fanout connections are created, corresponding
+ objects should be already created.
+
+ The number of objects is limited by 2^31. The number of fanins
+ of one object is restricted to 2^28. The SOP representation can
+ have arbitrary many products (cubes), as long as memory is enough
+ to represent them in the C-string form, as described above.
+
+ (2) To write the manager into a file, call procedure Bbl_ManDumpBinaryBlif().
+ It is recommended to use files with extension ".bblif" because it
+ will allow ABC to call the approapriate reader in command "read".
+
+ (3) To read the network from file, call procedure Bbl_ManReadBinaryBlif().
+
+ (4) It is assumed that ABC will return the network after mapping.
+ This network will arrive in a BBLIF file, from which the BBLIF
+ manager is created by the call to Bbl_ManReadBinaryBlif(). The
+ following APIs are useful to extract the mapped network from the manager:
+
+ Iterator Bbl_ManForEachObj() iterates through the pointers to the
+ BBLIF objects, which are guaranteed to be in a topological order.
+
+ For each object, the following APIs can be used:
+ Bbl_ObjIsInput() returns 1 if the object is a CI
+ Bbl_ObjIsOutput() returns 1 if the object is a CO
+ Bbl_ObjIsLut() returns 1 if the object is a logic node (lookup table)
+ Bbl_ObjFaninNumber() returns the number of fanins of the node
+ Bbl_ObjSop() returns the SOP representation of the node, as described above.
+
+ A special attention should be given to the representation of object IDs
+ after mapping. Recall that when the outgoing BBLIF network is constructed,
+ the IDs of objects are assigned by the calling application and given to
+ the BBLIF manager when procedure Bbl_ManCreateObject() is called.
+ We refer to these object IDs as "original IDs of the objects".
+
+ When the network has been given to ABC, mapped, and returned to the
+ calling application in the incoming BBLIF file, only CIs and COs are
+ guaranteed to preserve their "original IDs". Other objects may be created
+ during synthesis/mapping. The original IDs of these objects are set to -1.
+
+ The following two APIs are used to return the IDs of objects after mapping:
+ Bbl_ObjId() returns the new ID (useful to construct network after mapping)
+ Bbl_ObjIdOriginal() returns the original ID (or -1 if this is a new object).
+
+ !!!***!!!
+ Note: The original ID currently cannot be returned by Bbl_ObjIdOriginal().
+ It is recommended to use the work-around described below.
+ !!!***!!!
+
+ The original ID is useful to map CIs/COs after mapping into CIs/COs before
+ mapping. However, the order of CIs/COs after mapping in the incoming network
+ is the same as the order of their creation by the calling application
+ in the outgoing network. This allows for a workaround that does not have
+ the need for the original IDs. We can simply iterate through the objects
+ after mapping, and create CIs and COs in the order of their appearance,
+ and this order is guaranteed to be the same as the order of their
+ construction by the calling application.
+
+ It is also worth noting that currently the internal node names are not
+ preserved by ABC during synthesis. This may change in the future. and then
+ some of the internal nodes will preserve their IDs, which may allow the
+ calling application to reconstruct the names of some of the nodes after
+ synthesis/mapping in ABC using their original IDs whenever available.
+
+ Finally, iterator Bbl_ObjForEachFanin() can be used to iterate through
+ the fanins of each mapped object. For CIs, there will be no fanins.
+ For COs, there will be exactly one fanin. For the internal nodes (LUTs)
+ the number of fanins is the number of inputs of these nodes.
+
+ A demo of using this interface is included at the bottom of file "bblif.c" in
+ procedure Bbl_ManSimpleDemo(). Additional examples can be found in the files
+ "abc\src\base\io\ioReadBblif.c" and "abc\src\base\io\ioWriteBblif.c". These
+ files illustrate how an ABC network is created from the BBLIF data manager
+ and how the data manager is created from the ABC network.
+
+ Note that only the files "bblif.h" and "bblif.c" are needed for interfacing
+ the user's application with ABC, while other files should not be compiled
+ as part of the application code.
+
+ Finally, a warning regarding endianness. The interface may not work
+ if the BBLIF file is produced on a machine whose engianness is different
+ from the machine, which is reading this file.
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+#define inline __inline
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// object types
+typedef enum {
+ BBL_OBJ_NONE, // 0: non-existent object
+ BBL_OBJ_CI, // 1: primary input
+ BBL_OBJ_CO, // 2: primary output
+ BBL_OBJ_NODE, // 3: buffer node
+ BBL_OBJ_VOID // 4: unused object
+} Bbl_Type_t;
+
+// data manager
+typedef struct Bbl_Man_t_ Bbl_Man_t;
+
+// data object
+typedef struct Bbl_Obj_t_ Bbl_Obj_t;
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// (1) creating the data manager in the application code
+extern Bbl_Man_t * Bbl_ManStart( char * pName );
+extern void Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop );
+extern void Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId );
+extern int Bbl_ManCheck( Bbl_Man_t * p );
+extern void Bbl_ManPrintStats( Bbl_Man_t * p );
+extern void Bbl_ManStop( Bbl_Man_t * p );
+
+// (2) writing the data manager into file
+extern void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName );
+
+// (3) reading the data manager from file
+extern Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName );
+
+// (4) returning the mapped network after reading the data manaager from file
+extern char * Bbl_ManName( Bbl_Man_t * p );
+extern int Bbl_ObjIsInput( Bbl_Obj_t * p );
+extern int Bbl_ObjIsOutput( Bbl_Obj_t * p );
+extern int Bbl_ObjIsLut( Bbl_Obj_t * p );
+extern int Bbl_ObjId( Bbl_Obj_t * p );
+extern int Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p );
+extern int Bbl_ObjFaninNumber( Bbl_Obj_t * p );
+extern char * Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p );
+
+// for the use in iterators only
+extern Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p );
+extern Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj );
+extern Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p );
+extern Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev );
+
+// iterator through the objects
+#define Bbl_ManForEachObj( p, pObj ) \
+ for ( pObj = Bbl_ManObjFirst(p); pObj; pObj = Bbl_ManObjNext(p, pObj) )
+// iterator through the fanins fo the an object
+#define Bbl_ObjForEachFanin( pObj, pFanin ) \
+ for ( pFanin = Bbl_ObjFaninFirst(pObj); pFanin; pFanin = Bbl_ObjFaninNext(pObj, pFanin) )
+
+// these additional procedures are provided to transform truth tables into SOPs, and vice versa
+extern char * Bbl_ManTruthToSop( unsigned * pTruth, int nVars );
+extern unsigned * Bbl_ManSopToTruth( char * pSop, int nVars );
+
+// write text BLIF file for debugging
+extern void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName );
+
+// a simple demo procedure
+extern void Bbl_ManSimpleDemo();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/aig/bbl/module.make b/src/aig/bbl/module.make
new file mode 100644
index 00000000..89ed2fa3
--- /dev/null
+++ b/src/aig/bbl/module.make
@@ -0,0 +1 @@
+SRC += src/aig/bbl/bblif.c
diff --git a/src/aig/cec/cec.h b/src/aig/cec/cec.h
index fa7c5dbc..16748233 100644
--- a/src/aig/cec/cec.h
+++ b/src/aig/cec/cec.h
@@ -45,24 +45,42 @@ struct Cec_ParSat_t_
int nSatVarMax; // the max number of SAT variables
int nCallsRecycle; // calls to perform before recycling SAT solver
int fPolarFlip; // flops polarity of variables
+ int fCheckMiter; // the circuit is the miter
int fFirstStop; // stop on the first sat output
int fVerbose; // verbose stats
};
+// simulation parameters
+typedef struct Cec_ParSim_t_ Cec_ParSim_t;
+struct Cec_ParSim_t_
+{
+ int nWords; // the number of simulation words
+ int nRounds; // the number of simulation rounds
+ int TimeLimit; // the runtime limit in seconds
+ int fDoubleOuts; // miter with separate outputs
+ int fCheckMiter; // the circuit is the miter
+ int fFirstStop; // stop on the first sat output
+ int fSeqSimulate; // performs sequential simulation
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+};
+
// combinational SAT sweeping parameters
-typedef struct Cec_ParCsw_t_ Cec_ParCsw_t;
-struct Cec_ParCsw_t_
+typedef struct Cec_ParFra_t_ Cec_ParFra_t;
+struct Cec_ParFra_t_
{
int nWords; // the number of simulation words
int nRounds; // the number of simulation rounds
int nItersMax; // the maximum number of iterations of SAT sweeping
int nBTLimit; // conflict limit at a node
- int nSatVarMax; // the max number of SAT variables
- int nCallsRecycle; // calls to perform before recycling SAT solver
+ int TimeLimit; // the runtime limit in seconds
int nLevelMax; // restriction on the level nodes to be swept
int nDepthMax; // the depth in terms of steps of speculative reduction
int fRewriting; // enables AIG rewriting
+ int fCheckMiter; // the circuit is the miter
int fFirstStop; // stop on the first sat output
+ int fDoubleOuts; // miter with separate outputs
+ int fColorDiff; // miter with separate outputs
int fVeryVerbose; // verbose stats
int fVerbose; // verbose stats
};
@@ -71,13 +89,12 @@ struct Cec_ParCsw_t_
typedef struct Cec_ParCec_t_ Cec_ParCec_t;
struct Cec_ParCec_t_
{
- int nIters; // iterations of SAT solving/sweeping
- int nBTLimitBeg; // starting backtrack limit
- int nBTlimitMulti; // multiple of backtrack limit
+ int nBTLimit; // conflict limit at a node
+ int TimeLimit; // the runtime limit in seconds
+ int fFirstStop; // stop on the first sat output
int fUseSmartCnf; // use smart CNF computation
int fRewriting; // enables AIG rewriting
- int fSatSweeping; // enables SAT sweeping
- int fFirstStop; // stop on the first sat output
+ int fVeryVerbose; // verbose stats
int fVerbose; // verbose stats
};
@@ -89,12 +106,17 @@ struct Cec_ParCec_t_
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+/*=== cecCec.c ==========================================================*/
+extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars );
+extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose );
/*=== cecCore.c ==========================================================*/
extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p );
-extern void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p );
+extern void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p );
+extern void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p );
extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p );
-extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParCsw_t * pPars );
+extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars );
extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars );
+extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars );
#ifdef __cplusplus
}
diff --git a/src/aig/cec/cecCec.c b/src/aig/cec/cecCec.c
new file mode 100644
index 00000000..ea730693
--- /dev/null
+++ b/src/aig/cec/cecCec.c
@@ -0,0 +1,241 @@
+/**CFile****************************************************************
+
+ FileName [cecCec.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinatinoal equivalence checking.]
+
+ Synopsis [Integrated combinatinal equivalence checker.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecCec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Saves the input pattern with the given number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues )
+{
+ int i;
+ assert( p->pCexComb == NULL );
+ p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char,
+ sizeof(Gia_Cex_t) + sizeof(unsigned) * Aig_BitWordNum(Gia_ManCiNum(p)) );
+ p->pCexComb->iPo = iOut;
+ p->pCexComb->nPis = Gia_ManCiNum(p);
+ p->pCexComb->nBits = Gia_ManCiNum(p);
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ if ( pValues[i] )
+ Aig_InfoSetBit( p->pCexComb->pData, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interface to the old CEC engine]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose )
+{
+ extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose );
+ extern int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs );
+ Gia_Man_t * pTemp = Gia_ManTransformMiter( pMiter );
+ Aig_Man_t * pMiterCec = Gia_ManToAig( pTemp );
+ int RetValue, iOut, nOuts, clkTotal = clock();
+ Gia_ManStop( pTemp );
+ // run CEC on this miter
+ RetValue = Fra_FraigCec( &pMiterCec, 100000, fVerbose );
+ // report the miter
+ if ( RetValue == 1 )
+ {
+ printf( "Networks are equivalent. " );
+ABC_PRT( "Time", clock() - clkTotal );
+ }
+ else if ( RetValue == 0 )
+ {
+ printf( "Networks are NOT EQUIVALENT. " );
+ABC_PRT( "Time", clock() - clkTotal );
+ if ( pMiterCec->pData == NULL )
+ printf( "Counter-example is not available.\n" );
+ else
+ {
+ iOut = Ssw_SecCexResimulate( pMiterCec, pMiterCec->pData, &nOuts );
+ if ( iOut == -1 )
+ printf( "Counter-example verification has failed.\n" );
+ else
+ {
+ printf( "Primary output %d has failed in frame %d.\n", iOut );
+ printf( "The counter-example detected %d incorrect outputs.\n", nOuts );
+ }
+ Cec_ManTransformPattern( pMiter, iOut, pMiterCec->pData );
+ }
+ }
+ else
+ {
+ printf( "Networks are UNDECIDED. " );
+ABC_PRT( "Time", clock() - clkTotal );
+ }
+ fflush( stdout );
+ Aig_ManStop( pMiterCec );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [New CEC engine.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars )
+{
+ int fDumpUndecided = 1;
+ Cec_ParFra_t ParsFra, * pParsFra = &ParsFra;
+ Gia_Man_t * pNew;
+ int RetValue, clk = clock();
+ double clkTotal = clock();
+ // sweep for equivalences
+ Cec_ManFraSetDefaultParams( pParsFra );
+ pParsFra->nBTLimit = pPars->nBTLimit;
+ pParsFra->TimeLimit = pPars->TimeLimit;
+ pParsFra->fVerbose = pPars->fVerbose;
+ pParsFra->fCheckMiter = 1;
+ pParsFra->fFirstStop = 1;
+ pParsFra->fDoubleOuts = 1;
+ pNew = Cec_ManSatSweeping( p, pParsFra );
+ if ( pNew == NULL )
+ {
+ if ( !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) )
+ printf( "Counter-example simulation has failed.\n" );
+ printf( "Networks are NOT EQUIVALENT. " );
+ ABC_PRT( "Time", clock() - clk );
+ return 0;
+ }
+ if ( Gia_ManAndNum(pNew) == 0 )
+ {
+ printf( "Networks are equivalent. " );
+ ABC_PRT( "Time", clock() - clk );
+ Gia_ManStop( pNew );
+ return 1;
+ }
+ printf( "Networks are UNDECIDED after the new CEC engine. " );
+ ABC_PRT( "Time", clock() - clk );
+ if ( fDumpUndecided )
+ {
+ Gia_WriteAiger( pNew, "gia_cec_undecided.aig", 0, 0 );
+ printf( "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" );
+ }
+ if ( pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit )
+ {
+ Gia_ManStop( pNew );
+ return -1;
+ }
+ // call other solver
+ printf( "Calling the old CEC engine.\n" );
+ fflush( stdout );
+ RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose );
+ p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL;
+ if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) )
+ printf( "Counter-example simulation has failed.\n" );
+ Gia_ManStop( pNew );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [New CEC engine applied to two circuits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose )
+{
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ Gia_Man_t * pMiter;
+ int RetValue;
+ Cec_ManCecSetDefaultParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pMiter = Gia_ManMiter( p0, p1, 0, 1, pPars->fVerbose );
+ if ( pMiter == NULL )
+ return -1;
+ RetValue = Cec_ManVerify( pMiter, pPars );
+ p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL;
+ Gia_ManStop( pMiter );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [New CEC engine applied to two circuits.]
+
+ Description [Returns 1 if equivalent, 0 if counter-example, -1 if undecided.
+ Counter-example is returned in the first manager as pAig0->pSeqModel.
+ The format is given in Gia_Cex_t (file "abc\src\aig\gia\gia.h").]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose )
+{
+ Gia_Man_t * p0, * p1, * pTemp;
+ int RetValue;
+
+ p0 = Gia_ManFromAig( pAig0 );
+ p0 = Gia_ManCleanup( pTemp = p0 );
+ Gia_ManStop( pTemp );
+
+ p1 = Gia_ManFromAig( pAig1 );
+ p1 = Gia_ManCleanup( pTemp = p1 );
+ Gia_ManStop( pTemp );
+
+ RetValue = Cec_ManVerifyTwo( p0, p1, fVerbose );
+ pAig0->pSeqModel = p0->pCexComb; p0->pCexComb = NULL;
+ Gia_ManStop( p0 );
+ Gia_ManStop( p1 );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/cec/cecClass.c b/src/aig/cec/cecClass.c
index 65fa2e9b..aaa85ffa 100644
--- a/src/aig/cec/cecClass.c
+++ b/src/aig/cec/cecClass.c
@@ -24,39 +24,10 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static inline int Cec_ObjRepr( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iRepr; }
-static inline void Cec_ObjSetRepr( Cec_ManCsw_t * p, int Id, int Num ) { p->pObjs[Id].iRepr = Num; }
-
-static inline int Cec_ObjProved( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iProved; }
-static inline void Cec_ObjSetProved( Cec_ManCsw_t * p, int Id ) { p->pObjs[Id].iProved = 1; }
-
-static inline int Cec_ObjFailed( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iFailed; }
-static inline void Cec_ObjSetFailed( Cec_ManCsw_t * p, int Id ) { p->pObjs[Id].iFailed = 1; }
-
-static inline int Cec_ObjNext( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iNext; }
-static inline void Cec_ObjSetNext( Cec_ManCsw_t * p, int Id, int Num ) { p->pObjs[Id].iNext = Num; }
-
-static inline unsigned Cec_ObjSim( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].SimNum; }
-static inline unsigned * Cec_ObjSimP1( Cec_ManCsw_t * p, int Id ) { return &p->pObjs[Id].SimNum; }
-static inline unsigned * Cec_ObjSimP( Cec_ManCsw_t * p, int Id ) { return p->pMems + Cec_ObjSim(p, Id) + 1; }
-static inline void Cec_ObjSetSim( Cec_ManCsw_t * p, int Id, unsigned n ) { p->pObjs[Id].SimNum = n; }
-
-static inline int Cec_ObjIsConst( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) == 0; }
-static inline int Cec_ObjIsHead( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) < 0 && Cec_ObjNext(p, Id) > 0; }
-static inline int Cec_ObjIsNone( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) < 0 && Cec_ObjNext(p, Id) == 0; }
-static inline int Cec_ObjIsTail( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) > 0 && Cec_ObjNext(p, Id) == 0; }
-static inline int Cec_ObjIsClass( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) > 0 || Cec_ObjNext(p, Id) > 0; }
-
-#define Cec_ManForEachObj( p, i ) \
- for ( i = 0; i < Gia_ManObjNum(p->pAig); i++ )
-#define Cec_ManForEachObj1( p, i ) \
- for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ )
-#define Cec_ManForEachClass( p, i ) \
- for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) if ( !Cec_ObjIsHead(p, i) ) {} else
-#define Cec_ClassForEachObj( p, i, iObj ) \
- for ( assert(Cec_ObjIsHead(p, i)), iObj = i; iObj; iObj = Cec_ObjNext(p, iObj) )
-#define Cec_ClassForEachObj1( p, i, iObj ) \
- for ( assert(Cec_ObjIsHead(p, i)), iObj = Cec_ObjNext(p, i); iObj; iObj = Cec_ObjNext(p, iObj) )
+static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id ) { return p->pMems + p->pSimInfo[Id] + 1; }
+static inline void Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n ) { p->pSimInfo[Id] = n; }
+
+static inline float Cec_MemUsage( Cec_ManSim_t * p ) { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -64,30 +35,7 @@ static inline int Cec_ObjIsClass( Cec_ManCsw_t * p, int Id ) {
/**Function*************************************************************
- Synopsis [Creates the set of representatives.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p )
-{
- int i, * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) );
- for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ )
- if ( Cec_ObjProved(p, i) )
- {
- assert( Cec_ObjRepr(p, i) >= 0 );
- pReprs[i] = Cec_ObjRepr(p, i);
- }
- return pReprs;
-}
-
-/**Function*************************************************************
-
- Synopsis []
+ Synopsis [Compares simulation info of one node with constant 0.]
Description []
@@ -96,250 +44,28 @@ int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Cec_ManCswDupWithClasses( Cec_ManCsw_t * p )
+int Cec_ManSimCompareConst( unsigned * p, int nWords )
{
- Gia_Man_t * pNew, * pTemp;
- Gia_Obj_t * pObj, * pRepr;
- int iRes0, iRes1, iRepr, iNode;
- int i, fCompl, * piCopies;
- Vec_IntClear( p->vXorNodes );
- Gia_ManLevelNum( p->pAig );
- pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) );
- pNew->pName = Aig_UtilStrsav( p->pAig->pName );
- Gia_ManHashAlloc( pNew );
- piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) );
- piCopies[0] = 0;
- Gia_ManForEachObj1( p->pAig, pObj, i )
- {
- if ( Gia_ObjIsCi(pObj) )
- {
- piCopies[i] = Gia_ManAppendCi( pNew );
- continue;
- }
- iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) );
- if ( Gia_ObjIsCo(pObj) )
- {
- Gia_ManAppendCo( pNew, iRes0 );
- continue;
- }
- iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) );
- iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 );
- if ( Cec_ObjRepr(p, i) < 0 || !Cec_ObjProved(p, i) )
- continue;
- assert( Cec_ObjRepr(p, i) < i );
- iRepr = piCopies[Cec_ObjRepr(p, i)];
- if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) )
- continue;
- pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) );
- fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr);
- piCopies[i] = Gia_LitNotCond( iRepr, fCompl );
- }
- ABC_FREE( piCopies );
- Gia_ManHashStop( pNew );
- Gia_ManSetRegNum( pNew, 0 );
- pNew = Gia_ManCleanup( pTemp = pNew );
- Gia_ManStop( pTemp );
- return pNew;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Gia_Man_t * Cec_ManCswSpecReduction( Cec_ManCsw_t * p )
-{
- Gia_Man_t * pNew, * pTemp;
- Gia_Obj_t * pObj, * pRepr;
- int iRes0, iRes1, iRepr, iNode, iMiter;
- int i, fCompl, * piCopies, * pDepths;
- Vec_IntClear( p->vXorNodes );
-// Gia_ManLevelNum( p->pAig );
- pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) );
- pNew->pName = Aig_UtilStrsav( p->pAig->pName );
- Gia_ManHashAlloc( pNew );
- piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) );
- pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
- piCopies[0] = 0;
- Gia_ManForEachObj1( p->pAig, pObj, i )
- {
- if ( Gia_ObjIsCi(pObj) )
- {
- piCopies[i] = Gia_ManAppendCi( pNew );
- continue;
- }
- if ( Gia_ObjIsCo(pObj) )
- continue;
- if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 ||
- piCopies[Gia_ObjFaninId1(pObj,i)] == -1 )
- continue;
- iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) );
- iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) );
- iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 );
- pDepths[i] = AIG_MAX( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] );
- if ( Cec_ObjRepr(p, i) < 0 || Cec_ObjFailed(p, i) )
- continue;
- assert( Cec_ObjRepr(p, i) < i );
- iRepr = piCopies[Cec_ObjRepr(p, i)];
- if ( iRepr == -1 )
- continue;
- if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) )
- continue;
- pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) );
- fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr);
- piCopies[i] = Gia_LitNotCond( iRepr, fCompl );
- if ( Cec_ObjProved(p, i) )
- continue;
-// if ( p->pPars->nLevelMax &&
-// (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax ||
-// Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) )
-// continue;
- // produce speculative miter
- iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] );
- Gia_ManAppendCo( pNew, iMiter );
- Vec_IntPush( p->vXorNodes, Cec_ObjRepr(p, i) );
- Vec_IntPush( p->vXorNodes, i );
- // add to the depth of this node
- pDepths[i] = 1 + AIG_MAX( pDepths[i], pDepths[Cec_ObjRepr(p, i)] );
- if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax )
- piCopies[i] = -1;
- }
- ABC_FREE( piCopies );
- ABC_FREE( pDepths );
- Gia_ManHashStop( pNew );
- Gia_ManSetRegNum( pNew, 0 );
- pNew = Gia_ManCleanup( pTemp = pNew );
- Gia_ManStop( pTemp );
- return pNew;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Gia_Man_t * Cec_ManCswSpecReductionProved( Cec_ManCsw_t * p )
-{
- Gia_Man_t * pNew, * pTemp;
- Gia_Obj_t * pObj, * pRepr;
- int iRes0, iRes1, iRepr, iNode, iMiter;
- int i, fCompl, * piCopies;
- Vec_IntClear( p->vXorNodes );
- Gia_ManLevelNum( p->pAig );
- pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) );
- pNew->pName = Aig_UtilStrsav( p->pAig->pName );
- Gia_ManHashAlloc( pNew );
- piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) );
- piCopies[0] = 0;
- Gia_ManForEachObj1( p->pAig, pObj, i )
+ int w;
+ if ( p[0] & 1 )
{
- if ( Gia_ObjIsCi(pObj) )
- {
- piCopies[i] = Gia_ManAppendCi( pNew );
- continue;
- }
- if ( Gia_ObjIsCo(pObj) )
- continue;
- iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) );
- iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) );
- iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 );
- if ( Cec_ObjRepr(p, i) < 0 || !Cec_ObjProved(p, i) )
- continue;
- assert( Cec_ObjRepr(p, i) < i );
- iRepr = piCopies[Cec_ObjRepr(p, i)];
- if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) )
- continue;
- pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) );
- fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr);
- piCopies[i] = Gia_LitNotCond( iRepr, fCompl );
- // add speculative miter
- iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] );
- Gia_ManAppendCo( pNew, iMiter );
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != ~0 )
+ return 0;
+ return 1;
}
- ABC_FREE( piCopies );
- Gia_ManHashStop( pNew );
- Gia_ManSetRegNum( pNew, 0 );
- pNew = Gia_ManCleanup( pTemp = pNew );
- Gia_ManStop( pTemp );
- return pNew;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Cec_ManCswCountOne( Cec_ManCsw_t * p, int i )
-{
- int Ent, nLits = 1;
- Cec_ClassForEachObj1( p, i, Ent )
+ else
{
- assert( Cec_ObjRepr(p, Ent) == i );
- nLits++;
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != 0 )
+ return 0;
+ return 1;
}
- return nLits;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Cec_ManCswCountLitsAll( Cec_ManCsw_t * p )
-{
- int i, nLits = 0;
- Cec_ManForEachObj( p, i )
- nLits += (Cec_ObjRepr(p, i) >= 0);
- return nLits;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cec_ManCswPrintOne( Cec_ManCsw_t * p, int i, int Counter )
-{
- int Ent;
- printf( "Class %4d : Num = %2d {", Counter, Cec_ManCswCountOne(p, i) );
- Cec_ClassForEachObj( p, i, Ent )
- printf(" %d", Ent );
- printf( " }\n" );
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Compares simulation info of two nodes.]
Description []
@@ -348,32 +74,28 @@ void Cec_ManCswPrintOne( Cec_ManCsw_t * p, int i, int Counter )
SeeAlso []
***********************************************************************/
-void Cec_ManCswPrintClasses( Cec_ManCsw_t * p, int fVerbose )
+int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords )
{
- int i, Counter = 0, Counter1 = 0, CounterX = 0, nLits;
- Cec_ManForEachObj1( p, i )
+ int w;
+ if ( (p0[0] & 1) == (p1[0] & 1) )
{
- if ( Cec_ObjIsHead(p, i) )
- Counter++;
- else if ( Cec_ObjIsConst(p, i) )
- Counter1++;
- else if ( Cec_ObjIsNone(p, i) )
- CounterX++;
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != p1[w] )
+ return 0;
+ return 1;
}
- nLits = Cec_ManCswCountLitsAll( p );
- printf( "Class =%7d. Const =%7d. Unsed =%7d. Lits =%8d. All =%8d. Mem = %5.2f Mb\n",
- Counter, Counter1, CounterX, nLits-Counter1, nLits, 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20) );
- if ( fVerbose )
+ else
{
- Counter = 0;
- Cec_ManForEachClass( p, i )
- Cec_ManCswPrintOne( p, i, ++Counter );
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != ~p1[w] )
+ return 0;
+ return 1;
}
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Returns the number of the first non-equal bit.]
Description []
@@ -382,28 +104,28 @@ void Cec_ManCswPrintClasses( Cec_ManCsw_t * p, int fVerbose )
SeeAlso []
***********************************************************************/
-int Cec_ManCswCompareEqual( unsigned * p0, unsigned * p1, int nWords )
+int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords )
{
int w;
- if ( (p0[0] & 1) == (p1[0] & 1) )
+ if ( p[0] & 1 )
{
for ( w = 0; w < nWords; w++ )
- if ( p0[w] != p1[w] )
- return 0;
- return 1;
+ if ( p[w] != ~0 )
+ return 32*w + Aig_WordFindFirstBit( ~p[w] );
+ return -1;
}
else
{
for ( w = 0; w < nWords; w++ )
- if ( p0[w] != ~p1[w] )
- return 0;
- return 1;
+ if ( p[w] != 0 )
+ return 32*w + Aig_WordFindFirstBit( p[w] );
+ return -1;
}
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Compares simulation info of two nodes.]
Description []
@@ -412,28 +134,28 @@ int Cec_ManCswCompareEqual( unsigned * p0, unsigned * p1, int nWords )
SeeAlso []
***********************************************************************/
-int Cec_ManCswCompareConst( unsigned * p, int nWords )
+int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords )
{
int w;
- if ( p[0] & 1 )
+ if ( (p0[0] & 1) == (p1[0] & 1) )
{
for ( w = 0; w < nWords; w++ )
- if ( p[w] != ~0 )
- return 0;
- return 1;
+ if ( p0[w] != p1[w] )
+ return 32*w + Aig_WordFindFirstBit( p0[w] ^ p1[w] );
+ return -1;
}
else
{
for ( w = 0; w < nWords; w++ )
- if ( p[w] != 0 )
- return 0;
- return 1;
+ if ( p0[w] != ~p1[w] )
+ return 32*w + Aig_WordFindFirstBit( p0[w] ^ ~p1[w] );
+ return -1;
}
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Creates equivalence class.]
Description []
@@ -442,31 +164,31 @@ int Cec_ManCswCompareConst( unsigned * p, int nWords )
SeeAlso []
***********************************************************************/
-void Cec_ManCswClassCreate( Cec_ManCsw_t * p, Vec_Int_t * vClass )
+void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass )
{
- int Repr = -1, EntPrev = -1, Ent, i;
+ int Repr = GIA_VOID, EntPrev = -1, Ent, i;
assert( Vec_IntSize(vClass) > 0 );
Vec_IntForEachEntry( vClass, Ent, i )
{
if ( i == 0 )
{
Repr = Ent;
- Cec_ObjSetRepr( p, Ent, -1 );
+ Gia_ObjSetRepr( p, Ent, GIA_VOID );
EntPrev = Ent;
}
else
{
- Cec_ObjSetRepr( p, Ent, Repr );
- Cec_ObjSetNext( p, EntPrev, Ent );
+ Gia_ObjSetRepr( p, Ent, Repr );
+ Gia_ObjSetNext( p, EntPrev, Ent );
EntPrev = Ent;
}
}
- Cec_ObjSetNext( p, EntPrev, 0 );
+ Gia_ObjSetNext( p, EntPrev, 0 );
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Refines one equivalence class.]
Description []
@@ -475,34 +197,34 @@ void Cec_ManCswClassCreate( Cec_ManCsw_t * p, Vec_Int_t * vClass )
SeeAlso []
***********************************************************************/
-int Cec_ManCswClassRefineOne( Cec_ManCsw_t * p, int i, int fFirst )
+int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i )
{
unsigned * pSim0, * pSim1;
int Ent;
Vec_IntClear( p->vClassOld );
Vec_IntClear( p->vClassNew );
Vec_IntPush( p->vClassOld, i );
- pSim0 = fFirst? Cec_ObjSimP1(p, i) : Cec_ObjSimP(p, i);
- Cec_ClassForEachObj1( p, i, Ent )
+ pSim0 = Cec_ObjSim(p, i);
+ Gia_ClassForEachObj1( p->pAig, i, Ent )
{
- pSim1 = fFirst? Cec_ObjSimP1(p, Ent) : Cec_ObjSimP(p, Ent);
- if ( Cec_ManCswCompareEqual( pSim0, pSim1, p->nWords ) )
+ pSim1 = Cec_ObjSim(p, Ent);
+ if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) )
Vec_IntPush( p->vClassOld, Ent );
else
Vec_IntPush( p->vClassNew, Ent );
}
if ( Vec_IntSize( p->vClassNew ) == 0 )
return 0;
- Cec_ManCswClassCreate( p, p->vClassOld );
- Cec_ManCswClassCreate( p, p->vClassNew );
+ Cec_ManSimClassCreate( p->pAig, p->vClassOld );
+ Cec_ManSimClassCreate( p->pAig, p->vClassNew );
if ( Vec_IntSize(p->vClassNew) > 1 )
- return 1 + Cec_ManCswClassRefineOne( p, Vec_IntEntry(p->vClassNew,0), fFirst );
+ return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) );
return 1;
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Computes hash key of the simuation info.]
Description []
@@ -511,7 +233,7 @@ int Cec_ManCswClassRefineOne( Cec_ManCsw_t * p, int i, int fFirst )
SeeAlso []
***********************************************************************/
-int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize )
+int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize )
{
static int s_Primes[16] = {
1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
@@ -530,7 +252,7 @@ int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize )
/**Function*************************************************************
- Synopsis []
+ Synopsis [Resets pointers to the simulation memory.]
Description []
@@ -539,90 +261,7 @@ int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize )
SeeAlso []
***********************************************************************/
-void Cec_ManCswClassesCreate( Cec_ManCsw_t * p )
-{
- int * pTable, nTableSize, i, Key;
- p->nWords = 1;
- nTableSize = Aig_PrimeCudd( 100 + Gia_ManObjNum(p->pAig) / 10 );
- pTable = ABC_CALLOC( int, nTableSize );
- Cec_ObjSetRepr( p, 0, -1 );
- Cec_ManForEachObj1( p, i )
- {
- if ( Gia_ObjIsCo(Gia_ManObj(p->pAig, i)) )
- {
- Cec_ObjSetRepr( p, i, -1 );
- continue;
- }
- if ( Cec_ManCswCompareConst( Cec_ObjSimP1(p, i), p->nWords ) )
- {
- Cec_ObjSetRepr( p, i, 0 );
- continue;
- }
- Key = Cec_ManCswHashKey( Cec_ObjSimP1(p, i), p->nWords, nTableSize );
- if ( pTable[Key] == 0 )
- Cec_ObjSetRepr( p, i, -1 );
- else
- {
- Cec_ObjSetNext( p, pTable[Key], i );
- Cec_ObjSetRepr( p, i, Cec_ObjRepr(p, pTable[Key]) );
- if ( Cec_ObjRepr(p, i) == -1 )
- Cec_ObjSetRepr( p, i, pTable[Key] );
- }
- pTable[Key] = i;
- }
- ABC_FREE( pTable );
- if ( p->pPars->fVeryVerbose )
- Cec_ManCswPrintClasses( p, 0 );
- // refine classes
- Cec_ManForEachClass( p, i )
- Cec_ManCswClassRefineOne( p, i, 1 );
- // clean memory
- Cec_ManForEachObj( p, i )
- Cec_ObjSetSim( p, i, 0 );
- if ( p->pPars->fVeryVerbose )
- Cec_ManCswPrintClasses( p, 0 );
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cec_ManCswSimulateSimple( Cec_ManCsw_t * p )
-{
- Gia_Obj_t * pObj;
- unsigned Res0, Res1;
- int i;
- Gia_ManForEachCi( p->pAig, pObj, i )
- Cec_ObjSetSim( p, i, Aig_ManRandom(0) );
- Gia_ManForEachAnd( p->pAig, pObj, i )
- {
- Res0 = Cec_ObjSim( p, Gia_ObjFaninId0(pObj, i) );
- Res1 = Cec_ObjSim( p, Gia_ObjFaninId1(pObj, i) );
- Cec_ObjSetSim( p, i, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) &
- (Gia_ObjFaninC1(pObj)? ~Res1: Res1) );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [References simulation info.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p )
+void Cec_ManSimMemRelink( Cec_ManSim_t * p )
{
unsigned * pPlace, Ent;
pPlace = &p->MemFree;
@@ -634,6 +273,7 @@ void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p )
pPlace = p->pMems + Ent;
}
*pPlace = 0;
+ p->nWordsOld = p->nWords;
}
/**Function*************************************************************
@@ -647,10 +287,10 @@ void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p )
SeeAlso []
***********************************************************************/
-unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i )
+unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i )
{
unsigned * pSim;
- assert( p->pObjs[i].SimNum == 0 );
+ assert( p->pSimInfo[i] == 0 );
if ( p->MemFree == 0 )
{
if ( p->nWordsAlloc == 0 )
@@ -661,9 +301,9 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i )
}
p->nWordsAlloc *= 2;
p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc );
- Cec_ManCswSimMemRelink( p );
+ Cec_ManSimMemRelink( p );
}
- p->pObjs[i].SimNum = p->MemFree;
+ p->pSimInfo[i] = p->MemFree;
pSim = p->pMems + p->MemFree;
p->MemFree = pSim[0];
pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) );
@@ -675,7 +315,7 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i )
/**Function*************************************************************
- Synopsis [Dereference simulaton info.]
+ Synopsis [Dereferences simulaton info.]
Description []
@@ -684,16 +324,16 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i )
SeeAlso []
***********************************************************************/
-unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i )
+unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i )
{
unsigned * pSim;
- assert( p->pObjs[i].SimNum > 0 );
- pSim = p->pMems + p->pObjs[i].SimNum;
+ assert( p->pSimInfo[i] > 0 );
+ pSim = p->pMems + p->pSimInfo[i];
if ( --pSim[0] == 0 )
{
pSim[0] = p->MemFree;
- p->MemFree = p->pObjs[i].SimNum;
- p->pObjs[i].SimNum = 0;
+ p->MemFree = p->pSimInfo[i];
+ p->pSimInfo[i] = 0;
p->nMems--;
}
return pSim;
@@ -701,7 +341,7 @@ unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i )
/**Function*************************************************************
- Synopsis []
+ Synopsis [Refines nodes belonging to candidate constant class.]
Description []
@@ -710,52 +350,145 @@ unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i )
SeeAlso []
***********************************************************************/
-void Cec_ManCswProcessRefined( Cec_ManCsw_t * p, Vec_Int_t * vRefined )
+void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined )
{
unsigned * pSim;
int * pTable, nTableSize, i, k, Key;
if ( Vec_IntSize(vRefined) == 0 )
return;
- nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 );
+ nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 );
pTable = ABC_CALLOC( int, nTableSize );
Vec_IntForEachEntry( vRefined, i, k )
{
- if ( i == 7720 )
- {
- int s = 0;
- }
- pSim = Cec_ObjSimP( p, i );
- assert( !Cec_ManCswCompareConst( pSim, p->nWords ) );
- Key = Cec_ManCswHashKey( pSim, p->nWords, nTableSize );
+ pSim = Cec_ObjSim( p, i );
+ assert( !Cec_ManSimCompareConst( pSim, p->nWords ) );
+ Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize );
if ( pTable[Key] == 0 )
{
- assert( Cec_ObjRepr(p, i) == 0 );
- assert( Cec_ObjNext(p, i) == 0 );
- Cec_ObjSetRepr( p, i, -1 );
+ assert( Gia_ObjRepr(p->pAig, i) == 0 );
+ assert( Gia_ObjNext(p->pAig, i) == 0 );
+ Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
}
else
{
- Cec_ObjSetNext( p, pTable[Key], i );
- Cec_ObjSetRepr( p, i, Cec_ObjRepr(p, pTable[Key]) );
- if ( Cec_ObjRepr(p, i) == -1 )
- Cec_ObjSetRepr( p, i, pTable[Key] );
- assert( Cec_ObjRepr(p, i) > 0 );
+ Gia_ObjSetNext( p->pAig, pTable[Key], i );
+ Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) );
+ if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID )
+ Gia_ObjSetRepr( p->pAig, i, pTable[Key] );
+ assert( Gia_ObjRepr(p->pAig, i) > 0 );
}
pTable[Key] = i;
}
Vec_IntForEachEntry( vRefined, i, k )
{
- if ( Cec_ObjIsHead( p, i ) )
- Cec_ManCswClassRefineOne( p, i, 0 );
+ if ( Gia_ObjIsHead( p->pAig, i ) )
+ Cec_ManSimClassRefineOne( p, i );
}
Vec_IntForEachEntry( vRefined, i, k )
- Cec_ManCswSimDeref( p, i );
+ Cec_ManSimSimDeref( p, i );
ABC_FREE( pTable );
}
/**Function*************************************************************
+ Synopsis [Saves the input pattern with the given number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat )
+{
+ unsigned * pInfo;
+ int i;
+ assert( p->pCexComb == NULL );
+ assert( iPat >= 0 && iPat < 32 * p->nWords );
+ p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char,
+ sizeof(Gia_Cex_t) + sizeof(unsigned) * Aig_BitWordNum(Gia_ManCiNum(p->pAig)) );
+ p->pCexComb->iPo = p->iOut;
+ p->pCexComb->nPis = Gia_ManCiNum(p->pAig);
+ p->pCexComb->nBits = Gia_ManCiNum(p->pAig);
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ {
+ pInfo = Vec_PtrEntry( p->vCiSimInfo, i );
+ if ( Aig_InfoHasBit( pInfo, iPat ) )
+ Aig_InfoSetBit( p->pCexComb->pData, i );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if computation should stop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p )
+{
+ unsigned * pInfo, * pInfo2;
+ int i;
+ if ( p->vCoSimInfo == NULL )
+ return 0;
+ // compare outputs with 0
+ if ( p->pPars->fDoubleOuts )
+ {
+ assert( (Gia_ManCoNum(p->pAig) & 1) == 0 );
+ for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ )
+ {
+ pInfo = Vec_PtrEntry( p->vCoSimInfo, i );
+ pInfo2 = Vec_PtrEntry( p->vCoSimInfo, ++i );
+ if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) )
+ {
+ if ( p->iOut == -1 )
+ {
+ p->iOut = i/2;
+ Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) );
+ }
+ if ( p->pCexes == NULL )
+ p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig)/2 );
+ if ( p->pCexes[i/2] == NULL )
+ {
+ p->nOuts++;
+ p->pCexes[i/2] = (void *)1;
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ )
+ {
+ pInfo = Vec_PtrEntry( p->vCoSimInfo, i );
+ if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) )
+ {
+ if ( p->iOut == -1 )
+ {
+ p->iOut = i;
+ Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) );
+ }
+ if ( p->pCexes == NULL )
+ p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig) );
+ if ( p->pCexes[i] == NULL )
+ {
+ p->nOuts++;
+ p->pCexes[i] = (void *)1;
+ }
+ }
+ }
+ }
+ return p->pCexes != NULL && p->pPars->fFirstStop;
+}
+
+/**Function*************************************************************
+
Synopsis [Simulates one round.]
Description [Returns the number of PO entry if failed; 0 otherwise.]
@@ -765,17 +498,20 @@ void Cec_ManCswProcessRefined( Cec_ManCsw_t * p, Vec_Int_t * vRefined )
SeeAlso []
***********************************************************************/
-void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos, int iSeries, int fRandomize )
+int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
{
- static int nCountRand = 0;
Gia_Obj_t * pObj;
unsigned * pRes0, * pRes1, * pRes;
int i, k, w, Ent, iCiId = 0, iCoId = 0;
+ // prepare internal storage
+ if ( p->nWordsOld != p->nWords )
+ Cec_ManSimMemRelink( p );
p->nMemsMax = 0;
+ // simulate nodes
Vec_IntClear( p->vRefinedC );
if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) )
{
- pRes = Cec_ManCswSimRef( p, 0 );
+ pRes = Cec_ManSimSimRef( p, 0 );
for ( w = 1; w <= p->nWords; w++ )
pRes[w] = 0;
}
@@ -788,16 +524,12 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t
iCiId++;
continue;
}
- pRes = Cec_ManCswSimRef( p, i );
+ pRes = Cec_ManSimSimRef( p, i );
if ( vInfoCis )
{
pRes0 = Vec_PtrEntry( vInfoCis, iCiId++ );
for ( w = 1; w <= p->nWords; w++ )
- {
- pRes[w] = pRes0[iSeries*p->nWords+w-1];
- if ( fRandomize )
- pRes[w] ^= (1 << (nCountRand++ & 0x1f));
- }
+ pRes[w] = pRes0[w-1];
}
else
{
@@ -810,7 +542,7 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t
}
if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin
{
- pRes0 = Cec_ManCswSimDeref( p, Gia_ObjFaninId0(pObj,i) );
+ pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
if ( vInfoCos )
{
pRes = Vec_PtrEntry( vInfoCos, iCoId++ );
@@ -824,9 +556,9 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t
continue;
}
assert( Gia_ObjValue(pObj) );
- pRes = Cec_ManCswSimRef( p, i );
- pRes0 = Cec_ManCswSimDeref( p, Gia_ObjFaninId0(pObj,i) );
- pRes1 = Cec_ManCswSimDeref( p, Gia_ObjFaninId1(pObj,i) );
+ pRes = Cec_ManSimSimRef( p, i );
+ pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
+ pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) );
if ( Gia_ObjFaninC0(pObj) )
{
if ( Gia_ObjFaninC1(pObj) )
@@ -847,47 +579,50 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t
}
references:
// if this node is candidate constant, collect it
- if ( Cec_ObjIsConst(p, i) && !Cec_ManCswCompareConst(pRes + 1, p->nWords) )
+ if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) )
{
pRes[0]++;
Vec_IntPush( p->vRefinedC, i );
}
// if the node belongs to a class, save it
- if ( Cec_ObjIsClass(p, i) )
+ if ( Gia_ObjIsClass(p->pAig, i) )
pRes[0]++;
// if this is the last node of the class, process it
- if ( Cec_ObjIsTail(p, i) )
+ if ( Gia_ObjIsTail(p->pAig, i) )
{
Vec_IntClear( p->vClassTemp );
- Cec_ClassForEachObj( p, Cec_ObjRepr(p, i), Ent )
+ Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent )
Vec_IntPush( p->vClassTemp, Ent );
- Cec_ManCswClassRefineOne( p, Cec_ObjRepr(p, i), 0 );
+ Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) );
Vec_IntForEachEntry( p->vClassTemp, Ent, k )
- Cec_ManCswSimDeref( p, Ent );
+ Cec_ManSimSimDeref( p, Ent );
}
}
if ( Vec_IntSize(p->vRefinedC) > 0 )
- Cec_ManCswProcessRefined( p, p->vRefinedC );
+ Cec_ManSimProcessRefined( p, p->vRefinedC );
assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) );
assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) );
assert( p->nMems == 1 );
+ if ( p->nMems != 1 )
+ printf( "Cec_ManSimSimulateRound(): Memory management error!\n" );
if ( p->pPars->fVeryVerbose )
- Cec_ManCswPrintClasses( p, 0 );
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
/*
- if ( p->nMems > 1 )
- {
+ if ( p->nMems > 1 ) {
for ( i = 1; i < p->nObjs; i++ )
- if ( p->pSims[i] )
- {
+ if ( p->pSims[i] ) {
int x = 0;
}
}
*/
+ return Cec_ManSimAnalyzeOutputs( p );
}
+
+
/**Function*************************************************************
- Synopsis []
+ Synopsis [Creates simulation info for this round.]
Description []
@@ -896,28 +631,41 @@ references:
SeeAlso []
***********************************************************************/
-int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p )
+void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
{
- int i;
- Gia_ManSetRefs( p->pAig );
- Cec_ManCswSimulateSimple( p );
- Cec_ManCswClassesCreate( p );
- for ( i = 0; i < p->pPars->nRounds; i++ )
+ unsigned * pRes0, * pRes1;
+ int i, w;
+ if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 )
{
- p->nWords = i + 1;
- Cec_ManCswSimMemRelink( p );
- Cec_ManCswSimulateRound( p, NULL, NULL, 0, 0 );
+ assert( vInfoCis && vInfoCos );
+ for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ )
+ {
+ pRes0 = Vec_PtrEntry( vInfoCis, i );
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = Aig_ManRandom( 0 );
+ }
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ pRes0 = Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i );
+ pRes1 = Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i );
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = pRes1[w];
+ }
+ }
+ else
+ {
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ {
+ pRes0 = Vec_PtrEntry( vInfoCis, i );
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = Aig_ManRandom( 0 );
+ }
}
- p->nWords = p->pPars->nWords;
- Cec_ManCswSimMemRelink( p );
- for ( i = 0; i < p->pPars->nRounds; i++ )
- Cec_ManCswSimulateRound( p, NULL, NULL, 0, 0 );
- return 1;
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Returns 1 if the bug is found.]
Description []
@@ -926,21 +674,37 @@ int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p )
SeeAlso []
***********************************************************************/
-int Cec_ManCswClassesUpdate_rec( Gia_Obj_t * pObj )
+int Cec_ManSimClassesPrepare( Cec_ManSim_t * p )
{
- int Result;
- if ( pObj->fMark0 )
- return 1;
- if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) )
- return 0;
- Result = (Cec_ManCswClassesUpdate_rec( Gia_ObjFanin0(pObj) ) |
- Cec_ManCswClassesUpdate_rec( Gia_ObjFanin1(pObj) ));
- return pObj->fMark0 = Result;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pAig->pReprs == NULL );
+ // allocate representation
+ p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) );
+ p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
+ Gia_ManForEachObj( p->pAig, pObj, i )
+ Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj)) ? 0 : GIA_VOID );
+ // perform simulation
+ Gia_ManSetRefs( p->pAig );
+ p->nWords = 1;
+ do {
+ if ( p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ for ( i = 0; i < 4; i++ )
+ {
+ Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
+ }
+ p->nWords = 2 * p->nWords + 1;
+ }
+ while ( p->nWords <= p->pPars->nWords );
+ return 0;
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Returns 1 if the bug is found.]
Description []
@@ -949,100 +713,23 @@ int Cec_ManCswClassesUpdate_rec( Gia_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-int Cec_ManCswClassesUpdate( Cec_ManCsw_t * p, Cec_ManPat_t * pPat, Gia_Man_t * pNew )
+int Cec_ManSimClassesRefine( Cec_ManSim_t * p )
{
- Vec_Ptr_t * vInfo;
- Gia_Obj_t * pObj, * pObjOld, * pReprOld;
- int i, k, iRepr, iNode;
- vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), p->pPars->nWords );
- if ( vInfo != NULL )
- {
- for ( i = 0; i < pPat->nSeries; i++ )
- Cec_ManCswSimulateRound( p, vInfo, NULL, i, 0 );
- Vec_PtrFree( vInfo );
- }
- assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) );
- // mark the transitive fanout of failed nodes
- if ( p->pPars->nDepthMax != 1 )
+ int i;
+ Gia_ManSetRefs( p->pAig );
+ p->nWords = p->pPars->nWords;
+ for ( i = 0; i < p->pPars->nRounds; i++ )
{
- Gia_ManCleanMark0( p->pAig );
- Gia_ManCleanMark1( p->pAig );
- Gia_ManForEachCo( pNew, pObj, k )
- {
- iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
- iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
- if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved
- continue;
-// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1;
- Gia_ManObj(p->pAig, iNode)->fMark0 = 1;
- }
- // mark the nodes reachable through the failed nodes
- Gia_ManForEachAnd( p->pAig, pObjOld, k )
- pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0);
- // unmark the disproved nodes
- Gia_ManForEachCo( pNew, pObj, k )
- {
- iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
- iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
- if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved
- continue;
- pObjOld = Gia_ManObj(p->pAig, iNode);
- assert( pObjOld->fMark0 == 1 );
- if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 )
- pObjOld->fMark1 = 1;
- }
- // clean marks
- Gia_ManForEachAnd( p->pAig, pObjOld, k )
- if ( pObjOld->fMark1 )
- {
- pObjOld->fMark0 = 0;
- pObjOld->fMark1 = 0;
- }
+ if ( (i % 4) == 0 && p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
}
- // set the results
- Gia_ManForEachCo( pNew, pObj, k )
- {
- iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
- iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
- pReprOld = Gia_ManObj(p->pAig, iRepr);
- pObjOld = Gia_ManObj(p->pAig, iNode);
- if ( pObj->fMark1 )
- { // proved
- assert( pObj->fMark0 == 0 );
- assert( !Cec_ObjProved(p, iNode) );
- if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 )
-// if ( pObjOld->fMark0 == 0 )
- {
- assert( iRepr == Cec_ObjRepr(p, iNode) );
- Cec_ObjSetProved( p, iNode );
- p->nAllProved++;
- }
- }
- else if ( pObj->fMark0 )
- { // disproved
- assert( pObj->fMark1 == 0 );
- if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 )
-// if ( pObjOld->fMark0 == 0 )
- {
- if ( iRepr == Cec_ObjRepr(p, iNode) )
- printf( "Cec_ManCswClassesUpdate(): Error! Node is not refined!\n" );
- p->nAllDisproved++;
- }
- }
- else
- { // failed
- assert( pObj->fMark0 == 0 );
- assert( pObj->fMark1 == 0 );
- assert( !Cec_ObjFailed(p, iNode) );
- assert( !Cec_ObjProved(p, iNode) );
- Cec_ObjSetFailed( p, iNode );
- p->nAllFailed++;
- }
- }
+ if ( p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
return 0;
}
-
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c
index ab8fd5cf..e25ddc90 100644
--- a/src/aig/cec/cecCore.c
+++ b/src/aig/cec/cecCore.c
@@ -44,11 +44,37 @@ void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p )
memset( p, 0, sizeof(Cec_ParSat_t) );
p->nBTLimit = 10; // conflict limit at a node
p->nSatVarMax = 2000; // the max number of SAT variables
- p->nCallsRecycle = 100; // calls to perform before recycling SAT solver
+ p->nCallsRecycle = 200; // calls to perform before recycling SAT solver
p->fPolarFlip = 1; // flops polarity of variables
+ p->fCheckMiter = 0; // the circuit is the miter
p->fFirstStop = 0; // stop on the first sat output
- p->fVerbose = 1; // verbose stats
+ p->fVerbose = 0; // verbose stats
}
+
+/**Function************ *************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParSim_t) );
+ p->nWords = 15; // the number of simulation words
+ p->nRounds = 15; // the number of simulation rounds
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->fCheckMiter = 0; // the circuit is the miter
+ p->fFirstStop = 0; // stop on the first sat output
+ p->fDoubleOuts = 0; // miter with separate outputs
+ p->fSeqSimulate = 0; // performs sequential simulation
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+}
/**Function************ *************************************************
@@ -61,19 +87,21 @@ void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p )
SeeAlso []
***********************************************************************/
-void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p )
+void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p )
{
- memset( p, 0, sizeof(Cec_ParCsw_t) );
- p->nWords = 20; // the number of simulation words
- p->nRounds = 20; // the number of simulation rounds
- p->nItersMax = 20; // the maximum number of iterations of SAT sweeping
- p->nBTLimit = 10000; // conflict limit at a node
- p->nSatVarMax = 2000; // the max number of SAT variables
- p->nCallsRecycle = 100; // calls to perform before recycling SAT solver
+ memset( p, 0, sizeof(Cec_ParFra_t) );
+ p->nWords = 15; // the number of simulation words
+ p->nRounds = 15; // the number of simulation rounds
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->nItersMax = 1000; // the maximum number of iterations of SAT sweeping
+ p->nBTLimit = 1000; // conflict limit at a node
p->nLevelMax = 0; // restriction on the level of nodes to be swept
p->nDepthMax = 1; // the depth in terms of steps of speculative reduction
p->fRewriting = 0; // enables AIG rewriting
+ p->fCheckMiter = 0; // the circuit is the miter
p->fFirstStop = 0; // stop on the first sat output
+ p->fDoubleOuts = 0; // miter with separate outputs
+ p->fColorDiff = 0; // miter with separate outputs
p->fVeryVerbose = 0; // verbose stats
p->fVerbose = 0; // verbose stats
}
@@ -92,14 +120,13 @@ void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p )
void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p )
{
memset( p, 0, sizeof(Cec_ParCec_t) );
- p->nIters = 1; // iterations of SAT solving/sweeping
- p->nBTLimitBeg = 2; // starting backtrack limit
- p->nBTlimitMulti = 8; // multiple of backtrack limiter
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->fFirstStop = 0; // stop on the first sat output
p->fUseSmartCnf = 0; // use smart CNF computation
p->fRewriting = 0; // enables AIG rewriting
- p->fSatSweeping = 0; // enables SAT sweeping
- p->fFirstStop = 0; // stop on the first sat output
- p->fVerbose = 1; // verbose stats
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
}
/**Function*************************************************************
@@ -124,6 +151,35 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Core procedure for simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars )
+{
+ Cec_ManSim_t * pSim;
+ int RetValue, clkTotal = clock();
+ if ( pPars->fSeqSimulate )
+ printf( "Performing sequential simulation of %d frames with %d words.\n",
+ pPars->nWords, pPars->nRounds );
+ Aig_ManRandom( 1 );
+ pSim = Cec_ManSimStart( pAig, pPars );
+ if ( pAig->pReprs == NULL )
+ RetValue = Cec_ManSimClassesPrepare( pSim );
+ Cec_ManSimClassesRefine( pSim );
+ if ( pPars->fCheckMiter )
+ printf( "The number of failed outputs of the miter = %6d. (Words = %4d. Rounds = %4d.)\n",
+ pSim->iOut, pSim->nOuts, pPars->nWords, pPars->nRounds );
+ ABC_PRT( "Time", clock() - clkTotal );
+ Cec_ManSimStop( pSim );
+}
/**Function*************************************************************
@@ -136,96 +192,185 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParCsw_t * pPars )
+Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars )
{
+ int fOutputResult = 0;
Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
- Gia_Man_t * pNew;
- Cec_ManCsw_t * p;
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Gia_Man_t * pIni, * pSrm, * pTemp;
+ Cec_ManFra_t * p;
+ Cec_ManSim_t * pSim;
Cec_ManPat_t * pPat;
- int i, RetValue, clk, clk2, clkTotal = clock();
+ int i, fTimeOut = 0, nMatches = 0, clk, clk2;
+ double clkTotal = clock();
+
+ // duplicate AIG and transfer equivalence classes
Aig_ManRandom( 1 );
- Gia_ManSetPhase( pAig );
- Gia_ManCleanMark0( pAig );
- Gia_ManCleanMark1( pAig );
- p = Cec_ManCswStart( pAig, pPars );
-clk = clock();
- RetValue = Cec_ManCswClassesPrepare( p );
-p->timeSim += clock() - clk;
+ pIni = Gia_ManDup(pAig);
+ pIni->pReprs = pAig->pReprs; pAig->pReprs = NULL;
+ pIni->pNexts = pAig->pNexts; pAig->pNexts = NULL;
+
+ // prepare the managers
+ // SAT sweeping
+ p = Cec_ManFraStart( pIni, pPars );
+ if ( pPars->fDoubleOuts )
+ pPars->fColorDiff = 1;
+ // simulation
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nWords = pPars->nWords;
+ pParsSim->nRounds = pPars->nRounds;
+ pParsSim->fCheckMiter = pPars->fCheckMiter;
+ pParsSim->fFirstStop = pPars->fFirstStop;
+ pParsSim->fDoubleOuts = pPars->fDoubleOuts;
+ pParsSim->fVerbose = pPars->fVerbose;
+ pSim = Cec_ManSimStart( p->pAig, pParsSim );
+ pSim->nWords = p->pPars->nWords;
+ // SAT solving
Cec_ManSatSetDefaultParams( pParsSat );
pParsSat->nBTLimit = pPars->nBTLimit;
pParsSat->fVerbose = pPars->fVeryVerbose;
+ // simulation patterns
pPat = Cec_ManPatStart();
pPat->fVerbose = pPars->fVeryVerbose;
+
+ // start equivalence classes
+clk = clock();
+ if ( p->pAig->pReprs == NULL )
+ {
+ if ( Cec_ManSimClassesPrepare(pSim) || Cec_ManSimClassesRefine(pSim) )
+ {
+ Gia_ManStop( p->pAig );
+ p->pAig = NULL;
+ goto finalize;
+ }
+ }
+p->timeSim += clock() - clk;
+ // perform solving
for ( i = 1; i <= pPars->nItersMax; i++ )
{
clk2 = clock();
- pNew = Cec_ManCswSpecReduction( p );
- if ( pPars->fVeryVerbose )
+ nMatches = 0;
+ if ( pPars->fDoubleOuts )
{
- Gia_ManPrintStats( p->pAig );
- Gia_ManPrintStats( pNew );
+ nMatches = Gia_ManEquivSetColors( p->pAig, pPars->fVeryVerbose );
+// p->pAig->pIso = Cec_ManDetectIsomorphism( p->pAig );
+// Gia_ManEquivTransform( p->pAig, 1 );
}
- if ( Gia_ManCoNum(pNew) == 0 )
+ pSrm = Cec_ManFraSpecReduction( p );
+ if ( pPars->fVeryVerbose )
+ Gia_ManPrintStats( pSrm );
+ if ( Gia_ManCoNum(pSrm) == 0 )
{
- Gia_ManStop( pNew );
+ Gia_ManStop( pSrm );
+ if ( p->pPars->fVerbose )
+ printf( "Considered all available candidate equivalences.\n" );
+ if ( pPars->fDoubleOuts && Gia_ManAndNum(p->pAig) > 0 )
+ {
+ if ( pPars->fColorDiff )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Switching into reduced mode.\n" );
+ pPars->fColorDiff = 0;
+ }
+ else
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Switching into normal mode.\n" );
+ pPars->fDoubleOuts = 0;
+ }
+ continue;
+ }
break;
}
clk = clock();
- Cec_ManSatSolve( pPat, pNew, pParsSat );
+ Cec_ManSatSolve( pPat, pSrm, pParsSat );
p->timeSat += clock() - clk;
-clk = clock();
- Cec_ManCswClassesUpdate( p, pPat, pNew );
-p->timeSim += clock() - clk;
- Gia_ManStop( pNew );
- pNew = Cec_ManCswDupWithClasses( p );
- Gia_WriteAiger( pNew, "gia_temp_new.aig", 0, 1 );
+ if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) )
+ {
+ Gia_ManStop( pSrm );
+ Gia_ManStop( p->pAig );
+ p->pAig = NULL;
+ goto finalize;
+ }
+ Gia_ManStop( pSrm );
+
+ // update the manager
+ pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDoubleOuts );
+ Gia_ManStop( pTemp );
if ( p->pPars->fVerbose )
{
- printf( "%3d : P =%7d. D =%7d. F =%6d. Lit =%8d. And =%8d. ",
- i, p->nAllProved, p->nAllDisproved, p->nAllFailed,
- Cec_ManCswCountLitsAll(p), Gia_ManAndNum(pNew) );
+ printf( "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ",
+ i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) );
ABC_PRT( "Time", clock() - clk2 );
}
- if ( p->pPars->fVeryVerbose )
+ if ( Gia_ManAndNum(p->pAig) == 0 )
{
- ABC_PRTP( "Sim ", p->timeSim, clock() - clkTotal );
- ABC_PRTP( "Sat ", p->timeSat, clock() - clkTotal );
- ABC_PRT( "Time", clock() - clkTotal );
- printf( "****** Intermedate result %3d ******\n", i );
- Gia_ManPrintStats( p->pAig );
- Gia_ManPrintStats( pNew );
- printf("The result is written into file \"%s\".\n", "gia_temp.aig" );
- printf( "************************************\n" );
+ if ( p->pPars->fVerbose )
+ printf( "Network after reduction is empty.\n" );
+ break;
}
- if ( Gia_ManAndNum(pNew) == 0 )
+ // check resource limits
+ if ( p->pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= p->pPars->TimeLimit )
{
- Gia_ManStop( pNew );
+ fTimeOut = 1;
break;
}
- Gia_ManStop( pNew );
+// if ( p->nAllFailed && !p->nAllProved && !p->nAllDisproved )
+ if ( p->nAllFailed > p->nAllProved + p->nAllDisproved )
+ {
+ if ( pParsSat->nBTLimit >= 10000 )
+ break;
+ pParsSat->nBTLimit *= 10;
+ if ( p->pPars->fVerbose )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Increasing conflict limit to %d.\n", pParsSat->nBTLimit );
+ if ( fOutputResult )
+ {
+ Gia_WriteAiger( p->pAig, "gia_cec_temp.aig", 0, 0 );
+ printf("The result is written into file \"%s\".\n", "gia_cec_temp.aig" );
+ }
+ }
+ }
+ if ( pPars->fDoubleOuts && pPars->fColorDiff && Gia_ManAndNum(p->pAig) < 100000 )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Switching into reduced mode.\n" );
+ pPars->fColorDiff = 0;
+ }
+ if ( pPars->fDoubleOuts && Gia_ManAndNum(p->pAig) < 20000 )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Switching into normal mode.\n" );
+ pPars->fColorDiff = 0;
+ pPars->fDoubleOuts = 0;
+ }
}
- Gia_ManCleanMark0( pAig );
- Gia_ManCleanMark1( pAig );
-
- // verify the result
+finalize:
if ( p->pPars->fVerbose )
{
- printf( "Verifying the result:\n" );
- pNew = Cec_ManCswSpecReductionProved( p );
- pParsSat->nBTLimit = 1000000;
- pParsSat->fVerbose = 1;
- Cec_ManSatSolve( NULL, pNew, pParsSat );
- Gia_ManStop( pNew );
+ ABC_PRTP( "Sim ", p->timeSim, clock() - (int)clkTotal );
+ ABC_PRTP( "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal );
+ ABC_PRTP( "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal );
+ ABC_PRT( "Time", clock() - clkTotal );
}
- // create the resulting miter
- pAig->pReprs = Cec_ManCswDeriveReprs( p );
- pNew = Gia_ManDupDfsClasses( pAig );
- Cec_ManCswStop( p );
+ pTemp = p->pAig; p->pAig = NULL;
+ if ( pTemp == NULL )
+ printf( "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut );
+ else if ( pSim->pCexes )
+ printf( "Disproved %d outputs of the miter.\n", pSim->nOuts );
+ if ( fTimeOut )
+ printf( "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC );
+
+ pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL;
+ Cec_ManSimStop( pSim );
Cec_ManPatStop( pPat );
- return pNew;
+ Cec_ManFraStop( p );
+ return pTemp;
}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/cec/cecInt.h b/src/aig/cec/cecInt.h
index 309f4292..1898b07c 100644
--- a/src/aig/cec/cecInt.h
+++ b/src/aig/cec/cecInt.h
@@ -65,6 +65,7 @@ struct Cec_ManPat_t_
int timeSort; // sorting literals
int timePack; // packing into sim info structures
int timeTotal; // total runtime
+ int timeTotalSave; // total runtime for saving
};
// SAT solving manager
@@ -100,38 +101,43 @@ struct Cec_ManSat_t_
int timeTotal; // total runtime
};
-// combinational sweeping object
-typedef struct Cec_ObjCsw_t_ Cec_ObjCsw_t;
-struct Cec_ObjCsw_t_
-{
- int iRepr; // representative node
- unsigned iNext : 30; // next node in the class
- unsigned iProved : 1; // this node is proved
- unsigned iFailed : 1; // this node is failed
- unsigned SimNum; // simulation info number
-};
-
// combinational simulation manager
-typedef struct Cec_ManCsw_t_ Cec_ManCsw_t;
-struct Cec_ManCsw_t_
+typedef struct Cec_ManSim_t_ Cec_ManSim_t;
+struct Cec_ManSim_t_
{
// parameters
Gia_Man_t * pAig; // the AIG to be used for simulation
- Cec_ParCsw_t * pPars; // SAT sweeping parameters
+ Cec_ParSim_t * pPars; // simulation parameters
int nWords; // the number of simulation words
- // equivalence classes
- Cec_ObjCsw_t * pObjs; // objects used for SAT sweeping
// recycable memory
+ int * pSimInfo; // simulation information offsets
unsigned * pMems; // allocated simulaton memory
int nWordsAlloc; // the number of allocated entries
int nMems; // the number of used entries
int nMemsMax; // the max number of used entries
int MemFree; // next free entry
+ int nWordsOld; // the number of simulation words after previous relink
+ // bug catcher
+ Vec_Ptr_t * vCiSimInfo; // CI simulation info
+ Vec_Ptr_t * vCoSimInfo; // CO simulation info
+ void ** pCexes; // counter-examples for each output
+ int iOut; // first failed output
+ int nOuts; // the number of failed outputs
+ Gia_Cex_t * pCexComb; // counter-example for the first failed output
// temporaries
Vec_Int_t * vClassOld; // old class numbers
Vec_Int_t * vClassNew; // new class numbers
Vec_Int_t * vClassTemp; // temporary storage
Vec_Int_t * vRefinedC; // refined const reprs
+};
+
+// combinational simulation manager
+typedef struct Cec_ManFra_t_ Cec_ManFra_t;
+struct Cec_ManFra_t_
+{
+ // parameters
+ Gia_Man_t * pAig; // the AIG to be used for simulation
+ Cec_ParFra_t * pPars; // SAT sweeping parameters
// simulation patterns
Vec_Int_t * vXorNodes; // nodes used in speculative reduction
int nAllProved; // total number of proved nodes
@@ -139,6 +145,7 @@ struct Cec_ManCsw_t_
int nAllFailed; // total number of failed nodes
// runtime stats
int timeSim; // unsat
+ int timePat; // unsat
int timeSat; // sat
int timeTotal; // total runtime
};
@@ -153,29 +160,31 @@ struct Cec_ManCsw_t_
/*=== cecCore.c ============================================================*/
/*=== cecClass.c ============================================================*/
-extern int Cec_ManCswCountLitsAll( Cec_ManCsw_t * p );
-extern int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p );
-extern Gia_Man_t * Cec_ManCswSpecReduction( Cec_ManCsw_t * p );
-extern Gia_Man_t * Cec_ManCswSpecReductionProved( Cec_ManCsw_t * p );
-extern Gia_Man_t * Cec_ManCswDupWithClasses( Cec_ManCsw_t * p );
-extern int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p );
-extern int Cec_ManCswClassesUpdate( Cec_ManCsw_t * p, Cec_ManPat_t * pPat, Gia_Man_t * pNew );
+extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p );
+extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p );
+extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos );
+/*=== cecIso.c ============================================================*/
+extern int * Cec_ManDetectIsomorphism( Gia_Man_t * p );
/*=== cecMan.c ============================================================*/
-extern Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars );
-extern void Cec_ManCswStop( Cec_ManCsw_t * p );
-extern Cec_ManPat_t * Cec_ManPatStart();
-extern void Cec_ManPatPrintStats( Cec_ManPat_t * p );
-extern void Cec_ManPatStop( Cec_ManPat_t * p );
extern Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars );
extern void Cec_ManSatPrintStats( Cec_ManSat_t * p );
extern void Cec_ManSatStop( Cec_ManSat_t * p );
+extern Cec_ManPat_t * Cec_ManPatStart();
+extern void Cec_ManPatPrintStats( Cec_ManPat_t * p );
+extern void Cec_ManPatStop( Cec_ManPat_t * p );
+extern Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars );
+extern void Cec_ManSimStop( Cec_ManSim_t * p );
+extern Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars );
+extern void Cec_ManFraStop( Cec_ManFra_t * p );
/*=== cecPat.c ============================================================*/
extern void Cec_ManPatSavePattern( Cec_ManPat_t * pPat, Cec_ManSat_t * p, Gia_Obj_t * pObj );
extern Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWords );
/*=== cecSolve.c ============================================================*/
extern int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj );
extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars );
-/*=== cecUtil.c ============================================================*/
+/*=== ceFraeep.c ============================================================*/
+extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p );
+extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew );
#ifdef __cplusplus
}
diff --git a/src/aig/cec/cecIso.c b/src/aig/cec/cecIso.c
new file mode 100644
index 00000000..08d4b7ec
--- /dev/null
+++ b/src/aig/cec/cecIso.c
@@ -0,0 +1,370 @@
+/**CFile****************************************************************
+
+ FileName [cecIso.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinatinoal equivalence checking.]
+
+ Synopsis [Detection of structural isomorphism.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecIso.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline unsigned * Cec_ManIsoInfo( unsigned * pStore, int nWords, int Id ) { return pStore + nWords * Id; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes simulation info for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoSimulate( Gia_Obj_t * pObj, int Id, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo = Cec_ManIsoInfo( pStore, nWords, Id );
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId0(pObj, Id) );
+ unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId1(pObj, Id) );
+ int w;
+ if ( Gia_ObjFaninC0(pObj) )
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = ~(pInfo0[w] | pInfo1[w]);
+ else
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = ~pInfo0[w] & pInfo1[w];
+ }
+ else
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = pInfo0[w] & ~pInfo1[w];
+ else
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = pInfo0[w] & pInfo1[w];
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copies simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoCopy( int IdDest, int IdSour, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, IdDest );
+ unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, IdSour );
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pInfo0[w] = pInfo1[w];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares simulation info of two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManIsoEqual( int Id0, int Id1, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id0 );
+ unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Id1 );
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( pInfo0[w] != pInfo1[w] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generates random simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoRandom( int Id, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id );
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pInfo0[w] = Aig_ManRandom( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash key of the simuation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManIsoHashKey( int Id, unsigned * pStore, int nWords, int nTableSize )
+{
+ static int s_Primes[16] = {
+ 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
+ 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id );
+ unsigned uHash = 0;
+ int i;
+ for ( i = 0; i < nWords; i++ )
+ uHash ^= pInfo0[i] * s_Primes[i & 0xf];
+ return (int)(uHash % nTableSize);
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds node to the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoTableAdd( Gia_Man_t * p, int Id, unsigned * pStore, int nWords, int * pTable, int nTableSize )
+{
+ Gia_Obj_t * pTemp;
+ int Key, Ent, Counter = 0, Color = Gia_ObjColors( p, Id );
+ assert( Color == 1 || Color == 2 );
+ Key = Gia_ManIsoHashKey( Id, pStore, nWords, nTableSize );
+ for ( Ent = pTable[Key], pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp;
+ Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) )
+ {
+ if ( Gia_ObjColors( p, Ent ) != Color )
+ continue;
+ if ( !Gia_ManIsoEqual( Id, Ent, pStore, nWords ) )
+ continue;
+ // found node with the same color and signature - mark it and do not add new node
+ pTemp->fMark0 = 1;
+ return;
+ }
+ // did not find the node with the same color and signature - add new node
+ pTemp = Gia_ManObj( p, Id );
+ assert( pTemp->Value == 0 );
+ assert( pTemp->fMark0 == 0 );
+ pTemp->Value = pTable[Key];
+ pTable[Key] = Id;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts equivalence class candidates from one bin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManIsoExtractClasses( Gia_Man_t * p, int Bin, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB )
+{
+ Gia_Obj_t * pTemp;
+ int Ent;
+ Vec_IntClear( vNodesA );
+ Vec_IntClear( vNodesB );
+ for ( Ent = Bin, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp;
+ Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) )
+ {
+ if ( pTemp->fMark0 )
+ {
+ pTemp->fMark0 = 0;
+ continue;
+ }
+ if ( Gia_ObjColors( p, Ent ) == 1 )
+ Vec_IntPush( vNodesA, Ent );
+ else
+ Vec_IntPush( vNodesB, Ent );
+ }
+ return Vec_IntSize(vNodesA) > 0 && Vec_IntSize(vNodesB) > 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Matches nodes in the extacted classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoMatchNodes( int * pIso, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB )
+{
+ int k0, k1, IdA, IdB;
+ Vec_IntForEachEntry( vNodesA, IdA, k0 )
+ Vec_IntForEachEntry( vNodesB, IdB, k1 )
+ {
+ if ( Gia_ManIsoEqual( IdA, IdB, pStore, nWords ) )
+ {
+ assert( pIso[IdA] == 0 );
+ assert( pIso[IdB] == 0 );
+ assert( IdA != IdB );
+ pIso[IdA] = IdB;
+ pIso[IdB] = IdA;
+ continue;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms iso into equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManTransformClasses( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pReprs && p->pNexts && p->pIso );
+ memset( p->pReprs, 0, sizeof(int) * Gia_ManObjNum(p) );
+ memset( p->pNexts, 0, sizeof(int) * Gia_ManObjNum(p) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ p->pReprs[i].iRepr = GIA_VOID;
+ if ( p->pIso[i] && p->pIso[i] < i )
+ {
+ p->pReprs[i].iRepr = p->pIso[i];
+ p->pNexts[p->pIso[i]] = i;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds node correspondences in the miter.]
+
+ Description [Assumes that the colors are assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Cec_ManDetectIsomorphism( Gia_Man_t * p )
+{
+ int nWords = 2;
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vNodesA, * vNodesB;
+ unsigned * pStore, Counter;
+ int i, * pIso, * pTable, nTableSize;
+ // start equivalence classes
+ pIso = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ assert( Gia_ObjColors(p, i) == 0 );
+ continue;
+ }
+ assert( Gia_ObjColors(p, i) );
+ if ( Gia_ObjColors(p, i) == 3 )
+ pIso[i] = i;
+ }
+ // start simulation info
+ pStore = ABC_ALLOC( unsigned, Gia_ManObjNum(p) * nWords );
+ // simulate and create table
+ nTableSize = Aig_PrimeCudd( 100 + Gia_ManObjNum(p)/2 );
+ pTable = ABC_CALLOC( int, nTableSize );
+ Gia_ManCleanValue( p );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ continue;
+ if ( pIso[i] == 0 ) // simulate
+ Gia_ManIsoSimulate( pObj, i, pStore, nWords );
+ else if ( pIso[i] < i ) // copy
+ Gia_ManIsoCopy( i, pIso[i], pStore, nWords );
+ else // generate
+ Gia_ManIsoRandom( i, pStore, nWords );
+ if ( pIso[i] == 0 )
+ Gia_ManIsoTableAdd( p, i, pStore, nWords, pTable, nTableSize );
+ }
+ // create equivalence classes
+ vNodesA = Vec_IntAlloc( 100 );
+ vNodesB = Vec_IntAlloc( 100 );
+ for ( i = 0; i < nTableSize; i++ )
+ if ( Gia_ManIsoExtractClasses( p, pTable[i], pStore, nWords, vNodesA, vNodesB ) )
+ Gia_ManIsoMatchNodes( pIso, pStore, nWords, vNodesA, vNodesB );
+ Vec_IntFree( vNodesA );
+ Vec_IntFree( vNodesB );
+ // collect info
+ Counter = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ Counter += (pIso[i] && pIso[i] < i);
+/*
+ if ( pIso[i] && pIso[i] < i )
+ {
+ if ( (Gia_ObjIsHead(p,pIso[i]) && Gia_ObjRepr(p,i)==pIso[i]) ||
+ (Gia_ObjIsClass(p,pIso[i]) && Gia_ObjRepr(p,i)==Gia_ObjRepr(p,pIso[i])) )
+ printf( "1" );
+ else
+ printf( "0" );
+ }
+*/
+ }
+ printf( "Computed %d pairs of structurally equivalent nodes.\n", Counter );
+// p->pIso = pIso;
+// Cec_ManTransformClasses( p );
+
+ ABC_FREE( pTable );
+ ABC_FREE( pStore );
+ return pIso;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/cec/cecMan.c b/src/aig/cec/cecMan.c
index b8ee75b2..1a94409f 100644
--- a/src/aig/cec/cecMan.c
+++ b/src/aig/cec/cecMan.c
@@ -30,7 +30,7 @@
/**Function*************************************************************
- Synopsis [Creates AIG.]
+ Synopsis [Creates the manager.]
Description []
@@ -39,26 +39,25 @@
SeeAlso []
***********************************************************************/
-Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars )
-{
- Cec_ManCsw_t * p;
- p = ABC_ALLOC( Cec_ManCsw_t, 1 );
- memset( p, 0, sizeof(Cec_ManCsw_t) );
- p->pAig = pAig;
- p->pPars = pPars;
- p->pObjs = ABC_CALLOC( Cec_ObjCsw_t, Gia_ManObjNum(pAig) );
- // temporaries
- p->vClassOld = Vec_IntAlloc( 1000 );
- p->vClassNew = Vec_IntAlloc( 1000 );
- p->vClassTemp = Vec_IntAlloc( 1000 );
- p->vRefinedC = Vec_IntAlloc( 10000 );
- p->vXorNodes = Vec_IntAlloc( 1000 );
+Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
+{
+ Cec_ManSat_t * p;
+ // create interpolation manager
+ p = ABC_ALLOC( Cec_ManSat_t, 1 );
+ memset( p, 0, sizeof(Cec_ManSat_t) );
+ p->pPars = pPars;
+ p->pAig = pAig;
+ // SAT solving
+ p->nSatVars = 1;
+ p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) );
+ p->vUsedNodes = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
return p;
}
/**Function*************************************************************
- Synopsis [Deletes AIG.]
+ Synopsis [Prints statistics of the manager.]
Description []
@@ -67,19 +66,46 @@ Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars )
SeeAlso []
***********************************************************************/
-void Cec_ManCswStop( Cec_ManCsw_t * p )
+void Cec_ManSatPrintStats( Cec_ManSat_t * p )
{
- Vec_IntFree( p->vXorNodes );
- Vec_IntFree( p->vClassOld );
- Vec_IntFree( p->vClassNew );
- Vec_IntFree( p->vClassTemp );
- Vec_IntFree( p->vRefinedC );
- ABC_FREE( p->pMems );
- ABC_FREE( p->pObjs );
+ printf( "CO = %6d ", Gia_ManCoNum(p->pAig) );
+ printf( "Conf = %5d ", p->pPars->nBTLimit );
+ printf( "MinVar = %5d ", p->pPars->nSatVarMax );
+ printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle );
+ printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
+ ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal );
+ printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
+ ABC_PRTP( "Time", p->timeSatSat, p->timeTotal );
+ printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
+ ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatStop( Cec_ManSat_t * p )
+{
+ if ( p->pSat )
+ sat_solver_delete( p->pSat );
+ Vec_PtrFree( p->vUsedNodes );
+ Vec_PtrFree( p->vFanins );
+ ABC_FREE( p->pSatVars );
ABC_FREE( p );
}
+
/**Function*************************************************************
Synopsis [Creates AIG.]
@@ -147,9 +173,11 @@ void Cec_ManPatStop( Cec_ManPat_t * p )
ABC_FREE( p );
}
+
+
/**Function*************************************************************
- Synopsis [Creates the manager.]
+ Synopsis [Creates AIG.]
Description []
@@ -158,25 +186,31 @@ void Cec_ManPatStop( Cec_ManPat_t * p )
SeeAlso []
***********************************************************************/
-Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
-{
- Cec_ManSat_t * p;
- // create interpolation manager
- p = ABC_ALLOC( Cec_ManSat_t, 1 );
- memset( p, 0, sizeof(Cec_ManSat_t) );
- p->pPars = pPars;
- p->pAig = pAig;
- // SAT solving
- p->nSatVars = 1;
- p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) );
- p->vUsedNodes = Vec_PtrAlloc( 1000 );
- p->vFanins = Vec_PtrAlloc( 100 );
+Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars )
+{
+ Cec_ManSim_t * p;
+ p = ABC_ALLOC( Cec_ManSim_t, 1 );
+ memset( p, 0, sizeof(Cec_ManSim_t) );
+ p->pAig = pAig;
+ p->pPars = pPars;
+ p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) );
+ p->vClassOld = Vec_IntAlloc( 1000 );
+ p->vClassNew = Vec_IntAlloc( 1000 );
+ p->vClassTemp = Vec_IntAlloc( 1000 );
+ p->vRefinedC = Vec_IntAlloc( 10000 );
+ p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords );
+ if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) )
+ {
+ p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords );
+ Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords );
+ }
+ p->iOut = -1;
return p;
}
/**Function*************************************************************
- Synopsis [Prints statistics of the manager.]
+ Synopsis [Deletes AIG.]
Description []
@@ -185,26 +219,27 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
SeeAlso []
***********************************************************************/
-void Cec_ManSatPrintStats( Cec_ManSat_t * p )
+void Cec_ManSimStop( Cec_ManSim_t * p )
{
- printf( "CO = %6d ", Gia_ManCoNum(p->pAig) );
- printf( "Conf = %5d ", p->pPars->nBTLimit );
- printf( "MinVar = %5d ", p->pPars->nSatVarMax );
- printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle );
- printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
- p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
- ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal );
- printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
- p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
- ABC_PRTP( "Time", p->timeSatSat, p->timeTotal );
- printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
- p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
- ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal );
+ Vec_IntFree( p->vClassOld );
+ Vec_IntFree( p->vClassNew );
+ Vec_IntFree( p->vClassTemp );
+ Vec_IntFree( p->vRefinedC );
+ if ( p->vCiSimInfo )
+ Vec_PtrFree( p->vCiSimInfo );
+ if ( p->vCoSimInfo )
+ Vec_PtrFree( p->vCoSimInfo );
+ ABC_FREE( p->pCexComb );
+ ABC_FREE( p->pCexes );
+ ABC_FREE( p->pMems );
+ ABC_FREE( p->pSimInfo );
+ ABC_FREE( p );
}
+
/**Function*************************************************************
- Synopsis [Frees the manager.]
+ Synopsis [Creates AIG.]
Description []
@@ -213,16 +248,35 @@ void Cec_ManSatPrintStats( Cec_ManSat_t * p )
SeeAlso []
***********************************************************************/
-void Cec_ManSatStop( Cec_ManSat_t * p )
+Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars )
+{
+ Cec_ManFra_t * p;
+ p = ABC_ALLOC( Cec_ManFra_t, 1 );
+ memset( p, 0, sizeof(Cec_ManFra_t) );
+ p->pAig = pAig;
+ p->pPars = pPars;
+ p->vXorNodes = Vec_IntAlloc( 1000 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManFraStop( Cec_ManFra_t * p )
{
- if ( p->pSat )
- sat_solver_delete( p->pSat );
- Vec_PtrFree( p->vUsedNodes );
- Vec_PtrFree( p->vFanins );
- ABC_FREE( p->pSatVars );
+ Vec_IntFree( p->vXorNodes );
ABC_FREE( p );
}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/cec/cecPat.c b/src/aig/cec/cecPat.c
index 1af4f333..b80f1e44 100644
--- a/src/aig/cec/cecPat.c
+++ b/src/aig/cec/cecPat.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [cec.c]
+ FileName [cecPat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Combinatinoal equivalence checking.]
- Synopsis []
+ Synopsis [Simulation pattern manager.]
Author [Alan Mishchenko]
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: cec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
diff --git a/src/aig/cec/cecSim.c b/src/aig/cec/cecSim.c
new file mode 100644
index 00000000..dbd3bd5e
--- /dev/null
+++ b/src/aig/cec/cecSim.c
@@ -0,0 +1,48 @@
+/**CFile****************************************************************
+
+ FileName [cecSim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinatinoal equivalence checking.]
+
+ Synopsis [Simulation manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/cec/cecSolve.c b/src/aig/cec/cecSolve.c
index e4daf719..ba4b0477 100644
--- a/src/aig/cec/cecSolve.c
+++ b/src/aig/cec/cecSolve.c
@@ -390,6 +390,70 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p )
/**Function*************************************************************
+ Synopsis [Sets variable activities in the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_SetActivityFactors_rec( Cec_ManSat_t * p, Gia_Obj_t * pObj, int LevelMin, int LevelMax )
+{
+ float dActConeBumpMax = 20.0;
+ int iVar;
+ // skip visited variables
+ if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p->pAig, pObj);
+ // add the PI to the list
+ if ( Gia_ObjLevel(p->pAig, pObj) <= LevelMin || Gia_ObjIsCi(pObj) )
+ return;
+ // set the factor of this variable
+ // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pPars->dActConeBumpMax / ThisBump
+ if ( (iVar = Cec_ObjSatNum(p,pObj)) )
+ {
+ p->pSat->factors[iVar] = dActConeBumpMax * (Gia_ObjLevel(p->pAig, pObj) - LevelMin)/(LevelMax - LevelMin);
+ veci_push(&p->pSat->act_vars, iVar);
+ }
+ // explore the fanins
+ Cec_SetActivityFactors_rec( p, Gia_ObjFanin0(pObj), LevelMin, LevelMax );
+ Cec_SetActivityFactors_rec( p, Gia_ObjFanin1(pObj), LevelMin, LevelMax );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets variable activities in the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_SetActivityFactors( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ float dActConeRatio = 0.5;
+ int LevelMin, LevelMax;
+ // reset the active variables
+ veci_resize(&p->pSat->act_vars, 0);
+ // prepare for traversal
+ Gia_ManIncrementTravId( p->pAig );
+ // determine the min and max level to visit
+ assert( dActConeRatio > 0 && dActConeRatio < 1 );
+ LevelMax = Gia_ObjLevel(p->pAig,pObj);
+ LevelMin = (int)(LevelMax * (1.0 - dActConeRatio));
+ // traverse
+ Cec_SetActivityFactors_rec( p, pObj, LevelMin, LevelMax );
+//Cec_PrintActivity( p );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
Synopsis [Runs equivalence test for the two nodes.]
Description []
@@ -402,7 +466,7 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p )
int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj )
{
int nBTLimit = p->pPars->nBTLimit;
- int Lit, RetValue, status, clk, nConflicts;
+ int Lit, RetValue, status, clk, clk2, nConflicts;
p->nCallsSince++; // experiment with this!!!
p->nSatTotal++;
@@ -415,7 +479,14 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj )
Cec_ManSatSolverRecycle( p );
// if the nodes do not have SAT variables, allocate them
+clk2 = clock();
Cec_CnfNodeAddToSolver( p, Gia_ObjFanin0(pObj) );
+//ABC_PRT( "cnf", clock() - clk2 );
+//printf( "%d \n", p->pSat->size );
+
+clk2 = clock();
+// Cec_SetActivityFactors( p, Gia_ObjFanin0(pObj) );
+//ABC_PRT( "act", clock() - clk2 );
// propage unit clauses
if ( p->pSat->qtail != p->pSat->qhead )
@@ -435,8 +506,12 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj )
//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
clk = clock();
nConflicts = p->pSat->stats.conflicts;
+
+clk2 = clock();
RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1,
(ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+//ABC_PRT( "sat", clock() - clk2 );
+
if ( RetValue == l_False )
{
p->timeSatUnsat += clock() - clk;
@@ -466,6 +541,7 @@ p->timeSatUndec += clock() - clk;
}
}
+
/**Function*************************************************************
Synopsis [Performs one round of solving for the POs of the AIG.]
@@ -486,7 +562,7 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar
Bar_Progress_t * pProgress = NULL;
Cec_ManSat_t * p;
Gia_Obj_t * pObj;
- int i, status, clk = clock();
+ int i, status, clk = clock(), clk2;
// sprintf( Buffer, "gia%03d.aig", Counter++ );
//Gia_WriteAiger( pAig, Buffer, 0, 0 );
@@ -499,8 +575,9 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar
pPat->nPats = 0;
pPat->nPatLits = 0;
pPat->nPatLitsMin = 0;
- }
+ }
Gia_ManSetPhase( pAig );
+ Gia_ManLevelNum( pAig );
Gia_ManResetTravId( pAig );
p = Cec_ManSatCreate( pAig, pPars );
pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) );
@@ -512,13 +589,19 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar
pObj->fMark1 = 1;
continue;
}
-//printf( "Output %6d : ", i );
-
Bar_ProgressUpdate( pProgress, i, "SAT..." );
+clk2 = clock();
status = Cec_ManSatCheckNode( p, pObj );
pObj->fMark0 = (status == 0);
pObj->fMark1 = (status == 1);
/*
+printf( "Output %6d : ", i );
+printf( "conf = %6d ", p->pSat->stats.conflicts );
+printf( "prop = %6d ", p->pSat->stats.propagations );
+ABC_PRT( "time", clock() - clk2 );
+*/
+
+/*
if ( status == -1 )
{
Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj );
@@ -531,7 +614,11 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar
continue;
// save the pattern
if ( pPat )
+ {
+ int clk3 = clock();
Cec_ManPatSavePattern( pPat, p, pObj );
+ pPat->timeTotalSave += clock() - clk3;
+ }
// quit if one of them is solved
if ( pPars->fFirstStop )
break;
diff --git a/src/aig/cec/cecSweep.c b/src/aig/cec/cecSweep.c
new file mode 100644
index 00000000..20a668bd
--- /dev/null
+++ b/src/aig/cec/cecSweep.c
@@ -0,0 +1,294 @@
+/**CFile****************************************************************
+
+ FileName [ceFraeep.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinatinoal equivalence checking.]
+
+ Synopsis [SAT sweeping manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ceFraeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs limited speculative reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ int iRes0, iRes1, iRepr, iNode, iMiter;
+ int i, fCompl, * piCopies, * pDepths;
+ Gia_ManSetPhase( p->pAig );
+ Vec_IntClear( p->vXorNodes );
+ if ( p->pPars->nLevelMax )
+ Gia_ManLevelNum( p->pAig );
+ pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) );
+ pNew->pName = Aig_UtilStrsav( p->pAig->pName );
+ Gia_ManHashAlloc( pNew );
+ piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) );
+ pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
+ piCopies[0] = 0;
+ Gia_ManForEachObj1( p->pAig, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ piCopies[i] = Gia_ManAppendCi( pNew );
+ continue;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ continue;
+ if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 ||
+ piCopies[Gia_ObjFaninId1(pObj,i)] == -1 )
+ continue;
+ iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) );
+ iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) );
+ iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 );
+ pDepths[i] = AIG_MAX( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] );
+ if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID || Gia_ObjFailed(p->pAig, i) )
+ continue;
+ assert( Gia_ObjRepr(p->pAig, i) < i );
+ iRepr = piCopies[Gia_ObjRepr(p->pAig, i)];
+ if ( iRepr == -1 )
+ continue;
+ if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) )
+ continue;
+ if ( p->pPars->nLevelMax &&
+ (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax ||
+ Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) )
+ continue;
+ if ( p->pPars->fDoubleOuts )
+ {
+// if ( i % 1000 == 0 && Gia_ObjRepr(p->pAig, i) )
+// Gia_ManEquivPrintOne( p->pAig, Gia_ObjRepr(p->pAig, i), 0 );
+ if ( p->pPars->fColorDiff )
+ {
+ if ( !Gia_ObjDiffColors( p->pAig, Gia_ObjRepr(p->pAig, i), i ) )
+ continue;
+ }
+ else
+ {
+ if ( !Gia_ObjDiffColors2( p->pAig, Gia_ObjRepr(p->pAig, i), i ) )
+ continue;
+ }
+ }
+ pRepr = Gia_ManObj( p->pAig, Gia_ObjRepr(p->pAig, i) );
+ fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr);
+ piCopies[i] = Gia_LitNotCond( iRepr, fCompl );
+ if ( Gia_ObjProved(p->pAig, i) )
+ continue;
+ // produce speculative miter
+ iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] );
+ Gia_ManAppendCo( pNew, iMiter );
+ Vec_IntPush( p->vXorNodes, Gia_ObjRepr(p->pAig, i) );
+ Vec_IntPush( p->vXorNodes, i );
+ // add to the depth of this node
+ pDepths[i] = 1 + AIG_MAX( pDepths[i], pDepths[Gia_ObjRepr(p->pAig, i)] );
+ if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax )
+ piCopies[i] = -1;
+ }
+ ABC_FREE( piCopies );
+ ABC_FREE( pDepths );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, 0 );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManFraClassesUpdate_rec( Gia_Obj_t * pObj )
+{
+ int Result;
+ if ( pObj->fMark0 )
+ return 1;
+ if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) )
+ return 0;
+ Result = (Cec_ManFraClassesUpdate_rec( Gia_ObjFanin0(pObj) ) |
+ Cec_ManFraClassesUpdate_rec( Gia_ObjFanin1(pObj) ));
+ return pObj->fMark0 = Result;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates simulation info for this round.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManFraCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vCiInfo, Vec_Ptr_t * vInfo, int nSeries )
+{
+ unsigned * pRes0, * pRes1;
+ int i, w;
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ {
+ pRes0 = Vec_PtrEntry( vCiInfo, i );
+ pRes1 = Vec_PtrEntry( vInfo, i );
+ pRes1 += p->nWords * nSeries;
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = pRes1[w];
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates equivalence classes using the patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew )
+{
+ Vec_Ptr_t * vInfo;
+ Gia_Obj_t * pObj, * pObjOld, * pReprOld;
+ int i, k, iRepr, iNode, clk;
+clk = clock();
+ vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), pSim->nWords );
+p->timePat += clock() - clk;
+clk = clock();
+ if ( vInfo != NULL )
+ {
+ Gia_ManSetRefs( p->pAig );
+ for ( i = 0; i < pPat->nSeries; i++ )
+ {
+ Cec_ManFraCreateInfo( pSim, pSim->vCiSimInfo, vInfo, i );
+ if ( Cec_ManSimSimulateRound( pSim, pSim->vCiSimInfo, pSim->vCoSimInfo ) )
+ {
+ Vec_PtrFree( vInfo );
+ return 1;
+ }
+ }
+ Vec_PtrFree( vInfo );
+ }
+p->timeSim += clock() - clk;
+ assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) );
+ // mark the transitive fanout of failed nodes
+ if ( p->pPars->nDepthMax != 1 )
+ {
+ Gia_ManCleanMark0( p->pAig );
+ Gia_ManCleanMark1( p->pAig );
+ Gia_ManForEachCo( pNew, pObj, k )
+ {
+ iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
+ iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
+ if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved
+ continue;
+// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1;
+ Gia_ManObj(p->pAig, iNode)->fMark0 = 1;
+ }
+ // mark the nodes reachable through the failed nodes
+ Gia_ManForEachAnd( p->pAig, pObjOld, k )
+ pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0);
+ // unmark the disproved nodes
+ Gia_ManForEachCo( pNew, pObj, k )
+ {
+ iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
+ iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
+ if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved
+ continue;
+ pObjOld = Gia_ManObj(p->pAig, iNode);
+ assert( pObjOld->fMark0 == 1 );
+ if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 )
+ pObjOld->fMark1 = 1;
+ }
+ // clean marks
+ Gia_ManForEachAnd( p->pAig, pObjOld, k )
+ if ( pObjOld->fMark1 )
+ {
+ pObjOld->fMark0 = 0;
+ pObjOld->fMark1 = 0;
+ }
+ }
+ // set the results
+ p->nAllProved = p->nAllDisproved = p->nAllFailed = 0;
+ Gia_ManForEachCo( pNew, pObj, k )
+ {
+ iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
+ iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
+ pReprOld = Gia_ManObj(p->pAig, iRepr);
+ pObjOld = Gia_ManObj(p->pAig, iNode);
+ if ( pObj->fMark1 )
+ { // proved
+ assert( pObj->fMark0 == 0 );
+ assert( !Gia_ObjProved(p->pAig, iNode) );
+ if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 )
+// if ( pObjOld->fMark0 == 0 )
+ {
+ assert( iRepr == Gia_ObjRepr(p->pAig, iNode) );
+ Gia_ObjSetProved( p->pAig, iNode );
+ p->nAllProved++;
+ }
+ }
+ else if ( pObj->fMark0 )
+ { // disproved
+ assert( pObj->fMark1 == 0 );
+ if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 )
+// if ( pObjOld->fMark0 == 0 )
+ {
+ if ( iRepr == Gia_ObjRepr(p->pAig, iNode) )
+ printf( "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" );
+ p->nAllDisproved++;
+ }
+ }
+ else
+ { // failed
+ assert( pObj->fMark0 == 0 );
+ assert( pObj->fMark1 == 0 );
+ assert( !Gia_ObjFailed(p->pAig, iNode) );
+ assert( !Gia_ObjProved(p->pAig, iNode) );
+ Gia_ObjSetFailed( p->pAig, iNode );
+ p->nAllFailed++;
+ }
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/cec/module.make b/src/aig/cec/module.make
index f8e2602a..4618c424 100644
--- a/src/aig/cec/module.make
+++ b/src/aig/cec/module.make
@@ -1,5 +1,9 @@
-SRC += src/aig/cec/cecClass.c \
+SRC += src/aig/cec/cecCec.c \
+ src/aig/cec/cecClass.c \
src/aig/cec/cecCore.c \
+ src/aig/cec/cecIso.c \
src/aig/cec/cecMan.c \
src/aig/cec/cecPat.c \
- src/aig/cec/cecSolve.c
+ src/aig/cec/cecSim.c \
+ src/aig/cec/cecSolve.c \
+ src/aig/cec/cecSweep.c
diff --git a/src/aig/dar/darRefact.c b/src/aig/dar/darRefact.c
index f0173a3c..f64564fa 100644
--- a/src/aig/dar/darRefact.c
+++ b/src/aig/dar/darRefact.c
@@ -113,7 +113,7 @@ Ref_Man_t * Dar_ManRefStart( Aig_Man_t * pAig, Dar_RefPar_t * pPars )
// other data
p->vCuts = Vec_VecStart( pPars->nCutsMax );
p->vTruthElem = Vec_PtrAllocTruthTables( pPars->nLeafMax );
- p->vTruthStore = Vec_PtrAllocSimInfo( 256, Kit_TruthWordNum(pPars->nLeafMax) );
+ p->vTruthStore = Vec_PtrAllocSimInfo( 1024, Kit_TruthWordNum(pPars->nLeafMax) );
p->vMemory = Vec_IntAlloc( 1 << 16 );
p->vCutNodes = Vec_PtrAlloc( 256 );
p->vLeavesBest = Vec_PtrAlloc( pPars->nLeafMax );
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index b77dd76f..91507947 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -36,27 +36,50 @@ extern "C" {
#endif
#define GIA_NONE 0x1FFFFFFF
+#define GIA_VOID 0x0FFFFFFF
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+typedef struct Gia_Rpr_t_ Gia_Rpr_t;
+struct Gia_Rpr_t_
+{
+ unsigned iRepr : 28; // representative node
+ unsigned fProved : 1; // marks the proved equivalence
+ unsigned fFailed : 1; // marks the failed equivalence
+ unsigned fColorA : 1; // marks cone of A
+ unsigned fColorB : 1; // marks cone of B
+};
+
typedef struct Gia_Obj_t_ Gia_Obj_t;
struct Gia_Obj_t_
{
- unsigned iDiff0 : 29; // the diff of the first fanin
- unsigned fCompl0: 1; // the complemented attribute
- unsigned fMark0 : 1; // first user-controlled mark
- unsigned fTerm : 1; // terminal node (CI/CO)
+ unsigned iDiff0 : 29; // the diff of the first fanin
+ unsigned fCompl0: 1; // the complemented attribute
+ unsigned fMark0 : 1; // first user-controlled mark
+ unsigned fTerm : 1; // terminal node (CI/CO)
- unsigned iDiff1 : 29; // the diff of the second fanin
- unsigned fCompl1: 1; // the complemented attribute
- unsigned fMark1 : 1; // second user-controlled mark
- unsigned fPhase : 1; // value under 000 pattern
+ unsigned iDiff1 : 29; // the diff of the second fanin
+ unsigned fCompl1: 1; // the complemented attribute
+ unsigned fMark1 : 1; // second user-controlled mark
+ unsigned fPhase : 1; // value under 000 pattern
unsigned Value; // application-specific value
};
+// sequential counter-example
+typedef struct Gia_Cex_t_ Gia_Cex_t;
+struct Gia_Cex_t_
+{
+ int iPo; // the zero-based number of PO, for which verification failed
+ int iFrame; // the zero-based number of the time-frame, for which verificaiton failed
+ int nRegs; // the number of registers in the miter
+ int nPis; // the number of primary inputs in the miter
+ int nBits; // the number of words of bit data used
+ unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis)
+};
+
typedef struct Gia_Man_t_ Gia_Man_t;
struct Gia_Man_t_
{
@@ -76,23 +99,42 @@ struct Gia_Man_t_
int nLevels; // the mamixum level
int nTravIds; // the current traversal ID
int nFront; // frontier size
- int * pReprs; // representatives (for CIs and ANDs)
+ int * pReprsOld; // representatives (for CIs and ANDs)
+ Gia_Rpr_t * pReprs; // representatives (for CIs and ANDs)
+ int * pNexts; // next nodes in the equivalence classes
+ int * pIso; // pairs of structurally isomorphic nodes
int nTerLoop; // the state where loop begins
int nTerStates; // the total number of ternary states
int * pFanData; // the database to store fanout information
int nFansAlloc; // the size of fanout representation
+ int * pMapping; // mapping for each node
+ Gia_Cex_t * pCexComb; // combinational counter-example
};
+typedef struct Emb_Par_t_ Emb_Par_t;
+struct Emb_Par_t_
+{
+ int nDims; // the number of dimension
+ int nSols; // the number of solutions (typically, 2)
+ int nIters; // the number of iterations of FORCE
+ int fRefine; // use refinement by FORCE
+ int fCluster; // use clustered representation
+ int fDump; // dump Gnuplot file
+ int fDumpLarge; // dump Gnuplot file for large benchmarks
+ int fShowImage; // shows image if Gnuplot is installed
+ int fVerbose; // verbose flag
+};
+
// frames parameters
typedef struct Gia_ParFra_t_ Gia_ParFra_t;
struct Gia_ParFra_t_
{
- int nFrames; // the number of frames to unroll
- int fInit; // initialize the timeframes
- int fVerbose; // enables verbose output
+ int nFrames; // the number of frames to unroll
+ int fInit; // initialize the timeframes
+ int fVerbose; // enables verbose output
};
@@ -180,17 +222,17 @@ static inline int Gia_ObjFaninId0p( Gia_Man_t * p, Gia_Obj_t * pObj ) {
static inline int Gia_ObjFaninId1p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId1( pObj, Gia_ObjId(p, pObj) ); }
static inline int Gia_ObjFaninLit0( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninC0(pObj) ); }
static inline int Gia_ObjFaninLit1( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId1(pObj, ObjId), Gia_ObjFaninC1(pObj) ); }
-static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); }
-static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); }
+static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); }
+static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); }
static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); pObj->fCompl0 ^= 1; }
static inline int Gia_ObjWhatFanin( Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { return Gia_ObjFanin0(pObj) == pFanin ? 0 : (Gia_ObjFanin1(pObj) == pFanin ? 1 : -1); }
-static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); }
-static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); }
+static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); }
+static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); }
static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { return Gia_NotCond( Gia_ManObj(p, Gia_Lit2Var(iLit)), Gia_LitIsCompl(iLit) ); }
-static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); }
-static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); }
+static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); }
+static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); }
static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; }
static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(p->pLevels);return p->pLevels[Gia_ObjId(p, pObj)]; }
@@ -204,12 +246,12 @@ static inline void Gia_ObjRefFanin0Dec(Gia_Man_t * p, Gia_Obj_t * pObj){
static inline void Gia_ObjRefFanin1Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin1(pObj)); }
static inline void Gia_ManResetTravId( Gia_Man_t * p ) { extern void Gia_ManCleanValue( Gia_Man_t * p ); Gia_ManCleanValue( p ); p->nTravIds = 1; }
-static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; }
-static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; }
-static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; }
-static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; }
-static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); }
-static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); }
+static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; }
+static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; }
+static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; }
+static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; }
+static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); }
+static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); }
// AIG construction
extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
@@ -293,6 +335,54 @@ static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCom
return GIA_ONE;
}
+static inline Gia_Obj_t * Gia_ObjReprObj( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr == GIA_VOID ? NULL : Gia_ManObj( p, p->pReprs[Id].iRepr ); }
+static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; }
+static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { p->pReprs[Id].iRepr = Num; }
+
+static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; }
+static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; }
+
+static inline int Gia_ObjFailed( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fFailed; }
+static inline void Gia_ObjSetFailed( Gia_Man_t * p, int Id ) { p->pReprs[Id].fFailed = 1; }
+
+static inline int Gia_ObjColor( Gia_Man_t * p, int Id, int c ) { return c? p->pReprs[Id].fColorB : p->pReprs[Id].fColorA; }
+static inline int Gia_ObjColors( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fColorB * 2 + p->pReprs[Id].fColorA; }
+static inline void Gia_ObjSetColor( Gia_Man_t * p, int Id, int c ) { if (c) p->pReprs[Id].fColorB = 1; else p->pReprs[Id].fColorA = 1; }
+static inline void Gia_ObjSetColors( Gia_Man_t * p, int Id ) { p->pReprs[Id].fColorB = p->pReprs[Id].fColorA = 1; }
+static inline int Gia_ObjVisitColor( Gia_Man_t * p, int Id, int c ) { int x; if (c) { x = p->pReprs[Id].fColorB; p->pReprs[Id].fColorB = 1; } else { x = p->pReprs[Id].fColorA; p->pReprs[Id].fColorA = 1; } return x; }
+static inline int Gia_ObjDiffColors( Gia_Man_t * p, int i, int j ) { return (p->pReprs[i].fColorA ^ p->pReprs[j].fColorA) && (p->pReprs[i].fColorB ^ p->pReprs[j].fColorB); }
+static inline int Gia_ObjDiffColors2( Gia_Man_t * p, int i, int j ) { return (p->pReprs[i].fColorA ^ p->pReprs[j].fColorA) || (p->pReprs[i].fColorB ^ p->pReprs[j].fColorB); }
+
+static inline int Gia_ObjNext( Gia_Man_t * p, int Id ) { return p->pNexts[Id]; }
+static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p->pNexts[Id] = Num; }
+
+static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; }
+static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; }
+static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; }
+static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; }
+static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; }
+
+#define Gia_ManForEachConst( p, i ) \
+ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else
+#define Gia_ManForEachClass( p, i ) \
+ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
+#define Gia_ManForEachClassReverse( p, i ) \
+ for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else
+#define Gia_ClassForEachObj( p, i, iObj ) \
+ for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) )
+#define Gia_ClassForEachObj1( p, i, iObj ) \
+ for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) )
+
+
+static inline int Gia_ObjIsGate( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; }
+static inline int Gia_ObjGateSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; }
+static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; }
+
+#define Gia_ManForEachGate( p, i ) \
+ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsGate(p, i) ) {} else
+#define Gia_GateForEachFanin( p, i, iFan, k ) \
+ for ( k = 0; k < Gia_ObjGateSize(p,i) && ((iFan = Gia_ObjGateFanins(p,i)[k]),1); k++ )
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -351,18 +441,30 @@ extern Gia_Man_t * Gia_ManDupDfsSkip( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj );
extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p );
-extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p );
-extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar );
+extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos );
+extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan );
extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
+extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fXorOuts, int fComb, int fVerbose );
+extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p );
+/*=== giaEnable.c ==========================================================*/
+extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset );
+/*=== giaEquiv.c ==========================================================*/
+extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
+extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter );
+extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem );
+extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs );
+extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose );
+extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p );
+extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose );
/*=== giaFanout.c =========================================================*/
extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
extern void Gia_ManFanoutStart( Gia_Man_t * p );
extern void Gia_ManFanoutStop( Gia_Man_t * p );
/*=== giaForce.c =========================================================*/
-extern void For_ManExperiment( Gia_Man_t * pGia );
+extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose );
/*=== giaFrames.c =========================================================*/
extern void Gia_ManFraSetDefaultParams( Gia_ParFra_t * p );
extern Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars );
@@ -380,7 +482,7 @@ extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit
extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p );
/*=== giaLogic.c ===========================================================*/
extern void Gia_ManTestDistance( Gia_Man_t * p );
-extern void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, int fDump, int fVerbose );
+extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars );
/*=== giaMan.c ===========================================================*/
extern Gia_Man_t * Gia_ManStart( int nObjsMax );
extern void Gia_ManStop( Gia_Man_t * p );
@@ -388,13 +490,18 @@ extern void Gia_ManPrintStats( Gia_Man_t * p );
extern void Gia_ManPrintStatsShort( Gia_Man_t * p );
extern void Gia_ManPrintMiterStatus( Gia_Man_t * p );
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
+/*=== giaMap.c ===========================================================*/
+extern void Gia_ManPrintMappingStats( Gia_Man_t * p );
/*=== giaSat.c ============================================================*/
extern int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax );
/*=== giaScl.c ============================================================*/
+extern int Gia_ManSeqMarkUsed( Gia_Man_t * p );
extern int Gia_ManCombMarkUsed( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose );
+/*=== giaSort.c ============================================================*/
+extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize );
/*=== giaSim.c ============================================================*/
extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars );
/*=== giaTsim.c ============================================================*/
@@ -411,6 +518,7 @@ extern void Gia_ManFillValue( Gia_Man_t * p );
extern void Gia_ManSetPhase( Gia_Man_t * p );
extern int Gia_ManLevelNum( Gia_Man_t * p );
extern void Gia_ManSetRefs( Gia_Man_t * p );
+extern int * Gia_ManCreateMuxRefs( Gia_Man_t * p );
extern void Gia_ManCreateRefs( Gia_Man_t * p );
extern int Gia_ManCrossCut( Gia_Man_t * p );
extern int Gia_ManIsNormalized( Gia_Man_t * p );
@@ -418,6 +526,7 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p );
extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode );
extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 );
extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE );
+extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDoubleOuts );
#ifdef __cplusplus
}
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index 8b59341a..544cfe0d 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -92,10 +92,9 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
}
// add logic for the POs
Aig_ManForEachPo( p, pObj, i )
- {
Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) );
+ Aig_ManForEachPo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
- }
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
return pNew;
}
@@ -133,10 +132,9 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p )
}
// add logic for the POs
Aig_ManForEachPo( p, pObj, i )
- {
Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) );
+ Aig_ManForEachPo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
- }
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
return pNew;
}
diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c
index 40c5329d..cfd2dc73 100644
--- a/src/aig/gia/giaAiger.c
+++ b/src/aig/gia/giaAiger.c
@@ -175,6 +175,120 @@ char * Gia_TimeStamp()
/**Function*************************************************************
+ Synopsis [Read integer from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ReadInt( unsigned char * pPos )
+{
+ int i, Value = 0;
+ for ( i = 0; i < 4; i++ )
+ Value = (Value << 8) | *pPos++;
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize )
+{
+ Gia_Rpr_t * pReprs;
+ unsigned char * pStop;
+ int i, Item, fProved, iRepr, iNode;
+ pStop = *ppPos;
+ pStop += Gia_ReadInt( *ppPos ); *ppPos += 4;
+ pReprs = ABC_CALLOC( Gia_Rpr_t, nSize );
+ for ( i = 0; i < nSize; i++ )
+ pReprs[i].iRepr = GIA_VOID;
+ iRepr = iNode = 0;
+ while ( *ppPos < pStop )
+ {
+ Item = Gia_ReadAigerDecode( ppPos );
+ if ( Item & 1 )
+ {
+ iRepr += (Item >> 1);
+ iNode = iRepr;
+//printf( "\nRepr = %d ", iRepr );
+ continue;
+ }
+ Item >>= 1;
+ fProved = (Item & 1);
+ Item >>= 1;
+ iNode += Item;
+ pReprs[iNode].fProved = fProved;
+ pReprs[iNode].iRepr = iRepr;
+//printf( "Node = %d ", iNode );
+ }
+ return pReprs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads decoded value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev )
+{
+ int Item = Gia_ReadAigerDecode( ppPos );
+ if ( Item & 1 )
+ return iPrev + (Item >> 1);
+ return iPrev - (Item >> 1);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ReadMapping( unsigned char ** ppPos, int nSize )
+{
+ int * pMapping;
+ unsigned char * pStop;
+ int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize;
+ pStop = *ppPos;
+ pStop += Gia_ReadInt( *ppPos ); *ppPos += 4;
+ nAlloc = nSize + pStop - *ppPos;
+ pMapping = ABC_CALLOC( int, nAlloc );
+ while ( *ppPos < pStop )
+ {
+ k = iOffset;
+ pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos );
+ for ( j = 0; j <= nFanins; j++ )
+ pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode );
+ pMapping[iNode] = iOffset;
+ iOffset = k;
+ }
+ assert( iOffset <= nAlloc );
+ return pMapping;
+}
+
+/**Function*************************************************************
+
Synopsis [Reads the AIG in the binary AIGER format.]
Description []
@@ -328,6 +442,38 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
// create the latches
Gia_ManSetRegNum( pNew, nLatches );
+ // check if there are other types of information to read
+ pCur = pSymbols;
+ if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
+ {
+ pCur++;
+ if ( *pCur == 'e' )
+ {
+ pCur++;
+ // read equivalence classes
+ pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+ }
+ if ( *pCur == 'm' )
+ {
+ pCur++;
+ // read mapping
+ pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 'p' )
+ {
+ pCur++;
+ // read placement
+ }
+ if ( *pCur == 'n' )
+ {
+ pCur++;
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = Aig_UtilStrsav( pCur );
+ }
+ }
+
// skipping the comments
ABC_FREE( pContents );
Vec_IntFree( vNodes );
@@ -443,6 +589,144 @@ Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits )
/**Function*************************************************************
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteInt( unsigned char * pPos, int Value )
+{
+ int i;
+ for ( i = 3; i >= 0; i-- )
+ *pPos++ = (Value >> (8*i)) & 255;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize )
+{
+ unsigned char * pBuffer;
+ int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos;
+ assert( p->pReprs && p->pNexts );
+ // count the number of entries to be written
+ nItems = 0;
+ for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ )
+ {
+ nItems += Gia_ObjIsConst( p, iRepr );
+ if ( !Gia_ObjIsHead(p, iRepr) )
+ continue;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nItems++;
+ }
+ pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ // write constant class
+ iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) );
+//printf( "\nRepr = %d ", 0 );
+ iPrevNode = 0;
+ for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ )
+ if ( Gia_ObjIsConst(p, iNode) )
+ {
+//printf( "Node = %d ", iNode );
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) );
+ iPrevNode = iNode;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) );
+ }
+ // write non-constant classes
+ iPrevRepr = 0;
+ Gia_ManForEachClass( p, iRepr )
+ {
+//printf( "\nRepr = %d ", iRepr );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) );
+ iPrevRepr = iPrevNode = iRepr;
+ Gia_ClassForEachObj1( p, iRepr, iNode )
+ {
+//printf( "Node = %d ", iNode );
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) );
+ iPrevNode = iNode;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) );
+ }
+ }
+ Gia_WriteInt( pBuffer, iPos );
+ *pEquivSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads decoded value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis )
+{
+ if ( iPrev < iThis )
+ return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) );
+ return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize )
+{
+ unsigned char * pBuffer;
+ int i, k, iPrev, iFan, nItems, iPos = 4;
+ assert( p->pMapping );
+ // count the number of entries to be written
+ nItems = 0;
+ Gia_ManForEachGate( p, i )
+ nItems += 2 + Gia_ObjGateSize( p, i );
+ pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ // write non-constant classes
+ iPrev = 0;
+ Gia_ManForEachGate( p, i )
+ {
+//printf( "\nSize = %d ", Gia_ObjGateSize(p, i) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjGateSize(p, i) );
+ Gia_GateForEachFanin( p, i, iFan, k )
+ {
+//printf( "Fan = %d ", iFan );
+ iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan );
+ iPrev = iFan;
+ }
+ iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i );
+ iPrev = i;
+//printf( "Node = %d ", i );
+ }
+//printf( "\n" );
+ Gia_WriteInt( pBuffer, iPos );
+ *pMapSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
Synopsis [Writes the AIG in the binary AIGER format.]
Description []
@@ -536,10 +820,29 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
ABC_FREE( pBuffer );
// write the comment
- fprintf( pFile, "c\n" );
+ fprintf( pFile, "c" );
+ // write equivalences
+ if ( p->pReprs && p->pNexts )
+ {
+ int nEquivSize;
+ unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize );
+ fprintf( pFile, "e" );
+ fwrite( pEquivs, 1, nEquivSize, pFile );
+ ABC_FREE( pEquivs );
+ }
+ // write mapping
+ if ( p->pMapping )
+ {
+ int nMapSize;
+ unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize );
+ fprintf( pFile, "m" );
+ fwrite( pMaps, 1, nMapSize, pFile );
+ ABC_FREE( pMaps );
+ }
+ // write placement
if ( p->pName )
- fprintf( pFile, ".model %s\n", p->pName );
- fprintf( pFile, "This file was produced by the AIG package on %s\n", Gia_TimeStamp() );
+ fprintf( pFile, "n%s%c", p->pName, '\0' );
+ fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
fclose( pFile );
if ( p != pInit )
diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c
index d58429cd..735aca72 100644
--- a/src/aig/gia/giaCof.c
+++ b/src/aig/gia/giaCof.c
@@ -41,6 +41,7 @@ struct Cof_Obj_t_
unsigned fMark1 : 1; // second user-controlled mark
unsigned nFanins : 4; // the number of fanins
unsigned nFanouts : 24; // total number of fanouts
+ unsigned nFanoutsM; // total number of MUX ctrl fanouts
unsigned Value; // application specific data
int Id; // ID of the node
int iNext; // next one in the linked list
@@ -124,6 +125,7 @@ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia )
Cof_Man_t * p;
Cof_Obj_t * pObjLog, * pFanLog;
Gia_Obj_t * pObj;
+ int * pMuxRefs;
int i, iHandle = 0;
p = ABC_CALLOC( Cof_Man_t, 1 );
p->pGia = pGia;
@@ -173,11 +175,14 @@ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia )
p->nObjs++;
}
assert( iHandle == p->nObjData );
+ pMuxRefs = Gia_ManCreateMuxRefs( pGia );
Gia_ManForEachObj( pGia, pObj, i )
{
pObjLog = Cof_ManObj( p, Gia_ObjHandle(pObj) );
assert( pObjLog->nFanouts == pObjLog->Value );
+ pObjLog->nFanoutsM = pMuxRefs[i];
}
+ ABC_FREE( pMuxRefs );
return p;
}
@@ -509,8 +514,7 @@ int Cof_ManCountRemoved( Cof_Man_t * p, Cof_Obj_t * pRoot, int fConst1 )
void Cof_ManPrintHighFanoutOne( Cof_Man_t * p, Cof_Obj_t * pObj )
{
printf( "%7d : ", pObj->Id );
- printf( "fi =%2d ", Cof_ObjFaninNum(pObj) );
- printf( "fo =%5d ", Cof_ObjFanoutNum(pObj) );
+ printf( "i/o/c =%2d %5d %5d ", Cof_ObjFaninNum(pObj), Cof_ObjFanoutNum(pObj), 2*pObj->nFanoutsM );
printf( "l =%4d ", Cof_ObjLevel(p, pObj) );
printf( "s =%5d ", Cof_ManSuppSize(p, &pObj, 1) );
printf( "TFI =%7d ", Cof_ManTfiSize(p, &pObj, 1) );
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index d5c0862f..4821dba9 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -196,11 +196,11 @@ int Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( ~pObj->Value )
return pObj->Value;
- if ( p->pReprs && ~p->pReprs[Gia_ObjId(p, pObj)] )
+ if ( p->pReprsOld && ~p->pReprsOld[Gia_ObjId(p, pObj)] )
{
- Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprs[Gia_ObjId(p, pObj)] );
- pObj->Value = Gia_ManDupDfs_rec( pNew, p, pRepr );
- return pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprsOld[Gia_ObjId(p, pObj)] );
+ pRepr->Value = Gia_ManDupDfs_rec( pNew, p, pRepr );
+ return pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
}
if ( Gia_ObjIsCi(pObj) )
return pObj->Value = Gia_ManAppendCi(pNew);
@@ -380,7 +380,7 @@ Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p )
+Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
@@ -391,12 +391,12 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p )
Gia_ManSetRefs( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
- if ( pObj->Value > 0 || Gia_ObjIsRo(p, pObj) )
+ if ( !fTrimCis || pObj->Value > 0 || Gia_ObjIsRo(p, pObj) )
pObj->Value = Gia_ManAppendCi(pNew);
Gia_ManForEachAnd( p, pObj, i )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
Gia_ManForEachCo( p, pObj, i )
- if ( !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) )
+ if ( !fTrimCos || !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
return pNew;
@@ -413,11 +413,16 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar )
+Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan )
{
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj, * pPivot;
int i, iCofVar = -1;
+ if ( nLimFan > 0 )
+ {
+ printf( "This feature is not implemented.\n" );
+ return NULL;
+ }
if ( !(iVar > 0 && iVar < Gia_ManObjNum(p)) )
{
printf( "Gia_ManDupCofactored(): Variable %d is out of range (%d; %d).\n", iVar, 0, Gia_ManObjNum(p) );
@@ -502,7 +507,7 @@ void Gia_ManPrintRepr( Gia_Man_t * p )
Gia_Obj_t * pObj;
int i;
Gia_ManForEachObj( p, pObj, i )
- if ( ~p->pReprs[i] )
+ if ( ~p->pReprsOld[i] )
printf( "%d->%d ", i, p->pReprs[i] );
printf( "\n" );
}
@@ -569,7 +574,7 @@ Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p )
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj;
int i;
- assert( p->pReprs != NULL );
+ assert( p->pReprsOld != NULL );
Gia_ManFillValue( p );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
@@ -719,6 +724,195 @@ Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose )
}
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManMiter_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManMiter_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates miter of two designs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManMiter( Gia_Man_t * p0, Gia_Man_t * p1, int fXorOuts, int fComb, int fVerbose )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, iLit;
+ if ( fComb )
+ {
+ if ( Gia_ManCiNum(p0) != Gia_ManCiNum(p1) )
+ {
+ printf( "Gia_ManMiter(): Designs have different number of CIs.\n" );
+ return NULL;
+ }
+ if ( Gia_ManCoNum(p0) != Gia_ManCoNum(p1) )
+ {
+ printf( "Gia_ManMiter(): Designs have different number of COs.\n" );
+ return NULL;
+ }
+ }
+ else
+ {
+ if ( Gia_ManPiNum(p0) != Gia_ManPiNum(p1) )
+ {
+ printf( "Gia_ManMiter(): Designs have different number of PIs.\n" );
+ return NULL;
+ }
+ if ( Gia_ManPoNum(p0) != Gia_ManPoNum(p1) )
+ {
+ printf( "Gia_ManMiter(): Designs have different number of POs.\n" );
+ return NULL;
+ }
+ if ( Gia_ManRegNum(p0) == 0 || Gia_ManRegNum(p1) == 0 )
+ {
+ printf( "Gia_ManMiter(): At least one of the designs has no registers.\n" );
+ return NULL;
+ }
+ }
+ // start the manager
+ pNew = Gia_ManStart( Gia_ManObjNum(p0) + Gia_ManObjNum(p1) );
+ pNew->pName = Aig_UtilStrsav( "miter" );
+ // map combinational inputs
+ Gia_ManFillValue( p0 );
+ Gia_ManFillValue( p1 );
+ Gia_ManConst0(p0)->Value = 0;
+ Gia_ManConst0(p1)->Value = 0;
+ // map internal nodes and outputs
+ Gia_ManHashAlloc( pNew );
+ if ( fComb )
+ {
+ // create combinational inputs
+ Gia_ManForEachCi( p0, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachCi( p1, pObj, i )
+ pObj->Value = Gia_ObjToLit( pNew, Gia_ManCi(pNew, i) );
+ // create combinational outputs
+ Gia_ManForEachCo( p0, pObj, i )
+ {
+ Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) );
+ Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(Gia_ManCo(p1,i)) );
+ if ( fXorOuts )
+ {
+ iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(Gia_ManCo(p1,i)) );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ else
+ {
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p1,i)) );
+ }
+ }
+ }
+ else
+ {
+ // create primary inputs
+ Gia_ManForEachPi( p0, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachPi( p1, pObj, i )
+ pObj->Value = Gia_ObjToLit( pNew, Gia_ManPi(pNew, i) );
+ // create latch outputs
+ Gia_ManForEachRo( p0, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachRo( p1, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ // create primary outputs
+ Gia_ManForEachPo( p0, pObj, i )
+ {
+ Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) );
+ Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(Gia_ManPo(p1,i)) );
+ if ( fXorOuts )
+ {
+ iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(Gia_ManPo(p1,i)) );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ else
+ {
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManPo(p1,i)) );
+ }
+ }
+ // create register inputs
+ Gia_ManForEachRi( p0, pObj, i )
+ {
+ Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) );
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManForEachRi( p1, pObj, i )
+ {
+ Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(pObj) );
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p0) + Gia_ManRegNum(p1) );
+ }
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the circuit into a regular miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pObj2;
+ int i, iLit;
+ assert( (Gia_ManPoNum(p) & 1) == 0 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ {
+ pObj2 = Gia_ManPo( p, ++i );
+ iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(pObj2) );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ Gia_ManForEachRi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c
index 0469d1a4..6c2f00df 100644
--- a/src/aig/gia/giaEmbed.c
+++ b/src/aig/gia/giaEmbed.c
@@ -25,12 +25,18 @@
The code is based on the paper by D. Harel and Y. Koren,
"Graph drawing by high-dimensional embedding",
J. Graph Algs & Apps, Vol 8(2), pp. 195-217 (2004).
+ http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf
+
+ Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah.
+ "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03.
+ http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+
typedef float Emb_Dat_t;
typedef struct Emb_Obj_t_ Emb_Obj_t;
@@ -90,10 +96,10 @@ static inline Emb_Obj_t * Emb_ManCo( Emb_Man_t * p, int i )
static inline int Emb_ObjIsTerm( Emb_Obj_t * pObj ) { return pObj->fCi || pObj->fCo; }
static inline int Emb_ObjIsCi( Emb_Obj_t * pObj ) { return pObj->fCi; }
static inline int Emb_ObjIsCo( Emb_Obj_t * pObj ) { return pObj->fCo; }
-static inline int Emb_ObjIsPi( Emb_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; }
-static inline int Emb_ObjIsPo( Emb_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; }
+//static inline int Emb_ObjIsPi( Emb_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; }
+//static inline int Emb_ObjIsPo( Emb_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; }
static inline int Emb_ObjIsNode( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins > 0; }
-static inline int Emb_ObjIsConst0( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins == 0; }
+//static inline int Emb_ObjIsConst0( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins == 0; }
static inline int Emb_ObjSize( Emb_Obj_t * pObj ) { return sizeof(Emb_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; }
static inline int Emb_ObjFaninNum( Emb_Obj_t * pObj ) { return pObj->nFanins; }
@@ -109,8 +115,8 @@ static inline void Emb_ObjSetTravIdPrevious( Emb_Man_t * p, Emb_Obj_t * p
static inline int Emb_ObjIsTravIdCurrent( Emb_Man_t * p, Emb_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds); }
static inline int Emb_ObjIsTravIdPrevious( Emb_Man_t * p, Emb_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds - 1); }
-static inline Emb_Dat_t * Emb_ManVec( Emb_Man_t * p, int v ) { return p->pVecs + v * p->nObjs; }
-static inline float * Emb_ManSol( Emb_Man_t * p, int v ) { return p->pSols + v * p->nObjs; }
+static inline Emb_Dat_t * Emb_ManVec( Emb_Man_t * p, int v ) { return p->pVecs + v * p->nObjs; }
+static inline float * Emb_ManSol( Emb_Man_t * p, int v ) { return p->pSols + v * p->nObjs; }
#define Emb_ManForEachObj( p, pObj, i ) \
for ( i = 0; (i < p->nObjData) && (pObj = Emb_ManObj(p,i)); i += Emb_ObjSize(pObj) )
@@ -171,13 +177,13 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia )
p->nRegs = Gia_ManRegNum(pGia);
p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) );
p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) );
- p->nObjData = (sizeof(Emb_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia) + Gia_ManRegNum(pGia));
+ p->nObjData = (sizeof(Emb_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia) + Gia_ManRegNum(pGia) + Gia_ManCoNum(pGia));
p->pObjData = ABC_CALLOC( int, p->nObjData );
// create constant node
Gia_ManConst0(pGia)->Value = hHandle;
pObjLog = Emb_ManObj( p, hHandle );
pObjLog->hHandle = hHandle;
- pObjLog->nFanins = 0;
+ pObjLog->nFanins = Gia_ManCoNum(pGia); //0;
pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) );
// count objects
hHandle += Emb_ObjSize( pObjLog );
@@ -227,7 +233,7 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia )
pObjLog = Emb_ManObj( p, hHandle );
pObjLog->hHandle = hHandle;
pObjLog->nFanins = 1;
- pObjLog->nFanouts = Gia_ObjIsRi( pGia, pObj );
+ pObjLog->nFanouts = 1 + Gia_ObjIsRi( pGia, pObj );
pObjLog->fCo = 1;
// add fanins
pFanLog = Emb_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
@@ -249,8 +255,8 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia )
if ( !~Gia_ObjValue(pObj) )
continue;
pObjLog = Emb_ManObj( p, Gia_ObjValue(pObj) );
- assert( pObjLog->nFanins == pObjLog->iFanin );
- assert( pObjLog->nFanouts == pObjLog->iFanout );
+ assert( pObjLog->nFanins == pObjLog->iFanin || Gia_ObjIsConst0(pObj) );
+ assert( pObjLog->nFanouts == pObjLog->iFanout || Gia_ObjIsCo(pObj) );
pObjLog->iFanin = pObjLog->iFanout = 0;
}
ABC_FREE( pGia->pRefs );
@@ -496,13 +502,13 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia )
p->nRegs = Gia_ManRegNum(pGia);
p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) );
p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) );
- p->nObjData = (sizeof(Emb_Obj_t) / 4) * nObjs + 2 * (nFanios + Gia_ManRegNum(pGia));
+ p->nObjData = (sizeof(Emb_Obj_t) / 4) * nObjs + 2 * (nFanios + Gia_ManRegNum(pGia) + Gia_ManCoNum(pGia));
p->pObjData = ABC_CALLOC( int, p->nObjData );
// create constant node
Gia_ManConst0(pGia)->Value = hHandle;
pObjLog = Emb_ManObj( p, hHandle );
pObjLog->hHandle = hHandle;
- pObjLog->nFanins = 0;
+ pObjLog->nFanins = Gia_ManCoNum(pGia); //0;
pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) );
// count objects
hHandle += Emb_ObjSize( pObjLog );
@@ -563,7 +569,7 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia )
pObjLog = Emb_ManObj( p, hHandle );
pObjLog->hHandle = hHandle;
pObjLog->nFanins = 1;
- pObjLog->nFanouts = Gia_ObjIsRi( pGia, pObj );
+ pObjLog->nFanouts = 1 + Gia_ObjIsRi( pGia, pObj );
pObjLog->fCo = 1;
// add fanins
pFanLog = Emb_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
@@ -587,8 +593,8 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia )
if ( !~Gia_ObjValue(pObj) )
continue;
pObjLog = Emb_ManObj( p, Gia_ObjValue(pObj) );
- assert( pObjLog->nFanins == pObjLog->iFanin );
- assert( pObjLog->nFanouts == pObjLog->iFanout );
+ assert( pObjLog->nFanins == pObjLog->iFanin || Gia_ObjIsConst0(pObj) );
+ assert( pObjLog->nFanouts == pObjLog->iFanout || Gia_ObjIsCo(pObj) );
pObjLog->iFanin = pObjLog->iFanout = 0;
}
ABC_FREE( pGia->pRefs );
@@ -904,7 +910,7 @@ ABC_PRT( "Time", clock() - clk );
/**Function*************************************************************
- Synopsis [Computes the distances from the given set of objects.]
+ Synopsis [Perform BFS from the set of nodes.]
Description [Returns one of the most distant objects.]
@@ -913,20 +919,11 @@ ABC_PRT( "Time", clock() - clk );
SeeAlso []
***********************************************************************/
-Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * pDist )
+Emb_Obj_t * Emb_ManPerformBfs( Emb_Man_t * p, Vec_Int_t * vThis, Vec_Int_t * vNext, Emb_Dat_t * pDist )
{
- Vec_Int_t * vThis, * vNext, * vTemp;
+ Vec_Int_t * vTemp;
Emb_Obj_t * pThis, * pNext, * pResult;
int i, k;
- p->nReached = p->nDistMax = 0;
- vThis = Vec_IntAlloc( 1000 );
- vNext = Vec_IntAlloc( 1000 );
- Emb_ManIncrementTravId( p );
- Emb_ManForEachObjVec( vStart, p, pThis, i )
- {
- Emb_ObjSetTravIdCurrent( p, pThis );
- Vec_IntPush( vThis, pThis->hHandle );
- }
assert( Vec_IntSize(vThis) > 0 );
for ( p->nDistMax = 0; Vec_IntSize(vThis) > 0; p->nDistMax++ )
{
@@ -955,6 +952,74 @@ Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t *
assert( Vec_IntSize(vNext) > 0 );
pResult = Emb_ManObj( p, Vec_IntEntry(vNext, 0) );
assert( pDist == NULL || pDist[pResult->Value] == p->nDistMax - 1 );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the distances from the given set of objects.]
+
+ Description [Returns one of the most distant objects.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Emb_ManConnectedComponents( Emb_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vThis, * vNext, * vResult;
+ Emb_Obj_t * pThis;
+ int i;
+ vResult = Vec_IntAlloc( 1000 );
+ vThis = Vec_IntAlloc( 1000 );
+ vNext = Vec_IntAlloc( 1000 );
+ p->nReached = 0;
+ Emb_ManIncrementTravId( p );
+ Gia_ManForEachCo( p->pGia, pObj, i )
+ {
+ pThis = Emb_ManObj( p, Gia_ObjValue(pObj) );
+ if ( Emb_ObjIsTravIdCurrent(p, pThis) )
+ continue;
+ Emb_ObjSetTravIdCurrent( p, pThis );
+ Vec_IntPush( vResult, pThis->hHandle );
+ // perform BFS from this node
+ Vec_IntClear( vThis );
+ Vec_IntPush( vThis, pThis->hHandle );
+ Emb_ManPerformBfs( p, vThis, vNext, NULL );
+ }
+ Vec_IntFree( vThis );
+ Vec_IntFree( vNext );
+ return vResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the distances from the given set of objects.]
+
+ Description [Returns one of the most distant objects.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * pDist )
+{
+ Vec_Int_t * vThis, * vNext;
+ Emb_Obj_t * pThis, * pResult;
+ int i;
+ p->nReached = p->nDistMax = 0;
+ vThis = Vec_IntAlloc( 1000 );
+ vNext = Vec_IntAlloc( 1000 );
+ Emb_ManIncrementTravId( p );
+ Emb_ManForEachObjVec( vStart, p, pThis, i )
+ {
+ Emb_ObjSetTravIdCurrent( p, pThis );
+ Vec_IntPush( vThis, pThis->hHandle );
+ }
+ pResult = Emb_ManPerformBfs( p, vThis, vNext, pDist );
Vec_IntFree( vThis );
Vec_IntFree( vNext );
return pResult;
@@ -1029,13 +1094,28 @@ void Emb_DumpGraphIntoFile( Emb_Man_t * p )
void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims )
{
Emb_Obj_t * pRandom, * pPivot;
- Vec_Int_t * vStart;
+ Vec_Int_t * vStart, * vComps;
int d, nReached;
- int i, Counter;
+ int i;//, Counter;
+ // connect unconnected components
+ vComps = Emb_ManConnectedComponents( p );
+// printf( "Components = %d. Considered %d objects (out of %d).\n", Vec_IntSize(vComps), p->nReached, Emb_ManObjNum(p) );
+ if ( Vec_IntSize(vComps) > 1 )
+ {
+ Emb_Obj_t * pFanin, * pObj = Emb_ManObj( p, 0 );
+ Emb_ManForEachObjVec( vComps, p, pFanin, i )
+ {
+ assert( Emb_ObjIsCo(pFanin) );
+ pFanin->Fanios[pFanin->nFanins + pFanin->nFanouts-1] =
+ pObj->Fanios[i] = pObj->hHandle - pFanin->hHandle;
+ }
+ }
+ Vec_IntFree( vComps );
+ // allocate memory for vectors
assert( p->pVecs == NULL );
- p->pVecs = ABC_ALLOC( Emb_Dat_t, p->nObjs * nDims );
- for ( i = 0; i < p->nObjs * nDims; i++ )
- p->pVecs[i] = ABC_INFINITY;
+ p->pVecs = ABC_CALLOC( Emb_Dat_t, p->nObjs * nDims );
+// for ( i = 0; i < p->nObjs * nDims; i++ )
+// p->pVecs[i] = ABC_INFINITY;
vStart = Vec_IntAlloc( nDims );
// get the pivot vertex
pRandom = Emb_ManRandomVertex( p );
@@ -1046,7 +1126,7 @@ void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims )
nReached = p->nReached;
if ( nReached < Emb_ManObjNum(p) )
{
- printf( "Considering a connected component with %d objects (out of %d).\n", p->nReached, Emb_ManObjNum(p) );
+// printf( "Considering a connected component with %d objects (out of %d).\n", p->nReached, Emb_ManObjNum(p) );
}
// start dimensions with this vertex
Vec_IntClear( vStart );
@@ -1061,11 +1141,11 @@ void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims )
}
Vec_IntFree( vStart );
// make sure the number of reached objects is correct
- Counter = 0;
- for ( i = 0; i < p->nObjs; i++ )
- if ( p->pVecs[i] < ABC_INFINITY )
- Counter++;
- assert( Counter == nReached );
+// Counter = 0;
+// for ( i = 0; i < p->nObjs; i++ )
+// if ( p->pVecs[i] < ABC_INFINITY )
+// Counter++;
+// assert( Counter == nReached );
}
/**Function*************************************************************
@@ -1338,7 +1418,6 @@ void Emb_ManComputeSolutions( Emb_Man_t * p, int nDims, int nSols )
***********************************************************************/
void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols )
{
- extern int * Gia_SortFloats( float * pArray, int nSize );
float * pY0, * pY1, Max0, Max1, Min0, Min1, Str0, Str1;
int * pPerm0, * pPerm1;
int k;
@@ -1373,10 +1452,10 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols )
pY1[k] = (pY1[k] != 0.0) ? ((pY1[k] - Min1) * Str1) : 0.0;
// derive the order of these numbers
- pPerm0 = Gia_SortFloats( pY0, p->nObjs );
- pPerm1 = Gia_SortFloats( pY1, p->nObjs );
+ pPerm0 = Gia_SortFloats( pY0, NULL, p->nObjs );
+ pPerm1 = Gia_SortFloats( pY1, NULL, p->nObjs );
- // average solutions and project them into 32K by 32K square
+ // average solutions and project them into square [0;0xffff] x [0;0xffff]
p->pPlacement = ABC_ALLOC( unsigned short, 2 * p->nObjs );
for ( k = 0; k < p->nObjs; k++ )
{
@@ -1387,6 +1466,127 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols )
ABC_FREE( pPerm1 );
}
+
+/**Function*************************************************************
+
+ Synopsis [Computes wire-length.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+double Emb_ManComputeHPWL( Emb_Man_t * p )
+{
+ double Result = 0.0;
+ Emb_Obj_t * pThis, * pNext;
+ int i, k, iMinX, iMaxX, iMinY, iMaxY;
+ if ( p->pPlacement == NULL )
+ return 0.0;
+ Emb_ManForEachObj( p, pThis, i )
+ {
+ iMinX = iMaxX = p->pPlacement[2*pThis->Value+0];
+ iMinY = iMaxY = p->pPlacement[2*pThis->Value+1];
+ Emb_ObjForEachFanout( pThis, pNext, k )
+ {
+ iMinX = ABC_MIN( iMinX, p->pPlacement[2*pNext->Value+0] );
+ iMaxX = ABC_MAX( iMaxX, p->pPlacement[2*pNext->Value+0] );
+ iMinY = ABC_MIN( iMinY, p->pPlacement[2*pNext->Value+1] );
+ iMaxY = ABC_MAX( iMaxY, p->pPlacement[2*pNext->Value+1] );
+ }
+ Result += (iMaxX - iMinX) + (iMaxY - iMinY);
+ }
+ return Result;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs iterative refinement of the given placement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Emb_ManPlacementRefine( Emb_Man_t * p, int nIters, int fVerbose )
+{
+ Emb_Obj_t * pThis, * pNext;
+ double CostThis, CostPrev;
+ float * pEdgeX, * pEdgeY;
+ float * pVertX, * pVertY;
+ float VertX, VertY;
+ int * pPermX, * pPermY;
+ int i, k, Iter, iMinX, iMaxX, iMinY, iMaxY;
+ int clk = clock();
+ if ( p->pPlacement == NULL )
+ return;
+ pEdgeX = ABC_ALLOC( float, p->nObjs );
+ pEdgeY = ABC_ALLOC( float, p->nObjs );
+ pVertX = ABC_ALLOC( float, p->nObjs );
+ pVertY = ABC_ALLOC( float, p->nObjs );
+ // refine placement
+ CostPrev = 0.0;
+ for ( Iter = 0; Iter < nIters; Iter++ )
+ {
+ // compute centers of hyperedges
+ CostThis = 0.0;
+ Emb_ManForEachObj( p, pThis, i )
+ {
+ iMinX = iMaxX = p->pPlacement[2*pThis->Value+0];
+ iMinY = iMaxY = p->pPlacement[2*pThis->Value+1];
+ Emb_ObjForEachFanout( pThis, pNext, k )
+ {
+ iMinX = ABC_MIN( iMinX, p->pPlacement[2*pNext->Value+0] );
+ iMaxX = ABC_MAX( iMaxX, p->pPlacement[2*pNext->Value+0] );
+ iMinY = ABC_MIN( iMinY, p->pPlacement[2*pNext->Value+1] );
+ iMaxY = ABC_MAX( iMaxY, p->pPlacement[2*pNext->Value+1] );
+ }
+ pEdgeX[pThis->Value] = 0.5 * (iMaxX + iMinX);
+ pEdgeY[pThis->Value] = 0.5 * (iMaxY + iMinY);
+ CostThis += (iMaxX - iMinX) + (iMaxY - iMinY);
+ }
+ // compute new centers of objects
+ Emb_ManForEachObj( p, pThis, i )
+ {
+ VertX = pEdgeX[pThis->Value];
+ VertY = pEdgeY[pThis->Value];
+ Emb_ObjForEachFanin( pThis, pNext, k )
+ {
+ VertX += pEdgeX[pNext->Value];
+ VertY += pEdgeY[pNext->Value];
+ }
+ pVertX[pThis->Value] = VertX / (Emb_ObjFaninNum(pThis) + 1);
+ pVertY[pThis->Value] = VertY / (Emb_ObjFaninNum(pThis) + 1);
+ }
+ // sort these numbers
+ pPermX = Gia_SortFloats( pVertX, NULL, p->nObjs );
+ pPermY = Gia_SortFloats( pVertY, NULL, p->nObjs );
+ for ( k = 0; k < p->nObjs; k++ )
+ {
+ p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs);
+ p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs);
+ }
+ ABC_FREE( pPermX );
+ ABC_FREE( pPermY );
+ // evaluate cost
+ if ( fVerbose )
+ {
+ printf( "%2d : HPWL = %e ", Iter+1, CostThis );
+ ABC_PRT( "Time", clock() - clk );
+ }
+ }
+ ABC_FREE( pEdgeX );
+ ABC_FREE( pEdgeY );
+ ABC_FREE( pVertX );
+ ABC_FREE( pVertY );
+}
+
+
/**Function*************************************************************
Synopsis [Derives solutions from original vectors and eigenvectors.]
@@ -1413,6 +1613,68 @@ void Emb_ManPrintSolutions( Emb_Man_t * p, int nSols )
/**Function*************************************************************
+ Synopsis [Prepares image for dumping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Emb_ManDumpGnuplotPrepare( Emb_Man_t * p )
+{
+// int nRows = 496;
+// int nCols = 710;
+ int nRows = 500;
+ int nCols = 700;
+ Vec_Int_t * vLines;
+ Emb_Obj_t * pThis;
+ char * pBuffer, ** ppRows;
+ int i, k, placeX, placeY;
+ int fStart;
+ // alloc memory
+ pBuffer = ABC_CALLOC( char, nRows * (nCols+1) );
+ ppRows = ABC_ALLOC( char *, nRows );
+ for ( i = 0; i < nRows; i++ )
+ ppRows[i] = pBuffer + i*(nCols+1);
+ // put data into them
+ Emb_ManForEachObj( p, pThis, i )
+ {
+ placeX = p->pPlacement[2*pThis->Value+0] * nCols / (1<<16);
+ placeY = p->pPlacement[2*pThis->Value+1] * nRows / (1<<16);
+ assert( placeX < nCols && placeY < nRows );
+ ppRows[placeY][placeX] = 1;
+ }
+ // select lines
+ vLines = Vec_IntAlloc( 1000 );
+ for ( i = 0; i < nRows; i++ )
+ {
+ fStart = 0;
+ for ( k = 0; k <= nCols; k++ )
+ {
+ if ( ppRows[i][k] && !fStart )
+ {
+ Vec_IntPush( vLines, k );
+ Vec_IntPush( vLines, i );
+ fStart = 1;
+ }
+ if ( !ppRows[i][k] && fStart )
+ {
+ Vec_IntPush( vLines, k-1 );
+ Vec_IntPush( vLines, i );
+ fStart = 0;
+ }
+ }
+ assert( fStart == 0 );
+ }
+ ABC_FREE( pBuffer );
+ ABC_FREE( ppRows );
+ return vLines;
+}
+
+/**Function*************************************************************
+
Synopsis [Derives solutions from original vectors and eigenvectors.]
Description []
@@ -1422,71 +1684,89 @@ void Emb_ManPrintSolutions( Emb_Man_t * p, int nSols )
SeeAlso []
***********************************************************************/
-void Emb_ManDumpGnuplot( Emb_Man_t * p, int nSols, char * pName )
+void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowImage )
{
- int fDumpImage = 1;
+ extern void Gia_ManGnuplotShow( char * pPlotFileName );
// char * pDirectory = "place\\";
char * pDirectory = "";
extern char * Ioa_TimeStamp();
FILE * pFile;
char Buffer[1000];
Emb_Obj_t * pThis, * pNext;
- float * pSol0, * pSol1;
int i, k;
- if ( nSols < 2 )
- return;
if ( p->pPlacement == NULL )
{
printf( "Emb_ManDumpGnuplot(): Placement is not available.\n" );
return;
}
- pSol0 = Emb_ManSol( p, 0 );
- pSol1 = Emb_ManSol( p, 1 );
sprintf( Buffer, "%s%s", pDirectory, Aig_FileNameGenericAppend(pName, ".plt") );
pFile = fopen( Buffer, "w" );
fprintf( pFile, "# This Gnuplot file was produced by ABC on %s\n", Ioa_TimeStamp() );
fprintf( pFile, "\n" );
- if ( fDumpImage )
- {
fprintf( pFile, "set nokey\n" );
+ fprintf( pFile, "\n" );
+ if ( !fShowImage )
+ {
// fprintf( pFile, "set terminal postscript\n" );
-// fprintf( pFile, "set output \'%s\'\n", Aig_FileNameGenericAppend(pName, ".ps") );
fprintf( pFile, "set terminal gif font \'arial\' 10 size 800,600 xffffff x000000 x000000 x000000\n" );
fprintf( pFile, "set output \'%s\'\n", Aig_FileNameGenericAppend(pName, ".gif") );
fprintf( pFile, "\n" );
}
- fprintf( pFile, "set title \"%s : PI = %d PO = %d FF = %d Node = %d Obj = %d\\n",
- pName, Emb_ManPiNum(p), Emb_ManPoNum(p), Emb_ManRegNum(p), Emb_ManNodeNum(p), Emb_ManObjNum(p) );
+ fprintf( pFile, "set title \"%s : PI = %d PO = %d FF = %d Node = %d Obj = %d HPWL = %.2e\\n",
+ pName, Emb_ManPiNum(p), Emb_ManPoNum(p), Emb_ManRegNum(p), Emb_ManNodeNum(p), Emb_ManObjNum(p), Emb_ManComputeHPWL(p) );
fprintf( pFile, "(image generated by ABC and Gnuplot on %s)\"", Ioa_TimeStamp() );
fprintf( pFile, "font \"Times, 12\"\n" );
fprintf( pFile, "\n" );
fprintf( pFile, "plot [:] '-' w l\n" );
fprintf( pFile, "\n" );
- Emb_ManForEachObj( p, pThis, i )
+ if ( fDumpLarge )
{
- if ( !Emb_ObjIsTravIdCurrent(p, pThis) )
- continue;
- Emb_ObjForEachFanout( pThis, pNext, k )
+ int begX, begY, endX, endY;
+ Vec_Int_t * vLines = Emb_ManDumpGnuplotPrepare( p );
+ Vec_IntForEachEntry( vLines, begX, i )
{
- assert( Emb_ObjIsTravIdCurrent(p, pNext) );
-// fprintf( pFile, "%d %d\n", (int)pSol0[pThis->Value], (int)pSol1[pThis->Value] );
-// fprintf( pFile, "%d %d\n", (int)pSol0[pNext->Value], (int)pSol1[pNext->Value] );
-// fprintf( pFile, "%5.2f %5.2f\n", pSol0[pThis->Value], pSol1[pThis->Value] );
-// fprintf( pFile, "%5.2f %5.2f\n", pSol0[pNext->Value], pSol1[pNext->Value] );
- fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pThis->Value+0], p->pPlacement[2*pThis->Value+1] );
- fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pNext->Value+0], p->pPlacement[2*pNext->Value+1] );
+ begY = Vec_IntEntry( vLines, i+1 );
+ endX = Vec_IntEntry( vLines, i+2 );
+ endY = Vec_IntEntry( vLines, i+3 );
+ i += 3;
+ fprintf( pFile, "%5d %5d\n", begX, begY );
+ fprintf( pFile, "%5d %5d\n", endX, endY );
fprintf( pFile, "\n" );
}
+ Vec_IntFree( vLines );
+ }
+ else
+ {
+ Emb_ManForEachObj( p, pThis, i )
+ {
+ if ( !Emb_ObjIsTravIdCurrent(p, pThis) )
+ continue;
+ Emb_ObjForEachFanout( pThis, pNext, k )
+ {
+ assert( Emb_ObjIsTravIdCurrent(p, pNext) );
+ fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pThis->Value+0], p->pPlacement[2*pThis->Value+1] );
+ fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pNext->Value+0], p->pPlacement[2*pNext->Value+1] );
+ fprintf( pFile, "\n" );
+ }
+ }
}
fprintf( pFile, "EOF\n" );
fprintf( pFile, "\n" );
- if ( !fDumpImage )
+ if ( fShowImage )
{
- fprintf( pFile, "pause -1 \"Hit return to continue\"\n" );
+ fprintf( pFile, "pause -1 \"Close window\"\n" ); // Hit return to continue
fprintf( pFile, "reset\n" );
fprintf( pFile, "\n" );
}
+ else
+ {
+ fprintf( pFile, "# pause -1 \"Close window\"\n" ); // Hit return to continue
+ fprintf( pFile, "# reset\n" );
+ fprintf( pFile, "\n" );
+ }
fclose( pFile );
+ if ( fShowImage )
+ Gia_ManGnuplotShow( Buffer );
}
/**Function*************************************************************
@@ -1500,7 +1780,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, int nSols, char * pName )
SeeAlso []
***********************************************************************/
-void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, int fDump, int fVerbose )
+void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars )
{
Emb_Man_t * p;
int clk, clkSetup;
@@ -1508,18 +1788,18 @@ void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster,
// transform AIG into internal data-structure
clk = clock();
- if ( fCluster )
+ if ( pPars->fCluster )
{
p = Emb_ManStart( pGia );
- if ( fVerbose )
+ if ( pPars->fVerbose )
{
- printf( "After clustering: " );
+ printf( "Clustered: " );
Emb_ManPrintStats( p );
}
}
else
p = Emb_ManStartSimple( pGia );
- p->fVerbose = fVerbose;
+ p->fVerbose = pPars->fVerbose;
// Emb_ManPrintFanio( p );
// prepare data-structure
@@ -1529,26 +1809,40 @@ clk = clock();
clkSetup = clock() - clk;
clk = clock();
- Emb_ManComputeDimensions( p, nDims );
-if ( fVerbose )
+ Emb_ManComputeDimensions( p, pPars->nDims );
+if ( pPars->fVerbose )
ABC_PRT( "Setup ", clkSetup );
-if ( fVerbose )
+if ( pPars->fVerbose )
ABC_PRT( "Dimensions", clock() - clk );
clk = clock();
- Emb_ManComputeCovariance( p, nDims );
-if ( fVerbose )
+ Emb_ManComputeCovariance( p, pPars->nDims );
+if ( pPars->fVerbose )
ABC_PRT( "Matrix ", clock() - clk );
clk = clock();
- Emb_ManComputeEigenvectors( p, nDims, nSols );
- Emb_ManComputeSolutions( p, nDims, nSols );
- Emb_ManDerivePlacement( p, nSols );
-if ( fVerbose )
+ Emb_ManComputeEigenvectors( p, pPars->nDims, pPars->nSols );
+ Emb_ManComputeSolutions( p, pPars->nDims, pPars->nSols );
+ Emb_ManDerivePlacement( p, pPars->nSols );
+if ( pPars->fVerbose )
ABC_PRT( "Eigenvecs ", clock() - clk );
- if ( fDump )
- Emb_ManDumpGnuplot( p, nSols, pGia->pName );
+ if ( pPars->fRefine )
+ {
+clk = clock();
+ Emb_ManPlacementRefine( p, pPars->nIters, pPars->fVerbose );
+if ( pPars->fVerbose )
+ABC_PRT( "Refinement", clock() - clk );
+ }
+
+ if ( (pPars->fDump || pPars->fDumpLarge) && pPars->nSols == 2 )
+ {
+clk = clock();
+ Emb_ManDumpGnuplot( p, pGia->pName, pPars->fDumpLarge, pPars->fShowImage );
+if ( pPars->fVerbose )
+ABC_PRT( "Image dump", clock() - clk );
+ }
+
Emb_ManStop( p );
}
diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c
new file mode 100644
index 00000000..d05dc5a9
--- /dev/null
+++ b/src/aig/gia/giaEnable.c
@@ -0,0 +1,210 @@
+/**CFile****************************************************************
+
+ FileName [gia.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Structural detection of enables, sets and resets.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_CollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ // go through the branches
+ Gia_CollectSuper_rec( p, Gia_ObjChild0(pObj), vSuper );
+ Gia_CollectSuper_rec( p, Gia_ObjChild1(pObj), vSuper );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_CollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ Vec_IntClear( vSuper );
+// Gia_CollectSuper_rec( p, pObj, vSuper );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin0(pObj)) );
+ Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin1(pObj)) );
+ }
+ else
+ Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) );
+
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintSignals( Gia_Man_t * p, int * pFreq, char * pStr )
+{
+ Vec_Int_t * vObjs;
+ int i, Counter = 0, nTotal = 0;
+ vObjs = Vec_IntAlloc( 100 );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ if ( pFreq[i] > 1 )
+ {
+ nTotal += pFreq[i];
+ Counter++;
+ }
+ printf( "%s (total = %d driven = %d)\n", pStr, Counter, nTotal );
+ Counter = 0;
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ if ( pFreq[i] > 1 )
+ {
+ printf( "%3d : Obj = %6d Refs = %6d Freq = %6d\n",
+ ++Counter, i, Gia_ObjRefs(p, Gia_ManObj(p,i)), pFreq[i] );
+ Vec_IntPush( vObjs, i );
+ }
+ Vec_IntFree( vObjs );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset )
+{
+ Vec_Int_t * vSuper;
+ Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp;
+ int i, k, Ent, * pSets, * pResets, * pEnables;
+ int nHaveSetReset = 0, nHaveEnable = 0;
+ assert( Gia_ManRegNum(p) > 0 );
+ pSets = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ pResets = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ vSuper = Vec_IntAlloc( 100 );
+ Gia_ManForEachRi( p, pFlop, i )
+ {
+ pNode = Gia_ObjFanin0(pFlop);
+ if ( !Gia_ObjIsAnd(pNode) )
+ continue;
+ // detect sets/resets
+ Gia_CollectSuper( p, pNode, vSuper );
+ if ( Gia_ObjFaninC0(pFlop) )
+ Vec_IntForEachEntry( vSuper, Ent, k )
+ pSets[Ent]++;
+ else
+ Vec_IntForEachEntry( vSuper, Ent, k )
+ pResets[Ent]++;
+ // detect enables
+ if ( !Gia_ObjIsMuxType(pNode) )
+ continue;
+ pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 );
+ pTemp = Gia_ObjRiToRo( p, pFlop );
+ if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp )
+ continue;
+ if ( !Gia_ObjFaninC0(pFlop) )
+ {
+ pObj0 = Gia_Not(pObj0);
+ pObj1 = Gia_Not(pObj1);
+ }
+ if ( Gia_IsComplement(pObjC) )
+ {
+ pObjC = Gia_Not(pObjC);
+ pTemp = pObj0;
+ pObj0 = pObj1;
+ pObj1 = pTemp;
+ }
+ // detect controls
+// Gia_CollectSuper( p, pObjC, vSuper );
+// Vec_IntForEachEntry( vSuper, Ent, k )
+// pEnables[Ent]++;
+ pEnables[Gia_ObjId(p, pObjC)]++;
+ nHaveEnable++;
+ }
+ Gia_ManForEachRi( p, pFlop, i )
+ {
+ pNode = Gia_ObjFanin0(pFlop);
+ if ( !Gia_ObjIsAnd(pNode) )
+ continue;
+ // detect sets/resets
+ Gia_CollectSuper( p, pNode, vSuper );
+ Vec_IntForEachEntry( vSuper, Ent, k )
+ if ( pSets[Ent] > 1 || pResets[Ent] > 1 )
+ {
+ nHaveSetReset++;
+ break;
+ }
+ }
+ Vec_IntFree( vSuper );
+ Gia_ManCreateRefs( p );
+ printf( "Flops with set/reset = %6d. Flops with enable = %6d.\n", nHaveSetReset, nHaveEnable );
+ if ( fSetReset )
+ {
+ Gia_ManPrintSignals( p, pSets, "Set signals" );
+ Gia_ManPrintSignals( p, pResets, "Reset signals" );
+ }
+ Gia_ManPrintSignals( p, pEnables, "Enable signals" );
+ ABC_FREE( p->pRefs );
+ ABC_FREE( pSets );
+ ABC_FREE( pResets );
+ ABC_FREE( pEnables );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
new file mode 100644
index 00000000..9e190da3
--- /dev/null
+++ b/src/aig/gia/giaEquiv.c
@@ -0,0 +1,618 @@
+/**CFile****************************************************************
+
+ FileName [giaEquiv.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Manipulation of equivalence classes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaEquiv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Given representatives, derives pointers to the next objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManDeriveNexts( Gia_Man_t * p )
+{
+ unsigned * pNexts, * pTails;
+ int i;
+ assert( p->pReprs );
+ pNexts = ABC_CALLOC( unsigned, Gia_ManObjNum(p) );
+ pTails = ABC_ALLOC( unsigned, Gia_ManObjNum(p) );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ pTails[i] = i;
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID )
+ continue;
+ pNexts[ pTails[p->pReprs[i].iRepr] ] = i;
+ pTails[p->pReprs[i].iRepr] = i;
+ }
+ ABC_FREE( pTails );
+ return (int *)pNexts;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEquivCountOne( Gia_Man_t * p, int i )
+{
+ int Ent, nLits = 1;
+ Gia_ClassForEachObj1( p, i, Ent )
+ {
+ assert( Gia_ObjRepr(p, Ent) == i );
+ nLits++;
+ }
+ return nLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter )
+{
+ int Ent;
+ printf( "Class %4d : Num = %2d {", Counter, Gia_ManEquivCountOne(p, i) );
+ Gia_ClassForEachObj( p, i, Ent )
+ {
+ printf(" %d", Ent );
+ if ( p->pReprs[Ent].fColorA || p->pReprs[Ent].fColorB )
+ printf(" <%d%d>", p->pReprs[Ent].fColorA, p->pReprs[Ent].fColorB );
+ }
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEquivCountLitsAll( Gia_Man_t * p )
+{
+ int i, nLits = 0;
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ nLits += (Gia_ObjRepr(p, i) != GIA_VOID);
+ return nLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEquivCheckLits( Gia_Man_t * p, int nLits )
+{
+ int nLitsReal = Gia_ManEquivCountLitsAll( p );
+ if ( nLitsReal != nLits )
+ printf( "Detected a mismatch in counting equivalence classes (%d).\n", nLitsReal - nLits );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
+{
+ int i, Counter = 0, Counter1 = 0, CounterX = 0, Proved = 0, nLits;
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( Gia_ObjIsHead(p, i) )
+ Counter++;
+ else if ( Gia_ObjIsConst(p, i) )
+ Counter1++;
+ else if ( Gia_ObjIsNone(p, i) )
+ CounterX++;
+ if ( Gia_ObjProved(p, i) )
+ Proved++;
+ }
+ CounterX -= Gia_ManCoNum(p);
+ nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
+ printf( "cls =%7d cst =%8d lit =%8d unused =%8d proof =%6d mem =%5.2f Mb\n",
+ Counter, Counter1, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
+ assert( Gia_ManEquivCheckLits( p, nLits ) );
+ if ( fVerbose )
+ {
+ Counter = 0;
+ Gia_ManForEachClass( p, i )
+ Gia_ManEquivPrintOne( p, i, ++Counter );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns representative node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
+ return NULL;
+ return Gia_ManObj( p, Gia_ObjRepr(p, Gia_ObjId(p,pObj)) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pRepr;
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( (pRepr = Gia_ManEquivRepr(p, pObj)) )
+ {
+ Gia_ManEquivReduce_rec( pNew, p, pRepr );
+ pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ return;
+ }
+ Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG using equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj, * pRepr;
+ int i;
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_ManAppendCi(pNew);
+ if ( (pRepr = Gia_ManEquivRepr(p, pObj)) )
+ pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ }
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG using equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivFixOutputPairs( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj0, * pObj1;
+ int i;
+ assert( (Gia_ManPoNum(p) & 1) == 0 );
+ Gia_ManForEachPo( p, pObj0, i )
+ {
+ pObj1 = Gia_ManPo( p, ++i );
+ if ( Gia_ObjChild0(pObj0) != Gia_ObjChild0(pObj1) )
+ continue;
+ pObj0->iDiff0 = Gia_ObjId(p, pObj0);
+ pObj0->fCompl0 = 0;
+ pObj1->iDiff0 = Gia_ObjId(p, pObj1);
+ pObj1->fCompl0 = 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes pointers to the unmarked nodes..]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivUpdatePointers( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ Gia_Obj_t * pObj, * pObjNew;
+ int i;
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( !~pObj->Value )
+ continue;
+ pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) );
+ if ( pObjNew->fMark0 )
+ pObj->Value = ~0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes pointers to the unmarked nodes..]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivDeriveReprs( Gia_Man_t * p, Gia_Man_t * pNew, Gia_Man_t * pFinal )
+{
+ Vec_Int_t * vClass;
+ Gia_Obj_t * pObj, * pObjNew;
+ int i, k, iNode, iRepr, iPrev;
+ // start representatives
+ pFinal->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pFinal) );
+ for ( i = 0; i < Gia_ManObjNum(pFinal); i++ )
+ Gia_ObjSetRepr( pFinal, i, GIA_VOID );
+ // iterate over constant candidates
+ Gia_ManForEachConst( p, i )
+ {
+ pObj = Gia_ManObj( p, i );
+ if ( !~pObj->Value )
+ continue;
+ pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) );
+ if ( Gia_Lit2Var(pObjNew->Value) == 0 )
+ continue;
+ Gia_ObjSetRepr( pFinal, Gia_Lit2Var(pObjNew->Value), 0 );
+ }
+ // iterate over class candidates
+ vClass = Vec_IntAlloc( 100 );
+ Gia_ManForEachClass( p, i )
+ {
+ Vec_IntClear( vClass );
+ Gia_ClassForEachObj( p, i, k )
+ {
+ pObj = Gia_ManObj( p, k );
+ if ( !~pObj->Value )
+ continue;
+ pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) );
+ Vec_IntPushUnique( vClass, Gia_Lit2Var(pObjNew->Value) );
+ }
+ if ( Vec_IntSize( vClass ) < 2 )
+ continue;
+ Vec_IntSort( vClass, 0 );
+ iRepr = iPrev = Vec_IntEntry( vClass, 0 );
+ Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
+ {
+ Gia_ObjSetRepr( pFinal, iNode, iRepr );
+ assert( iPrev < iNode );
+ iPrev = iNode;
+ }
+ }
+ Vec_IntFree( vClass );
+ pFinal->pNexts = Gia_ManDeriveNexts( pFinal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG while remapping equivalence classes.]
+
+ Description [Drops the pairs of outputs if they are proved equivalent.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs )
+{
+ Gia_Man_t * pNew, * pFinal;
+ pNew = Gia_ManEquivReduce( p );
+ if ( fMiterPairs )
+ Gia_ManEquivFixOutputPairs( pNew );
+ if ( fSeq )
+ Gia_ManSeqMarkUsed( pNew );
+ else
+ Gia_ManCombMarkUsed( pNew );
+ Gia_ManEquivUpdatePointers( p, pNew );
+ pFinal = Gia_ManDupMarked( pNew );
+ Gia_ManEquivDeriveReprs( p, pNew, pFinal );
+ Gia_ManStop( pNew );
+ return pFinal;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks CIs/COs/ANDs unreachable from POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEquivSetColor_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fOdds )
+{
+ if ( Gia_ObjVisitColor( p, Gia_ObjId(p,pObj), fOdds ) )
+ return 0;
+ if ( Gia_ObjIsRo(p, pObj) )
+ return 1 + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj)), fOdds );
+ assert( Gia_ObjIsAnd(pObj) );
+ return 1 + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), fOdds )
+ + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin1(pObj), fOdds );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks CIs/COs/ANDs unreachable from POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose )
+{
+ Gia_Obj_t * pObj;
+ int i, nNodes[2] = {0,0}, nDiffs[2];
+ assert( (Gia_ManPoNum(p) & 1) == 0 );
+ Gia_ObjSetColors( p, 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetColors( p, Gia_ObjId(p,pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ nNodes[i&1] += Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), i&1 );
+// Gia_ManForEachObj( p, pObj, i )
+// if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) )
+// assert( Gia_ObjColors(p, i) );
+ nDiffs[0] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[0]);
+ nDiffs[1] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[1]);
+ if ( fVerbose )
+ {
+ printf( "CI+AND = %7d A = %7d B = %7d Ad = %7d Bd = %7d AB = %7d.\n",
+ Gia_ManCiNum(p) + Gia_ManAndNum(p),
+ Gia_ManPiNum(p) + nNodes[0], Gia_ManPiNum(p) + nNodes[1],
+ nDiffs[0], nDiffs[1],
+ Gia_ManCiNum(p) + Gia_ManAndNum(p) - nDiffs[0] - nDiffs[1] );
+ }
+ return (nDiffs[0] + nDiffs[1]) / 2;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits )
+{
+ Gia_Obj_t * pRepr;
+ int iLitNew;
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits );
+ Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ return;
+ iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ if ( pObj->Value != (unsigned)iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) );
+ pObj->Value = iLitNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG using equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ Vec_Int_t * vXorLits;
+ int i, iLitNew;
+ if ( !p->pReprs )
+ return NULL;
+ vXorLits = Vec_IntAlloc( 1000 );
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ continue;
+ iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ if ( pObj->Value != (unsigned)iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) );
+ pObj->Value = iLitNew;
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits );
+ Vec_IntForEachEntry( vXorLits, iLitNew, i )
+ Gia_ManAppendCo( pNew, iLitNew );
+ if ( Vec_IntSize(vXorLits) == 0 )
+ {
+ printf( "Speculatively reduced model has no primary outputs.\n" );
+ Gia_ManAppendCo( pNew, 0 );
+ }
+ Gia_ManForEachRi( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntFree( vXorLits );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms equiv classes by removing the AB nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose )
+{
+ extern void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass );
+ Vec_Int_t * vClass, * vClassNew;
+ int iRepr, iNode, Ent, k;
+ int nRemovedLits = 0, nRemovedClas = 0;
+ int nTotalLits = 0, nTotalClas = 0;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pReprs && p->pNexts );
+ vClass = Vec_IntAlloc( 100 );
+ vClassNew = Vec_IntAlloc( 100 );
+ Gia_ManForEachObj( p, pObj, i )
+ if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) )
+ assert( Gia_ObjColors(p, i) );
+ Gia_ManForEachClassReverse( p, iRepr )
+ {
+ nTotalClas++;
+ Vec_IntClear( vClass );
+ Vec_IntClear( vClassNew );
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ {
+ nTotalLits++;
+ Vec_IntPush( vClass, iNode );
+ assert( Gia_ObjColors(p, iNode) );
+ if ( Gia_ObjColors(p, iNode) != 3 )
+ Vec_IntPush( vClassNew, iNode );
+ else
+ nRemovedLits++;
+ }
+ Vec_IntForEachEntry( vClass, Ent, k )
+ {
+ p->pReprs[Ent].fFailed = p->pReprs[Ent].fProved = 0;
+ p->pReprs[Ent].iRepr = GIA_VOID;
+ p->pNexts[Ent] = 0;
+ }
+ if ( Vec_IntSize(vClassNew) < 2 )
+ {
+ nRemovedClas++;
+ continue;
+ }
+ Cec_ManSimClassCreate( p, vClassNew );
+ }
+ Vec_IntFree( vClass );
+ Vec_IntFree( vClassNew );
+ if ( fVerbose )
+ printf( "Removed classes = %6d (out of %6d). Removed literals = %6d (out of %6d).\n",
+ nRemovedClas, nTotalClas, nRemovedLits, nTotalLits );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c
index c2d2d33f..cf4c4aa5 100644
--- a/src/aig/gia/giaForce.c
+++ b/src/aig/gia/giaForce.c
@@ -23,47 +23,100 @@
/*
The code is based on the paper by F. A. Aloul, I. L. Markov, and K. A. Sakallah.
"FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03.
+ http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-typedef struct For_Obj_t_ For_Obj_t;
-struct For_Obj_t_
+typedef struct Frc_Obj_t_ Frc_Obj_t;
+struct Frc_Obj_t_
{
- int iObj;
- float lNode;
+ unsigned fCi : 1; // terminal node CI
+ unsigned fCo : 1; // terminal node CO
+ unsigned fMark0 : 1; // first user-controlled mark
+ unsigned fMark1 : 1; // second user-controlled mark
+ unsigned nFanins : 28; // the number of fanins
+ unsigned nFanouts; // the number of fanouts
+ unsigned iFanout; // the current number of fanouts
+ int hHandle; // the handle of the node
+ int pPlace; // the placement of each node
+ union {
+ float fEdgeCenter; // center-of-gravity of the edge
+ unsigned iFanin;
+ };
+ int Fanios[0]; // the array of fanins/fanouts
};
-typedef struct For_Man_t_ For_Man_t;
-struct For_Man_t_
+typedef struct Frc_Man_t_ Frc_Man_t;
+struct Frc_Man_t_
{
Gia_Man_t * pGia; // the original AIG manager
+ Vec_Int_t * vCis; // the vector of CIs (PIs + LOs)
+ Vec_Int_t * vCos; // the vector of COs (POs + LIs)
int nObjs; // the number of objects
- int iObj; // the last added object
- int * pPlace; // coordinates of objects
- int * piNext; // array of next pointers
- int * piRoot; // array of root pointers
- float * plEdge; // edge coordinates
- For_Obj_t * pNodes; // the array of nodes
+ int nRegs; // the number of registers
+ int * pObjData; // the array containing data for objects
+ int nObjData; // the size of array to store the logic network
+ int fVerbose; // verbose output flag
+ int nCutCur; // current cut
+ int nCutMax; // max cut seen
};
-static inline int Gia_ObjPlace( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjId(p->pGia, pObj)]; }
-static inline int Gia_ObjPlaceFanin0( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjFaninId0p(p->pGia, pObj)]; }
-static inline int Gia_ObjPlaceFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjFaninId1p(p->pGia, pObj)]; }
-
-static inline int Gia_ObjEdge( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjId(p->pGia, pObj)]; }
-static inline int Gia_ObjEdgeFanin0( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)]; }
-static inline int Gia_ObjEdgeFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjFaninId1p(p->pGia, pObj)]; }
+static inline int Frc_ManRegNum( Frc_Man_t * p ) { return p->nRegs; }
+static inline int Frc_ManCiNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCis); }
+static inline int Frc_ManCoNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCos); }
+static inline int Frc_ManPiNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCis) - p->nRegs; }
+static inline int Frc_ManPoNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCos) - p->nRegs; }
+static inline int Frc_ManObjNum( Frc_Man_t * p ) { return p->nObjs; }
+static inline int Frc_ManNodeNum( Frc_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos); }
+
+static inline Frc_Obj_t * Frc_ManObj( Frc_Man_t * p, int hHandle ) { return (Frc_Obj_t *)(p->pObjData + hHandle); }
+static inline Frc_Obj_t * Frc_ManCi( Frc_Man_t * p, int i ) { return Frc_ManObj( p, Vec_IntEntry(p->vCis,i) ); }
+static inline Frc_Obj_t * Frc_ManCo( Frc_Man_t * p, int i ) { return Frc_ManObj( p, Vec_IntEntry(p->vCos,i) ); }
+
+static inline int Frc_ObjIsTerm( Frc_Obj_t * pObj ) { return pObj->fCi || pObj->fCo; }
+static inline int Frc_ObjIsCi( Frc_Obj_t * pObj ) { return pObj->fCi; }
+static inline int Frc_ObjIsCo( Frc_Obj_t * pObj ) { return pObj->fCo; }
+static inline int Frc_ObjIsPi( Frc_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; }
+static inline int Frc_ObjIsPo( Frc_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; }
+static inline int Frc_ObjIsNode( Frc_Obj_t * pObj ) { return!Frc_ObjIsTerm(pObj) && pObj->nFanins > 0; }
+static inline int Frc_ObjIsConst0( Frc_Obj_t * pObj ) { return!Frc_ObjIsTerm(pObj) && pObj->nFanins == 0; }
+
+static inline int Frc_ObjSize( Frc_Obj_t * pObj ) { return sizeof(Frc_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; }
+static inline int Frc_ObjFaninNum( Frc_Obj_t * pObj ) { return pObj->nFanins; }
+static inline int Frc_ObjFanoutNum( Frc_Obj_t * pObj ) { return pObj->nFanouts; }
+static inline Frc_Obj_t * Frc_ObjFanin( Frc_Obj_t * pObj, int i ) { return (Frc_Obj_t *)(((int *)pObj) - pObj->Fanios[i]); }
+static inline Frc_Obj_t * Frc_ObjFanout( Frc_Obj_t * pObj, int i ) { return (Frc_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); }
+
+#define Frc_ManForEachObj( p, pObj, i ) \
+ for ( i = 0; (i < p->nObjData) && (pObj = Frc_ManObj(p,i)); i += Frc_ObjSize(pObj) )
+#define Frc_ManForEachObjVec( vVec, p, pObj, i ) \
+ for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Frc_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+
+#define Frc_ManForEachNode( p, pObj, i ) \
+ for ( i = 0; (i < p->nObjData) && (pObj = Frc_ManObj(p,i)); i += Frc_ObjSize(pObj) ) if ( Frc_ObjIsTerm(pObj) ) {} else
+#define Frc_ManForEachCi( p, pObj, i ) \
+ for ( i = 0; (i < Vec_IntSize(p->vCis)) && (pObj = Frc_ManObj(p,Vec_IntEntry(p->vCis,i))); i++ )
+#define Frc_ManForEachCo( p, pObj, i ) \
+ for ( i = 0; (i < Vec_IntSize(p->vCos)) && (pObj = Frc_ManObj(p,Vec_IntEntry(p->vCos,i))); i++ )
+
+#define Frc_ObjForEachFanin( pObj, pNext, i ) \
+ for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Frc_ObjFanin(pObj,i)); i++ )
+#define Frc_ObjForEachFaninReverse( pObj, pNext, i ) \
+ for ( i = (int)pObj->nFanins - 1; (i >= 0) && (pNext = Frc_ObjFanin(pObj,i)); i-- )
+#define Frc_ObjForEachFanout( pObj, pNext, i ) \
+ for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Frc_ObjFanout(pObj,i)); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
+
/**Function*************************************************************
- Synopsis []
+ Synopsis [Creates fanin/fanout pair.]
Description []
@@ -72,23 +125,128 @@ static inline int Gia_ObjEdgeFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { retu
SeeAlso []
***********************************************************************/
-For_Man_t * For_ManStart( Gia_Man_t * pGia )
+void Frc_ObjAddFanin( Frc_Obj_t * pObj, Frc_Obj_t * pFanin )
+{
+ assert( pObj->iFanin < pObj->nFanins );
+ assert( pFanin->iFanout < pFanin->nFanouts );
+ pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] =
+ pObj->Fanios[pObj->iFanin++] = pObj->hHandle - pFanin->hHandle;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates logic network isomorphic to the given AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Frc_Man_t * Frc_ManStartSimple( Gia_Man_t * pGia )
{
- For_Man_t * p;
- p = ABC_CALLOC( For_Man_t, 1 );
- p->pGia = pGia;
- p->nObjs = Gia_ManObjNum(pGia);
- p->pPlace = ABC_ALLOC( int, p->nObjs );
- p->piNext = ABC_ALLOC( int, p->nObjs );
- p->piRoot = ABC_ALLOC( int, p->nObjs );
- p->plEdge = ABC_ALLOC( float, p->nObjs );
- p->pNodes = ABC_ALLOC( For_Obj_t, p->nObjs );
+ Frc_Man_t * p;
+ Frc_Obj_t * pObjLog, * pFanLog;
+ Gia_Obj_t * pObj;//, * pObjRi, * pObjRo;
+ int i, nNodes, hHandle = 0;
+ // prepare the AIG
+ Gia_ManCreateRefs( pGia );
+ // create logic network
+ p = ABC_CALLOC( Frc_Man_t, 1 );
+ p->pGia = pGia;
+ p->nRegs = Gia_ManRegNum(pGia);
+ p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) );
+ p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) );
+ p->nObjData = (sizeof(Frc_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia));
+ p->pObjData = ABC_CALLOC( int, p->nObjData );
+ // create constant node
+ Gia_ManConst0(pGia)->Value = hHandle;
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 0;
+ pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) );
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ nNodes = 1;
+ p->nObjs++;
+ // create the PIs
+ Gia_ManForEachCi( pGia, pObj, i )
+ {
+ // create PI object
+ pObj->Value = hHandle;
+ Vec_IntPush( p->vCis, hHandle );
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 0;
+ pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj );
+ pObjLog->fCi = 0;
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ p->nObjs++;
+ }
+ // create internal nodes
+ Gia_ManForEachAnd( pGia, pObj, i )
+ {
+ assert( Gia_ObjRefs( pGia, pObj ) > 0 );
+ // create node object
+ pObj->Value = hHandle;
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 2;
+ pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj );
+ // add fanins
+ pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
+ Frc_ObjAddFanin( pObjLog, pFanLog );
+ pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin1(pObj)) );
+ Frc_ObjAddFanin( pObjLog, pFanLog );
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ nNodes++;
+ p->nObjs++;
+ }
+ // create the POs
+ Gia_ManForEachCo( pGia, pObj, i )
+ {
+ // create PO object
+ pObj->Value = hHandle;
+ Vec_IntPush( p->vCos, hHandle );
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 1;
+ pObjLog->nFanouts = 0;
+ pObjLog->fCo = 1;
+ // add fanins
+ pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
+ Frc_ObjAddFanin( pObjLog, pFanLog );
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ p->nObjs++;
+ }
+ // connect registers
+// Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, i )
+// Frc_ObjAddFanin( Frc_ManObj(p,Gia_ObjValue(pObjRo)), Frc_ManObj(p,Gia_ObjValue(pObjRi)) );
+ assert( nNodes == Frc_ManNodeNum(p) );
+ assert( hHandle == p->nObjData );
+ if ( hHandle != p->nObjData )
+ printf( "Frc_ManStartSimple(): Fatal error in internal representation.\n" );
+ // make sure the fanin/fanout counters are correct
+ Gia_ManForEachObj( pGia, pObj, i )
+ {
+ if ( !~Gia_ObjValue(pObj) )
+ continue;
+ pObjLog = Frc_ManObj( p, Gia_ObjValue(pObj) );
+ assert( pObjLog->nFanins == pObjLog->iFanin );
+ assert( pObjLog->nFanouts == pObjLog->iFanout );
+ pObjLog->iFanin = pObjLog->iFanout = 0;
+ }
+ ABC_FREE( pGia->pRefs );
return p;
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Collect the fanin IDs.]
Description []
@@ -97,19 +255,50 @@ For_Man_t * For_ManStart( Gia_Man_t * pGia )
SeeAlso []
***********************************************************************/
-void For_ManStop( For_Man_t * p )
+void Frc_ManCollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper, Vec_Int_t * vVisit )
{
- ABC_FREE( p->pPlace );
- ABC_FREE( p->piNext );
- ABC_FREE( p->piRoot );
- ABC_FREE( p->plEdge );
- ABC_FREE( p->pNodes );
- ABC_FREE( p );
+ if ( pObj->fMark1 )
+ return;
+ pObj->fMark1 = 1;
+ Vec_IntPush( vVisit, Gia_ObjId(p, pObj) );
+ if ( pObj->fMark0 )
+ {
+ Vec_IntPush( vSuper, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Frc_ManCollectSuper_rec( p, Gia_ObjFanin0(pObj), vSuper, vVisit );
+ Frc_ManCollectSuper_rec( p, Gia_ObjFanin1(pObj), vSuper, vVisit );
+
}
/**Function*************************************************************
- Synopsis [Derives random ordering of nodes.]
+ Synopsis [Collect the fanin IDs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Frc_ManCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper, Vec_Int_t * vVisit )
+{
+ int Entry, i;
+ Vec_IntClear( vSuper );
+ Vec_IntClear( vVisit );
+ assert( pObj->fMark0 == 1 );
+ pObj->fMark0 = 0;
+ Frc_ManCollectSuper_rec( p, pObj, vSuper, vVisit );
+ pObj->fMark0 = 1;
+ Vec_IntForEachEntry( vVisit, Entry, i )
+ Gia_ManObj(p, Entry)->fMark1 = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns references while removing the MUX/XOR ones.]
Description []
@@ -118,24 +307,44 @@ void For_ManStop( For_Man_t * p )
SeeAlso []
***********************************************************************/
-void For_ManSetInitPlaceRandom( For_Man_t * p )
+void Frc_ManCreateRefsSpecial( Gia_Man_t * p )
{
- int i, Temp, iNext;
- Aig_ManRandom( 1 );
- for ( i = 0; i < p->nObjs; i++ )
- p->pPlace[i] = i;
- for ( i = 0; i < p->nObjs; i++ )
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ Gia_Obj_t * pObjC, * pObjD0, * pObjD1;
+ int i;
+ assert( p->pRefs == NULL );
+ Gia_ManCleanMark0( p );
+ Gia_ManCreateRefs( p );
+ Gia_ManForEachAnd( p, pObj, i )
{
- iNext = Aig_ManRandom( 0 ) % p->nObjs;
- Temp = p->pPlace[i];
- p->pPlace[i] = p->pPlace[iNext];
- p->pPlace[iNext] = Temp;
+ assert( pObj->fMark0 == 0 );
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ // skip nodes whose fanins are PIs or are already marked
+ if ( Gia_ObjIsCi(pFan0) || pFan0->fMark0 ||
+ Gia_ObjIsCi(pFan1) || pFan1->fMark0 )
+ continue;
+ // skip nodes that are not MUX type
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ // the node is MUX type, mark it and its fanins
+ pObj->fMark0 = 1;
+ pFan0->fMark0 = 1;
+ pFan1->fMark0 = 1;
+ // deref the control
+ pObjC = Gia_ObjRecognizeMux( pObj, &pObjD1, &pObjD0 );
+ Gia_ObjRefDec( p, Gia_Regular(pObjC) );
+ if ( Gia_Regular(pObjD0) == Gia_Regular(pObjD1) )
+ Gia_ObjRefDec( p, Gia_Regular(pObjD0) );
}
+ Gia_ManForEachAnd( p, pObj, i )
+ assert( Gia_ObjRefs(p, pObj) > 0 );
+ Gia_ManCleanMark0( p );
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Assigns references while removing the MUX/XOR ones.]
Description []
@@ -144,39 +353,196 @@ void For_ManSetInitPlaceRandom( For_Man_t * p )
SeeAlso []
***********************************************************************/
-void For_ManSetInitPlaceDfs_rec( For_Man_t * p, Gia_Obj_t * pObj, int fRev )
+void Frc_ManTransformRefs( Gia_Man_t * p, int * pnObjs, int * pnFanios )
{
- if ( pObj->fMark0 )
- return;
- pObj->fMark0 = 1;
- if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) )
+ Vec_Int_t * vSuper, * vVisit;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k, Counter;
+ assert( p->pRefs != NULL );
+
+ // mark nodes to be used in the logic network
+ Gia_ManCleanMark0( p );
+ Gia_ManConst0(p)->fMark0 = 1;
+ // mark the inputs
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->fMark0 = 1;
+ // mark those nodes that have ref count more than 1
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->fMark0 = (Gia_ObjRefs(p, pObj) > 1);
+ // mark the output drivers
+ Gia_ManForEachCoDriver( p, pObj, i )
+ pObj->fMark0 = 1;
+
+ // count the number of nodes
+ Counter = 0;
+ Gia_ManForEachObj( p, pObj, i )
+ Counter += pObj->fMark0;
+ *pnObjs = Counter + Gia_ManCoNum(p);
+
+ // reset the references
+ ABC_FREE( p->pRefs );
+ p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ // reference from internal nodes
+ Counter = 0;
+ vSuper = Vec_IntAlloc( 100 );
+ vVisit = Vec_IntAlloc( 100 );
+ Gia_ManCleanMark1( p );
+ Gia_ManForEachAnd( p, pObj, i )
{
- p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++;
- return;
+ if ( pObj->fMark0 == 0 )
+ continue;
+ Frc_ManCollectSuper( p, pObj, vSuper, vVisit );
+ Gia_ManForEachObjVec( vSuper, p, pFanin, k )
+ {
+ assert( pFanin->fMark0 );
+ Gia_ObjRefInc( p, pFanin );
+ }
+ Counter += Vec_IntSize( vSuper );
}
- if ( Gia_ObjIsCo(pObj) )
+ Gia_ManCheckMark1( p );
+ Vec_IntFree( vSuper );
+ Vec_IntFree( vVisit );
+ // reference from outputs
+ Gia_ManForEachCoDriver( p, pObj, i )
{
- For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev );
- p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++;
- return;
+ assert( pObj->fMark0 );
+ Gia_ObjRefInc( p, pObj );
}
- assert( Gia_ObjIsAnd(pObj) );
- if ( fRev )
+ *pnFanios = Counter + Gia_ManCoNum(p);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates logic network isomorphic to the given AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Frc_Man_t * Frc_ManStart( Gia_Man_t * pGia )
+{
+ Frc_Man_t * p;
+ Frc_Obj_t * pObjLog, * pFanLog;
+ Gia_Obj_t * pObj, * pFanin;//, * pObjRi, * pObjRo;
+ Vec_Int_t * vSuper, * vVisit;
+ int nObjs, nFanios, nNodes = 0;
+ int i, k, hHandle = 0;
+ // prepare the AIG
+// Gia_ManCreateRefs( pGia );
+ Frc_ManCreateRefsSpecial( pGia );
+ Frc_ManTransformRefs( pGia, &nObjs, &nFanios );
+ Gia_ManFillValue( pGia );
+ // create logic network
+ p = ABC_CALLOC( Frc_Man_t, 1 );
+ p->pGia = pGia;
+ p->nRegs = Gia_ManRegNum(pGia);
+ p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) );
+ p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) );
+ p->nObjData = (sizeof(Frc_Obj_t) / 4) * nObjs + 2 * nFanios;
+ p->pObjData = ABC_CALLOC( int, p->nObjData );
+ // create constant node
+ Gia_ManConst0(pGia)->Value = hHandle;
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 0;
+ pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) );
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ nNodes++;
+ p->nObjs++;
+ // create the PIs
+ Gia_ManForEachCi( pGia, pObj, i )
{
- For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin1(pObj), fRev );
- For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev );
+ // create PI object
+ pObj->Value = hHandle;
+ Vec_IntPush( p->vCis, hHandle );
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 0;
+ pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj );
+ pObjLog->fCi = 1;
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ p->nObjs++;
}
- else
+ // create internal nodes
+ vSuper = Vec_IntAlloc( 100 );
+ vVisit = Vec_IntAlloc( 100 );
+ Gia_ManForEachAnd( pGia, pObj, i )
{
- For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev );
- For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin1(pObj), fRev );
+ if ( pObj->fMark0 == 0 )
+ {
+ assert( Gia_ObjRefs( pGia, pObj ) == 0 );
+ continue;
+ }
+ assert( Gia_ObjRefs( pGia, pObj ) > 0 );
+ Frc_ManCollectSuper( pGia, pObj, vSuper, vVisit );
+ // create node object
+ pObj->Value = hHandle;
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = Vec_IntSize( vSuper );
+ pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj );
+ // add fanins
+ Gia_ManForEachObjVec( vSuper, pGia, pFanin, k )
+ {
+ pFanLog = Frc_ManObj( p, Gia_ObjValue(pFanin) );
+ Frc_ObjAddFanin( pObjLog, pFanLog );
+ }
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ nNodes++;
+ p->nObjs++;
+ }
+ Vec_IntFree( vSuper );
+ Vec_IntFree( vVisit );
+ // create the POs
+ Gia_ManForEachCo( pGia, pObj, i )
+ {
+ // create PO object
+ pObj->Value = hHandle;
+ Vec_IntPush( p->vCos, hHandle );
+ pObjLog = Frc_ManObj( p, hHandle );
+ pObjLog->hHandle = hHandle;
+ pObjLog->nFanins = 1;
+ pObjLog->nFanouts = 0;
+ pObjLog->fCo = 1;
+ // add fanins
+ pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
+ Frc_ObjAddFanin( pObjLog, pFanLog );
+ // count objects
+ hHandle += Frc_ObjSize( pObjLog );
+ p->nObjs++;
}
- p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++;
+ // connect registers
+// Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, i )
+// Frc_ObjAddFanin( Frc_ManObj(p,Gia_ObjValue(pObjRo)), Frc_ManObj(p,Gia_ObjValue(pObjRi)) );
+ Gia_ManCleanMark0( pGia );
+ assert( nNodes == Frc_ManNodeNum(p) );
+ assert( nObjs == p->nObjs );
+ assert( hHandle == p->nObjData );
+ if ( hHandle != p->nObjData )
+ printf( "Frc_ManStart(): Fatal error in internal representation.\n" );
+ // make sure the fanin/fanout counters are correct
+ Gia_ManForEachObj( pGia, pObj, i )
+ {
+ if ( !~Gia_ObjValue(pObj) )
+ continue;
+ pObjLog = Frc_ManObj( p, Gia_ObjValue(pObj) );
+ assert( pObjLog->nFanins == pObjLog->iFanin );
+ assert( pObjLog->nFanouts == pObjLog->iFanout );
+ pObjLog->iFanin = pObjLog->iFanout = 0;
+ }
+ ABC_FREE( pGia->pRefs );
+ return p;
}
/**Function*************************************************************
- Synopsis [Derives DFS ordering of nodes.]
+ Synopsis [Creates logic network isomorphic to the given AIG.]
Description []
@@ -185,25 +551,25 @@ void For_ManSetInitPlaceDfs_rec( For_Man_t * p, Gia_Obj_t * pObj, int fRev )
SeeAlso []
***********************************************************************/
-void For_ManSetInitPlaceDfs( For_Man_t * p, int fRev )
+void Frc_ManPrintStats( Frc_Man_t * p )
{
- Gia_Obj_t * pObj;
- int i;
- p->iObj = 0;
- Gia_ManCleanMark0( p->pGia );
- For_ManSetInitPlaceDfs_rec( p, Gia_ManConst0(p->pGia), fRev );
- Gia_ManForEachCo( p->pGia, pObj, i )
- For_ManSetInitPlaceDfs_rec( p, pObj, fRev );
- Gia_ManForEachCi( p->pGia, pObj, i )
- if ( pObj->fMark0 == 0 )
- For_ManSetInitPlaceDfs_rec( p, pObj, fRev );
- assert( p->iObj == p->nObjs );
- Gia_ManCleanMark0( p->pGia );
+// if ( p->pName )
+// printf( "%8s : ", p->pName );
+ printf( "i/o =%7d/%7d ", Frc_ManPiNum(p), Frc_ManPoNum(p) );
+ if ( Frc_ManRegNum(p) )
+ printf( "ff =%7d ", Frc_ManRegNum(p) );
+ printf( "node =%8d ", Frc_ManNodeNum(p) );
+ printf( "obj =%8d ", Frc_ManObjNum(p) );
+// printf( "lev =%5d ", Frc_ManLevelNum(p) );
+// printf( "cut =%5d ", Frc_ManCrossCut(p) );
+ printf( "mem =%5.2f Mb", 4.0*p->nObjData/(1<<20) );
+// printf( "obj =%5d ", Frc_ManObjNum(p) );
+ printf( "\n" );
}
/**Function*************************************************************
- Synopsis [Computes span for the given placement.]
+ Synopsis [Creates logic network isomorphic to the given AIG.]
Description []
@@ -212,29 +578,72 @@ void For_ManSetInitPlaceDfs( For_Man_t * p, int fRev )
SeeAlso []
***********************************************************************/
-double For_ManGetEdgeSpan( For_Man_t * p )
+void Frc_ManStop( Frc_Man_t * p )
{
- double Result = 0.0;
- Gia_Obj_t * pObj;
- int i, Diff;
- Gia_ManForEachAnd( p->pGia, pObj, i )
+ Vec_IntFree( p->vCis );
+ Vec_IntFree( p->vCos );
+ ABC_FREE( p->pObjData );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes cross cut size for the given order of POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Frc_ManCrossCut_rec( Frc_Man_t * p, Frc_Obj_t * pObj )
+{
+ assert( pObj->iFanout > 0 );
+ if ( pObj->iFanout-- == pObj->nFanouts )
{
- Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin0(p, pObj);
- Result += (double)ABC_ABS(Diff);
- Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin1(p, pObj);
- Result += (double)ABC_ABS(Diff);
+ Frc_Obj_t * pFanin;
+ int i;
+ p->nCutCur++;
+ p->nCutMax = ABC_MAX( p->nCutMax, p->nCutCur );
+ if ( !Frc_ObjIsCi(pObj) )
+ Frc_ObjForEachFanin( pObj, pFanin, i )
+ p->nCutCur -= Frc_ManCrossCut_rec( p, pFanin );
}
- Gia_ManForEachCo( p->pGia, pObj, i )
+ return pObj->iFanout == 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes cross cut size for the given order of POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Frc_ManCrossCut2_rec( Frc_Man_t * p, Frc_Obj_t * pObj )
+{
+ assert( pObj->iFanout > 0 );
+ if ( pObj->iFanout-- == pObj->nFanouts )
{
- Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin0(p, pObj);
- Result += (double)ABC_ABS(Diff);
+ Frc_Obj_t * pFanin;
+ int i;
+ p->nCutCur++;
+ p->nCutMax = ABC_MAX( p->nCutMax, p->nCutCur );
+ if ( !Frc_ObjIsCi(pObj) )
+ Frc_ObjForEachFaninReverse( pObj, pFanin, i )
+ p->nCutCur -= Frc_ManCrossCut2_rec( p, pFanin );
}
- return Result;
+ return pObj->iFanout == 0;
}
/**Function*************************************************************
- Synopsis [Computes max cut of the given placement.]
+ Synopsis [Computes cross cut size for the given order of POs.]
Description []
@@ -243,68 +652,138 @@ double For_ManGetEdgeSpan( For_Man_t * p )
SeeAlso []
***********************************************************************/
-int For_ManGetMaxCut( For_Man_t * p )
+int Frc_ManCrossCut( Frc_Man_t * p, Vec_Int_t * vOrder, int fReverse )
{
- Gia_Obj_t * pObj;
- int i, iObj, iFan, * pTemp;
- int nCutCut, nCutMax;
- pTemp = ABC_CALLOC( int, p->nObjs );
- Gia_ManForEachAnd( p->pGia, pObj, i )
+ Frc_Obj_t * pObj;
+ int i;
+ assert( Vec_IntSize(vOrder) == Frc_ManCoNum(p) );
+ p->nCutCur = 0;
+ p->nCutMax = 0;
+ Frc_ManForEachObj( p, pObj, i )
+ pObj->iFanout = pObj->nFanouts;
+ Frc_ManForEachObjVec( vOrder, p, pObj, i )
{
- iObj = Gia_ObjPlace(p, pObj);
- iFan = Gia_ObjPlaceFanin0(p, pObj);
- if ( iObj < iFan )
- {
- pTemp[iObj]++;
- pTemp[iFan]--;
- }
- else
- {
- pTemp[iObj]--;
- pTemp[iFan]++;
- }
- iObj = Gia_ObjPlace(p, pObj);
- iFan = Gia_ObjPlaceFanin1(p, pObj);
- if ( iObj < iFan )
- {
- pTemp[iObj]++;
- pTemp[iFan]--;
- }
+ assert( Frc_ObjIsCo(pObj) );
+ if ( fReverse )
+ p->nCutCur -= Frc_ManCrossCut2_rec( p, Frc_ObjFanin(pObj,0) );
else
- {
- pTemp[iObj]--;
- pTemp[iFan]++;
- }
+ p->nCutCur -= Frc_ManCrossCut_rec( p, Frc_ObjFanin(pObj,0) );
}
- Gia_ManForEachCo( p->pGia, pObj, i )
+ assert( p->nCutCur == 0 );
+// Frc_ManForEachObj( p, pObj, i )
+// assert( pObj->iFanout == 0 );
+ return p->nCutMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects CO handles.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Frc_ManCollectCos( Frc_Man_t * p )
+{
+ Vec_Int_t * vCoOrder;
+ Frc_Obj_t * pObj;
+ int i;
+ vCoOrder = Vec_IntAlloc( Frc_ManCoNum(p) );
+ Frc_ManForEachCo( p, pObj, i )
+ Vec_IntPush( vCoOrder, pObj->hHandle );
+ return vCoOrder;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes cross cut size for the given order of POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Frc_ManCrossCutTest( Frc_Man_t * p, Vec_Int_t * vOrderInit )
+{
+ Vec_Int_t * vOrder;
+ int clk = clock();
+ vOrder = vOrderInit? vOrderInit : Frc_ManCollectCos( p );
+ printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 0 ) );
+ printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 1 ) );
+ Vec_IntReverseOrder( vOrder );
+ printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 0 ) );
+ printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 1 ) );
+ Vec_IntReverseOrder( vOrder );
+ if ( vOrder != vOrderInit )
+ Vec_IntFree( vOrder );
+// ABC_PRT( "Time", clock() - clk );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Generates random placement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Frc_ManPlaceRandom( Frc_Man_t * p )
+{
+ Frc_Obj_t * pThis;
+ int * pPlacement;
+ int i, h, Temp, iNext, Counter;
+ pPlacement = ABC_ALLOC( int, p->nObjs );
+ for ( i = 0; i < p->nObjs; i++ )
+ pPlacement[i] = i;
+ for ( i = 0; i < p->nObjs; i++ )
{
- iObj = Gia_ObjPlace(p, pObj);
- iFan = Gia_ObjPlaceFanin0(p, pObj);
- if ( iObj < iFan )
- {
- pTemp[iObj]++;
- pTemp[iFan]--;
- }
- else
- {
- pTemp[iObj]--;
- pTemp[iFan]++;
- }
+ iNext = Aig_ManRandom( 0 ) % p->nObjs;
+ Temp = pPlacement[i];
+ pPlacement[i] = pPlacement[iNext];
+ pPlacement[iNext] = Temp;
}
- nCutCut = nCutMax = 0;
- for ( i = 0; i < p->nObjs; i++ )
+ Counter = 0;
+ Frc_ManForEachObj( p, pThis, h )
+ pThis->pPlace = pPlacement[Counter++];
+ ABC_FREE( pPlacement );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Shuffles array of random integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Frc_ManArrayShuffle( Vec_Int_t * vArray )
+{
+ int i, iNext, Temp;
+ for ( i = 0; i < vArray->nSize; i++ )
{
- nCutCut += pTemp[i];
- nCutMax = ABC_MAX( nCutCut, nCutMax );
+ iNext = Aig_ManRandom( 0 ) % vArray->nSize;
+ Temp = vArray->pArray[i];
+ vArray->pArray[i] = vArray->pArray[iNext];
+ vArray->pArray[iNext] = Temp;
}
- ABC_FREE( pTemp );
- assert( nCutCut == 0 );
- return nCutMax;
}
/**Function*************************************************************
- Synopsis [Computes hyper-edge centers.]
+ Synopsis [Computes cross cut size for the given order of POs.]
Description []
@@ -313,31 +792,23 @@ int For_ManGetMaxCut( For_Man_t * p )
SeeAlso []
***********************************************************************/
-void For_ManEdgeCenters( For_Man_t * p )
+void Frc_ManPlaceDfs_rec( Frc_Man_t * p, Frc_Obj_t * pObj, int * piPlace )
{
- Gia_Obj_t * pObj;
- int i;
- memset( p->plEdge, 0, sizeof(float) * p->nObjs );
- Gia_ManForEachObj( p->pGia, pObj, i )
+ assert( pObj->iFanout > 0 );
+ if ( pObj->iFanout-- == pObj->nFanouts )
{
- p->plEdge[i] = Gia_ObjPlace(p, pObj);
- if ( Gia_ObjIsAnd(pObj) )
- {
- p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj);
- p->plEdge[Gia_ObjFaninId1p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj);
- }
- else if ( Gia_ObjIsCo(pObj) )
- {
- p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj);
- }
+ Frc_Obj_t * pFanin;
+ int i;
+ if ( !Frc_ObjIsCi(pObj) )
+ Frc_ObjForEachFanin( pObj, pFanin, i )
+ Frc_ManPlaceDfs_rec( p, pFanin, piPlace );
+ pObj->pPlace = (*piPlace)++;
}
- Gia_ManForEachObj( p->pGia, pObj, i )
- p->plEdge[i] /= 1.0 + Gia_ObjRefs( p->pGia, pObj );
}
/**Function*************************************************************
- Synopsis [Computes object centers.]
+ Synopsis [Generates DFS placement.]
Description []
@@ -346,30 +817,156 @@ void For_ManEdgeCenters( For_Man_t * p )
SeeAlso []
***********************************************************************/
-void For_ManObjCenters( For_Man_t * p )
+void Frc_ManPlaceDfs( Frc_Man_t * p, Vec_Int_t * vCoOrder )
{
- Gia_Obj_t * pObj;
- int i;
- Gia_ManForEachObj( p->pGia, pObj, i )
+ Frc_Obj_t * pObj;
+ int i, nPlaces = 0;
+ Frc_ManForEachObj( p, pObj, i )
{
- p->pNodes[i].lNode = Gia_ObjEdge(p, pObj);
- if ( Gia_ObjIsAnd(pObj) )
+ pObj->iFanout = pObj->nFanouts;
+ if ( pObj->nFanouts == 0 && !Frc_ObjIsCo(pObj) )
+ pObj->pPlace = nPlaces++;
+ }
+ Frc_ManForEachObjVec( vCoOrder, p, pObj, i )
+ {
+ assert( Frc_ObjIsCo(pObj) );
+ Frc_ManPlaceDfs_rec( p, Frc_ObjFanin(pObj,0), &nPlaces );
+ pObj->pPlace = nPlaces++;
+ }
+ assert( nPlaces == p->nObjs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generates DFS placement by trying both orders.]
+
+ Description [Returns the cross cut size of the best order. ]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Frc_ManPlaceDfsBoth( Frc_Man_t * p, Vec_Int_t * vCoOrder, int * piCutSize2 )
+{
+ int nCutStart1, nCutStart2;
+ nCutStart1 = Frc_ManCrossCut( p, vCoOrder, 0 );
+ Vec_IntReverseOrder( vCoOrder );
+ nCutStart2 = Frc_ManCrossCut( p, vCoOrder, 0 );
+ if ( nCutStart1 <= nCutStart2 )
+ {
+ Vec_IntReverseOrder( vCoOrder ); // undo
+ Frc_ManPlaceDfs( p, vCoOrder );
+ *piCutSize2 = nCutStart2;
+ return nCutStart1;
+ }
+ else
+ {
+ Frc_ManPlaceDfs( p, vCoOrder );
+ Vec_IntReverseOrder( vCoOrder ); // undo
+ *piCutSize2 = nCutStart1;
+ return nCutStart2;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs iterative refinement of the given placement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Frc_ManPlacementRefine( Frc_Man_t * p, int nIters, int fVerbose )
+{
+ int fRandomize = 0;
+ Vec_Int_t * vCoOrder;
+ Frc_Obj_t * pThis, * pNext;
+ double CostThis, CostPrev;
+ float * pVertX, VertX;
+ int * pPermX, * pHandles;
+ int k, h, Iter, iMinX, iMaxX, Counter, nCutStart, nCutCur, nCutCur2, nCutPrev;
+ int clk = clock(), clk2, clk2Total = 0;
+ // create starting one-dimensional placement
+ vCoOrder = Frc_ManCollectCos( p );
+ if ( fRandomize )
+ Frc_ManArrayShuffle( vCoOrder );
+ nCutStart = Frc_ManPlaceDfsBoth( p, vCoOrder, &nCutCur2 );
+ // refine placement
+ CostPrev = 0.0;
+ nCutPrev = nCutStart;
+ pHandles = ABC_ALLOC( int, p->nObjs );
+ pVertX = ABC_ALLOC( float, p->nObjs );
+ for ( Iter = 0; Iter < nIters; Iter++ )
+ {
+ // compute centers of hyperedges
+ CostThis = 0.0;
+ Frc_ManForEachObj( p, pThis, h )
+ {
+ iMinX = iMaxX = pThis->pPlace;
+ Frc_ObjForEachFanout( pThis, pNext, k )
+ {
+ iMinX = ABC_MIN( iMinX, pNext->pPlace );
+ iMaxX = ABC_MAX( iMaxX, pNext->pPlace );
+ }
+ pThis->fEdgeCenter = 0.5 * (iMaxX + iMinX);
+ CostThis += (iMaxX - iMinX);
+ }
+ // compute new centers of objects
+ Counter = 0;
+ Frc_ManForEachObj( p, pThis, h )
{
- p->pNodes[i].lNode += Gia_ObjEdgeFanin0(p, pObj);
- p->pNodes[i].lNode += Gia_ObjEdgeFanin1(p, pObj);
- p->pNodes[i].lNode /= 3.0;
+ VertX = pThis->fEdgeCenter;
+ Frc_ObjForEachFanin( pThis, pNext, k )
+ VertX += pNext->fEdgeCenter;
+ pVertX[Counter] = VertX / (Frc_ObjFaninNum(pThis) + 1);
+ pHandles[Counter++] = h;
}
- else if ( Gia_ObjIsCo(pObj) )
+ assert( Counter == Frc_ManObjNum(p) );
+ // sort these numbers
+ clk2 = clock();
+ pPermX = Gia_SortFloats( pVertX, pHandles, p->nObjs );
+ clk2Total += clock() - clk2;
+ assert( pPermX == pHandles );
+ Vec_IntClear( vCoOrder );
+ for ( k = 0; k < p->nObjs; k++ )
{
- p->pNodes[i].lNode += Gia_ObjEdgeFanin0(p, pObj);
- p->pNodes[i].lNode /= 2.0;
+ pThis = Frc_ManObj( p, pPermX[k] );
+ pThis->pPlace = k;
+ if ( Frc_ObjIsCo(pThis) )
+ Vec_IntPush( vCoOrder, pThis->hHandle );
}
+/*
+ printf( "Ordering of PIs:\n" );
+ Frc_ManForEachCi( p, pThis, k )
+ printf( "PI number = %7d. Object handle = %7d, Coordinate = %7d.\n",
+ k, pThis->hHandle, pThis->pPlace );
+*/
+ nCutCur = Frc_ManPlaceDfsBoth( p, vCoOrder, &nCutCur2 );
+ // evaluate cost
+ if ( fVerbose )
+ {
+ printf( "%2d : Span = %e ", Iter+1, CostThis );
+ printf( "Cut = %6d (%5.2f %%) CutR = %6d ", nCutCur, 100.0*(nCutStart-nCutCur)/nCutStart, nCutCur2 );
+ ABC_PRTn( "Total", clock() - clk );
+ ABC_PRT( "Sort", clk2Total );
+// Frc_ManCrossCutTest( p, vCoOrder );
+ }
+// if ( 1.0 * nCutPrev / nCutCur < 1.001 )
+// break;
+ nCutPrev = nCutCur;
}
+ ABC_FREE( pHandles );
+ ABC_FREE( pVertX );
+ Vec_IntFree( vCoOrder );
}
/**Function*************************************************************
- Synopsis [Sorts objects by their new centers.]
+ Synopsis [Returns 1 if all fanouts are COsw.]
Description []
@@ -378,65 +975,56 @@ void For_ManObjCenters( For_Man_t * p )
SeeAlso []
***********************************************************************/
-int For_ObjCompare( For_Obj_t ** pp0, For_Obj_t ** pp1 )
+int Frc_ObjFanoutsAreCos( Frc_Obj_t * pThis )
{
- if ( (*pp0)->lNode < (*pp1)->lNode )
- return -1;
- if ( (*pp0)->lNode > (*pp1)->lNode )
- return 1;
- return 0;
+ Frc_Obj_t * pNext;
+ int i;
+ Frc_ObjForEachFanout( pThis, pNext, i )
+ if ( !Frc_ObjIsCo(pNext) )
+ return 0;
+ return 1;
}
/**Function*************************************************************
- Synopsis [Sorts objects by their new centers.]
+ Synopsis [Computes the distances from the given set of objects.]
- Description []
+ Description [Returns one of the most distant objects.]
SideEffects []
SeeAlso []
-
+
***********************************************************************/
-void For_ManSortObjects( For_Man_t * p )
+void Frc_DumpGraphIntoFile( Frc_Man_t * p )
{
- For_Obj_t * pNode, * pPrev;
- Vec_Ptr_t * vArray;
- int i, k, iPlace;
- // link the nodes into lists by cost
- memset( p->piRoot, 0xff, sizeof(int) * p->nObjs );
- for ( i = 0; i < p->nObjs; i++ )
+ FILE * pFile;
+ Frc_Obj_t * pThis, * pNext;
+ int i, k, Counter = 0;
+ // assign numbers to CIs and internal nodes
+ Frc_ManForEachObj( p, pThis, i )
{
- p->pNodes[i].iObj = i;
- iPlace = (int)p->pNodes[i].lNode;
- assert( iPlace >= 0 && iPlace < p->nObjs );
- p->piNext[i] = p->piRoot[iPlace];
- p->piRoot[iPlace] = i;
+ if ( i && ((Frc_ObjIsCi(pThis) && !Frc_ObjFanoutsAreCos(pThis)) || Frc_ObjIsNode(pThis)) )
+ pThis->iFanin = Counter++;
+ else
+ pThis->iFanin = ~0;
}
- // reconstruct the order
- p->iObj = 0;
- pPrev = NULL;
- vArray = Vec_PtrAlloc( 100 );
- for ( i = 0; i < p->nObjs; i++ )
+ // assign numbers to all other nodes
+ pFile = fopen( "x\\large\\aig\\dg1.g", "w" );
+ Frc_ManForEachObj( p, pThis, i )
{
- Vec_PtrClear( vArray );
- for ( k = p->piRoot[i]; ~((unsigned)k); k = p->piNext[k] )
- Vec_PtrPush( vArray, p->pNodes + k );
- Vec_PtrSort( vArray, (int (*)())For_ObjCompare );
- Vec_PtrForEachEntry( vArray, pNode, k )
+ Frc_ObjForEachFanout( pThis, pNext, k )
{
- p->pPlace[ pNode->iObj ] = p->iObj++;
- assert( !pPrev || pPrev->lNode <= pNode->lNode );
- pPrev = pNode;
+ if ( ~pThis->iFanin && ~pNext->iFanin )
+ fprintf( pFile, "%d %d\n", pThis->iFanin, pNext->iFanin );
}
}
- Vec_PtrFree( vArray );
- assert( p->iObj == p->nObjs );
+ fclose( pFile );
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Experiment with the FORCE algorithm.]
Description []
@@ -445,33 +1033,25 @@ void For_ManSortObjects( For_Man_t * p )
SeeAlso []
***********************************************************************/
-void For_ManPlaceByForce( For_Man_t * p )
+void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose )
{
- int clk, Iter, fUseCut = 1;
- double iCostThis, iCostPrev;
- iCostThis = fUseCut? For_ManGetMaxCut(p) : For_ManGetEdgeSpan(p);
- printf( "Init = %12.0f. \n", iCostThis );
- Iter = 0;
- do {
- Iter++;
- iCostPrev = iCostThis;
-clk = clock();
- For_ManEdgeCenters( p );
-//ABC_PRT( "Time", clock() - clk );
-clk = clock();
- For_ManObjCenters( p );
-//ABC_PRT( "Time", clock() - clk );
-clk = clock();
- For_ManSortObjects( p );
-//ABC_PRT( "Time", clock() - clk );
- iCostThis = fUseCut? For_ManGetMaxCut(p) : For_ManGetEdgeSpan(p);
- printf( "%4d = %12.0f. \n", Iter, iCostThis );
- } while ( iCostPrev > iCostThis );
+ Frc_Man_t * p;
+ Aig_ManRandom( 1 );
+ if ( fClustered )
+ p = Frc_ManStart( pGia );
+ else
+ p = Frc_ManStartSimple( pGia );
+// Frc_DumpGraphIntoFile( p );
+ if ( fVerbose )
+ Frc_ManPrintStats( p );
+// Frc_ManCrossCutTest( p, NULL );
+ Frc_ManPlacementRefine( p, nIters, fVerbose );
+ Frc_ManStop( p );
}
/**Function*************************************************************
- Synopsis []
+ Synopsis [Experiment with the FORCE algorithm.]
Description []
@@ -480,51 +1060,40 @@ clk = clock();
SeeAlso []
***********************************************************************/
-void For_ManExperiment( Gia_Man_t * pGia )
+void For_ManFileExperiment()
{
- For_Man_t * p;
+ FILE * pFile;
+ int * pBuffer;
+ int i, Size, Exp = 25;
int clk = clock();
- p = For_ManStart( pGia );
- Gia_ManCreateRefs( pGia );
-
- // use DSF order
-clk = clock();
- For_ManSetInitPlaceDfs( p, 0 );
- printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) );
- printf( "Max span = %8d ", For_ManGetMaxCut(p) );
-ABC_PRT( "Time", clock() - clk );
-
-clk = clock();
- For_ManPlaceByForce( p );
-ABC_PRT( "Time", clock() - clk );
- // use modified DFS order
-clk = clock();
- For_ManSetInitPlaceDfs( p, 1 );
- printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) );
- printf( "Max span = %8d ", For_ManGetMaxCut(p) );
-ABC_PRT( "Time", clock() - clk );
+ Size = (1 << Exp);
+ printf( "2^%d machine words (%d bytes).\n", Exp, sizeof(int) * Size );
-clk = clock();
- For_ManPlaceByForce( p );
-ABC_PRT( "Time", clock() - clk );
+ pBuffer = ABC_ALLOC( int, Size );
+ for ( i = 0; i < Size; i++ )
+ pBuffer[i] = i;
+ABC_PRT( "Fillup", clock() - clk );
- // use random order
clk = clock();
- For_ManSetInitPlaceRandom( p );
- printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) );
- printf( "Max span = %8d ", For_ManGetMaxCut(p) );
-ABC_PRT( "Time", clock() - clk );
+ pFile = fopen( "test.txt", "rb" );
+ fread( pBuffer, 1, sizeof(int) * Size, pFile );
+ fclose( pFile );
+ABC_PRT( "Read ", clock() - clk );
clk = clock();
- For_ManPlaceByForce( p );
-ABC_PRT( "Time", clock() - clk );
-
- For_ManStop( p );
+ pFile = fopen( "test.txt", "wb" );
+ fwrite( pBuffer, 1, sizeof(int) * Size, pFile );
+ fclose( pFile );
+ABC_PRT( "Write ", clock() - clk );
+/*
+2^25 machine words (134217728 bytes).
+Fillup = 0.06 sec
+Read = 0.08 sec
+Write = 1.81 sec
+*/
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
+//////////////////////////////////////////////////////////////////////// \ No newline at end of file
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index e6e45cb5..95bffee8 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -68,8 +68,13 @@ void Gia_ManStop( Gia_Man_t * p )
{
Vec_IntFree( p->vCis );
Vec_IntFree( p->vCos );
+ ABC_FREE( p->pCexComb );
+ ABC_FREE( p->pIso );
+ ABC_FREE( p->pMapping );
ABC_FREE( p->pFanData );
+ ABC_FREE( p->pReprsOld );
ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
ABC_FREE( p->pName );
ABC_FREE( p->pRefs );
ABC_FREE( p->pLevels );
@@ -98,12 +103,16 @@ void Gia_ManPrintStats( Gia_Man_t * p )
printf( "ff =%7d ", Gia_ManRegNum(p) );
printf( "and =%8d ", Gia_ManAndNum(p) );
printf( "lev =%5d ", Gia_ManLevelNum(p) );
-// printf( "cut =%5d ", Gia_ManCrossCut(p) );
+ printf( "cut =%5d ", Gia_ManCrossCut(p) );
printf( "mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) );
// printf( "obj =%5d ", Gia_ManObjNum(p) );
printf( "\n" );
// Gia_ManSatExperiment( p );
+ if ( p->pReprs && p->pNexts )
+ Gia_ManEquivPrintClasses( p, 0, 0.0 );
+ if ( p->pMapping )
+ Gia_ManPrintMappingStats( p );
}
/**Function*************************************************************
diff --git a/src/aig/gia/giaMap.c b/src/aig/gia/giaMap.c
new file mode 100644
index 00000000..72bdb001
--- /dev/null
+++ b/src/aig/gia/giaMap.c
@@ -0,0 +1,305 @@
+/**CFile****************************************************************
+
+ FileName [giaMap.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Manipulation of mapping associated with the AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into FPGA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSetIfParsDefault( If_Par_t * pPars )
+{
+// extern void * Abc_FrameReadLibLut();
+ // set defaults
+ memset( pPars, 0, sizeof(If_Par_t) );
+ // user-controlable paramters
+// pPars->nLutSize = -1;
+ pPars->nLutSize = 6;
+ pPars->nCutsMax = 8;
+ pPars->nFlowIters = 1;
+ pPars->nAreaIters = 2;
+ pPars->DelayTarget = -1;
+ pPars->Epsilon = (float)0.005;
+ pPars->fPreprocess = 1;
+ pPars->fArea = 0;
+ pPars->fFancy = 0;
+ pPars->fExpRed = 1; ////
+ pPars->fLatchPaths = 0;
+ pPars->fEdge = 1;
+ pPars->fPower = 0;
+ pPars->fCutMin = 0;
+ pPars->fSeqMap = 0;
+ pPars->fVerbose = 0;
+ // internal parameters
+ pPars->fTruth = 0;
+ pPars->nLatches = 0;
+ pPars->fLiftLeaves = 0;
+// pPars->pLutLib = Abc_FrameReadLibLut();
+ pPars->pLutLib = NULL;
+ pPars->pTimesArr = NULL;
+ pPars->pTimesArr = NULL;
+ pPars->pFuncCost = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into FPGA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
+{
+// extern Vec_Int_t * SGia_ManComputeSwitchProbs( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );
+// Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL;
+// float * pSwitching, * pSwitching2;
+ If_Man_t * pIfMan;
+ If_Obj_t * pIfObj;
+ Gia_Obj_t * pNode;
+ int i, clk = clock();
+ Gia_ManLevelNum( p );
+/*
+ // set the number of registers (switch activity will be combinational)
+ Gia_ManSetRegNum( p, 0 );
+ if ( pPars->fPower )
+ {
+ vSwitching = SGia_ManComputeSwitchProbs( p, 48, 16, 0 );
+ if ( pPars->fVerbose )
+ {
+ ABC_PRT( "Computing switching activity", clock() - clk );
+ }
+ pSwitching = (float *)vSwitching->pArray;
+ vSwitching2 = Vec_IntStart( Gia_ManObjNumMax(p) );
+ pSwitching2 = (float *)vSwitching2->pArray;
+ }
+*/
+ // start the mapping manager and set its parameters
+ pIfMan = If_ManStart( pPars );
+// pIfMan->vSwitching = vSwitching2;
+ // load the AIG into the mapper
+ Gia_ManForEachObj( p, pNode, i )
+ {
+ if ( Gia_ObjIsAnd(pNode) )
+ pIfObj = If_ManCreateAnd( pIfMan,
+ If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ),
+ If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) );
+ else if ( Gia_ObjIsCi(pNode) )
+ {
+ pIfObj = If_ManCreateCi( pIfMan );
+ If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) );
+// printf( "pi=%d ", pIfObj->Level );
+ if ( pIfMan->nLevelMax < (int)pIfObj->Level )
+ pIfMan->nLevelMax = (int)pIfObj->Level;
+ }
+ else if ( Gia_ObjIsCo(pNode) )
+ {
+ pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) );
+// printf( "po=%d ", pIfObj->Level );
+ }
+ else if ( Gia_ObjIsConst0(pNode) )
+ pIfObj = If_Not(If_ManConst1( pIfMan ));
+ else // add the node to the mapper
+ assert( 0 );
+ // save the result
+ assert( Vec_PtrEntry(vAigToIf, i) == NULL );
+ Vec_PtrWriteEntry( vAigToIf, i, pIfObj );
+// if ( vSwitching2 )
+// pSwitching2[pIfObj->Id] = pSwitching[pNode->Id];
+/* // set up the choice node
+ if ( Gia_ObjIsChoice( p, pNode ) )
+ {
+ pIfMan->nChoices++;
+ for ( pPrev = pNode, pFanin = Gia_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Gia_ObjEquiv(p, pFanin) )
+ If_ObjSetChoice( pPrev->pData, pFanin->pData );
+ If_ManCreateChoice( pIfMan, pNode->pData );
+ }
+// assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) );
+*/
+ }
+// if ( vSwitching )
+// Vec_IntFree( vSwitching );
+ return pIfMan;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf )
+{
+ int * pMapping, iOffset;
+ Vec_Ptr_t * vIfToAig;
+ Gia_Obj_t * pObj, * pObjRepr;
+ If_Obj_t * pIfObj;
+ If_Cut_t * pCutBest;
+ int i, k, j, nLeaves, * ppLeaves;
+ int nItems = 0;
+ assert( Gia_ManCiNum(p) == If_ManCiNum(pIfMan) );
+ assert( Gia_ManCoNum(p) == If_ManCoNum(pIfMan) );
+ assert( Gia_ManAndNum(p) == If_ManAndNum(pIfMan) );
+ // create mapping of IF to AIG
+ vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ pIfObj = Vec_PtrEntry( vAigToIf, i );
+ Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj );
+ if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 )
+ continue;
+ nItems += 2 + If_CutLeaveNum( If_ObjCutBest(pIfObj) );
+ }
+ // construct the network
+ pMapping = ABC_CALLOC( int, Gia_ManObjNum(p) + nItems );
+ iOffset = Gia_ManObjNum(p);
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ pIfObj = Vec_PtrEntry( vAigToIf, i );
+ if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 )
+ continue;
+ pCutBest = If_ObjCutBest( pIfObj );
+ nLeaves = If_CutLeaveNum( pCutBest );
+ ppLeaves = If_CutLeaves( pCutBest );
+ // create node
+ k = iOffset;
+ pMapping[k++] = nLeaves;
+ for ( j = 0; j < nLeaves; j++ )
+ {
+ pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[j] );
+ pMapping[k++] = Gia_ObjId( p, pObjRepr );
+ }
+ pMapping[k++] = i;
+ pMapping[i] = iOffset;
+ iOffset = k;
+ }
+ assert( iOffset <= Gia_ManObjNum(p) + nItems );
+ Vec_PtrFree( vIfToAig );
+// pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 );
+ return pMapping;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars )
+{
+ If_Man_t * pIfMan;
+ Vec_Ptr_t * vAigToIf;
+ // set the arrival times
+ pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) );
+ memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) );
+ // translate into the mapper
+ vAigToIf = Vec_PtrStart( Gia_ManObjNum(p) );
+ pIfMan = Gia_ManToIf( p, pPars, vAigToIf );
+ if ( pIfMan == NULL )
+ return 0;
+// pIfMan->pManTim = Tim_ManDup( pManTime, 0 );
+ if ( !If_ManPerformMapping( pIfMan ) )
+ {
+ If_ManStop( pIfMan );
+ return 0;
+ }
+ // transform the result of mapping into the new network
+ ABC_FREE( p->pMapping );
+ p->pMapping = Gia_ManFromIf( pIfMan, p, vAigToIf );
+// if ( pPars->fBidec && pPars->nLutSize <= 8 )
+// Gia_ManBidecResyn( pNtk, 0 );
+ If_ManStop( pIfMan );
+ Vec_PtrFree( vAigToIf );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints mapping statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintMappingStats( Gia_Man_t * p )
+{
+ int * pLevels;
+ int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0;
+ if ( !p->pMapping )
+ return;
+ pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachGate( p, i )
+ {
+ nLuts++;
+ nFanins += Gia_ObjGateSize(p, i);
+ nLutSize = ABC_MAX( nLutSize, Gia_ObjGateSize(p, i) );
+ Gia_GateForEachFanin( p, i, iFan, k )
+ pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] );
+ pLevels[i]++;
+ LevelMax = ABC_MAX( LevelMax, pLevels[i] );
+ }
+ ABC_FREE( pLevels );
+ printf( "mapping : " );
+ printf( "%d=lut =%7d ", nLutSize, nLuts );
+ printf( "edge =%8d ", nFanins );
+ printf( "lev =%5d ", LevelMax );
+ printf( "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
+ printf( "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c
index 3f72b0b9..9058af7d 100644
--- a/src/aig/gia/giaScl.c
+++ b/src/aig/gia/giaScl.c
@@ -30,7 +30,7 @@
/**Function*************************************************************
- Synopsis [Returns the number of unmarked nodes.]
+ Synopsis [Marks unreachable internal nodes and returned their number.]
Description []
@@ -45,13 +45,13 @@ int Gia_ManCombMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
return 0;
pObj->fMark0 = 0;
assert( Gia_ObjIsAnd(pObj) );
- return Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) +
- Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ) + 1;
+ return 1 + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) )
+ + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) );
}
/**Function*************************************************************
- Synopsis [Returns the number of unused nodes.]
+ Synopsis [Marks unreachable internal nodes and returned their number.]
Description []
@@ -90,7 +90,7 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p )
/**Function*************************************************************
- Synopsis [Marks CIs/COs reachable from POs.]
+ Synopsis [Marks CIs/COs/ANDs unreachable from POs.]
Description []
@@ -99,29 +99,26 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots )
+int Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots )
{
if ( !pObj->fMark0 )
- return;
+ return 0;
pObj->fMark0 = 0;
if ( Gia_ObjIsCo(pObj) )
- {
- Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots );
- return;
- }
+ return Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots );
if ( Gia_ObjIsRo(p, pObj) )
{
Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ObjRoToRi(p, pObj)) );
- return;
+ return 0;
}
assert( Gia_ObjIsAnd(pObj) );
- Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots );
- Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots );
+ return 1 + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots )
+ + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots );
}
/**Function*************************************************************
- Synopsis [Performs sequential cleanup.]
+ Synopsis [Marks CIs/COs/ANDs unreachable from POs.]
Description []
@@ -130,19 +127,38 @@ void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p )
+int Gia_ManSeqMarkUsed( Gia_Man_t * p )
{
Vec_Int_t * vRoots;
Gia_Obj_t * pObj;
- int i;
+ int i, nNodes = 0;
Gia_ManSetMark0( p );
Gia_ManConst0(p)->fMark0 = 0;
Gia_ManForEachPi( p, pObj, i )
pObj->fMark0 = 0;
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->fMark0 = 0;
vRoots = Gia_ManCollectPoIds( p );
Gia_ManForEachObjVec( vRoots, p, pObj, i )
- Gia_ManSeqMarkUsed_rec( p, pObj, vRoots );
+ nNodes += Gia_ManSeqMarkUsed_rec( p, pObj, vRoots );
Vec_IntFree( vRoots );
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs sequential cleanup.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p )
+{
+ Gia_ManSeqMarkUsed( p );
return Gia_ManDupMarked( p );
}
diff --git a/src/aig/gia/giaSort.c b/src/aig/gia/giaSort.c
index aec98fd8..8574297d 100644
--- a/src/aig/gia/giaSort.c
+++ b/src/aig/gia/giaSort.c
@@ -245,12 +245,15 @@ void minisat_sort3(float* array, int* perm, int size)
SeeAlso []
***********************************************************************/
-int * Gia_SortFloats( float * pArray, int nSize )
+int * Gia_SortFloats( float * pArray, int * pPerm, int nSize )
{
- int i, * pPerm;
- pPerm = ABC_ALLOC( int, nSize );
- for ( i = 0; i < nSize; i++ )
- pPerm[i] = i;
+ int i;
+ if ( pPerm == NULL )
+ {
+ pPerm = ABC_ALLOC( int, nSize );
+ for ( i = 0; i < nSize; i++ )
+ pPerm[i] = i;
+ }
minisat_sort3( pArray, pPerm, nSize );
// for ( i = 1; i < nSize; i++ )
// assert( pArray[i-1] <= pArray[i] );
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index 64f191f1..cc1a3861 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -300,6 +300,34 @@ void Gia_ManCreateRefs( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Assigns references.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManCreateMuxRefs( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pCtrl, * pFan0, * pFan1;
+ int i, * pMuxRefs;
+ pMuxRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
+ continue;
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pFan0, &pFan1 );
+ pMuxRefs[ Gia_ObjId(p, Gia_Regular(pCtrl)) ]++;
+ }
+ return pMuxRefs;
+}
+
+/**Function*************************************************************
+
Synopsis [Computes the maximum frontier size.]
Description []
@@ -549,6 +577,45 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob
return NULL;
}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDoubleOuts )
+{
+ Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+ int RetValue, i, k, iBit = 0;
+ Gia_ManForEachRo( pAig, pObj, i )
+ pObj->fMark0 = Aig_InfoHasBit(p->pData, iBit++);
+ for ( i = 0; i <= p->iFrame; i++ )
+ {
+ Gia_ManForEachPi( pAig, pObj, k )
+ pObj->fMark0 = Aig_InfoHasBit(p->pData, iBit++);
+ Gia_ManForEachAnd( pAig, pObj, k )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachCo( pAig, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k )
+ pObjRo->fMark0 = pObjRi->fMark0;
+ }
+ assert( iBit == p->nBits );
+ if ( fDoubleOuts )
+ RetValue = Gia_ManPo(pAig, 2*p->iPo)->fMark0 ^ Gia_ManPo(pAig, 2*p->iPo+1)->fMark0;
+ else
+ RetValue = Gia_ManPo(pAig, p->iPo)->fMark0;
+ Gia_ManCleanMark0(pAig);
+ return RetValue;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 7a68b554..4410b497 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -5,6 +5,8 @@ SRC += src/aig/gia/gia.c \
src/aig/gia/giaDfs.c \
src/aig/gia/giaDup.c \
src/aig/gia/giaEmbed.c \
+ src/aig/gia/giaEnable.c \
+ src/aig/gia/giaEquiv.c \
src/aig/gia/giaFanout.c \
src/aig/gia/giaForce.c \
src/aig/gia/giaFrames.c \
@@ -12,6 +14,7 @@ SRC += src/aig/gia/gia.c \
src/aig/gia/giaGlitch.c \
src/aig/gia/giaHash.c \
src/aig/gia/giaMan.c \
+ src/aig/gia/giaMap.c \
src/aig/gia/giaScl.c \
src/aig/gia/giaSim.c \
src/aig/gia/giaSort.c \
diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c
index 11c866f4..b81414a5 100644
--- a/src/aig/ioa/ioaReadAig.c
+++ b/src/aig/ioa/ioaReadAig.c
@@ -341,6 +341,18 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck )
Aig_ManShortNames( pNew );
}
*/
+ pCur = pSymbols;
+ if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
+ {
+ pCur++;
+ if ( *pCur == 'n' )
+ {
+ pCur++;
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = Aig_UtilStrsav( pCur );
+ }
+ }
// skipping the comments
ABC_FREE( pContents );
diff --git a/src/aig/ioa/ioaWriteAig.c b/src/aig/ioa/ioaWriteAig.c
index 3d37c0a7..42aa42db 100644
--- a/src/aig/ioa/ioaWriteAig.c
+++ b/src/aig/ioa/ioaWriteAig.c
@@ -375,10 +375,10 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int
}
*/
// write the comment
- fprintf( pFile, "c\n" );
+ fprintf( pFile, "c" );
if ( pMan->pName )
- fprintf( pFile, ".model %s\n", pMan->pName );
- fprintf( pFile, "This file was produced by the AIG package on %s\n", Ioa_TimeStamp() );
+ fprintf( pFile, "n%s%c", pMan->pName, '\0' );
+ fprintf( pFile, "\nThis file was produced by the IOA package in ABC on %s\n", Ioa_TimeStamp() );
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
fclose( pFile );
}
diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c
index 174a3e97..71bdadf6 100644
--- a/src/aig/saig/saigMiter.c
+++ b/src/aig/saig/saigMiter.c
@@ -568,13 +568,17 @@ int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t **
printf( "The output number %d of the miter is constant 1.\n", i );
Counter++;
continue;
- }
+ }
if ( !Aig_ObjIsNode(pFanin) || !Aig_ObjRecognizeExor( pFanin, &pObj0, &pObj1 ) )
{
+/*
printf( "The miter cannot be demitered.\n" );
Vec_PtrFree( vSet0 );
Vec_PtrFree( vSet1 );
return 0;
+*/
+ printf( "The output number %d cannot be demitered.\n", i );
+ continue;
}
if ( Aig_ObjFaninC0(pObj) )
pObj0 = Aig_Not(pObj0);
diff --git a/src/aig/ssw/sswCore.c b/src/aig/ssw/sswCore.c
index 16430ace..9d09d4e7 100644
--- a/src/aig/ssw/sswCore.c
+++ b/src/aig/ssw/sswCore.c
@@ -179,7 +179,8 @@ clk = clock();
printf( "Cex =%5d. ", p->nSatCallsSat-nSatCallsSat );
printf( "R =%4d. ", p->nRecycles-nRecycles );
}
- printf( "F =%5d. ", p->nSatFailsReal-nSatFailsReal );
+ printf( "F =%5d. %s ", p->nSatFailsReal-nSatFailsReal,
+ (Saig_ManPoNum(p->pAig)==1 && Ssw_ObjIsConst1Cand(p->pAig,Aig_ObjFanin0(Aig_ManPo(p->pAig,0))))? "+" : "-" );
ABC_PRT( "T", clock() - clk );
}
// if ( p->pPars->fDynamic && p->nSatCallsSat-nSatCallsSat < 100 )