summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2009-03-10 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2009-03-10 08:01:00 -0700
commit32314347bae6ddcd841a268e797ec4da45726abb (patch)
treee2e5fd1711f04a06d0da2b8003bc02cb9a5dd446 /src
parentc03f9b516bed2c06ec2bfc78617eba5fc9a11c32 (diff)
downloadabc-32314347bae6ddcd841a268e797ec4da45726abb.tar.gz
abc-32314347bae6ddcd841a268e797ec4da45726abb.tar.bz2
abc-32314347bae6ddcd841a268e797ec4da45726abb.zip
Version abc90310
Diffstat (limited to 'src')
-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
-rw-r--r--src/base/abc/abcBlifMv.zipbin6552 -> 0 bytes
-rw-r--r--src/base/abc/abcFanio.c6
-rw-r--r--src/base/abci/abc.c1295
-rw-r--r--src/base/abci/abcDar.c122
-rw-r--r--src/base/abci/abcDsd.c3
-rw-r--r--src/base/abci/abcLutmin.c209
-rw-r--r--src/base/abci/module.make1
-rw-r--r--src/base/cmd/cmd.c67
-rw-r--r--src/base/io/io.c106
-rw-r--r--src/base/io/ioAbc.h5
-rw-r--r--src/base/io/ioReadAiger.c14
-rw-r--r--src/base/io/ioReadBblif.c342
-rw-r--r--src/base/io/ioUtil.c22
-rw-r--r--src/base/io/ioWriteAiger.c6
-rw-r--r--src/base/io/ioWriteBblif.c111
-rw-r--r--src/base/io/module.make2
-rw-r--r--src/base/ver/verCore.c13
-rw-r--r--src/base/ver/verParse.c9
-rw-r--r--src/map/amap/amapLiberty.c33
-rw-r--r--src/map/amap/amapParse.c10
-rw-r--r--src/map/if/ifCore.c9
-rw-r--r--src/map/if/ifMap.c4
-rw-r--r--src/map/if/ifSeq.c71
-rw-r--r--src/map/if/module.make1
-rw-r--r--src/map/mio/mio81214.zipbin16939 -> 0 bytes
-rw-r--r--src/misc/vec/vecFlt.h2
-rw-r--r--src/misc/vec/vecInt.h29
-rw-r--r--src/misc/vec/vecPtr.h30
-rw-r--r--src/misc/vec/vecStr.h7
-rw-r--r--src/opt/dec/decAbc.c47
-rw-r--r--src/sat/bsat/satSolver.c1
66 files changed, 8677 insertions, 1793 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 )
diff --git a/src/base/abc/abcBlifMv.zip b/src/base/abc/abcBlifMv.zip
deleted file mode 100644
index 4a4d080a..00000000
--- a/src/base/abc/abcBlifMv.zip
+++ /dev/null
Binary files differ
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
index fb8dcaae..6c75cf3f 100644
--- a/src/base/abc/abcFanio.c
+++ b/src/base/abc/abcFanio.c
@@ -92,6 +92,12 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
{
printf( "Abc_ObjAddFanin(): Error! Creating net \"%s\" with two fanins.\n", Abc_ObjName(pObj) );
}
+/*
+ if ( Abc_ObjIsCo(pFanin) )
+ {
+ printf( "Abc_ObjAddFanin(): Error! Creating fanout of a CO.\n", Abc_ObjName(pFanin) );
+ }
+*/
}
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index e7187a9f..1164c3da 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -82,6 +82,7 @@ static int Abc_CommandFastExtract ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandEliminate ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDisjoint ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLutpack ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandLutmin ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandImfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTrace ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -151,14 +152,13 @@ static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandISat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandNFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSimSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMatch ( Abc_Frame_t * pAbc, int argc, char ** argv );
//static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
+//static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandQbf ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -217,7 +217,6 @@ static int Abc_CommandExtWin ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandInsWin ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandCec2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -258,6 +257,7 @@ static int Abc_CommandAbc8Bidec ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandAbc8Strash ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Lutpack ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc8Lutmin ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Balance ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Speedup ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Merge ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -279,6 +279,7 @@ static int Abc_CommandAbc9Read ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandAbc9Write ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Ps ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9PFan ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9PSig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Status ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Show ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Hash ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -287,13 +288,18 @@ static int Abc_CommandAbc9Cof ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandAbc9Trim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Dfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Sim ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Equiv ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Times ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Frames ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Miter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Scl ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Sat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Fraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Srm ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Cec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Force ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Embed ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9If ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbcTestNew ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -391,6 +397,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "eliminate", Abc_CommandEliminate, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "dsd", Abc_CommandDisjoint, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "lutpack", Abc_CommandLutpack, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "lutmin", Abc_CommandLutmin, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "imfs", Abc_CommandImfs, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "mfs", Abc_CommandMfs, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "trace", Abc_CommandTrace, 0 );
@@ -460,10 +467,9 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "New AIG", "isat", Abc_CommandISat, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "ifraig", Abc_CommandIFraig, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "dfraig", Abc_CommandDFraig, 1 );
- Cmd_CommandAdd( pAbc, "New AIG", "nfraig", Abc_CommandNFraig, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "csweep", Abc_CommandCSweep, 1 );
// Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 );
- Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 );
+// Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "qbf", Abc_CommandQbf, 0 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
@@ -520,7 +526,6 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Sequential", "inswin", Abc_CommandInsWin, 1 );
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
- Cmd_CommandAdd( pAbc, "Verification", "cec2", Abc_CommandCec2, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dcec", Abc_CommandDCec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dsec", Abc_CommandDSec, 0 );
@@ -582,6 +587,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "AIG", "&w", Abc_CommandAbc9Write, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&ps", Abc_CommandAbc9Ps, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&pfan", Abc_CommandAbc9PFan, 0 );
+ Cmd_CommandAdd( pAbc, "AIG", "&psig", Abc_CommandAbc9PSig, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&status", Abc_CommandAbc9Status, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&show", Abc_CommandAbc9Show, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&hash", Abc_CommandAbc9Hash, 0 );
@@ -590,13 +596,18 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "AIG", "&trim", Abc_CommandAbc9Trim, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&dfs", Abc_CommandAbc9Dfs, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&sim", Abc_CommandAbc9Sim, 0 );
+ Cmd_CommandAdd( pAbc, "AIG", "&equiv", Abc_CommandAbc9Equiv, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&times", Abc_CommandAbc9Times, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&frames", Abc_CommandAbc9Frames, 0 );
+ Cmd_CommandAdd( pAbc, "AIG", "&miter", Abc_CommandAbc9Miter, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&scl", Abc_CommandAbc9Scl, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&sat", Abc_CommandAbc9Sat, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&fraig", Abc_CommandAbc9Fraig, 0 );
+ Cmd_CommandAdd( pAbc, "AIG", "&srm", Abc_CommandAbc9Srm, 0 );
+ Cmd_CommandAdd( pAbc, "AIG", "&cec", Abc_CommandAbc9Cec, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&force", Abc_CommandAbc9Force, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&embed", Abc_CommandAbc9Embed, 0 );
+ Cmd_CommandAdd( pAbc, "AIG", "&if", Abc_CommandAbc9If, 0 );
Cmd_CommandAdd( pAbc, "AIG", "&test", Abc_CommandAbc9Test, 0 );
Cmd_CommandAdd( pAbc, "Various", "testnew", Abc_CommandAbcTestNew, 0 );
@@ -634,6 +645,10 @@ void Abc_Init( Abc_Frame_t * pAbc )
extern void Gia_SortTest();
// Gia_SortTest();
}
+ {
+ void For_ManFileExperiment();
+// For_ManFileExperiment();
+ }
}
@@ -3694,6 +3709,85 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandLutmin( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int nLutSize;
+ int fVerbose;
+ extern Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nLutSize = 6;
+ fVerbose = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-K\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLutSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLutSize > 1 )
+ goto usage;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ // modify the current network
+ pNtkRes = Abc_NtkLutmin( pNtk, nLutSize, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "The command has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: lutmin [-K <num>] [-vh]\n" );
+ fprintf( pErr, "\t perform FPGA mapping while minimizing the LUT count\n" );
+ fprintf( pErr, "\t as described in the paper T. Sasao and A. Mishchenko:\n" );
+ fprintf( pErr, "\t \"On the number of LUTs to implement logic functions\".\n" );
+ fprintf( pErr, "\t-K <num> : the LUT size to use for the mapping (2 <= num) [default = %d]\n", nLutSize );
+ fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandImfs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
@@ -5369,12 +5463,6 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) )
- {
- fprintf( pErr, "The miter's PO is not an EXOR.\n" );
- return 1;
- }
-
// get the new network
if ( fSeq )
{
@@ -5391,6 +5479,11 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "The network is not a single-output miter.\n" );
return 1;
}
+ if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) )
+ {
+ fprintf( pErr, "The miter's PO is not an EXOR.\n" );
+ return 1;
+ }
if ( !Abc_NtkDemiter( pNtk ) )
{
fprintf( pErr, "Demitering has failed.\n" );
@@ -8163,6 +8256,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
extern void Abc_NtkDarTest( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkDarTestNtk( Abc_Ntk_t * pNtk );
extern void Amap_LibertyTest( char * pFileName );
+ extern void Bbl_ManTest( Abc_Ntk_t * pNtk );
+ extern void Bbl_ManSimpleDemo();
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@@ -8379,6 +8474,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// Abc_NtkDarTest( pNtk );
+ Bbl_ManTest( pNtk );
+// Bbl_ManSimpleDemo();
return 0;
usage:
fprintf( pErr, "usage: test [-h] <file_name>\n" );
@@ -10076,152 +10173,6 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandNFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
- Cec_ParCsw_t Pars, * p = &Pars;
- FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk, * pNtkRes;
- int c;
- extern Abc_Ntk_t * Abc_NtkDarSatSweep( Abc_Ntk_t * pNtk, Cec_ParCsw_t * pPars );
-
- pNtk = Abc_FrameReadNtk(pAbc);
- pOut = Abc_FrameReadOut(pAbc);
- pErr = Abc_FrameReadErr(pAbc);
-
- // set defaults
- Cec_ManCswSetDefaultParams( p );
- Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WRCNZLrfvh" ) ) != EOF )
- {
- switch ( c )
- {
- case 'W':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-W\" should be followed by an integer.\n" );
- goto usage;
- }
- p->nWords = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( p->nWords < 0 )
- goto usage;
- break;
- case 'R':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" );
- goto usage;
- }
- p->nRounds = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( p->nRounds < 0 )
- goto usage;
- break;
- case 'C':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
- goto usage;
- }
- p->nBTLimit = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( p->nBTLimit < 0 )
- goto usage;
- break;
- case 'N':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
- goto usage;
- }
- p->nSatVarMax = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( p->nSatVarMax < 0 )
- goto usage;
- break;
- case 'Z':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-Z\" should be followed by an integer.\n" );
- goto usage;
- }
- p->nCallsRecycle = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( p->nCallsRecycle < 0 )
- goto usage;
- break;
- case 'L':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" );
- goto usage;
- }
- p->nLevelMax = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( p->nLevelMax < 0 )
- goto usage;
- break;
- case 'r':
- p->fRewriting ^= 1;
- break;
- case 'f':
- p->fFirstStop ^= 1;
- break;
- case 'v':
- p->fVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
- }
- }
- if ( pNtk == NULL )
- {
- fprintf( pErr, "Empty network.\n" );
- return 1;
- }
- if ( !Abc_NtkIsStrash(pNtk) )
- {
- fprintf( pErr, "This command works only for strashed networks.\n" );
- return 1;
- }
- pNtkRes = Abc_NtkDarSatSweep( pNtk, p );
- if ( pNtkRes == NULL )
- {
- fprintf( pErr, "Command has failed.\n" );
- return 0;
- }
- // replace the current network
- Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
- return 0;
-usage:
- fprintf( pErr, "usage: nfraig [-WRCNZL num] [-rfvh]\n" );
- fprintf( pErr, "\t performs fraiging using a new method\n" );
- fprintf( pErr, "\t-W num : lthe number of simulation words [default = %d]\n", p->nWords );
- fprintf( pErr, "\t-R num : the number of simulation rounds [default = %d]\n", p->nRounds );
- fprintf( pErr, "\t-C num : limit on conflicts at a node [default = %d]\n", p->nBTLimit );
- fprintf( pErr, "\t-N num : the min number of SAT vars before recycling [default = %d]\n", p->nSatVarMax );
- fprintf( pErr, "\t-Z num : the min number of SAT calls before recycling [default = %d]\n", p->nCallsRecycle );
- fprintf( pErr, "\t-L num : the maximum level of the nodes to be swept [default = %d]\n", p->nLevelMax );
- fprintf( pErr, "\t-r : toggle the use of AIG rewriting [default = %s]\n", p->fRewriting? "yes": "no" );
- fprintf( pErr, "\t-f : stop after one output is disproved [default = %s]\n", p->fFirstStop? "yes": "no" );
- fprintf( pErr, "\t-v : enable verbose printout [default = %s]\n", p->fVerbose? "yes": "no" );
- fprintf( pErr, "\t-h : print the command usage\n");
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
int Abc_CommandCSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
@@ -12792,6 +12743,13 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" );
return 1;
}
+/*
+ if ( pPars->fSeqMap )
+ {
+ fprintf( pErr, "Sequential mapping is currently disabled.\n" );
+ return 1;
+ }
+*/
if ( pPars->fSeqMap && pPars->nLatches == 0 )
{
@@ -12825,12 +12783,6 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( pPars->fSeqMap )
- {
- fprintf( pErr, "Sequential mapping is currently disabled.\n" );
- return 1;
- }
-
// enable truth table computation if choices are selected
if ( (c = Abc_NtkGetChoiceNum( pNtk )) )
{
@@ -15828,6 +15780,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
int nConfLimit;
int nInsLimit;
int fPartition;
+ int fIgnoreNames;
extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit );
extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose );
@@ -15846,8 +15799,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
nConfLimit = 10000;
nInsLimit = 0;
fPartition = 0;
+ fIgnoreNames = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "TCIPpsvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "TCIPpsnvh" ) ) != EOF )
{
switch ( c )
{
@@ -15901,6 +15855,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
case 's':
fSat ^= 1;
break;
+ case 'n':
+ fIgnoreNames ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -15913,6 +15870,12 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
nArgcNew = argc - globalUtilOptind;
if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
return 1;
+
+ if ( fIgnoreNames )
+ {
+ Abc_NtkShortNames( pNtk1 );
+ Abc_NtkShortNames( pNtk2 );
+ }
// perform equivalence checking
if ( fPartition )
@@ -15933,7 +15896,7 @@ usage:
strcpy( Buffer, "unused" );
else
sprintf( Buffer, "%d", nPartSize );
- fprintf( pErr, "usage: cec [-T num] [-C num] [-I num] [-P num] [-psvh] <file1> <file2>\n" );
+ fprintf( pErr, "usage: cec [-T num] [-C num] [-I num] [-P num] [-psnvh] <file1> <file2>\n" );
fprintf( pErr, "\t performs combinational equivalence checking\n" );
fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
@@ -15941,6 +15904,7 @@ usage:
fprintf( pErr, "\t-P num : partition size for multi-output networks [default = %s]\n", Buffer );
fprintf( pErr, "\t-p : toggle automatic partitioning [default = %s]\n", fPartition? "yes": "no" );
fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
+ fprintf( pErr, "\t-n : toggle using names to match CIs/COs [default = %s]\n", fIgnoreNames? "yes": "no" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
@@ -16115,149 +16079,6 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandCec2( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
- Cec_ParCec_t Pars, * pPars = &Pars;
- FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk, * pNtk1, * pNtk2;
- int fDelete1, fDelete2;
- char ** pArgvNew;
- int nArgcNew;
- int fMiter;
- int c;
-
- extern int Abc_NtkDarCec2( Abc_Ntk_t * pNtk0, Abc_Ntk_t * pNtk1, Cec_ParCec_t * pPars );
-
- pNtk = Abc_FrameReadNtk(pAbc);
- pOut = Abc_FrameReadOut(pAbc);
- pErr = Abc_FrameReadErr(pAbc);
-
- // set defaults
- fMiter = 0;
- Cec_ManCecSetDefaultParams( pPars );
- Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "BMImfrsvh" ) ) != EOF )
- {
- switch ( c )
- {
- case 'B':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-B\" should be followed by an integer.\n" );
- goto usage;
- }
- pPars->nBTLimitBeg = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( pPars->nBTLimitBeg < 0 )
- goto usage;
- break;
- case 'M':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-M\" should be followed by an integer.\n" );
- goto usage;
- }
- pPars->nBTlimitMulti = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( pPars->nBTlimitMulti < 0 )
- goto usage;
- break;
- case 'I':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
- goto usage;
- }
- pPars->nIters = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( pPars->nIters < 0 )
- goto usage;
- break;
- case 'm':
- fMiter ^= 1;
- break;
- case 'f':
- pPars->fFirstStop ^= 1;
- break;
- case 'r':
- pPars->fRewriting ^= 1;
- break;
- case 's':
- pPars->fSatSweeping ^= 1;
- break;
- case 'v':
- pPars->fVerbose ^= 1;
- break;
- default:
- goto usage;
- }
- }
-
- pArgvNew = argv + globalUtilOptind;
- nArgcNew = argc - globalUtilOptind;
- if ( fMiter )
- {
- if ( pNtk == NULL )
- {
- fprintf( pErr, "Empty network.\n" );
- return 1;
- }
- if ( Abc_NtkIsStrash(pNtk) )
- {
- pNtk1 = pNtk;
- fDelete1 = 0;
- }
- else
- {
- pNtk1 = Abc_NtkStrash( pNtk, 0, 1, 0 );
- fDelete1 = 1;
- }
- pNtk2 = NULL;
- fDelete2 = 0;
- }
- else
- {
- if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
- return 1;
- }
-
- // perform equivalence checking
- Abc_NtkDarCec2( pNtk1, pNtk2, pPars );
-
- if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
- if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
- return 0;
-
-usage:
- fprintf( pErr, "usage: cec2 [-BMI num] [-frsvh] <file1> <file2>\n" );
- fprintf( pErr, "\t performs combinational equivalence checking\n" );
- fprintf( pErr, "\t-B num : staring limit on the number of conflicts [default = %d]\n", pPars->nBTLimitBeg );
- fprintf( pErr, "\t-M num : multiple of the above limit [default = %d]\n", pPars->nBTlimitMulti );
- fprintf( pErr, "\t-I num : the number of iterations [default = %d]\n", pPars->nIters );
- fprintf( pErr, "\t-m : toggle working on two networks or a miter [default = %s]\n", fMiter? "miter": "two networks" );
- fprintf( pErr, "\t-f : toggle stopping after first mismatch [default = %s]\n", pPars->fFirstStop? "yes": "no" );
- fprintf( pErr, "\t-r : toggle AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" );
- fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", pPars->fSatSweeping? "SAT only": "FRAIG + SAT" );
- fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
- fprintf( pErr, "\t-h : print the command usage\n");
- fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
- fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
- fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
- fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
@@ -22157,6 +21978,56 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9PSig( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ int c;
+ int fSetReset = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "rh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'r':
+ fSetReset ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pAig == NULL )
+ {
+ printf( "Abc_CommandAbc9PSigs(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( Gia_ManRegNum(pAbc->pAig) == 0 )
+ {
+ printf( "Abc_CommandAbc9PSigs(): Works only for sequential circuits.\n" );
+ return 1;
+ }
+ Gia_ManDetectSeqSignals( pAbc->pAig, fSetReset );
+ return 0;
+
+usage:
+ fprintf( stdout, "usage: &psig [-rh]\n" );
+ fprintf( stdout, "\t prints enable/set/reset statistics\n" );
+ fprintf( stdout, "\t-r : toggle printing set/reset signals [default = %s]\n", fSetReset? "yes": "no" );
+ fprintf( stdout, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Status( Abc_Frame_t * pAbc, int argc, char ** argv )
{
int c;
@@ -22336,9 +22207,9 @@ usage:
int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
- int c, iVar = 0;
+ int c, iVar = 0, nLimFan = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Vh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "VLh" ) ) != EOF )
{
switch ( c )
{
@@ -22353,6 +22224,17 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( iVar < 0 )
goto usage;
break;
+ case 'L':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-L\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLimFan = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLimFan < 0 )
+ goto usage;
+ break;
case 'h':
goto usage;
default:
@@ -22364,7 +22246,7 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "Abc_CommandAbc9Cof(): There is no AIG.\n" );
return 1;
}
- pAbc->pAig = Gia_ManDupCofactored( pTemp = pAbc->pAig, iVar );
+ pAbc->pAig = Gia_ManDupCofactored( pTemp = pAbc->pAig, iVar, nLimFan );
if ( pAbc->pAig == NULL )
{
pAbc->pAig = pTemp;
@@ -22375,9 +22257,10 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( stdout, "usage: &cof [-V num] [-h]\n" );
+ fprintf( stdout, "usage: &cof [-VL num] [-h]\n" );
fprintf( stdout, "\t performs cofactoring w.r.t. a variable\n" );
fprintf( stdout, "\t-V num : the zero-based ID of the variable to cofactor [default = %d]\n", iVar );
+ fprintf( stdout, "\t-L num : cofactor w.r.t. variables whose fanout is higher [default = %d]\n", nLimFan );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
@@ -22397,11 +22280,19 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
int c;
+ int fTrimCis = 1;
+ int fTrimCos = 1;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ioh" ) ) != EOF )
{
switch ( c )
{
+ case 'i':
+ fTrimCis ^= 1;
+ break;
+ case 'o':
+ fTrimCos ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -22413,13 +22304,15 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "Abc_CommandAbc9Trim(): There is no AIG.\n" );
return 1;
}
- pAbc->pAig = Gia_ManDupTrimmed( pTemp = pAbc->pAig );
+ pAbc->pAig = Gia_ManDupTrimmed( pTemp = pAbc->pAig, fTrimCis, fTrimCos );
Gia_ManStop( pTemp );
return 0;
usage:
- fprintf( stdout, "usage: &trim [-h]\n" );
+ fprintf( stdout, "usage: &trim [-ioh]\n" );
fprintf( stdout, "\t removes PIs without fanout and PO driven by constants\n" );
+ fprintf( stdout, "\t-i : toggle removing PIs [default = %s]\n", fTrimCis? "yes": "no" );
+ fprintf( stdout, "\t-o : toggle removing POs [default = %s]\n", fTrimCos? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
@@ -22563,6 +22456,104 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Equiv( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Cec_ParSim_t Pars, * pPars = &Pars;
+ int c;
+ Cec_ManSimSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WRTsmfdvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'W':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-W\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nWords = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nWords < 0 )
+ goto usage;
+ break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-R\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nRounds = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nRounds < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->TimeLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->TimeLimit < 0 )
+ goto usage;
+ break;
+ case 's':
+ pPars->fSeqSimulate ^= 1;
+ break;
+ case 'm':
+ pPars->fCheckMiter ^= 1;
+ break;
+ case 'f':
+ pPars->fFirstStop ^= 1;
+ break;
+ case 'd':
+ pPars->fDoubleOuts ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pAig == NULL )
+ {
+ printf( "Abc_CommandAbc9Equiv(): There is no AIG.\n" );
+ return 1;
+ }
+ Cec_ManSimulation( pAbc->pAig, pPars );
+ return 0;
+
+usage:
+ fprintf( stdout, "usage: &equiv [-WRT <num>] [-smfdvh]\n" );
+ fprintf( stdout, "\t computes candidate equivalence classes\n" );
+ fprintf( stdout, "\t-W num : the number of words to simulate [default = %d]\n", pPars->nWords );
+ fprintf( stdout, "\t-R num : the number of rounds to simulate [default = %d]\n", pPars->nRounds );
+ fprintf( stdout, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
+ fprintf( stdout, "\t-s : toggle seq vs. comb simulation [default = %s]\n", pPars->fSeqSimulate? "yes": "no" );
+ fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" );
+ fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" );
+ fprintf( stdout, "\t-d : toggle using two POs intead of XOR [default = %s]\n", pPars->fDoubleOuts? "yes": "no" );
+ fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ fprintf( stdout, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Times( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
@@ -22685,6 +22676,119 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pFile;
+ Gia_Man_t * pAux;
+ Gia_Man_t * pSecond;
+ char * FileName, * pTemp;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fXorOuts = 1;
+ int fComb = 1;
+ int fTrans = 0;
+ int fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "xctvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'x':
+ fXorOuts ^= 1;
+ break;
+ case 'c':
+ fComb ^= 1;
+ break;
+ case 't':
+ fTrans ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( fTrans )
+ {
+ if ( (Gia_ManPoNum(pAbc->pAig) & 1) == 1 )
+ {
+ printf( "Abc_CommandAbc9Miter(): The number of outputs should be even.\n" );
+ return 0;
+ }
+ pAbc->pAig = Gia_ManTransformMiter( pAux = pAbc->pAig );
+ Gia_ManStop( pAux );
+ printf( "Abc_CommandAbc9Miter(): Miter is transformed by merging POs pair-wise.\n" );
+ return 0;
+ }
+
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ {
+ printf( "File name is not given on the command line.\n" );
+ return 1;
+ }
+
+ // get the input file name
+ FileName = pArgvNew[0];
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pSecond = Gia_ReadAiger( FileName, 0 );
+ if ( pSecond == NULL )
+ {
+ printf( "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ // compute the miter
+ pAbc->pAig = Gia_ManMiter( pAux = pAbc->pAig, pSecond, fXorOuts, fComb, fVerbose );
+ Gia_ManStop( pSecond );
+ if ( pAbc->pAig == NULL )
+ {
+ printf( "Miter construction has failed.\n" );
+ pAbc->pAig = pAux;
+ }
+ else
+ Gia_ManStop( pAux );
+ return 0;
+
+usage:
+ fprintf( stdout, "usage: &miter [-xctvh] <file>\n" );
+ fprintf( stdout, "\t creates miter of two designs (current AIG vs. <file>)\n" );
+ fprintf( stdout, "\t-x : toggle creating XOR of output pairs [default = %s]\n", fXorOuts? "yes": "no" );
+ fprintf( stdout, "\t-c : toggle creating combinational miter [default = %s]\n", fComb? "yes": "no" );
+ fprintf( stdout, "\t-t : toggle XORing pair-wise POs of the miter [default = %s]\n", fTrans? "yes": "no" );
+ fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( stdout, "\t-h : print the command usage\n");
+ fprintf( stdout, "\t<file> : AIGER file with the design to miter\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Scl( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
@@ -22747,7 +22851,7 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Cec_ManSatSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CSNfvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CSNmfvh" ) ) != EOF )
{
switch ( c )
{
@@ -22784,6 +22888,9 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nCallsRecycle < 0 )
goto usage;
break;
+ case 'm':
+ pPars->fCheckMiter ^= 1;
+ break;
case 'f':
pPars->fFirstStop ^= 1;
break;
@@ -22804,12 +22911,13 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( stdout, "usage: &sat [-CSN <num>] [-fvh]\n" );
+ fprintf( stdout, "usage: &sat [-CSN <num>] [-mfvh]\n" );
fprintf( stdout, "\t performs SAT solving for the combinational outputs\n" );
fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
fprintf( stdout, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax );
- fprintf( stdout, "\t-N num : the max number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );
- fprintf( stdout, "\t-f : toggle stopping when an output is satisfiable [default = %s]\n", pPars->fFirstStop? "yes": "no" );
+ fprintf( stdout, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );
+ fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" );
+ fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" );
fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
@@ -22828,12 +22936,12 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Cec_ParCsw_t ParsCsw, * pPars = &ParsCsw;
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
Gia_Man_t * pTemp;
int c;
- Cec_ManCswSetDefaultParams( pPars );
+ Cec_ManFraSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WRILDCSNrmwvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WRILDCrmfdwvh" ) ) != EOF )
{
switch ( c )
{
@@ -22903,34 +23011,18 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nBTLimit < 0 )
goto usage;
break;
- case 'S':
- if ( globalUtilOptind >= argc )
- {
- fprintf( stdout, "Command line switch \"-S\" should be followed by an integer.\n" );
- goto usage;
- }
- pPars->nSatVarMax = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( pPars->nSatVarMax < 0 )
- goto usage;
- break;
- case 'N':
- if ( globalUtilOptind >= argc )
- {
- fprintf( stdout, "Command line switch \"-N\" should be followed by an integer.\n" );
- goto usage;
- }
- pPars->nCallsRecycle = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( pPars->nCallsRecycle < 0 )
- goto usage;
- break;
case 'r':
pPars->fRewriting ^= 1;
break;
case 'm':
+ pPars->fCheckMiter ^= 1;
+ break;
+ case 'f':
pPars->fFirstStop ^= 1;
break;
+ case 'd':
+ pPars->fDoubleOuts ^= 1;
+ break;
case 'w':
pPars->fVeryVerbose ^= 1;
break;
@@ -22946,12 +23038,16 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "Abc_CommandAbc9Fraig(): There is no AIG.\n" );
return 1;
}
- pAbc->pAig = Cec_ManSatSweeping( pTemp = pAbc->pAig, pPars );
- Gia_ManStop( pTemp );
+ pTemp = Cec_ManSatSweeping( pAbc->pAig, pPars );
+ if ( pTemp )
+ {
+ Gia_ManStop( pAbc->pAig );
+ pAbc->pAig = pTemp;
+ }
return 0;
usage:
- fprintf( stdout, "usage: &fraig [-WRILDCSN <num>] [-rmwvh]\n" );
+ fprintf( stdout, "usage: &fraig [-WRILDC <num>] [-rmfdwvh]\n" );
fprintf( stdout, "\t performs combinational SAT sweeping\n" );
fprintf( stdout, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords );
fprintf( stdout, "\t-R num : the number of simulation rounds [default = %d]\n", pPars->nRounds );
@@ -22959,10 +23055,10 @@ usage:
fprintf( stdout, "\t-L num : the max number of levels of nodes to consider [default = %d]\n", pPars->nLevelMax );
fprintf( stdout, "\t-D num : the max number of steps of speculative reduction [default = %d]\n", pPars->nDepthMax );
fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
- fprintf( stdout, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax );
- fprintf( stdout, "\t-N num : the max number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );
fprintf( stdout, "\t-r : toggle the use of AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" );
- fprintf( stdout, "\t-m : toggle stopping when an output is satisfiable [default = %s]\n", pPars->fFirstStop? "yes": "no" );
+ fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" );
+ fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" );
+ fprintf( stdout, "\t-d : toggle using double output miters [default = %s]\n", pPars->fDoubleOuts? "yes": "no" );
fprintf( stdout, "\t-w : toggle printing even more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
@@ -22980,14 +23076,196 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Gia_Man_t * pTemp;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pAig == NULL )
+ {
+ printf( "Abc_CommandAbc9Srm(): There is no AIG.\n" );
+ return 1;
+ }
+ pAbc->pAig = Gia_ManSpecReduce( pTemp = pAbc->pAig );
+ Gia_ManStop( pTemp );
+ return 0;
+
+usage:
+ fprintf( stdout, "usage: &srm [-vh]\n" );
+ fprintf( stdout, "\t testing various procedures\n" );
+ fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( stdout, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ FILE * pFile;
+ Gia_Man_t * pSecond, * pMiter;
+ char * FileName, * pTemp;
+ char ** pArgvNew;
+ int c, nArgcNew, fMiter = 0;
+ Cec_ManCecSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTmvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBTLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBTLimit < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->TimeLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->TimeLimit < 0 )
+ goto usage;
+ break;
+ case 'm':
+ fMiter ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( fMiter )
+ {
+ printf( "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Cec_ManVerify( pAbc->pAig, pPars );
+ return 0;
+ }
+
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ {
+ printf( "File name is not given on the command line.\n" );
+ return 1;
+ }
+
+ // get the input file name
+ FileName = pArgvNew[0];
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pSecond = Gia_ReadAiger( FileName, 0 );
+ if ( pSecond == NULL )
+ {
+ printf( "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ // compute the miter
+ pMiter = Gia_ManMiter( pAbc->pAig, pSecond, 0, 1, pPars->fVerbose );
+ if ( pMiter )
+ {
+ Cec_ManVerify( pMiter, pPars );
+ Gia_ManStop( pMiter );
+ }
+ Gia_ManStop( pSecond );
+ return 0;
+
+usage:
+ fprintf( stdout, "usage: &cec [-CT num] [-mvh]\n" );
+ fprintf( stdout, "\t new combinational equivalence checker\n" );
+ fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
+ fprintf( stdout, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
+ fprintf( stdout, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits");
+ fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
+ fprintf( stdout, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Force( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ int nIters = 20;
+ int fClustered = 1;
+ int fVerbose = 1;
int c;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Icvh" ) ) != EOF )
{
switch ( c )
{
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nIters < 0 )
+ goto usage;
+ break;
+ case 'c':
+ fClustered ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -22996,17 +23274,20 @@ int Abc_CommandAbc9Force( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( pAbc->pAig == NULL )
{
- printf( "Abc_CommandAbc9Test(): There is no AIG.\n" );
+ printf( "Abc_CommandAbc9Force(): There is no AIG.\n" );
return 1;
}
- For_ManExperiment( pAbc->pAig );
+ For_ManExperiment( pAbc->pAig, nIters, fClustered, fVerbose );
return 0;
usage:
- fprintf( stdout, "usage: &force [-h]\n" );
- fprintf( stdout, "\t one-dimensional placement algorithm FORCE introduced by\n" );
- fprintf( stdout, "\t F. A. Aloul, I. L. Markov, and K. A. Sakallah (GLSVLSI’03).\n" );
- fprintf( stdout, "\t-h : print the command usage\n");
+ fprintf( stdout, "usage: &force [-I <num>] [-cvh]\n" );
+ fprintf( stdout, "\t one-dimensional placement algorithm FORCE introduced by\n" );
+ fprintf( stdout, "\t F. A. Aloul, I. L. Markov, and K. A. Sakallah (GLSVLSI’03).\n" );
+ fprintf( stdout, "\t-I num : the number of refinement iterations [default = %d]\n", nIters );
+ fprintf( stdout, "\t-c : toggle clustered representation [default = %s]\n", fClustered? "yes":"no");
+ fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes":"no");
+ fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
@@ -23023,13 +23304,19 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Embed( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- int nDims = 30;
- int fCluster = 0;
- int fDump = 0;
- int fVerbose = 0;
+ Emb_Par_t Pars, * pPars = &Pars;
int c;
+ pPars->nDims = 30;
+ pPars->nIters = 10;
+ pPars->nSols = 2;
+ pPars->fRefine = 0;
+ pPars->fCluster = 0;
+ pPars->fDump = 0;
+ pPars->fDumpLarge = 0;
+ pPars->fShowImage = 0;
+ pPars->fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Ddcvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "DIrcdlsvh" ) ) != EOF )
{
switch ( c )
{
@@ -23039,19 +23326,39 @@ int Abc_CommandAbc9Embed( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( stdout, "Command line switch \"-D\" should be followed by an integer.\n" );
goto usage;
}
- nDims = atoi(argv[globalUtilOptind]);
+ pPars->nDims = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nDims < 0 )
+ if ( pPars->nDims < 0 )
goto usage;
break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-D\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIters < 0 )
+ goto usage;
+ break;
+ case 'r':
+ pPars->fRefine ^= 1;
+ break;
case 'c':
- fCluster ^= 1;
+ pPars->fCluster ^= 1;
break;
case 'd':
- fDump ^= 1;
+ pPars->fDump ^= 1;
+ break;
+ case 'l':
+ pPars->fDumpLarge ^= 1;
+ break;
+ case 's':
+ pPars->fShowImage ^= 1;
break;
case 'v':
- fVerbose ^= 1;
+ pPars->fVerbose ^= 1;
break;
case 'h':
goto usage;
@@ -23061,24 +23368,247 @@ int Abc_CommandAbc9Embed( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( pAbc->pAig == NULL )
{
- printf( "Abc_CommandAbc9Test(): There is no AIG.\n" );
+ printf( "Abc_CommandAbc9Embed(): There is no AIG.\n" );
return 1;
}
- Gia_ManSolveProblem( pAbc->pAig, nDims, 2, fCluster, fDump, fVerbose );
+ Gia_ManSolveProblem( pAbc->pAig, pPars );
return 0;
usage:
- fprintf( stdout, "usage: &embed [-D num] [-dcvh]\n" );
+ fprintf( stdout, "usage: &embed [-DI <num>] [-rdlscvh]\n" );
fprintf( stdout, "\t fast placement based on high-dimensional embedding from\n" );
fprintf( stdout, "\t D. Harel and Y. Koren, \"Graph drawing by high-dimensional\n" );
fprintf( stdout, "\t embedding\", J. Graph Algs & Apps, 2004, Vol 8(2), pp. 195-217\n" );
- fprintf( stdout, "\t-D num : the number of dimensions for embedding [default = %d]\n", nDims );
- fprintf( stdout, "\t-d : toggle dumping placement into a Gnuplot file [default = %s]\n", fDump? "yes":"no");
- fprintf( stdout, "\t-c : toggle clustered representation [default = %s]\n", fCluster? "yes":"no");
- fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes":"no");
+ fprintf( stdout, "\t-D num : the number of dimensions for embedding [default = %d]\n", pPars->nDims );
+ fprintf( stdout, "\t-I num : the number of refinement iterations [default = %d]\n", pPars->nIters );
+ fprintf( stdout, "\t-r : toggle the use of refinement [default = %s]\n", pPars->fRefine? "yes":"no");
+ fprintf( stdout, "\t-c : toggle clustered representation [default = %s]\n", pPars->fCluster? "yes":"no");
+ fprintf( stdout, "\t-d : toggle dumping placement into a Gnuplot file [default = %s]\n", pPars->fDump? "yes":"no");
+ fprintf( stdout, "\t-l : toggle dumping Gnuplot for large placement [default = %s]\n", pPars->fDumpLarge? "yes":"no");
+ fprintf( stdout, "\t-s : toggle showing image if Gnuplot is installed [default = %s]\n", pPars->fShowImage? "yes":"no");
+ fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ char Buffer[200];
+ char LutSize[200];
+ If_Par_t Pars, * pPars = &Pars;
+ int c;
+ extern void Gia_ManSetIfParsDefault( If_Par_t * pPars );
+ extern int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars );
+ if ( pAbc->pAbc8Lib == NULL )
+ {
+ printf( "LUT library is not given. Using default 6-LUT library.\n" );
+ pAbc->pAbc8Lib = If_SetSimpleLutLib( 6 );
+ }
+ // set defaults
+ Gia_ManSetIfParsDefault( pPars );
+ pPars->pLutLib = pAbc->pAbc8Lib;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KCFADEqaflepmrstbvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-K\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ pPars->nLutSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nLutSize < 0 )
+ goto usage;
+ // if the LUT size is specified, disable library
+ pPars->pLutLib = NULL;
+ break;
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-C\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ pPars->nCutsMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCutsMax < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-F\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ pPars->nFlowIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nFlowIters < 0 )
+ goto usage;
+ break;
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-A\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ pPars->nAreaIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nAreaIters < 0 )
+ goto usage;
+ break;
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-D\" should be followed by a floating point number.\n" );
+ goto usage;
+ }
+ pPars->DelayTarget = (float)atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->DelayTarget <= 0.0 )
+ goto usage;
+ break;
+ case 'E':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( stdout, "Command line switch \"-E\" should be followed by a floating point number.\n" );
+ goto usage;
+ }
+ pPars->Epsilon = (float)atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->Epsilon < 0.0 || pPars->Epsilon > 1.0 )
+ goto usage;
+ break;
+ case 'q':
+ pPars->fPreprocess ^= 1;
+ break;
+ case 'a':
+ pPars->fArea ^= 1;
+ break;
+ case 'r':
+ pPars->fExpRed ^= 1;
+ break;
+ case 'f':
+ pPars->fFancy ^= 1;
+ break;
+ case 'l':
+ pPars->fLatchPaths ^= 1;
+ break;
+ case 'e':
+ pPars->fEdge ^= 1;
+ break;
+ case 'p':
+ pPars->fPower ^= 1;
+ break;
+ case 'm':
+ pPars->fCutMin ^= 1;
+ break;
+ case 's':
+ pPars->fSeqMap ^= 1;
+ break;
+ case 't':
+ pPars->fLiftLeaves ^= 1;
+ break;
+ case 'b':
+ pPars->fBidec ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pAig == NULL )
+ {
+ printf( "Abc_CommandAbc9If(): There is no AIG to map.\n" );
+ return 1;
+ }
+
+ if ( pPars->nLutSize < 3 || pPars->nLutSize > IF_MAX_LUTSIZE )
+ {
+ fprintf( stdout, "Incorrect LUT size (%d).\n", pPars->nLutSize );
+ return 1;
+ }
+
+ if ( pPars->nCutsMax < 1 || pPars->nCutsMax >= (1<<12) )
+ {
+ fprintf( stdout, "Incorrect number of cuts.\n" );
+ return 1;
+ }
+/*
+ // enable truth table computation if choices are selected
+ if ( (c = Aig_ManChoiceNum( pAbc->pAbc8Aig )) )
+ {
+ printf( "Performing LUT mapping with %d choices.\n", c );
+ pPars->fExpRed = 0;
+ }
+*/
+ // enable truth table computation if cut minimization is selected
+ if ( pPars->fCutMin )
+ {
+ pPars->fTruth = 1;
+ pPars->fExpRed = 0;
+ }
+
+ // complain if truth tables are requested but the cut size is too large
+ if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE )
+ {
+ fprintf( stdout, "Truth tables cannot be computed for LUT larger than %d inputs.\n", IF_MAX_FUNC_LUTSIZE );
+ return 1;
+ }
+
+ if ( !Gia_MappingIf( pAbc->pAig, pPars ) )
+ {
+ printf( "Abc_CommandAbc9If(): Mapping of the AIG has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ if ( pPars->DelayTarget == -1 )
+ sprintf( Buffer, "best possible" );
+ else
+ sprintf( Buffer, "%.2f", pPars->DelayTarget );
+ if ( pPars->nLutSize == -1 )
+ sprintf( LutSize, "library" );
+ else
+ sprintf( LutSize, "%d", pPars->nLutSize );
+ fprintf( stdout, "usage: &if [-KCFA num] [-DE float] [-qarlepmbvh]\n" );
+ fprintf( stdout, "\t performs FPGA technology mapping of the network\n" );
+ fprintf( stdout, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize );
+ fprintf( stdout, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
+ fprintf( stdout, "\t-F num : the number of area flow recovery iterations (num >= 0) [default = %d]\n", pPars->nFlowIters );
+ fprintf( stdout, "\t-A num : the number of exact area recovery iterations (num >= 0) [default = %d]\n", pPars->nAreaIters );
+ fprintf( stdout, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer );
+ fprintf( stdout, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->Epsilon );
+ fprintf( stdout, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
+ fprintf( stdout, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
+// fprintf( stdout, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
+ fprintf( stdout, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "yes": "no" );
+ fprintf( stdout, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" );
+ fprintf( stdout, "\t-e : uses edge-based cut selection heuristics [default = %s]\n", pPars->fEdge? "yes": "no" );
+ fprintf( stdout, "\t-p : uses power-aware cut selection heuristics [default = %s]\n", pPars->fPower? "yes": "no" );
+ fprintf( stdout, "\t-m : enables cut minimization by removing vacuous variables [default = %s]\n", pPars->fCutMin? "yes": "no" );
+// fprintf( stdout, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeqMap? "yes": "no" );
+// fprintf( stdout, "\t-t : toggles the use of true sequential cuts [default = %s]\n", pPars->fLiftLeaves? "yes": "no" );
+ fprintf( stdout, "\t-b : toggles deriving local AIGs using bi-decomposition [default = %s]\n", pPars->fBidec? "yes": "no" );
+ fprintf( stdout, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ fprintf( stdout, "\t-h : prints the command usage\n");
+ return 1;
+}
/**Function*************************************************************
@@ -23093,14 +23623,18 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- int c;
+ Gia_Man_t * pTemp = NULL;
+ int c, fVerbose = 0;
extern void Gia_SatSolveTest( Gia_Man_t * p );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
switch ( c )
{
+ case 'v':
+ fVerbose ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -23116,19 +23650,18 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
// Gia_ManReduceConst( pAbc->pAig, 1 );
// Sat_ManTest( pAbc->pAig, Gia_ManCo(pAbc->pAig, 0), 0 );
// Gia_ManTestDistance( pAbc->pAig );
-// For_ManExperiment( pAbc->pAig );
- Gia_ManSolveProblem( pAbc->pAig, 30, 2, 1, 0, 1 );
// Gia_SatSolveTest( pAbc->pAig );
+// For_ManExperiment( pAbc->pAig, 20, 1, 1 );
return 0;
usage:
- fprintf( stdout, "usage: &test [-h]\n" );
+ fprintf( stdout, "usage: &test [-vh]\n" );
fprintf( stdout, "\t testing various procedures\n" );
+ fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
-
/**Function*************************************************************
Synopsis []
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index dbd461c4..ca33667f 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -702,35 +702,6 @@ Abc_Ntk_t * Abc_NtkDarFraig( Abc_Ntk_t * pNtk, int nConfLimit, int fDoSparse, in
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Abc_NtkDarSatSweep( Abc_Ntk_t * pNtk, Cec_ParCsw_t * pPars )
-{
-/*
- extern Aig_Man_t * Cec_ManSatSweep( Aig_Man_t * pAig, Cec_ParCsw_t * pPars );
- Abc_Ntk_t * pNtkAig;
- Aig_Man_t * pMan, * pTemp;
- pMan = Abc_NtkToDar( pNtk, 0, 0 );
- if ( pMan == NULL )
- return NULL;
- pMan = Cec_ManSatSweep( pTemp = pMan, pPars );
- Aig_ManStop( pTemp );
- pNtkAig = Abc_NtkFromDar( pNtk, pMan );
- Aig_ManStop( pMan );
- return pNtkAig;
- */
- return NULL;
-}
-
-/**Function*************************************************************
-
- Synopsis [Gives the current ABC network to AIG manager for processing.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
Abc_Ntk_t * Abc_NtkDarFraigPart( Abc_Ntk_t * pNtk, int nPartSize, int nConfLimit, int nLevelMax, int fVerbose )
{
Abc_Ntk_t * pNtkAig;
@@ -1184,7 +1155,17 @@ int Abc_NtkDarCec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int fPa
Aig_Man_t * pMan, * pMan1, * pMan2;
Abc_Ntk_t * pMiter;
int RetValue, clkTotal = clock();
-
+/*
+ {
+ extern void Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose );
+ Aig_Man_t * pAig0 = Abc_NtkToDar( pNtk1, 0, 0 );
+ Aig_Man_t * pAig1 = Abc_NtkToDar( pNtk2, 0, 0 );
+ Cec_ManVerifyTwoAigs( pAig0, pAig1, 1 );
+ Aig_ManStop( pAig0 );
+ Aig_ManStop( pAig1 );
+ return 1;
+ }
+*/
// cannot partition if it is already a miter
if ( pNtk2 == NULL && fPartition == 1 )
{
@@ -1285,82 +1266,6 @@ ABC_PRT( "Time", clock() - clkTotal );
SeeAlso []
***********************************************************************/
-int Abc_NtkDarCec2( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Cec_ParCec_t * pPars )
-{
- Aig_Man_t * pMan1, * pMan2 = NULL;
- int RetValue, clkTotal = clock();
- if ( pNtk2 )
- {
- if ( Abc_NtkPiNum(pNtk1) != Abc_NtkPiNum(pNtk2) )
- {
- printf( "Networks have different number of PIs.\n" );
- return -1;
- }
- if ( Abc_NtkPoNum(pNtk1) != Abc_NtkPoNum(pNtk2) )
- {
- printf( "Networks have different number of POs.\n" );
- return -1;
- }
- }
- if ( pNtk1 )
- {
- pMan1 = Abc_NtkToDar( pNtk1, 0, 0 );
- if ( pMan1 == NULL )
- {
- printf( "Converting into AIG has failed.\n" );
- return -1;
- }
- }
- if ( pNtk2 )
- {
- pMan2 = Abc_NtkToDar( pNtk2, 0, 0 );
- if ( pMan2 == NULL )
- {
- Aig_ManStop( pMan1 );
- printf( "Converting into AIG has failed.\n" );
- return -1;
- }
- }
- // perform verification
-// RetValue = Cec_Solve( pMan1, pMan2, pPars );
- RetValue = -1;
- // transfer model if given
- pNtk1->pModel = pMan1->pData, pMan1->pData = NULL;
- Aig_ManStop( pMan1 );
- if ( pMan2 )
- Aig_ManStop( pMan2 );
-
- // 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 );
- }
- else
- {
- printf( "Networks are UNDECIDED. " );
-ABC_PRT( "Time", clock() - clkTotal );
- }
- fflush( stdout );
- return RetValue;
-}
-
-/**Function*************************************************************
-
- Synopsis [Gives the current ABC network to AIG manager for processing.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, Fra_Ssw_t * pPars )
{
Fraig_Params_t Params;
@@ -1797,8 +1702,8 @@ int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk )
Aig_ManStop( pPart1 );
Aig_ManStop( pMan );
return 1;
-}
-
+}
+
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
@@ -1826,6 +1731,7 @@ int Abc_NtkDarProve( Abc_Ntk_t * pNtk, Fra_Sec_t * pSecPar )
Abc_NtkMakeComb( pNtkComb, 1 );
// solve it using combinational equivalence checking
Prove_ParamsSetDefault( pParams );
+ pParams->fVerbose = 1;
RetValue = Abc_NtkIvyProve( &pNtkComb, pParams );
// transfer model if given
// pNtk->pModel = pNtkComb->pModel; pNtkComb->pModel = NULL;
diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c
index 7f3d2071..796a51a4 100644
--- a/src/base/abci/abcDsd.c
+++ b/src/base/abci/abcDsd.c
@@ -161,7 +161,8 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
int i, nNodesDsd;
// save the CI nodes in the DSD nodes
- Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)(ABC_PTRINT_T)Abc_NtkCreateNodeConst1(pNtkNew) );
+ Abc_AigConst1(pNtk)->pCopy = pNodeNew = Abc_NtkCreateNodeConst1(pNtkNew);
+ Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)(ABC_PTRINT_T)pNodeNew );
Abc_NtkForEachCi( pNtk, pNode, i )
{
pNodeDsd = Dsd_ManagerReadInput( pManDsd, i );
diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c
new file mode 100644
index 00000000..6906e2c4
--- /dev/null
+++ b/src/base/abci/abcLutmin.c
@@ -0,0 +1,209 @@
+/**CFile****************************************************************
+
+ FileName [abcLutmin.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Minimization of the number of LUTs.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcLutmin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node to MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateNodeLut( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc, Abc_Obj_t * pNode, int nLutSize )
+{
+ DdNode * bFuncNew;
+ Abc_Obj_t * pNodeNew;
+ int i, nStart = ABC_MIN( 0, Abc_ObjFaninNum(pNode) - nLutSize );
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ // add the fanins in the order, in which they appear in the reordered manager
+ for ( i = nStart; i < Abc_ObjFaninNum(pNode); i++ )
+ Abc_ObjAddFanin( pNodeNew, Abc_ObjFanin(pNode, i)->pCopy );
+ // transfer the function
+ bFuncNew = Extra_bddMove( dd, bFunc, nStart ); Cudd_Ref( bFuncNew );
+ assert( Cudd_SupportSize(dd, bFuncNew) <= nLutSize );
+ pNodeNew->pData = Extra_TransferLevelByLevel( dd, pNtkNew->pManFunc, bFuncNew ); Cudd_Ref( pNodeNew->pData );
+ Cudd_RecursiveDeref( dd, bFuncNew );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node to MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeBddToMuxesLut_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node, Abc_Obj_t * pNode, int nLutSize )
+{
+ Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
+ assert( !Cudd_IsComplement(bFunc) );
+ if ( bFunc == b1 )
+ return Abc_NtkCreateNodeConst1(pNtkNew);
+ if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) )
+ return pNodeNew;
+ if ( dd->perm[bFunc->index] >= Abc_ObjFaninNum(pNode) - nLutSize )
+ {
+ pNodeNew = Abc_NtkCreateNodeLut( pNtkNew, dd, bFunc, pNode, nLutSize );
+ st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew );
+ return pNodeNew;
+ }
+ // solve for the children nodes
+ pNodeNew0 = Abc_NodeBddToMuxesLut_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node, pNode, nLutSize );
+ if ( Cudd_IsComplement(cuddE(bFunc)) )
+ pNodeNew0 = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew0 );
+ pNodeNew1 = Abc_NodeBddToMuxesLut_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node, pNode, nLutSize );
+ if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) )
+ assert( 0 );
+ // create the MUX node
+ pNodeNew = Abc_NtkCreateNodeMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 );
+ st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node to MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeBddToMuxesLut( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, int nLutSize )
+{
+ DdManager * dd = pNodeOld->pNtk->pManFunc;
+ DdNode * bFunc = pNodeOld->pData;
+ Abc_Obj_t * pFaninOld, * pNodeNew;
+ st_table * tBdd2Node;
+ int i;
+ // create the table mapping BDD nodes into the ABC nodes
+ tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash );
+ // add the constant and the elementary vars
+ Abc_ObjForEachFanin( pNodeOld, pFaninOld, i )
+ st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy );
+ // create the new nodes recursively
+ pNodeNew = Abc_NodeBddToMuxesLut_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node, pNodeOld, nLutSize );
+ st_free_table( tBdd2Node );
+ if ( Cudd_IsComplement(bFunc) )
+ pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkLutminConstruct( Abc_Ntk_t * pNtkClp, Abc_Ntk_t * pNtkDec, int nLutSize )
+{
+ Abc_Obj_t * pObj, * pDriver;
+ int i;
+ Abc_NtkForEachCo( pNtkClp, pObj, i )
+ {
+ pDriver = Abc_ObjFanin0( pObj );
+ if ( !Abc_ObjIsNode(pDriver) )
+ continue;
+ if ( Abc_ObjFaninNum(pDriver) == 0 )
+ pDriver->pCopy = Abc_NtkDupObj( pNtkDec, pDriver, 0 );
+ else
+ pDriver->pCopy = Abc_NodeBddToMuxesLut( pNtkDec, pDriver, nLutSize );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
+{
+ extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );
+ Abc_Ntk_t * pNtkDec, * pNtkClp, * pTemp;
+ // collapse the network and reorder BDDs
+ if ( Abc_NtkIsStrash(pNtk) )
+ pTemp = Abc_NtkDup( pNtk );
+ else
+ pTemp = Abc_NtkStrash( pNtk, 0, 1, 0 );
+ pNtkClp = Abc_NtkCollapse( pTemp, 10000, 0, 1, 0 );
+ Abc_NtkDelete( pTemp );
+ if ( pNtkClp == NULL )
+ return NULL;
+ if ( !Abc_NtkIsBddLogic(pNtkClp) )
+ Abc_NtkToBdd( pNtkClp );
+ Abc_NtkBddReorder( pNtkClp, fVerbose );
+ // decompose one output at a time
+ pNtkDec = Abc_NtkStartFrom( pNtkClp, ABC_NTK_LOGIC, ABC_FUNC_BDD );
+ // make sure the new manager has enough inputs
+ Cudd_bddIthVar( pNtkDec->pManFunc, nLutSize );
+ // put the results into the new network (save new CO drivers in old CO drivers)
+ Abc_NtkLutminConstruct( pNtkClp, pNtkDec, nLutSize );
+ // finalize the new network
+ Abc_NtkFinalize( pNtkClp, pNtkDec );
+ Abc_NtkDelete( pNtkClp );
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkDec );
+ // fix the problem with complemented and duplicated CO edges
+ Abc_NtkLogicMakeSimpleCos( pNtkDec, 0 );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkDec ) )
+ {
+ printf( "Abc_NtkLutmin: The network check has failed.\n" );
+ return 0;
+ }
+ return pNtkDec;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
index e520dcce..9214bb52 100644
--- a/src/base/abci/module.make
+++ b/src/base/abci/module.make
@@ -24,6 +24,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcIf.c \
src/base/abci/abcIvy.c \
src/base/abci/abcLut.c \
+ src/base/abci/abcLutmin.c \
src/base/abci/abcMap.c \
src/base/abci/abcMerge.c \
src/base/abci/abcMini.c \
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index 21853e9a..398415ae 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -1737,6 +1737,73 @@ usage:
}
+/**Function*************************************************************
+
+ Synopsis [Computes dimentions of the graph.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManGnuplotShow( char * pPlotFileName )
+{
+ FILE * pFile;
+ void * pAbc;
+ char * pProgNameGnuplotWin = "wgnuplot.exe";
+ char * pProgNameGnuplotUnix = "gnuplot";
+ char * pProgNameGnuplot;
+
+ // read in the Capo plotting output
+ if ( (pFile = fopen( pPlotFileName, "r" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the plot file \"%s\".\n\n", pPlotFileName );
+ return;
+ }
+ fclose( pFile );
+
+ pAbc = Abc_FrameGetGlobalFrame();
+
+ // get the names from the plotting software
+ if ( Cmd_FlagReadByName(pAbc, "gnuplotwin") )
+ pProgNameGnuplotWin = Cmd_FlagReadByName(pAbc, "gnuplotwin");
+ if ( Cmd_FlagReadByName(pAbc, "gnuplotunix") )
+ pProgNameGnuplotUnix = Cmd_FlagReadByName(pAbc, "gnuplotunix");
+
+ // check if Gnuplot is available
+ if ( (pFile = fopen( pProgNameGnuplotWin, "r" )) )
+ pProgNameGnuplot = pProgNameGnuplotWin;
+ else if ( (pFile = fopen( pProgNameGnuplotUnix, "r" )) )
+ pProgNameGnuplot = pProgNameGnuplotUnix;
+ else if ( pFile == NULL )
+ {
+ fprintf( stdout, "Cannot find \"%s\" or \"%s\" in the current directory.\n", pProgNameGnuplotWin, pProgNameGnuplotUnix );
+ return;
+ }
+ fclose( pFile );
+
+ // spawn the viewer
+#ifdef WIN32
+ if ( _spawnl( _P_NOWAIT, pProgNameGnuplot, pProgNameGnuplot, pPlotFileName, NULL ) == -1 )
+ {
+ fprintf( stdout, "Cannot find \"%s\".\n", pProgNameGnuplot );
+ return;
+ }
+#else
+ {
+ char Command[1000];
+ sprintf( Command, "%s %s ", pProgNameGnuplot, pPlotFileName );
+ if ( system( Command ) == -1 )
+ {
+ fprintf( stdout, "Cannot execute \"%s\".\n", Command );
+ return;
+ }
+ }
+#endif
+}
+
/**Function********************************************************************
Synopsis [Calls Capo internally.]
diff --git a/src/base/io/io.c b/src/base/io/io.c
index ee5df414..e8af161e 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -28,6 +28,7 @@
static int IoCommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadAiger ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadBaf ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadBblif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadBlifMv ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadBench ( Abc_Frame_t * pAbc, int argc, char **argv );
@@ -45,6 +46,7 @@ static int IoCommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteHie ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteAiger ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBaf ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteBblif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBlifMv ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBench ( Abc_Frame_t * pAbc, int argc, char **argv );
@@ -83,6 +85,7 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "read", IoCommandRead, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_aiger", IoCommandReadAiger, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_baf", IoCommandReadBaf, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_bblif", IoCommandReadBblif, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_blif", IoCommandReadBlif, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_blif_mv", IoCommandReadBlifMv, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_bench", IoCommandReadBench, 1 );
@@ -100,6 +103,7 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "write_hie", IoCommandWriteHie, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_aiger", IoCommandWriteAiger, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_baf", IoCommandWriteBaf, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_bblif", IoCommandWriteBblif, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_blif", IoCommandWriteBlif, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_blif_mv", IoCommandWriteBlifMv, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_bench", IoCommandWriteBench, 0 );
@@ -316,6 +320,60 @@ usage:
SeeAlso []
***********************************************************************/
+int IoCommandReadBblif( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_BBLIF, fCheck );
+ if ( pNtk == NULL )
+ return 1;
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_bblif [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in a binary BLIF format\n" );
+ fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk;
@@ -1329,6 +1387,54 @@ usage:
SeeAlso []
***********************************************************************/
+int IoCommandWriteBblif( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BBLIF );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_bblif [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network into a binary BLIF file\n" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .bblif)\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
{
char * pFileName;
diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h
index c11168df..bade17df 100644
--- a/src/base/io/ioAbc.h
+++ b/src/base/io/ioAbc.h
@@ -44,6 +44,7 @@ typedef enum {
IO_FILE_NONE = 0,
IO_FILE_AIGER,
IO_FILE_BAF,
+ IO_FILE_BBLIF,
IO_FILE_BLIF,
IO_FILE_BLIFMV,
IO_FILE_BENCH,
@@ -73,6 +74,8 @@ typedef enum {
extern Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck );
/*=== abcReadBaf.c ============================================================*/
extern Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck );
+/*=== abcReadBblif.c ============================================================*/
+extern Abc_Ntk_t * Io_ReadBblif( char * pFileName, int fCheck );
/*=== abcReadBlif.c ===========================================================*/
extern Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck );
/*=== abcReadBlifMv.c =========================================================*/
@@ -91,6 +94,8 @@ extern Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck );
extern void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int fCompact );
/*=== abcWriteBaf.c ===========================================================*/
extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName );
+/*=== abcWriteBblif.c ===========================================================*/
+extern void Io_WriteBblif( Abc_Ntk_t * pNtk, char * pFileName );
/*=== abcWriteBlif.c ==========================================================*/
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
diff --git a/src/base/io/ioReadAiger.c b/src/base/io/ioReadAiger.c
index 2c37e210..c26e4cd5 100644
--- a/src/base/io/ioReadAiger.c
+++ b/src/base/io/ioReadAiger.c
@@ -463,19 +463,19 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
}
// read the name of the model if given
- if ( *pCur == 'c' && pCur < pContents + nFileSize )
+ pCur = pSymbols;
+ if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
{
- if ( !strncmp( pCur + 2, ".model", 6 ) )
+ pCur++;
+ if ( *pCur == 'n' )
{
- char * pTemp;
- for ( pTemp = pCur + 9; *pTemp && *pTemp != '\n'; pTemp++ );
- *pTemp = 0;
+ pCur++;
+ // read model name
ABC_FREE( pNtkNew->pName );
- pNtkNew->pName = Extra_UtilStrsav( pCur + 9 );
+ pNtkNew->pName = Extra_UtilStrsav( pCur );
}
}
-
// skipping the comments
ABC_FREE( pContents );
Vec_PtrFree( vNodes );
diff --git a/src/base/io/ioReadBblif.c b/src/base/io/ioReadBblif.c
new file mode 100644
index 00000000..84ef1e29
--- /dev/null
+++ b/src/base/io/ioReadBblif.c
@@ -0,0 +1,342 @@
+/**CFile****************************************************************
+
+ FileName [ioReadBblif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read AIG in the binary format.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioReadBblif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ioAbc.h"
+#include "dec.h"
+#include "bblif.h"
+
+// For description of Binary BLIF format, refer to "abc/src/aig/bbl/bblif.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Fnction*************************************************************
+
+ Synopsis [Constructs ABC network from the manager.]
+
+ Description [The ABC network is started, as well as the array vCopy,
+ which will map the new ID of each object in the BBLIF manager into
+ the ponter ot the corresponding object in the ABC. For each internal
+ node, determined by Bbl_ObjIsLut(), the SOP representation is created
+ by retrieving the SOP representation of the BBLIF object. Finally,
+ the objects are connected using fanin/fanout creation, and the dummy
+ names are assigned because ABC requires each CI/CO to have a name.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Bbl_ManToAbc( Bbl_Man_t * p )
+{
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pObjNew;
+ Bbl_Obj_t * pObj, * pFanin;
+ Vec_Ptr_t * vCopy;
+ // start the network
+ pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) );
+ // create objects
+ vCopy = Vec_PtrStart( 1000 );
+ Bbl_ManForEachObj( p, pObj )
+ {
+ if ( Bbl_ObjIsInput(pObj) )
+ pObjNew = Abc_NtkCreatePi( pNtk );
+ else if ( Bbl_ObjIsOutput(pObj) )
+ pObjNew = Abc_NtkCreatePo( pNtk );
+ else if ( Bbl_ObjIsLut(pObj) )
+ pObjNew = Abc_NtkCreateNode( pNtk );
+ else assert( 0 );
+ if ( Bbl_ObjIsLut(pObj) )
+ pObjNew->pData = Abc_SopRegister( pNtk->pManFunc, Bbl_ObjSop(p, pObj) );
+ Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew );
+ }
+ // connect objects
+ Bbl_ManForEachObj( p, pObj )
+ Bbl_ObjForEachFanin( pObj, pFanin )
+ Abc_ObjAddFanin( Vec_PtrEntry(vCopy, Bbl_ObjId(pObj)), Vec_PtrEntry(vCopy, Bbl_ObjId(pFanin)) );
+ // finalize
+ Vec_PtrFree( vCopy );
+ Abc_NtkAddDummyPiNames( pNtk );
+ Abc_NtkAddDummyPoNames( pNtk );
+ if ( !Abc_NtkCheck( pNtk ) )
+ printf( "Bbl_ManToAbc(): Network check has failed.\n" );
+ return pNtk;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Collects internal nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManDfs_rec( Bbl_Obj_t * pObj, Vec_Ptr_t * vNodes )
+{
+ extern void Bbl_ObjMark( Bbl_Obj_t * p );
+ extern int Bbl_ObjIsMarked( Bbl_Obj_t * p );
+ Bbl_Obj_t * pFanin;
+ if ( Bbl_ObjIsMarked(pObj) || Bbl_ObjIsInput(pObj) )
+ return;
+ Bbl_ObjForEachFanin( pObj, pFanin )
+ Bbl_ManDfs_rec( pFanin, vNodes );
+ assert( !Bbl_ObjIsMarked(pObj) ); // checks if acyclic
+ Bbl_ObjMark( pObj );
+ Vec_PtrPush( vNodes, pObj );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Collects internal nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Bbl_ManDfs( Bbl_Man_t * p )
+{
+ Vec_Ptr_t * vNodes;
+ Bbl_Obj_t * pObj;
+ vNodes = Vec_PtrAlloc( 1000 );
+ Bbl_ManForEachObj( p, pObj )
+ if ( Bbl_ObjIsLut(pObj) )
+ Bbl_ManDfs_rec( pObj, vNodes );
+ return vNodes;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Constructs AIG in ABC from the manager.]
+
+ Description [The ABC network is started, as well as the array vCopy,
+ which will map the new ID of each object in the BBLIF manager into
+ the ponter ot the corresponding AIG object in the ABC. For each internal
+ node in a topological oder the AIG representation is created
+ by factoring the SOP representation of the BBLIF object. Finally,
+ the CO objects are created, and the dummy names are assigned because
+ ABC requires each CI/CO to have a name.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Bbl_ManToAig( Bbl_Man_t * p )
+{
+ extern int Bbl_ManFncSize( Bbl_Man_t * p );
+ extern int Bbl_ObjFncHandle( Bbl_Obj_t * p );
+ extern Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs );
+ int fVerbose = 0;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pObjNew;
+ Bbl_Obj_t * pObj, * pFanin;
+ Vec_Ptr_t * vCopy, * vNodes, * vFaninAigs;
+ Dec_Graph_t ** pFForms;
+ int i, clk;
+clk = clock();
+ // map SOP handles into factored forms
+ pFForms = ABC_CALLOC( Dec_Graph_t *, Bbl_ManFncSize(p) );
+ Bbl_ManForEachObj( p, pObj )
+ if ( pFForms[Bbl_ObjFncHandle(pObj)] == NULL )
+ pFForms[Bbl_ObjFncHandle(pObj)] = Dec_Factor( Bbl_ObjSop(p, pObj) );
+if ( fVerbose )
+ABC_PRT( "Fct", clock() - clk );
+ // start the network
+ pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
+ pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) );
+ vCopy = Vec_PtrStart( 1000 );
+ // create CIs
+ Bbl_ManForEachObj( p, pObj )
+ {
+ if ( !Bbl_ObjIsInput(pObj) )
+ continue;
+ Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), Abc_NtkCreatePi(pNtk) );
+ }
+clk = clock();
+ // create internal nodes
+ vNodes = Bbl_ManDfs( p );
+ vFaninAigs = Vec_PtrAlloc( 100 );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ // collect fanin AIGs
+ Vec_PtrClear( vFaninAigs );
+ Bbl_ObjForEachFanin( pObj, pFanin )
+ Vec_PtrPush( vFaninAigs, Vec_PtrEntry( vCopy, Bbl_ObjId(pFanin) ) );
+ // create the new node
+ pObjNew = Dec_GraphToAig( pNtk, pFForms[Bbl_ObjFncHandle(pObj)], vFaninAigs );
+ Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew );
+ }
+ Vec_PtrFree( vFaninAigs );
+ Vec_PtrFree( vNodes );
+if ( fVerbose )
+ABC_PRT( "AIG", clock() - clk );
+ // create COs
+ Bbl_ManForEachObj( p, pObj )
+ {
+ if ( !Bbl_ObjIsOutput(pObj) )
+ continue;
+ pObjNew = Vec_PtrEntry( vCopy, Bbl_ObjId(Bbl_ObjFaninFirst(pObj)) );
+ Abc_ObjAddFanin( Abc_NtkCreatePo(pNtk), pObjNew );
+ }
+ Abc_AigCleanup( pNtk->pManFunc );
+ // clear factored forms
+ for ( i = Bbl_ManFncSize(p) - 1; i >= 0; i-- )
+ if ( pFForms[i] )
+ Dec_GraphFree( pFForms[i] );
+ ABC_FREE( pFForms );
+ // finalize
+clk = clock();
+ Vec_PtrFree( vCopy );
+ Abc_NtkAddDummyPiNames( pNtk );
+ Abc_NtkAddDummyPoNames( pNtk );
+if ( fVerbose )
+ABC_PRT( "Nam", clock() - clk );
+// if ( !Abc_NtkCheck( pNtk ) )
+// printf( "Bbl_ManToAig(): Network check has failed.\n" );
+ return pNtk;
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Verifies equivalence for two combinational networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManVerify( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose );
+ Abc_Ntk_t * pAig1, * pAig2;
+ pAig1 = Abc_NtkStrash( pNtk1, 0, 1, 0 );
+ pAig2 = Abc_NtkStrash( pNtk2, 0, 1, 0 );
+ Abc_NtkShortNames( pAig1 );
+ Abc_NtkShortNames( pAig2 );
+ Abc_NtkCecFraig( pAig1, pAig2, 0, 0 );
+ Abc_NtkDelete( pAig1 );
+ Abc_NtkDelete( pAig2 );
+}
+
+/**Fnction*************************************************************
+
+ Synopsis [Performs testing of the new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bbl_ManTest( Abc_Ntk_t * pNtk )
+{
+ extern Bbl_Man_t * Bbl_ManFromAbc( Abc_Ntk_t * pNtk );
+
+ Abc_Ntk_t * pNtkNew;
+ Bbl_Man_t * p, * pNew;
+ char * pFileName = "test.bblif";
+ int clk, clk1, clk2, clk3, clk4, clk5;
+clk = clock();
+ p = Bbl_ManFromAbc( pNtk );
+ Bbl_ManPrintStats( p );
+clk1 = clock() - clk;
+//Bbl_ManDumpBlif( p, "test_bbl.blif" );
+
+ // write into file and back
+clk = clock();
+ Bbl_ManDumpBinaryBlif( p, pFileName );
+clk2 = clock() - clk;
+
+ // read from file
+clk = clock();
+ pNew = Bbl_ManReadBinaryBlif( pFileName );
+ Bbl_ManStop( p ); p = pNew;
+clk3 = clock() - clk;
+
+ // generate ABC network
+clk = clock();
+ pNtkNew = Bbl_ManToAig( p );
+// pNtkNew = Bbl_ManToAbc( p );
+ Bbl_ManStop( p );
+clk4 = clock() - clk;
+
+ // equivalence check
+clk = clock();
+// Bbl_ManVerify( pNtk, pNtkNew );
+ Abc_NtkDelete( pNtkNew );
+clk5 = clock() - clk;
+
+printf( "Runtime stats:\n" );
+ABC_PRT( "ABC to Man", clk1 );
+ABC_PRT( "Writing ", clk2 );
+ABC_PRT( "Reading ", clk3 );
+ABC_PRT( "Man to ABC", clk4 );
+ABC_PRT( "Verify ", clk5 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the AIG in the binary format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBblif( char * pFileName, int fCheck )
+{
+ Bbl_Man_t * p;
+ Abc_Ntk_t * pNtkNew;
+ // read the file
+ p = Bbl_ManReadBinaryBlif( pFileName );
+ pNtkNew = Bbl_ManToAig( p );
+ Bbl_ManStop( p );
+ // check the result
+ if ( fCheck && !Abc_NtkCheckRead( pNtkNew ) )
+ {
+ printf( "Io_ReadBaf: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c
index c67c183d..c00c3008 100644
--- a/src/base/io/ioUtil.c
+++ b/src/base/io/ioUtil.c
@@ -51,6 +51,8 @@ Io_FileType_t Io_ReadFileType( char * pFileName )
return IO_FILE_AIGER;
if ( !strcmp( pExt, "baf" ) )
return IO_FILE_BAF;
+ if ( !strcmp( pExt, "bblif" ) )
+ return IO_FILE_BBLIF;
if ( !strcmp( pExt, "blif" ) )
return IO_FILE_BLIF;
if ( !strcmp( pExt, "bench" ) )
@@ -108,12 +110,14 @@ Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck
}
fclose( pFile );
// read the AIG
- if ( FileType == IO_FILE_AIGER || FileType == IO_FILE_BAF )
+ if ( FileType == IO_FILE_AIGER || FileType == IO_FILE_BAF || FileType == IO_FILE_BBLIF )
{
if ( FileType == IO_FILE_AIGER )
pNtk = Io_ReadAiger( pFileName, fCheck );
- else // if ( FileType == IO_FILE_BAF )
+ else if ( FileType == IO_FILE_BAF )
pNtk = Io_ReadBaf( pFileName, fCheck );
+ else // if ( FileType == IO_FILE_BBLIF )
+ pNtk = Io_ReadBblif( pFileName, fCheck );
if ( pNtk == NULL )
{
fprintf( stdout, "Reading AIG from file has failed.\n" );
@@ -258,7 +262,7 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType )
}
if ( FileType == IO_FILE_AIGER )
Io_WriteAiger( pNtk, pFileName, 1, 0 );
- else // if ( FileType == IO_FILE_BAF )
+ else //if ( FileType == IO_FILE_BAF )
Io_WriteBaf( pNtk, pFileName );
return;
}
@@ -278,6 +282,18 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType )
Io_WriteGml( pNtk, pFileName );
return;
}
+ if ( FileType == IO_FILE_BBLIF )
+ {
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ fprintf( stdout, "Writing Binary BLIF is only possible for logic networks.\n" );
+ return;
+ }
+ if ( !Abc_NtkHasSop(pNtk) )
+ Abc_NtkToSop( pNtk, 0 );
+ Io_WriteBblif( pNtk, pFileName );
+ return;
+ }
/*
if ( FileType == IO_FILE_BLIFMV )
{
diff --git a/src/base/io/ioWriteAiger.c b/src/base/io/ioWriteAiger.c
index f1793a59..8957743c 100644
--- a/src/base/io/ioWriteAiger.c
+++ b/src/base/io/ioWriteAiger.c
@@ -726,10 +726,10 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int f
}
// write the comment
- fprintfBz2Aig( &b, "c\n" );
+ fprintfBz2Aig( &b, "c" );
if ( pNtk->pName && strlen(pNtk->pName) > 0 )
- fprintfBz2Aig( &b, ".model %s\n", pNtk->pName );
- fprintfBz2Aig( &b, "This file was produced by ABC on %s\n", Extra_TimeStamp() );
+ fprintfBz2Aig( &b, "n%s%c", pNtk->pName, '\0' );
+ fprintfBz2Aig( &b, "\nThis file was written by ABC on %s\n", Extra_TimeStamp() );
fprintfBz2Aig( &b, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
// close the file
diff --git a/src/base/io/ioWriteBblif.c b/src/base/io/ioWriteBblif.c
new file mode 100644
index 00000000..e5bd6503
--- /dev/null
+++ b/src/base/io/ioWriteBblif.c
@@ -0,0 +1,111 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteBblif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to write AIG in the binary format.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteBblif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ioAbc.h"
+#include "bblif.h"
+
+// For description of Binary BLIF format, refer to "abc/src/aig/bbl/bblif.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Fnction*************************************************************
+
+ Synopsis [Construct manager from the ABC network.]
+
+ Description [In the ABC network each object has a unique integer ID.
+ This ID is used when we construct objects of the BBLIF manager
+ corresponding to each object of the ABC network. The objects can be
+ added to the manager in any order (although below they are added in the
+ topological order), but by the time fanin/fanout connections are created,
+ corresponding objects are already constructed. In the end the checking
+ procedure is called.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bbl_Man_t * Bbl_ManFromAbc( Abc_Ntk_t * pNtk )
+{
+ Bbl_Man_t * p;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pObj, * pFanin;
+ int i, k;
+ assert( Abc_NtkIsSopLogic(pNtk) );
+ // start the data manager
+ p = Bbl_ManStart( Abc_NtkName(pNtk) );
+ // collect internal nodes to be added
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+ // create combinational inputs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ Bbl_ManCreateObject( p, BBL_OBJ_CI, Abc_ObjId(pObj), 0, NULL );
+ // create internal nodes
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ Bbl_ManCreateObject( p, BBL_OBJ_NODE, Abc_ObjId(pObj), Abc_ObjFaninNum(pObj), pObj->pData );
+ // create combinational outputs
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Bbl_ManCreateObject( p, BBL_OBJ_CO, Abc_ObjId(pObj), 1, NULL );
+ // create fanin/fanout connections for internal nodes
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Bbl_ManAddFanin( p, Abc_ObjId(pObj), Abc_ObjId(pFanin) );
+ // create fanin/fanout connections for combinational outputs
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Bbl_ManAddFanin( p, Abc_ObjId(pObj), Abc_ObjId(pFanin) );
+ Vec_PtrFree( vNodes );
+ // sanity check
+ Bbl_ManCheck( p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteBblif( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ Bbl_Man_t * p;
+ p = Bbl_ManFromAbc( pNtk );
+//Bbl_ManPrintStats( p );
+//Bbl_ManDumpBlif( p, "test_bbl.blif" );
+ Bbl_ManDumpBinaryBlif( p, pFileName );
+ Bbl_ManStop( p );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/module.make b/src/base/io/module.make
index 6f4e2539..993bd7d2 100644
--- a/src/base/io/module.make
+++ b/src/base/io/module.make
@@ -1,6 +1,7 @@
SRC += src/base/io/io.c \
src/base/io/ioReadAiger.c \
src/base/io/ioReadBaf.c \
+ src/base/io/ioReadBblif.c \
src/base/io/ioReadBench.c \
src/base/io/ioReadBlif.c \
src/base/io/ioReadBlifAig.c \
@@ -13,6 +14,7 @@ SRC += src/base/io/io.c \
src/base/io/ioUtil.c \
src/base/io/ioWriteAiger.c \
src/base/io/ioWriteBaf.c \
+ src/base/io/ioWriteBblif.c \
src/base/io/ioWriteBench.c \
src/base/io/ioWriteBlif.c \
src/base/io/ioWriteBlifMv.c \
diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c
index f83747cf..aa213010 100644
--- a/src/base/ver/verCore.c
+++ b/src/base/ver/verCore.c
@@ -623,7 +623,7 @@ void Ver_ParseRemoveSuffixTable( Ver_Man_t * pMan )
***********************************************************************/
int Ver_ParseSignalPrefix( Ver_Man_t * pMan, char ** ppWord, int * pnMsb, int * pnLsb )
{
- char * pWord = *ppWord;
+ char * pWord = *ppWord, * pTemp;
int nMsb, nLsb;
assert( pWord[0] == '[' );
// get the beginning
@@ -654,6 +654,17 @@ int Ver_ParseSignalPrefix( Ver_Man_t * pMan, char ** ppWord, int * pnMsb, int *
}
assert( *pWord == ']' );
pWord++;
+
+ // fix the case when \<name> follows after [] without space
+ if ( *pWord == '\\' )
+ {
+ pWord++;
+ pTemp = pWord;
+ while ( *pTemp && *pTemp != ' ' )
+ pTemp++;
+ if ( *pTemp == ' ' )
+ *pTemp = 0;
+ }
}
assert( nMsb >= 0 && nLsb >= 0 );
// return
diff --git a/src/base/ver/verParse.c b/src/base/ver/verParse.c
index 9462fc8b..c38399f2 100644
--- a/src/base/ver/verParse.c
+++ b/src/base/ver/verParse.c
@@ -101,6 +101,15 @@ char * Ver_ParseGetName( Ver_Man_t * pMan )
pMan->fNameLast = 1;
Ver_StreamPopChar( p );
pWord = Ver_StreamGetWord( p, " \r\n" );
+ Ver_StreamSkipChars( p, " \r\n" );
+ if ( Ver_StreamScanChar(p) == '[' )
+ {
+ char This, * pEnd = pWord + strlen( pWord );
+ while ( (This = Ver_StreamPopChar(p)) != ']' )
+ *pEnd++ = This;
+ *pEnd++ = This;
+ *pEnd = 0;
+ }
}
else
pWord = Ver_StreamGetWord( p, " \t\n\r(),;" );
diff --git a/src/map/amap/amapLiberty.c b/src/map/amap/amapLiberty.c
index 7f46ffdf..4177e27e 100644
--- a/src/map/amap/amapLiberty.c
+++ b/src/map/amap/amapLiberty.c
@@ -346,6 +346,7 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName )
{
FILE * pFile;
Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput;
+ char * pForm;
int Counter;
if ( pFileName == NULL )
pFile = stdout;
@@ -408,6 +409,12 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName )
}
pOutput = Amap_LibertyCellOutput( p, pCell );
pFunc = Amap_LibertyPinFunction( p, pOutput );
+ pForm = Amap_LibertyGetStringFormula( p, pFunc->Head );
+ if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
+ {
+ printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm );
+ continue;
+ }
fprintf( pFile, "GATE " );
fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
@@ -542,13 +549,17 @@ static inline int Amap_LibertyCharIsSpace( char c )
SeeAlso []
***********************************************************************/
-static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd )
+static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd, int fStopAtNewLine )
{
char * pPos = *ppPos;
for ( ; pPos < pEnd; pPos++ )
{
if ( *pPos == '\n' )
+ {
p->nLines++;
+ if ( fStopAtNewLine )
+ break;
+ }
if ( !Amap_LibertyCharIsSpace(*pPos) )
break;
}
@@ -582,9 +593,9 @@ static inline int Amap_LibertySkipEntry( char ** ppPos, char * pEnd )
else
{
for ( ; pPos < pEnd; pPos++ )
- if ( *pPos == ' ' ||
- *pPos == ':' || *pPos == ';' ||
- *pPos == '(' || *pPos == ')' ||
+ if ( *pPos == ' ' || *pPos == '\r' || *pPos == '\n' ||
+ *pPos == ':' || *pPos == ';' ||
+ *pPos == '(' || *pPos == ')' ||
*pPos == '{' || *pPos == '}' )
break;
}
@@ -708,28 +719,28 @@ int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd )
Amap_Item_t * pItem;
Amap_Pair_t Key, Head, Body;
char * pNext, * pStop;
- if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) )
+ if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
return -2;
Key.Beg = *ppPos - p->pContents;
if ( Amap_LibertySkipEntry( ppPos, pEnd ) )
goto exit;
Key.End = *ppPos - p->pContents;
- if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) )
+ if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
goto exit;
pNext = *ppPos;
if ( *pNext == ':' )
{
*ppPos = pNext + 1;
- if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) )
+ if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
goto exit;
Head.Beg = *ppPos - p->pContents;
if ( Amap_LibertySkipEntry( ppPos, pEnd ) )
goto exit;
Head.End = *ppPos - p->pContents;
- if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) )
+ if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 1 ) )
goto exit;
pNext = *ppPos;
- if ( *pNext != ';' )
+ if ( *pNext != ';' && *pNext != '\n' )
goto exit;
*ppPos = pNext + 1;
// end of equation
@@ -747,7 +758,7 @@ int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd )
Head.Beg = pNext - p->pContents + 1;
Head.End = pStop - p->pContents;
*ppPos = pStop + 1;
- if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) )
+ if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
{
// end of list
pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_LIST );
@@ -883,7 +894,7 @@ int Amap_LibertyParse( char * pFileName, char * pFileGenlib, int fVerbose )
{
if ( fVerbose )
printf( "Parsing finished successfully.\n" );
-// Amap_LibertyPrintLiberty( p, "temp.lib" );
+// Amap_LibertyPrintLiberty( p, "temp_.lib" );
Amap_LibertyPrintGenlib( p, "temp.genlib" );
RetValue = 1;
}
diff --git a/src/map/amap/amapParse.c b/src/map/amap/amapParse.c
index 48dabca2..bfa8e6a5 100644
--- a/src/map/amap/amapParse.c
+++ b/src/map/amap/amapParse.c
@@ -35,6 +35,7 @@
#define AMAP_EQN_SYM_AND '*' // logic AND
#define AMAP_EQN_SYM_XOR '^' // logic XOR
#define AMAP_EQN_SYM_OR '+' // logic OR
+#define AMAP_EQN_SYM_OR2 '|' // logic OR
// the list of opcodes (also specifying operation precedence)
#define AMAP_EQN_OPER_NEG 10 // negation
@@ -180,6 +181,7 @@ Hop_Obj_t * Amap_ParseFormula( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVa
break;
case AMAP_EQN_SYM_AND:
case AMAP_EQN_SYM_OR:
+ case AMAP_EQN_SYM_OR2:
case AMAP_EQN_SYM_XOR:
if ( Flag != AMAP_EQN_FLAG_VAR )
{
@@ -189,7 +191,7 @@ Hop_Obj_t * Amap_ParseFormula( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVa
}
if ( *pTemp == AMAP_EQN_SYM_AND )
Vec_IntPush( pStackOp, AMAP_EQN_OPER_AND );
- else if ( *pTemp == AMAP_EQN_SYM_OR )
+ else if ( *pTemp == AMAP_EQN_SYM_OR || *pTemp == AMAP_EQN_SYM_OR2 )
Vec_IntPush( pStackOp, AMAP_EQN_OPER_OR );
else //if ( *pTemp == AMAP_EQN_SYM_XOR )
Vec_IntPush( pStackOp, AMAP_EQN_OPER_XOR );
@@ -246,9 +248,9 @@ Hop_Obj_t * Amap_ParseFormula( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVa
// scan the next name
for ( i = 0; pTemp[i] &&
pTemp[i] != ' ' && pTemp[i] != '\t' && pTemp[i] != '\r' && pTemp[i] != '\n' &&
- pTemp[i] != AMAP_EQN_SYM_AND && pTemp[i] != AMAP_EQN_SYM_OR &&
- pTemp[i] != AMAP_EQN_SYM_XOR && pTemp[i] != AMAP_EQN_SYM_NEGAFT &&
- pTemp[i] != AMAP_EQN_SYM_CLOSE; i++ )
+ pTemp[i] != AMAP_EQN_SYM_AND && pTemp[i] != AMAP_EQN_SYM_OR && pTemp[i] != AMAP_EQN_SYM_OR2 &&
+ pTemp[i] != AMAP_EQN_SYM_XOR && pTemp[i] != AMAP_EQN_SYM_NEGAFT && pTemp[i] != AMAP_EQN_SYM_CLOSE;
+ i++ )
{
if ( pTemp[i] == AMAP_EQN_SYM_NEG || pTemp[i] == AMAP_EQN_SYM_OPEN )
{
diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c
index 0f0ca002..e3fd47f1 100644
--- a/src/map/if/ifCore.c
+++ b/src/map/if/ifCore.c
@@ -55,13 +55,10 @@ int If_ManPerformMapping( If_Man_t * p )
// try sequential mapping
if ( p->pPars->fSeqMap )
{
- int RetValue = 1;
- printf( "Currently sequential mapping is not performed.\n" );
-// RetValue = If_ManPerformMappingSeq( p );
- return RetValue;
-// return 1;
+// if ( p->pPars->fVerbose )
+ printf( "Performing sequential mapping without retiming.\n" );
+ return If_ManPerformMappingSeq( p );
}
-
return If_ManPerformMappingComb( p );
}
diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c
index 2879081c..fd1078a6 100644
--- a/src/map/if/ifMap.c
+++ b/src/map/if/ifMap.c
@@ -169,7 +169,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
If_ObjForEachCut( pObj, pCut, i )
p->pPars->pFuncUser( p, pObj, pCut );
- // ABC_FREE the cuts
+ // free the cuts
If_ManDerefNodeCutSet( p, pObj );
}
@@ -253,7 +253,7 @@ void If_ObjPerformMappingChoice( If_Man_t * p, If_Obj_t * pObj, int Mode, int fP
if ( Mode && pObj->nRefs > 0 )
If_CutAreaRef( p, If_ObjCutBest(pObj) );
- // ABC_FREE the cuts
+ // free the cuts
If_ManDerefChoiceCutSet( p, pObj );
}
diff --git a/src/map/if/ifSeq.c b/src/map/if/ifSeq.c
index 8d1de8c1..e4e27e71 100644
--- a/src/map/if/ifSeq.c
+++ b/src/map/if/ifSeq.c
@@ -124,6 +124,16 @@ int If_ManPerformMappingRoundSeq( If_Man_t * p, int nIter )
int fVeryVerbose = 0;
int fChange = 0;
+ if ( nIter == 1 )
+ {
+ // if some latches depend on PIs, update their values
+ Vec_PtrForEachEntry( p->vLatchOrder, pObj, i )
+ {
+ If_ObjSetLValue( pObj, If_ObjLValue(If_ObjFanin0(pObj)) - p->Period );
+ If_ObjSetArrTime( pObj, If_ObjLValue(pObj) );
+ }
+ }
+
// map the internal nodes
p->nCutsMerged = 0;
If_ManForEachNode( p, pObj, i )
@@ -158,13 +168,14 @@ int If_ManPerformMappingRoundSeq( If_Man_t * p, int nIter )
}
// compute area and delay
+ If_ManMarkMapping( p );
if ( fVeryVerbose )
{
p->RequiredGlo = If_ManDelayMax( p, 1 );
- p->AreaGlo = If_ManScanMapping(p);
+// p->AreaGlo = If_ManScanMapping(p);
printf( "S%d: Fi = %6.2f. Del = %6.2f. Area = %8.2f. Cuts = %8d. ",
nIter, (float)p->Period, p->RequiredGlo, p->AreaGlo, p->nCutsMerged );
- PRT( "T", clock() - clk );
+ ABC_PRT( "T", clock() - clk );
}
return fChange;
}
@@ -185,26 +196,26 @@ int If_ManBinarySearchPeriod( If_Man_t * p )
If_Obj_t * pObj;
int i, c, fConverged;
int fResetRefs = 0;
-
p->nAttempts++;
// reset initial LValues (PIs to 0; others to -inf)
If_ManForEachObj( p, pObj, i )
{
- if ( If_ObjIsPi(pObj) || If_ObjIsConst1(pObj) )
- {
- If_ObjSetLValue( pObj, (float)0.0 );
- If_ObjSetArrTime( pObj, (float)0.0 );
- }
- else
- {
- If_ObjSetLValue( pObj, (float)-IF_INFINITY );
- If_ObjSetArrTime( pObj, (float)-IF_INFINITY );
- }
+ If_ObjSetLValue( pObj, (float)-IF_INFINITY );
+ If_ObjSetArrTime( pObj, (float)-IF_INFINITY );
// undo any previous mapping, except for CIs
if ( If_ObjIsAnd(pObj) )
If_ObjCutBest(pObj)->nLeaves = 0;
}
+ pObj = If_ManConst1( p );
+ If_ObjSetLValue( pObj, (float)0.0 );
+ If_ObjSetArrTime( pObj, (float)0.0 );
+ If_ManForEachPi( p, pObj, i )
+ {
+ pObj = If_ManCi( p, i );
+ If_ObjSetLValue( pObj, (float)0.0 );
+ If_ObjSetArrTime( pObj, (float)0.0 );
+ }
// update all values iteratively
fConverged = 0;
@@ -223,9 +234,10 @@ int If_ManBinarySearchPeriod( If_Man_t * p )
}
// report the results
+ If_ManMarkMapping( p );
if ( p->pPars->fVerbose )
{
- p->AreaGlo = If_ManScanMapping(p);
+// p->AreaGlo = If_ManScanMapping(p);
printf( "Attempt = %2d. Iters = %3d. Area = %10.2f. Fi = %6.2f. ", p->nAttempts, c, p->AreaGlo, (float)p->Period );
if ( fConverged )
printf( " Feasible" );
@@ -279,15 +291,6 @@ void If_ManPerformMappingSeqPost( If_Man_t * p )
If_Obj_t * pObjLi, * pObjLo, * pObj;
int i;
- // link the latch outputs (CIs) directly to the drivers of latch inputs (COs)
- for ( i = 0; i < p->pPars->nLatches; i++ )
- {
- pObjLi = If_ManLi( p, i );
- pObjLo = If_ManLo( p, i );
-// printf( "%3d : %2d -> %2d \n", i,
-// (int)If_ObjLValue(If_ObjFanin0(pObjLo)), (int)If_ObjLValue(pObjLo) );
- }
-
// set arrival times
assert( p->pPars->pTimesArr != NULL );
If_ManForEachLatchOutput( p, pObjLo, i )
@@ -295,7 +298,7 @@ void If_ManPerformMappingSeqPost( If_Man_t * p )
// set the required times
assert( p->pPars->pTimesReq == NULL );
- p->pPars->pTimesReq = ALLOC( float, If_ManCoNum(p) );
+ p->pPars->pTimesReq = ABC_ALLOC( float, If_ManCoNum(p) );
If_ManForEachPo( p, pObj, i )
{
p->pPars->pTimesReq[i] = p->RequiredGlo2;
@@ -338,7 +341,7 @@ int If_ManPerformMappingSeq( If_Man_t * p )
// perform combinational mapping to get the upper bound on the clock period
If_ManPerformMappingRound( p, 1, 0, 0, NULL );
- p->RequiredGlo = If_ManDelayMax( p, 0 );
+ p->RequiredGlo = If_ManDelayMax( p, 0 );
p->RequiredGlo2 = p->RequiredGlo;
// set direct linking of latches with their inputs
@@ -373,24 +376,12 @@ int If_ManPerformMappingSeq( If_Man_t * p )
return 0;
}
}
- if ( p->pPars->fVerbose )
+// if ( p->pPars->fVerbose )
{
-/*
- {
- FILE * pTable;
- pTable = fopen( "iscas/stats_new.txt", "a+" );
-// fprintf( pTable, "%s ", pNtk->pName );
- fprintf( pTable, "%d ", p->Period );
- // fprintf( pTable, "%.2f ", (float)(s_MappingMem)/(float)(1<<20) );
-// fprintf( pTable, "%.2f", (float)(s_MappingTime)/(float)(CLOCKS_PER_SEC) );
-// fprintf( pTable, "\n" );
- fclose( pTable );
- }
-*/
printf( "The best clock period is %3d. ", p->Period );
- PRT( "Sequential time", clock() - clkTotal );
+ ABC_PRT( "Time", clock() - clkTotal );
}
- p->RequiredGlo = (float)PeriodBest;
+ p->RequiredGlo = (float)(PeriodBest);
// postprocess it using combinational mapping
If_ManPerformMappingSeqPost( p );
diff --git a/src/map/if/module.make b/src/map/if/module.make
index 7489d3b4..53ed7c03 100644
--- a/src/map/if/module.make
+++ b/src/map/if/module.make
@@ -4,6 +4,7 @@ SRC += src/map/if/ifCore.c \
src/map/if/ifMan.c \
src/map/if/ifMap.c \
src/map/if/ifReduce.c \
+ src/map/if/ifSeq.c \
src/map/if/ifTime.c \
src/map/if/ifTruth.c \
src/map/if/ifUtil.c
diff --git a/src/map/mio/mio81214.zip b/src/map/mio/mio81214.zip
deleted file mode 100644
index 12f766a9..00000000
--- a/src/map/mio/mio81214.zip
+++ /dev/null
Binary files differ
diff --git a/src/misc/vec/vecFlt.h b/src/misc/vec/vecFlt.h
index 93402cf2..8f0ea42d 100644
--- a/src/misc/vec/vecFlt.h
+++ b/src/misc/vec/vecFlt.h
@@ -383,6 +383,8 @@ static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Entry )
int i;
if ( p->nSize >= nSize )
return;
+ if ( nSize < 2 * p->nSize )
+ nSize = 2 * p->nSize;
Vec_FltGrow( p, nSize );
for ( i = p->nSize; i < nSize; i++ )
p->pArray[i] = Entry;
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index 0f7a41ab..c3c92f09 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -409,10 +409,9 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill )
int i;
if ( p->nSize >= nSize )
return;
- if ( 2 * p->nSize > nSize )
- Vec_IntGrow( p, 2 * nSize );
- else
- Vec_IntGrow( p, nSize );
+ 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;
@@ -743,6 +742,28 @@ static inline int Vec_IntFindMin( Vec_Int_t * p )
/**Function*************************************************************
+ Synopsis [Reverses the order of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntReverseOrder( Vec_Int_t * p )
+{
+ int i, Temp;
+ for ( i = 0; i < p->nSize/2; i++ )
+ {
+ Temp = p->pArray[i];
+ p->pArray[i] = p->pArray[p->nSize-1-i];
+ p->pArray[p->nSize-1-i] = Temp;
+ }
+}
+
+/**Function*************************************************************
+
Synopsis [Comparison procedure for two integers.]
Description []
diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h
index 4d09acb7..6fc5109b 100644
--- a/src/misc/vec/vecPtr.h
+++ b/src/misc/vec/vecPtr.h
@@ -388,10 +388,9 @@ static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
if ( p->nSize >= nSize )
return;
assert( p->nSize < nSize );
- if ( 2 * p->nSize > nSize )
- Vec_PtrGrow( p, 2 * nSize );
- else
- Vec_PtrGrow( p, nSize );
+ if ( nSize < 2 * p->nSize )
+ nSize = 2 * p->nSize;
+ Vec_PtrGrow( p, nSize );
for ( i = p->nSize; i < nSize; i++ )
p->pArray[i] = Entry;
p->nSize = nSize;
@@ -616,6 +615,29 @@ static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
/**Function*************************************************************
+ Synopsis [Reverses the order of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrReverseOrder( Vec_Ptr_t * p )
+{
+ void * Temp;
+ int i;
+ for ( i = 0; i < p->nSize/2; i++ )
+ {
+ Temp = p->pArray[i];
+ p->pArray[i] = p->pArray[p->nSize-1-i];
+ p->pArray[p->nSize-1-i] = Temp;
+ }
+}
+
+/**Function*************************************************************
+
Synopsis [Sorting the entries by their integer value.]
Description []
diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h
index dc0b2bad..c77a3a17 100644
--- a/src/misc/vec/vecStr.h
+++ b/src/misc/vec/vecStr.h
@@ -361,10 +361,9 @@ static inline void Vec_StrFillExtra( Vec_Str_t * p, int nSize, char Fill )
int i;
if ( p->nSize >= nSize )
return;
- if ( 2 * p->nSize > nSize )
- Vec_StrGrow( p, 2 * nSize );
- else
- Vec_StrGrow( p, nSize );
+ if ( nSize < 2 * p->nSize )
+ nSize = 2 * p->nSize;
+ Vec_StrGrow( p, nSize );
for ( i = p->nSize; i < nSize; i++ )
p->pArray[i] = Fill;
p->nSize = nSize;
diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c
index 2886668e..158dc70a 100644
--- a/src/opt/dec/decAbc.c
+++ b/src/opt/dec/decAbc.c
@@ -66,6 +66,53 @@ Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph )
Synopsis [Transforms the decomposition graph into the AIG.]
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Dec_SopToAig( Abc_Ntk_t * pNtk, char * pSop, Vec_Ptr_t * vFaninAigs )
+{
+ Abc_Obj_t * pFunc;
+ Dec_Graph_t * pFForm;
+ Dec_Node_t * pNode;
+ int i;
+ pFForm = Dec_Factor( pSop );
+ Dec_GraphForEachLeaf( pFForm, pNode, i )
+ pNode->pFunc = Vec_PtrEntry( vFaninAigs, i );
+ pFunc = Dec_GraphToNetwork( pNtk, pFForm );
+ Dec_GraphFree( pFForm );
+ return pFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the decomposition graph into the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs )
+{
+ Abc_Obj_t * pFunc;
+ Dec_Node_t * pNode;
+ int i;
+ Dec_GraphForEachLeaf( pFForm, pNode, i )
+ pNode->pFunc = Vec_PtrEntry( vFaninAigs, i );
+ pFunc = Dec_GraphToNetwork( pNtk, pFForm );
+ return pFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the decomposition graph into the AIG.]
+
Description [AIG nodes for the fanins should be assigned to pNode->pFunc
of the leaves of the graph before calling this procedure.]
diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c
index d2ebf552..df04cd1f 100644
--- a/src/sat/bsat/satSolver.c
+++ b/src/sat/bsat/satSolver.c
@@ -851,6 +851,7 @@ static lbool sat_solver_search(sat_solver* s, ABC_INT64_T nof_conflicts, ABC_INT
// use activity factors in every even restart
if ( (s->nRestarts & 1) && veci_size(&s->act_vars) > 0 )
+// if ( veci_size(&s->act_vars) > 0 )
for ( i = 0; i < s->act_vars.size; i++ )
act_var_bump_factor(s, s->act_vars.ptr[i]);