diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2009-03-10 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2009-03-10 08:01:00 -0700 |
commit | 32314347bae6ddcd841a268e797ec4da45726abb (patch) | |
tree | e2e5fd1711f04a06d0da2b8003bc02cb9a5dd446 /src/aig | |
parent | c03f9b516bed2c06ec2bfc78617eba5fc9a11c32 (diff) | |
download | abc-32314347bae6ddcd841a268e797ec4da45726abb.tar.gz abc-32314347bae6ddcd841a268e797ec4da45726abb.tar.bz2 abc-32314347bae6ddcd841a268e797ec4da45726abb.zip |
Version abc90310
Diffstat (limited to 'src/aig')
35 files changed, 6679 insertions, 1214 deletions
diff --git a/src/aig/bbl/bblif.c b/src/aig/bbl/bblif.c new file mode 100644 index 00000000..adc10b28 --- /dev/null +++ b/src/aig/bbl/bblif.c @@ -0,0 +1,1511 @@ +/**CFile**************************************************************** + + FileName [bblif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Binary BLIF representation for logic networks.] + + Synopsis [Main implementation module.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 28, 2009.] + + Revision [$Id: bblif.c,v 1.00 2009/02/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <time.h> + +#include "bblif.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// vector of integers +typedef struct Vec_Int_t_ Vec_Int_t; +struct Vec_Int_t_ +{ + int nCap; + int nSize; + int * pArray; +}; + +// vector of characters +typedef struct Vec_Str_t_ Vec_Str_t; +struct Vec_Str_t_ +{ + int nCap; + int nSize; + char * pArray; +}; + +// network object +struct Bbl_Obj_t_ +{ + int Id; // user ID + int Fnc; // functionality + unsigned fCi : 1; // combinational input + unsigned fCo : 1; // combinational output + unsigned fBox : 1; // subcircuit + unsigned fMark : 1; // temporary mark + unsigned nFanins : 28; // fanin number + int pFanins[0]; // fanin array +}; + +// object function +typedef struct Bbl_Fnc_t_ Bbl_Fnc_t; +struct Bbl_Fnc_t_ +{ + int nWords; // word number + int pWords[0]; // word array +}; + +// object function +typedef struct Bbl_Ent_t_ Bbl_Ent_t; +struct Bbl_Ent_t_ +{ + int iFunc; // function handle + int iNext; // next entry handle +}; + +// data manager +struct Bbl_Man_t_ +{ + // data pool + Vec_Str_t * pName; // design name + Vec_Str_t * pObjs; // vector of objects + Vec_Str_t * pFncs; // vector of functions + // construction + Vec_Int_t * vId2Obj; // mapping user IDs into objects + Vec_Int_t * vObj2Id; // mapping objects into user IDs + Vec_Int_t * vFaninNums; // mapping user IDs into fanin number + // file contents + int nFileSize; // file size + char * pFileData; // file contents + // other data + Vec_Str_t * pEnts; // vector of entries + int SopMap[17][17]; // mapping vars x cubes into entry handles +}; + +static inline int Bbl_ObjIsCi( Bbl_Obj_t * pObj ) { return pObj->fCi; } +static inline int Bbl_ObjIsCo( Bbl_Obj_t * pObj ) { return pObj->fCo; } +static inline int Bbl_ObjIsNode( Bbl_Obj_t * pObj ) { return!pObj->fCi && !pObj->fCo; } + +static inline int Bbl_ObjFaninNum( Bbl_Obj_t * pObj ) { return pObj->nFanins; } +static inline Bbl_Obj_t * Bbl_ObjFanin( Bbl_Obj_t * pObj, int i ) { return (Bbl_Obj_t *)(((char *)pObj) - pObj->pFanins[i]); } + +static inline int Bbl_ObjSize( Bbl_Obj_t * pObj ) { return sizeof(Bbl_Obj_t) + sizeof(int) * pObj->nFanins; } +static inline int Bbl_FncSize( Bbl_Fnc_t * pFnc ) { return sizeof(Bbl_Fnc_t) + sizeof(int) * pFnc->nWords; } + +static inline Bbl_Obj_t * Bbl_VecObj( Vec_Str_t * p, int h ) { return (Bbl_Obj_t *)(p->pArray + h); } +static inline Bbl_Fnc_t * Bbl_VecFnc( Vec_Str_t * p, int h ) { return (Bbl_Fnc_t *)(p->pArray + h); } +static inline Bbl_Ent_t * Bbl_VecEnt( Vec_Str_t * p, int h ) { return (Bbl_Ent_t *)(p->pArray + h); } + +static inline char * Bbl_ManSop( Bbl_Man_t * p, int h ) { return (char *)Bbl_VecFnc(p->pFncs, h)->pWords; } +static inline Bbl_Obj_t * Bbl_ManObj( Bbl_Man_t * p, int Id ) { return Bbl_VecObj(p->pObjs, p->vId2Obj->pArray[Id]); } + +#define Bbl_ManForEachObj_int( p, pObj, h ) \ + for ( h = 0; (h < p->nSize) && (pObj = Bbl_VecObj(p,h)); h += Bbl_ObjSize(pObj) ) +#define Bbl_ManForEachFnc_int( p, pObj, h ) \ + for ( h = 0; (h < p->nSize) && (pObj = Bbl_VecFnc(p,h)); h += Bbl_FncSize(pObj) ) +#define Bbl_ObjForEachFanin_int( pObj, pFanin, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pFanin = Bbl_ObjFanin(pObj,i)); i++ ) + +#define BBLIF_ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) +#define BBLIF_CALLOC(type, num) ((type *) calloc((num), sizeof(type))) +#define BBLIF_FALLOC(type, num) ((type *) memset(malloc(sizeof(type) * (num)), 0xff, sizeof(type) * (num))) +#define BBLIF_FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#define BBLIF_REALLOC(type, obj, num) \ + ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num)))) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAlloc( int nCap ) +{ + Vec_Int_t * p; + p = BBLIF_ALLOC( Vec_Int_t, 1 ); + if ( nCap > 0 && nCap < 16 ) + nCap = 16; + p->nSize = 0; + p->nCap = nCap; + p->pArray = p->nCap? BBLIF_ALLOC( int, p->nCap ) : NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntStart( int nSize ) +{ + Vec_Int_t * p; + p = Vec_IntAlloc( nSize ); + p->nSize = nSize; + memset( p->pArray, 0, sizeof(int) * nSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntStartNatural( int nSize ) +{ + Vec_Int_t * p; + int i; + p = Vec_IntAlloc( nSize ); + p->nSize = nSize; + for ( i = 0; i < nSize; i++ ) + p->pArray[i] = i; + return p; +} + +/**Function************************************************************* + + Synopsis [Creates the vector from an integer array of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize ) +{ + Vec_Int_t * p; + p = BBLIF_ALLOC( Vec_Int_t, 1 ); + p->nSize = nSize; + p->nCap = nSize; + p->pArray = pArray; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntFree( Vec_Int_t * p ) +{ + BBLIF_FREE( p->pArray ); + BBLIF_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntSize( Vec_Int_t * p ) +{ + return p->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntEntry( Vec_Int_t * p, int i ) +{ + assert( i >= 0 && i < p->nSize ); + return p->pArray[i]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry ) +{ + assert( i >= 0 && i < p->nSize ); + p->pArray[i] = Entry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition ) +{ + assert( i >= 0 && i < p->nSize ); + p->pArray[i] += Addition; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntEntryLast( Vec_Int_t * p ) +{ + assert( p->nSize > 0 ); + return p->pArray[p->nSize-1]; +} + +/**Function************************************************************* + + Synopsis [Resizes the vector to the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin ) +{ + if ( p->nCap >= nCapMin ) + return; + p->pArray = BBLIF_REALLOC( int, p->pArray, nCapMin ); + assert( p->pArray ); + p->nCap = nCapMin; +} + +/**Function************************************************************* + + Synopsis [Fills the vector with given number of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Fill ) +{ + int i; + Vec_IntGrow( p, nSize ); + for ( i = 0; i < nSize; i++ ) + p->pArray[i] = Fill; + p->nSize = nSize; +} + +/**Function************************************************************* + + Synopsis [Fills the vector with given number of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill ) +{ + int i; + if ( p->nSize >= nSize ) + return; + if ( nSize < 2 * p->nSize ) + nSize = 2 * p->nSize; + Vec_IntGrow( p, nSize ); + for ( i = p->nSize; i < nSize; i++ ) + p->pArray[i] = Fill; + p->nSize = nSize; +} + +/**Function************************************************************* + + Synopsis [Returns the entry even if the place not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntGetEntry( Vec_Int_t * p, int i ) +{ + Vec_IntFillExtra( p, i + 1, 0 ); + return Vec_IntEntry( p, i ); +} + +/**Function************************************************************* + + Synopsis [Inserts the entry even if the place does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntSetEntry( Vec_Int_t * p, int i, int Entry ) +{ + Vec_IntFillExtra( p, i + 1, 0 ); + Vec_IntWriteEntry( p, i, Entry ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew ) +{ + assert( p->nSize >= nSizeNew ); + p->nSize = nSizeNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntClear( Vec_Int_t * p ) +{ + p->nSize = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntPush( Vec_Int_t * p, int Entry ) +{ + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_IntGrow( p, 16 ); + else + Vec_IntGrow( p, 2 * p->nCap ); + } + p->pArray[p->nSize++] = Entry; +} + + + + + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAlloc( int nCap ) +{ + Vec_Str_t * p; + p = BBLIF_ALLOC( Vec_Str_t, 1 ); + if ( nCap > 0 && nCap < 16 ) + nCap = 16; + p->nSize = 0; + p->nCap = nCap; + p->pArray = p->nCap? BBLIF_ALLOC( char, p->nCap ) : NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [Creates the vector from an array of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize ) +{ + Vec_Str_t * p; + p = BBLIF_ALLOC( Vec_Str_t, 1 ); + p->nSize = nSize; + p->nCap = nSize; + p->pArray = pArray; + return p; +} + +/**Fnction************************************************************* + + Synopsis [Returns a piece of memory.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Vec_StrFetch( Vec_Str_t * p, int nBytes ) +{ + while ( p->nSize + nBytes > p->nCap ) + { + p->pArray = BBLIF_REALLOC( char, p->pArray, 3 * p->nCap ); + p->nCap *= 3; + } + p->nSize += nBytes; + return p->pArray + p->nSize - nBytes; +} + +/**Fnction************************************************************* + + Synopsis [Write vector into file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vec_StrWrite( FILE * pFile, Vec_Str_t * p ) +{ + fwrite( &p->nSize, sizeof(int), 1, pFile ); + fwrite( p->pArray, sizeof(char), p->nSize, pFile ); +} + +/**Fnction************************************************************* + + Synopsis [Write vector into file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Vec_StrRead( char ** ppStr ) +{ + Vec_Str_t * p; + char * pStr = *ppStr; + p = Vec_StrAlloc( 0 ); + p->nSize = *(int *)pStr; + p->pArray = pStr + sizeof(int); + *ppStr = pStr + sizeof(int) + p->nSize * sizeof(char); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_StrSize( Vec_Str_t * p ) +{ + return p->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_StrFree( Vec_Str_t * p ) +{ + BBLIF_FREE( p->pArray ); + BBLIF_FREE( p ); +} + + + + + +/**Fnction************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManFileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Bbl_ManFileSize(): The file is unavailable (absent or open).\n" ); + return 0; + } + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + fclose( pFile ); + return nFileSize; +} + +/**Fnction************************************************************* + + Synopsis [Read data from file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManFileRead( char * pFileName ) +{ + FILE * pFile; + char * pContents; + int nFileSize; + nFileSize = Bbl_ManFileSize( pFileName ); + pFile = fopen( pFileName, "rb" ); + pContents = BBLIF_ALLOC( char, nFileSize ); + fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + return pContents; +} + + + +/**Fnction************************************************************* + + Synopsis [Writes data into file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName ) +{ + FILE * pFile; + pFile = fopen( pFileName, "wb" ); + Vec_StrWrite( pFile, p->pName ); + Vec_StrWrite( pFile, p->pObjs ); + Vec_StrWrite( pFile, p->pFncs ); + fclose( pFile ); +} + +/**Fnction************************************************************* + + Synopsis [Creates manager after reading.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName ) +{ + Bbl_Man_t * p; + Bbl_Obj_t * pObj; + char * pBuffer; + int h; + p = BBLIF_ALLOC( Bbl_Man_t, 1 ); + memset( p, 0, sizeof(Bbl_Man_t) ); + p->nFileSize = Bbl_ManFileSize( pFileName ); + p->pFileData = Bbl_ManFileRead( pFileName ); + // extract three managers + pBuffer = p->pFileData; + p->pName = Vec_StrRead( &pBuffer ); + p->pObjs = Vec_StrRead( &pBuffer ); + p->pFncs = Vec_StrRead( &pBuffer ); + assert( pBuffer - p->pFileData == p->nFileSize ); + // remember original IDs in the objects + p->vObj2Id = Vec_IntAlloc( 1000 ); + Bbl_ManForEachObj_int( p->pObjs, pObj, h ) + { + Vec_IntPush( p->vObj2Id, pObj->Id ); + pObj->Id = Vec_IntSize(p->vObj2Id) - 1; + } + return p; +} + +/**Fnction************************************************************* + + Synopsis [Prints stats of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManPrintStats( Bbl_Man_t * p ) +{ + Bbl_Obj_t * pObj; + Bbl_Fnc_t * pFnc; + int h, nFuncs = 0, nNodes = 0, nObjs = 0; + Bbl_ManForEachObj_int( p->pObjs, pObj, h ) + nObjs++, nNodes += Bbl_ObjIsNode(pObj); + Bbl_ManForEachFnc_int( p->pFncs, pFnc, h ) + nFuncs++; + printf( "Total objects = %7d. Total nodes = %7d. Unique functions = %7d.\n", nObjs, nNodes, nFuncs ); + printf( "Name manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pName)/(1 << 20) ); + printf( "Objs manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pObjs)/(1 << 20) ); + printf( "Fncs manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pFncs)/(1 << 20) ); +} + +/**Fnction************************************************************* + + Synopsis [Deletes the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManStop( Bbl_Man_t * p ) +{ + if ( p->vId2Obj ) Vec_IntFree( p->vId2Obj ); + if ( p->vObj2Id ) Vec_IntFree( p->vObj2Id ); + if ( p->vFaninNums ) Vec_IntFree( p->vFaninNums ); + if ( p->pFileData ) + { + BBLIF_FREE( p->pFileData ); + p->pName->pArray = NULL; + p->pObjs->pArray = NULL; + p->pFncs->pArray = NULL; + } + if ( p->pEnts ) + Vec_StrFree( p->pEnts ); + Vec_StrFree( p->pName ); + Vec_StrFree( p->pObjs ); + Vec_StrFree( p->pFncs ); + BBLIF_FREE( p ); +} + +/**Fnction************************************************************* + + Synopsis [Creates manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Man_t * Bbl_ManStart( char * pName ) +{ + Bbl_Man_t * p; + int nLength; + p = BBLIF_ALLOC( Bbl_Man_t, 1 ); + memset( p, 0, sizeof(Bbl_Man_t) ); + nLength = pName? 4 * ((strlen(pName) + 1) / 4 + 1) : 0; + p->pName = Vec_StrAlloc( nLength ); + p->pName->nSize = p->pName->nCap; + if ( pName ) + strcpy( p->pName->pArray, pName ); + p->pObjs = Vec_StrAlloc( 1 << 16 ); + p->pFncs = Vec_StrAlloc( 1 << 16 ); + p->pEnts = Vec_StrAlloc( 1 << 16 ); p->pEnts->nSize = 1; + p->vId2Obj = Vec_IntStart( 1 << 10 ); + p->vFaninNums = Vec_IntStart( 1 << 10 ); + return p; +} + + + + +/**Function************************************************************* + + Synopsis [Performs selection sort on the array of cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManSortCubes( char ** pCubes, int nCubes, int nVars ) +{ + char * pTemp; + int i, j, best_i; + for ( i = 0; i < nCubes-1; i++ ) + { + best_i = i; + for (j = i+1; j < nCubes; j++) + if ( memcmp( pCubes[j], pCubes[best_i], nVars ) < 0 ) + best_i = j; + pTemp = pCubes[i]; pCubes[i] = pCubes[best_i]; pCubes[best_i] = pTemp; + } +} + +/**Function************************************************************* + + Synopsis [Sorts the cubes in the SOP to uniqify them to some extent.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManSortSop( char * pSop, int nVars ) +{ + char ** pCubes, * pSopNew; + int c, Length, nCubes; + Length = strlen(pSop); + assert( Length % (nVars + 3) == 0 ); + nCubes = Length / (nVars + 3); + if ( nCubes < 2 ) + { + pSopNew = BBLIF_ALLOC( char, Length + 1 ); + memcpy( pSopNew, pSop, Length + 1 ); + return pSopNew; + } + pCubes = BBLIF_ALLOC( char *, nCubes ); + for ( c = 0; c < nCubes; c++ ) + pCubes[c] = pSop + c * (nVars + 3); + if ( nCubes < 300 ) + Bbl_ManSortCubes( pCubes, nCubes, nVars ); + pSopNew = BBLIF_ALLOC( char, Length + 1 ); + for ( c = 0; c < nCubes; c++ ) + memcpy( pSopNew + c * (nVars + 3), pCubes[c], nVars + 3 ); + BBLIF_FREE( pCubes ); + pSopNew[nCubes * (nVars + 3)] = 0; + return pSopNew; +} + +/**Fnction************************************************************* + + Synopsis [Saves one entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManCreateEntry( Bbl_Man_t * p, int iFunc, int iNext ) +{ + Bbl_Ent_t * pEnt; + pEnt = (Bbl_Ent_t *)Vec_StrFetch( p->pEnts, 2 * sizeof(int) ); + pEnt->iFunc = iFunc; + pEnt->iNext = iNext; + return (char *)pEnt - p->pEnts->pArray; +} + +/**Function************************************************************* + + Synopsis [Sorts the cubes in the SOP to uniqify them to some extent.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManSopCheckUnique( Bbl_Man_t * p, char * pSop, int nVars, int nCubes, int iFunc ) +{ + Bbl_Fnc_t * pFnc; + Bbl_Ent_t * pEnt; + int h, Length = strlen(pSop) + 1; + int nWords = (Length / 4 + (Length % 4 > 0)); + if ( nVars > 16 ) nVars = 16; + if ( nCubes > 16 ) nCubes = 16; +// if ( nVars == 16 && nCubes == 16 ) +// return iFunc; + for ( h = p->SopMap[nVars][nCubes]; h; h = pEnt->iNext ) + { + pEnt = Bbl_VecEnt( p->pEnts, h ); + pFnc = Bbl_VecFnc( p->pFncs, pEnt->iFunc ); + assert( nVars == 16 || nCubes == 16 || pFnc->nWords == nWords ); + if ( pFnc->nWords == nWords && memcmp( pFnc->pWords, pSop, Length ) == 0 ) + return pEnt->iFunc; + } + p->SopMap[nVars][nCubes] = Bbl_ManCreateEntry( p, iFunc, p->SopMap[nVars][nCubes] ); + return iFunc; +} + +/**Fnction************************************************************* + + Synopsis [Saves one SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManSaveSop( Bbl_Man_t * p, char * pSop, int nVars ) +{ + Bbl_Fnc_t * pFnc; + char * pSopNew; + int iFunc, Length = strlen(pSop) + 1; + int nWords = Length / 4 + (Length % 4 > 0); + // reorder cubes to semi-canicize SOPs + pSopNew = Bbl_ManSortSop( pSop, nVars ); + // get the candidate location + iFunc = Bbl_ManSopCheckUnique( p, pSopNew, nVars, Length / (nVars + 3), Vec_StrSize(p->pFncs) ); +// iFunc = Vec_StrSize(p->pFncs); + if ( iFunc == Vec_StrSize(p->pFncs) ) + { // store this SOP + pFnc = (Bbl_Fnc_t *)Vec_StrFetch( p->pFncs, sizeof(Bbl_Fnc_t) + nWords * sizeof(int) ); + pFnc->pWords[nWords-1] = 0; + pFnc->nWords = nWords; + strcpy( (char *)pFnc->pWords, pSopNew ); + assert( iFunc == (char *)pFnc - p->pFncs->pArray ); + } + BBLIF_FREE( pSopNew ); + return iFunc; +} + +/**Fnction************************************************************* + + Synopsis [Adds one object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop ) +{ + Bbl_Obj_t * pObj; + if ( Type == BBL_OBJ_CI && nFanins != 0 ) + { + printf( "Attempting to create a combinational input with %d fanins (should be 0).\n", nFanins ); + return; + } + if ( Type == BBL_OBJ_CO && nFanins != 1 ) + { + printf( "Attempting to create a combinational output with %d fanins (should be 1).\n", nFanins ); + return; + } + pObj = (Bbl_Obj_t *)Vec_StrFetch( p->pObjs, sizeof(Bbl_Obj_t) + nFanins * sizeof(int) ); + memset( pObj, 0, sizeof(Bbl_Obj_t) ); + Vec_IntSetEntry( p->vId2Obj, ObjId, (char *)pObj - p->pObjs->pArray ); + Vec_IntSetEntry( p->vFaninNums, ObjId, 0 ); + pObj->fCi = (Type == BBL_OBJ_CI); + pObj->fCo = (Type == BBL_OBJ_CO); + pObj->Id = ObjId; + pObj->Fnc = pSop? Bbl_ManSaveSop(p, pSop, nFanins) : -1; + pObj->nFanins = nFanins; +} + +/**Fnction************************************************************* + + Synopsis [Creates fanin/fanout relationship between two objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId ) +{ + Bbl_Obj_t * pObj, * pFanin; + int iFanin; + pObj = Bbl_ManObj( p, ObjId ); + if ( Bbl_ObjIsCi(pObj) ) + { + printf( "Bbl_ManAddFanin(): Cannot add fanin of the combinational input (Id = %d).\n", ObjId ); + return; + } + pFanin = Bbl_ManObj( p, FaninId ); + if ( Bbl_ObjIsCo(pFanin) ) + { + printf( "Bbl_ManAddFanin(): Cannot add fanout of the combinational output (Id = %d).\n", FaninId ); + return; + } + iFanin = Vec_IntEntry( p->vFaninNums, ObjId ); + if ( iFanin >= (int)pObj->nFanins ) + { + printf( "Bbl_ManAddFanin(): Trying to add more fanins to object (Id = %d) than declared (%d).\n", ObjId, pObj->nFanins ); + return; + } + assert( iFanin < (int)pObj->nFanins ); + Vec_IntWriteEntry( p->vFaninNums, ObjId, iFanin+1 ); + pObj->pFanins[iFanin] = (char *)pObj - (char *)pFanin; +} + + +/**Fnction************************************************************* + + Synopsis [Returns 1 if the manager was created correctly.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManCheck( Bbl_Man_t * p ) +{ + Bbl_Obj_t * pObj; + int h, RetValue = 1; + Bbl_ManForEachObj_int( p->pObjs, pObj, h ) + { + if ( Bbl_ObjIsNode(pObj) && pObj->Fnc == -1 ) + RetValue = 0, printf( "Bbl_ManCheck(): Node %d does not have function specified.\n", pObj->Id ); + if ( Bbl_ObjIsCi(pObj) && pObj->Fnc != -1 ) + RetValue = 0, printf( "Bbl_ManCheck(): CI with %d has function specified.\n", pObj->Id ); + if ( Bbl_ObjIsCo(pObj) && pObj->Fnc != -1 ) + RetValue = 0, printf( "Bbl_ManCheck(): CO with %d has function specified.\n", pObj->Id ); + if ( Vec_IntEntry(p->vFaninNums, pObj->Id) != (int)pObj->nFanins ) + RetValue = 0, printf( "Bbl_ManCheck(): Object %d has less fanins (%d) than declared (%d).\n", + pObj->Id, Vec_IntEntry(p->vFaninNums, pObj->Id), pObj->nFanins ); + } + return RetValue; +} + + +/**Fnction************************************************************* + + Synopsis [Misc APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ObjIsInput( Bbl_Obj_t * p ) { return Bbl_ObjIsCi(p); } +int Bbl_ObjIsOutput( Bbl_Obj_t * p ) { return Bbl_ObjIsCo(p); } +int Bbl_ObjIsLut( Bbl_Obj_t * p ) { return Bbl_ObjIsNode(p); } +int Bbl_ObjId( Bbl_Obj_t * p ) { return p->Id; } +int Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p ) { assert(0); return Vec_IntEntry(pMan->vObj2Id, p->Id); } +int Bbl_ObjFaninNumber( Bbl_Obj_t * p ) { return Bbl_ObjFaninNum(p); } +char * Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p ) { return Bbl_ManSop(pMan, p->Fnc); } +int Bbl_ObjIsMarked( Bbl_Obj_t * p ) { return p->fMark; } +void Bbl_ObjMark( Bbl_Obj_t * p ) { p->fMark = 1; } +int Bbl_ObjFncHandle( Bbl_Obj_t * p ) { return p->Fnc; } + +/**Fnction************************************************************* + + Synopsis [Returns the name of the design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManName( Bbl_Man_t * p ) +{ + return p->pName->pArray; +} + +/**Fnction************************************************************* + + Synopsis [Returns the maximum handle of the SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManFncSize( Bbl_Man_t * p ) +{ + return p->pFncs->nSize; +} + +/**Fnction************************************************************* + + Synopsis [Returns the first object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p ) +{ + return Bbl_VecObj( p->pObjs, 0 ); +} + +/**Fnction************************************************************* + + Synopsis [Returns the next object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj ) +{ + char * pNext = (char *)pObj + Bbl_ObjSize(pObj); + char * pEdge = p->pObjs->pArray + p->pObjs->nSize; + return (Bbl_Obj_t *)(pNext < pEdge ? pNext : NULL); +} + +/**Fnction************************************************************* + + Synopsis [Returns the first fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p ) +{ + return Bbl_ObjFaninNum(p) ? Bbl_ObjFanin( p, 0 ) : NULL; +} + +/**Fnction************************************************************* + + Synopsis [Returns the next fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev ) +{ + Bbl_Obj_t * pFanin; + int i; + Bbl_ObjForEachFanin_int( p, pFanin, i ) + if ( pFanin == pPrev ) + break; + return i < Bbl_ObjFaninNum(p) - 1 ? Bbl_ObjFanin( p, i+1 ) : NULL; +} + +/**Fnction************************************************************* + + Synopsis [Drives text BLIF file for debugging.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName ) +{ + FILE * pFile; + Bbl_Obj_t * pObj, * pFanin; + pFile = fopen( pFileName, "w" ); + fprintf( pFile, "# Test file written by Bbl_ManDumpBlif() in ABC.\n" ); + fprintf( pFile, ".model %s\n", Bbl_ManName(p) ); + // write objects + Bbl_ManForEachObj( p, pObj ) + { + if ( Bbl_ObjIsInput(pObj) ) + fprintf( pFile, ".inputs %d\n", Bbl_ObjId(pObj) ); + else if ( Bbl_ObjIsOutput(pObj) ) + fprintf( pFile, ".outputs %d\n", Bbl_ObjId(pObj) ); + else if ( Bbl_ObjIsLut(pObj) ) + { + fprintf( pFile, ".names" ); + Bbl_ObjForEachFanin( pObj, pFanin ) + fprintf( pFile, " %d", Bbl_ObjId(pFanin) ); + fprintf( pFile, " %d\n", Bbl_ObjId(pObj) ); + fprintf( pFile, "%s", Bbl_ObjSop(p, pObj) ); + } + else assert( 0 ); + } + // write output drivers + Bbl_ManForEachObj( p, pObj ) + { + if ( !Bbl_ObjIsOutput(pObj) ) + continue; + fprintf( pFile, ".names" ); + Bbl_ObjForEachFanin( pObj, pFanin ) + fprintf( pFile, " %d", Bbl_ObjId(pFanin) ); + fprintf( pFile, " %d\n", Bbl_ObjId(pObj) ); + fprintf( pFile, "1 1\n" ); + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +/**Fnction************************************************************* + + Synopsis [Converting truth table into an SOP.] + + Description [The truth table is given as a bit-string pTruth + composed of 2^nVars bits. The result is an SOP derived by + collecting minterms appearing in the truth table. The SOP is + represented as a C-string, as documented in file "bblif.h". + It is recommended to limit the use of this procedure to Boolean + functions up to 6 inputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManTruthToSop( unsigned * pTruth, int nVars ) +{ + char * pResult, * pTemp; + int nMints, nOnes, b, v; + assert( nVars >= 0 && nVars <= 16 ); + nMints = (1 << nVars); + // count the number of ones + nOnes = 0; + for ( b = 0; b < nMints; b++ ) + nOnes += ((pTruth[b>>5] >> (b&31)) & 1); + // handle constants + if ( nOnes == 0 || nOnes == nMints ) + { + pResult = pTemp = BBLIF_ALLOC( char, nVars + 4 ); + for ( v = 0; v < nVars; v++ ) + *pTemp++ = '-'; + *pTemp++ = ' '; + *pTemp++ = nOnes? '1' : '0'; + *pTemp++ = '\n'; + *pTemp++ = 0; + assert( pTemp - pResult == nVars + 4 ); + return pResult; + } + pResult = pTemp = BBLIF_ALLOC( char, nOnes * (nVars + 3) + 1 ); + for ( b = 0; b < nMints; b++ ) + { + if ( ((pTruth[b>>5] >> (b&31)) & 1) == 0 ) + continue; + for ( v = 0; v < nVars; v++ ) + *pTemp++ = ((b >> v) & 1)? '1' : '0'; + *pTemp++ = ' '; + *pTemp++ = '1'; + *pTemp++ = '\n'; + } + *pTemp++ = 0; + assert( pTemp - pResult == nOnes * (nVars + 3) + 1 ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Allocates the array of truth tables for the given number of vars.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Bbl_ManSopToTruthElem( int nVars, unsigned ** pVars ) +{ + unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; + int i, k, nWords; + nWords = (nVars <= 5 ? 1 : (1 << (nVars - 5))); + for ( i = 0; i < nVars; i++ ) + { + if ( i < 5 ) + { + for ( k = 0; k < nWords; k++ ) + pVars[i][k] = Masks[i]; + } + else + { + for ( k = 0; k < nWords; k++ ) + if ( k & (1 << (i-5)) ) + pVars[i][k] = ~(unsigned)0; + else + pVars[i][k] = 0; + } + } +} + +/**Fnction************************************************************* + + Synopsis [Converting SOP into a truth table.] + + Description [The SOP is represented as a C-string, as documented in + file "bblif.h". The truth table is returned as a bit-string composed + of 2^nVars bits. For functions of less than 6 variables, the full + machine word is returned. (The truth table looks as if the function + had 5 variables.) The use of this procedure should be limited to + Boolean functions with no more than 16 inputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Bbl_ManSopToTruth( char * pSop, int nVars ) +{ + unsigned * pTruth, * pCube, * pVars[16]; + int nWords = nVars <= 5 ? 1 : (1 << (nVars - 5)); + int v, c, w, nCubes, fCompl = 0; + if ( pSop == NULL ) + return NULL; + if ( strlen(pSop) % (nVars + 3) != 0 ) + { + printf( "Bbl_ManSopToTruth(): SOP is represented incorrectly.\n" ); + return NULL; + } + // create storage for TTs of the result, elementary variables and the temp cube + pTruth = BBLIF_ALLOC( unsigned, nWords ); + pVars[0] = BBLIF_ALLOC( unsigned, nWords * (nVars+1) ); + for ( v = 1; v < nVars; v++ ) + pVars[v] = pVars[v-1] + nWords; + pCube = pVars[v-1] + nWords; + Bbl_ManSopToTruthElem( nVars, pVars ); + // iterate through the cubes + memset( pTruth, 0, sizeof(unsigned) * nWords ); + nCubes = strlen(pSop) / (nVars + 3); + for ( c = 0; c < nCubes; c++ ) + { + fCompl = (pSop[nVars+1] == '0'); + memset( pCube, 0xff, sizeof(unsigned) * nWords ); + // iterate through the literals of the cube + for ( v = 0; v < nVars; v++ ) + if ( pSop[v] == '1' ) + for ( w = 0; w < nWords; w++ ) + pCube[w] &= pVars[v][w]; + else if ( pSop[v] == '0' ) + for ( w = 0; w < nWords; w++ ) + pCube[w] &= ~pVars[v][w]; + // add cube to storage + for ( w = 0; w < nWords; w++ ) + pTruth[w] |= pCube[w]; + // go to the next cube + pSop += (nVars + 3); + } + BBLIF_FREE( pVars[0] ); + if ( fCompl ) + for ( w = 0; w < nWords; w++ ) + pTruth[w] = ~pTruth[w]; + return pTruth; +} + + +/**Fnction************************************************************* + + Synopsis [Checks the truth table computation.] + + Description [We construct the logic network for the half-adder represnted + using the BLIF file below] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManTestTruth( char * pSop, int nVars ) +{ + unsigned * pTruth; + char * pSopNew; + pTruth = Bbl_ManSopToTruth( pSop, nVars ); + pSopNew = Bbl_ManTruthToSop( pTruth, nVars ); + printf( "Old SOP:\n%s\n", pSop ); + printf( "New SOP:\n%s\n", pSopNew ); + BBLIF_FREE( pSopNew ); + BBLIF_FREE( pTruth ); +} + +/**Fnction************************************************************* + + Synopsis [This demo shows using the internal to construct a half-adder.] + + Description [We construct the logic network for the half-adder represnted + using the BLIF file below] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManSimpleDemo() +{ +/* + # There are contents of a BLIF file representing a half-adder: + .model hadder + .inputs a // ID = 1 + .inputs b // ID = 2 + .inputs cin // ID = 3 + .outputs s // ID = 4 + .outputs cout // ID = 5 + .names a b cin s_driver // ID = 6 + 100 1 + 010 1 + 001 1 + 111 1 + .names a b cin cout_driver // ID = 7 + -11 1 + 1-1 1 + 11- 1 + .names s_driver s + 1 1 + .names cout_driver cout + 1 1 + .end +*/ + Bbl_Man_t * p; + // start the data manager + p = Bbl_ManStart( "hadder" ); + // create CIs + Bbl_ManCreateObject( p, BBL_OBJ_CI, 1, 0, NULL ); // a + Bbl_ManCreateObject( p, BBL_OBJ_CI, 2, 0, NULL ); // b + Bbl_ManCreateObject( p, BBL_OBJ_CI, 3, 0, NULL ); // cin + // create COs + Bbl_ManCreateObject( p, BBL_OBJ_CO, 4, 1, NULL ); // s + Bbl_ManCreateObject( p, BBL_OBJ_CO, 5, 1, NULL ); // cout + // create internal nodes + Bbl_ManCreateObject( p, BBL_OBJ_NODE, 6, 3, "100 1\n010 1\n001 1\n111 1\n" ); // s_driver + Bbl_ManCreateObject( p, BBL_OBJ_NODE, 7, 3, "-11 1\n1-1 1\n11- 1\n" ); // cout_driver + // add fanins of node 6 + Bbl_ManAddFanin( p, 6, 1 ); // s_driver <- a + Bbl_ManAddFanin( p, 6, 2 ); // s_driver <- b + Bbl_ManAddFanin( p, 6, 3 ); // s_driver <- cin + // add fanins of node 7 + Bbl_ManAddFanin( p, 7, 1 ); // cout_driver <- a + Bbl_ManAddFanin( p, 7, 2 ); // cout_driver <- b + Bbl_ManAddFanin( p, 7, 3 ); // cout_driver <- cin + // add fanins of COs + Bbl_ManAddFanin( p, 4, 6 ); // s <- s_driver + Bbl_ManAddFanin( p, 5, 7 ); // cout <- cout_driver + // sanity check + Bbl_ManCheck( p ); + // write BLIF file as a sanity check + Bbl_ManDumpBlif( p, "hadder.blif" ); + // write binary BLIF file + Bbl_ManDumpBinaryBlif( p, "hadder.bblif" ); + // remove the manager + Bbl_ManStop( p ); + + +// Bbl_ManTestTruth( "100 1\n010 1\n001 1\n111 1\n", 3 ); +// Bbl_ManTestTruth( "-11 0\n1-1 0\n11- 0\n", 3 ); +// Bbl_ManTestTruth( "--- 1\n", 3 ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/bbl/bblif.h b/src/aig/bbl/bblif.h new file mode 100644 index 00000000..db3eb2f5 --- /dev/null +++ b/src/aig/bbl/bblif.h @@ -0,0 +1,273 @@ +/**CFile**************************************************************** + + FileName [bblif.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Binary BLIF representation for logic networks.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 28, 2009.] + + Revision [$Id: bblif.h,v 1.00 2009/02/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __BBLIF_H__ +#define __BBLIF_H__ + +/* + This file (taken together with "bblif.c") implements a stand-alone + interface between ABC and an application that uses ABC. + + The interface is designed to pass a combinational logic network + from the calling application to ABC using a binary BLIF format (BBLIF) + and return the network after synthesis/mapping/verification in ABC + back to the caller. + + The interface can do the following: + (1) accept a combinational logic network via a set of APIs + (2) write the logic network into a binary BLIF file readable by ABC + (3) read a binary BLIF file with a mapped network produced by ABC + (4) return the mapped network to the caller through a set of APIs + + Here these steps are described in more detail: + + (1) The BBLIF manager is allocated by calling Bbl_ManStart() and + deallocated by calling Bbl_ManStop(). + + The combinational network is composed of three types of objects: + (a) combinational inputs (CIs), (b) combinational outputs (COs), + (c) internal logic nodes represented using Sum-of-Products (SOPs) + similar to the way logic nodes are represented in SIS. Sequential + elements (flops) are currently not supported. A CI has no fanins. + A CO has exactly one fanin and no fanouts. Internal nodes can + have any number of fanins and fanouts. Only an internal node can + have a logic function. + + Before constructing the BBLIF manager, each object should be + assigned a unique non-negative (0-based) integer ID. The sequence + of ID numbers may have gaps in it (for example, 0, 1, 2, 5, 6, etc) + but care should be taken that the ID numbers do not grow too large + because internally they are used to index the objects. So if + the largest given ID has value N, an array of 4*N bytes will be + allocated internally by the BBLIF manager. Obviously if N = 1M, + the array will use 4Mb, but if N = 100M, it will use 0.4Gb. + + This object ID (called also "the original ID of the object") is + given to Bbl_ManCreateObject(), which construct the BBLIF objects + and to the procedure Bbl_ManAddFanin(), which creates fanin/fanout + relations between two objects. The exact number of fanins of an + object should be declared when calling Bbl_ManCreateObject(). + Later on, each node should be assigned as many fanins using + Bbl_ManAddFanin(). The order/number of fanins corresponds to the + order/number of variables in the SOP of the logic function of the + node. The declared and actual number of fanins should be the same. + otherwise the interface will not function correctly. This is checked + by the procedure Bbl_ManCheck(), which should be called when + constructing all objects and their fanins is finished. + + The SOP representation of the logic function should be given to + every internal node. It is given as a C-string, showing the SOP + as it would appear in a BLIF or PLA file. Each cube is composed + of characters '0', '1', and '-', and ended by a seqence of three + characters: space ' ', followed by '0' or '1' (depending on whether + on- or off-set is used), followed by the new line character '\n'. + For example, a two-input OR has the following SOP representation: + "1- 1\n-1 1\n", or equivalently, "00 0\n". The SOP for a constant + function with no fanins is represented as " 0\n" (constant 0) and + " 1\n" (constant 1). SOP for a constant node with some fanins + may also be represented. For example, constant 0 node with three + fanins will have SOP representation as follows: "--- 0\n". + + The objects can be added to the BBLIF manager in any order, but + by the time the fanin/fanout connections are created, corresponding + objects should be already created. + + The number of objects is limited by 2^31. The number of fanins + of one object is restricted to 2^28. The SOP representation can + have arbitrary many products (cubes), as long as memory is enough + to represent them in the C-string form, as described above. + + (2) To write the manager into a file, call procedure Bbl_ManDumpBinaryBlif(). + It is recommended to use files with extension ".bblif" because it + will allow ABC to call the approapriate reader in command "read". + + (3) To read the network from file, call procedure Bbl_ManReadBinaryBlif(). + + (4) It is assumed that ABC will return the network after mapping. + This network will arrive in a BBLIF file, from which the BBLIF + manager is created by the call to Bbl_ManReadBinaryBlif(). The + following APIs are useful to extract the mapped network from the manager: + + Iterator Bbl_ManForEachObj() iterates through the pointers to the + BBLIF objects, which are guaranteed to be in a topological order. + + For each object, the following APIs can be used: + Bbl_ObjIsInput() returns 1 if the object is a CI + Bbl_ObjIsOutput() returns 1 if the object is a CO + Bbl_ObjIsLut() returns 1 if the object is a logic node (lookup table) + Bbl_ObjFaninNumber() returns the number of fanins of the node + Bbl_ObjSop() returns the SOP representation of the node, as described above. + + A special attention should be given to the representation of object IDs + after mapping. Recall that when the outgoing BBLIF network is constructed, + the IDs of objects are assigned by the calling application and given to + the BBLIF manager when procedure Bbl_ManCreateObject() is called. + We refer to these object IDs as "original IDs of the objects". + + When the network has been given to ABC, mapped, and returned to the + calling application in the incoming BBLIF file, only CIs and COs are + guaranteed to preserve their "original IDs". Other objects may be created + during synthesis/mapping. The original IDs of these objects are set to -1. + + The following two APIs are used to return the IDs of objects after mapping: + Bbl_ObjId() returns the new ID (useful to construct network after mapping) + Bbl_ObjIdOriginal() returns the original ID (or -1 if this is a new object). + + !!!***!!! + Note: The original ID currently cannot be returned by Bbl_ObjIdOriginal(). + It is recommended to use the work-around described below. + !!!***!!! + + The original ID is useful to map CIs/COs after mapping into CIs/COs before + mapping. However, the order of CIs/COs after mapping in the incoming network + is the same as the order of their creation by the calling application + in the outgoing network. This allows for a workaround that does not have + the need for the original IDs. We can simply iterate through the objects + after mapping, and create CIs and COs in the order of their appearance, + and this order is guaranteed to be the same as the order of their + construction by the calling application. + + It is also worth noting that currently the internal node names are not + preserved by ABC during synthesis. This may change in the future. and then + some of the internal nodes will preserve their IDs, which may allow the + calling application to reconstruct the names of some of the nodes after + synthesis/mapping in ABC using their original IDs whenever available. + + Finally, iterator Bbl_ObjForEachFanin() can be used to iterate through + the fanins of each mapped object. For CIs, there will be no fanins. + For COs, there will be exactly one fanin. For the internal nodes (LUTs) + the number of fanins is the number of inputs of these nodes. + + A demo of using this interface is included at the bottom of file "bblif.c" in + procedure Bbl_ManSimpleDemo(). Additional examples can be found in the files + "abc\src\base\io\ioReadBblif.c" and "abc\src\base\io\ioWriteBblif.c". These + files illustrate how an ABC network is created from the BBLIF data manager + and how the data manager is created from the ABC network. + + Note that only the files "bblif.h" and "bblif.c" are needed for interfacing + the user's application with ABC, while other files should not be compiled + as part of the application code. + + Finally, a warning regarding endianness. The interface may not work + if the BBLIF file is produced on a machine whose engianness is different + from the machine, which is reading this file. +*/ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +#define inline __inline +#endif + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// object types +typedef enum { + BBL_OBJ_NONE, // 0: non-existent object + BBL_OBJ_CI, // 1: primary input + BBL_OBJ_CO, // 2: primary output + BBL_OBJ_NODE, // 3: buffer node + BBL_OBJ_VOID // 4: unused object +} Bbl_Type_t; + +// data manager +typedef struct Bbl_Man_t_ Bbl_Man_t; + +// data object +typedef struct Bbl_Obj_t_ Bbl_Obj_t; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// (1) creating the data manager in the application code +extern Bbl_Man_t * Bbl_ManStart( char * pName ); +extern void Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop ); +extern void Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId ); +extern int Bbl_ManCheck( Bbl_Man_t * p ); +extern void Bbl_ManPrintStats( Bbl_Man_t * p ); +extern void Bbl_ManStop( Bbl_Man_t * p ); + +// (2) writing the data manager into file +extern void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName ); + +// (3) reading the data manager from file +extern Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName ); + +// (4) returning the mapped network after reading the data manaager from file +extern char * Bbl_ManName( Bbl_Man_t * p ); +extern int Bbl_ObjIsInput( Bbl_Obj_t * p ); +extern int Bbl_ObjIsOutput( Bbl_Obj_t * p ); +extern int Bbl_ObjIsLut( Bbl_Obj_t * p ); +extern int Bbl_ObjId( Bbl_Obj_t * p ); +extern int Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p ); +extern int Bbl_ObjFaninNumber( Bbl_Obj_t * p ); +extern char * Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p ); + +// for the use in iterators only +extern Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p ); +extern Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj ); +extern Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p ); +extern Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev ); + +// iterator through the objects +#define Bbl_ManForEachObj( p, pObj ) \ + for ( pObj = Bbl_ManObjFirst(p); pObj; pObj = Bbl_ManObjNext(p, pObj) ) +// iterator through the fanins fo the an object +#define Bbl_ObjForEachFanin( pObj, pFanin ) \ + for ( pFanin = Bbl_ObjFaninFirst(pObj); pFanin; pFanin = Bbl_ObjFaninNext(pObj, pFanin) ) + +// these additional procedures are provided to transform truth tables into SOPs, and vice versa +extern char * Bbl_ManTruthToSop( unsigned * pTruth, int nVars ); +extern unsigned * Bbl_ManSopToTruth( char * pSop, int nVars ); + +// write text BLIF file for debugging +extern void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName ); + +// a simple demo procedure +extern void Bbl_ManSimpleDemo(); + + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/bbl/module.make b/src/aig/bbl/module.make new file mode 100644 index 00000000..89ed2fa3 --- /dev/null +++ b/src/aig/bbl/module.make @@ -0,0 +1 @@ +SRC += src/aig/bbl/bblif.c diff --git a/src/aig/cec/cec.h b/src/aig/cec/cec.h index fa7c5dbc..16748233 100644 --- a/src/aig/cec/cec.h +++ b/src/aig/cec/cec.h @@ -45,24 +45,42 @@ struct Cec_ParSat_t_ int nSatVarMax; // the max number of SAT variables int nCallsRecycle; // calls to perform before recycling SAT solver int fPolarFlip; // flops polarity of variables + int fCheckMiter; // the circuit is the miter int fFirstStop; // stop on the first sat output int fVerbose; // verbose stats }; +// simulation parameters +typedef struct Cec_ParSim_t_ Cec_ParSim_t; +struct Cec_ParSim_t_ +{ + int nWords; // the number of simulation words + int nRounds; // the number of simulation rounds + int TimeLimit; // the runtime limit in seconds + int fDoubleOuts; // miter with separate outputs + int fCheckMiter; // the circuit is the miter + int fFirstStop; // stop on the first sat output + int fSeqSimulate; // performs sequential simulation + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + // combinational SAT sweeping parameters -typedef struct Cec_ParCsw_t_ Cec_ParCsw_t; -struct Cec_ParCsw_t_ +typedef struct Cec_ParFra_t_ Cec_ParFra_t; +struct Cec_ParFra_t_ { int nWords; // the number of simulation words int nRounds; // the number of simulation rounds int nItersMax; // the maximum number of iterations of SAT sweeping int nBTLimit; // conflict limit at a node - int nSatVarMax; // the max number of SAT variables - int nCallsRecycle; // calls to perform before recycling SAT solver + int TimeLimit; // the runtime limit in seconds int nLevelMax; // restriction on the level nodes to be swept int nDepthMax; // the depth in terms of steps of speculative reduction int fRewriting; // enables AIG rewriting + int fCheckMiter; // the circuit is the miter int fFirstStop; // stop on the first sat output + int fDoubleOuts; // miter with separate outputs + int fColorDiff; // miter with separate outputs int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -71,13 +89,12 @@ struct Cec_ParCsw_t_ typedef struct Cec_ParCec_t_ Cec_ParCec_t; struct Cec_ParCec_t_ { - int nIters; // iterations of SAT solving/sweeping - int nBTLimitBeg; // starting backtrack limit - int nBTlimitMulti; // multiple of backtrack limit + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int fFirstStop; // stop on the first sat output int fUseSmartCnf; // use smart CNF computation int fRewriting; // enables AIG rewriting - int fSatSweeping; // enables SAT sweeping - int fFirstStop; // stop on the first sat output + int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -89,12 +106,17 @@ struct Cec_ParCec_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== cecCec.c ==========================================================*/ +extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ); +extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); /*=== cecCore.c ==========================================================*/ extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ); -extern void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p ); +extern void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p ); +extern void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ); extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ); -extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ); +extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); +extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); #ifdef __cplusplus } diff --git a/src/aig/cec/cecCec.c b/src/aig/cec/cecCec.c new file mode 100644 index 00000000..ea730693 --- /dev/null +++ b/src/aig/cec/cecCec.c @@ -0,0 +1,241 @@ +/**CFile**************************************************************** + + FileName [cecCec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Integrated combinatinal equivalence checker.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecCec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Saves the input pattern with the given number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues ) +{ + int i; + assert( p->pCexComb == NULL ); + p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char, + sizeof(Gia_Cex_t) + sizeof(unsigned) * Aig_BitWordNum(Gia_ManCiNum(p)) ); + p->pCexComb->iPo = iOut; + p->pCexComb->nPis = Gia_ManCiNum(p); + p->pCexComb->nBits = Gia_ManCiNum(p); + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + if ( pValues[i] ) + Aig_InfoSetBit( p->pCexComb->pData, i ); +} + +/**Function************************************************************* + + Synopsis [Interface to the old CEC engine] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose ) +{ + extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); + extern int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs ); + Gia_Man_t * pTemp = Gia_ManTransformMiter( pMiter ); + Aig_Man_t * pMiterCec = Gia_ManToAig( pTemp ); + int RetValue, iOut, nOuts, clkTotal = clock(); + Gia_ManStop( pTemp ); + // run CEC on this miter + RetValue = Fra_FraigCec( &pMiterCec, 100000, fVerbose ); + // report the miter + if ( RetValue == 1 ) + { + printf( "Networks are equivalent. " ); +ABC_PRT( "Time", clock() - clkTotal ); + } + else if ( RetValue == 0 ) + { + printf( "Networks are NOT EQUIVALENT. " ); +ABC_PRT( "Time", clock() - clkTotal ); + if ( pMiterCec->pData == NULL ) + printf( "Counter-example is not available.\n" ); + else + { + iOut = Ssw_SecCexResimulate( pMiterCec, pMiterCec->pData, &nOuts ); + if ( iOut == -1 ) + printf( "Counter-example verification has failed.\n" ); + else + { + printf( "Primary output %d has failed in frame %d.\n", iOut ); + printf( "The counter-example detected %d incorrect outputs.\n", nOuts ); + } + Cec_ManTransformPattern( pMiter, iOut, pMiterCec->pData ); + } + } + else + { + printf( "Networks are UNDECIDED. " ); +ABC_PRT( "Time", clock() - clkTotal ); + } + fflush( stdout ); + Aig_ManStop( pMiterCec ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ) +{ + int fDumpUndecided = 1; + Cec_ParFra_t ParsFra, * pParsFra = &ParsFra; + Gia_Man_t * pNew; + int RetValue, clk = clock(); + double clkTotal = clock(); + // sweep for equivalences + Cec_ManFraSetDefaultParams( pParsFra ); + pParsFra->nBTLimit = pPars->nBTLimit; + pParsFra->TimeLimit = pPars->TimeLimit; + pParsFra->fVerbose = pPars->fVerbose; + pParsFra->fCheckMiter = 1; + pParsFra->fFirstStop = 1; + pParsFra->fDoubleOuts = 1; + pNew = Cec_ManSatSweeping( p, pParsFra ); + if ( pNew == NULL ) + { + if ( !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + printf( "Counter-example simulation has failed.\n" ); + printf( "Networks are NOT EQUIVALENT. " ); + ABC_PRT( "Time", clock() - clk ); + return 0; + } + if ( Gia_ManAndNum(pNew) == 0 ) + { + printf( "Networks are equivalent. " ); + ABC_PRT( "Time", clock() - clk ); + Gia_ManStop( pNew ); + return 1; + } + printf( "Networks are UNDECIDED after the new CEC engine. " ); + ABC_PRT( "Time", clock() - clk ); + if ( fDumpUndecided ) + { + Gia_WriteAiger( pNew, "gia_cec_undecided.aig", 0, 0 ); + printf( "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" ); + } + if ( pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) + { + Gia_ManStop( pNew ); + return -1; + } + // call other solver + printf( "Calling the old CEC engine.\n" ); + fflush( stdout ); + RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose ); + p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL; + if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + printf( "Counter-example simulation has failed.\n" ); + Gia_ManStop( pNew ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine applied to two circuits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + Gia_Man_t * pMiter; + int RetValue; + Cec_ManCecSetDefaultParams( pPars ); + pPars->fVerbose = fVerbose; + pMiter = Gia_ManMiter( p0, p1, 0, 1, pPars->fVerbose ); + if ( pMiter == NULL ) + return -1; + RetValue = Cec_ManVerify( pMiter, pPars ); + p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL; + Gia_ManStop( pMiter ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine applied to two circuits.] + + Description [Returns 1 if equivalent, 0 if counter-example, -1 if undecided. + Counter-example is returned in the first manager as pAig0->pSeqModel. + The format is given in Gia_Cex_t (file "abc\src\aig\gia\gia.h").] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose ) +{ + Gia_Man_t * p0, * p1, * pTemp; + int RetValue; + + p0 = Gia_ManFromAig( pAig0 ); + p0 = Gia_ManCleanup( pTemp = p0 ); + Gia_ManStop( pTemp ); + + p1 = Gia_ManFromAig( pAig1 ); + p1 = Gia_ManCleanup( pTemp = p1 ); + Gia_ManStop( pTemp ); + + RetValue = Cec_ManVerifyTwo( p0, p1, fVerbose ); + pAig0->pSeqModel = p0->pCexComb; p0->pCexComb = NULL; + Gia_ManStop( p0 ); + Gia_ManStop( p1 ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecClass.c b/src/aig/cec/cecClass.c index 65fa2e9b..aaa85ffa 100644 --- a/src/aig/cec/cecClass.c +++ b/src/aig/cec/cecClass.c @@ -24,39 +24,10 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Cec_ObjRepr( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iRepr; } -static inline void Cec_ObjSetRepr( Cec_ManCsw_t * p, int Id, int Num ) { p->pObjs[Id].iRepr = Num; } - -static inline int Cec_ObjProved( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iProved; } -static inline void Cec_ObjSetProved( Cec_ManCsw_t * p, int Id ) { p->pObjs[Id].iProved = 1; } - -static inline int Cec_ObjFailed( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iFailed; } -static inline void Cec_ObjSetFailed( Cec_ManCsw_t * p, int Id ) { p->pObjs[Id].iFailed = 1; } - -static inline int Cec_ObjNext( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iNext; } -static inline void Cec_ObjSetNext( Cec_ManCsw_t * p, int Id, int Num ) { p->pObjs[Id].iNext = Num; } - -static inline unsigned Cec_ObjSim( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].SimNum; } -static inline unsigned * Cec_ObjSimP1( Cec_ManCsw_t * p, int Id ) { return &p->pObjs[Id].SimNum; } -static inline unsigned * Cec_ObjSimP( Cec_ManCsw_t * p, int Id ) { return p->pMems + Cec_ObjSim(p, Id) + 1; } -static inline void Cec_ObjSetSim( Cec_ManCsw_t * p, int Id, unsigned n ) { p->pObjs[Id].SimNum = n; } - -static inline int Cec_ObjIsConst( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) == 0; } -static inline int Cec_ObjIsHead( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) < 0 && Cec_ObjNext(p, Id) > 0; } -static inline int Cec_ObjIsNone( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) < 0 && Cec_ObjNext(p, Id) == 0; } -static inline int Cec_ObjIsTail( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) > 0 && Cec_ObjNext(p, Id) == 0; } -static inline int Cec_ObjIsClass( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) > 0 || Cec_ObjNext(p, Id) > 0; } - -#define Cec_ManForEachObj( p, i ) \ - for ( i = 0; i < Gia_ManObjNum(p->pAig); i++ ) -#define Cec_ManForEachObj1( p, i ) \ - for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) -#define Cec_ManForEachClass( p, i ) \ - for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) if ( !Cec_ObjIsHead(p, i) ) {} else -#define Cec_ClassForEachObj( p, i, iObj ) \ - for ( assert(Cec_ObjIsHead(p, i)), iObj = i; iObj; iObj = Cec_ObjNext(p, iObj) ) -#define Cec_ClassForEachObj1( p, i, iObj ) \ - for ( assert(Cec_ObjIsHead(p, i)), iObj = Cec_ObjNext(p, i); iObj; iObj = Cec_ObjNext(p, iObj) ) +static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id ) { return p->pMems + p->pSimInfo[Id] + 1; } +static inline void Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n ) { p->pSimInfo[Id] = n; } + +static inline float Cec_MemUsage( Cec_ManSim_t * p ) { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -64,30 +35,7 @@ static inline int Cec_ObjIsClass( Cec_ManCsw_t * p, int Id ) { /**Function************************************************************* - Synopsis [Creates the set of representatives.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p ) -{ - int i, * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) - if ( Cec_ObjProved(p, i) ) - { - assert( Cec_ObjRepr(p, i) >= 0 ); - pReprs[i] = Cec_ObjRepr(p, i); - } - return pReprs; -} - -/**Function************************************************************* - - Synopsis [] + Synopsis [Compares simulation info of one node with constant 0.] Description [] @@ -96,250 +44,28 @@ int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Cec_ManCswDupWithClasses( Cec_ManCsw_t * p ) +int Cec_ManSimCompareConst( unsigned * p, int nWords ) { - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pRepr; - int iRes0, iRes1, iRepr, iNode; - int i, fCompl, * piCopies; - Vec_IntClear( p->vXorNodes ); - Gia_ManLevelNum( p->pAig ); - pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); - pNew->pName = Aig_UtilStrsav( p->pAig->pName ); - Gia_ManHashAlloc( pNew ); - piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - piCopies[0] = 0; - Gia_ManForEachObj1( p->pAig, pObj, i ) - { - if ( Gia_ObjIsCi(pObj) ) - { - piCopies[i] = Gia_ManAppendCi( pNew ); - continue; - } - iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); - if ( Gia_ObjIsCo(pObj) ) - { - Gia_ManAppendCo( pNew, iRes0 ); - continue; - } - iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); - iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); - if ( Cec_ObjRepr(p, i) < 0 || !Cec_ObjProved(p, i) ) - continue; - assert( Cec_ObjRepr(p, i) < i ); - iRepr = piCopies[Cec_ObjRepr(p, i)]; - if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) - continue; - pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) ); - fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); - piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); - } - ABC_FREE( piCopies ); - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, 0 ); - pNew = Gia_ManCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Cec_ManCswSpecReduction( Cec_ManCsw_t * p ) -{ - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pRepr; - int iRes0, iRes1, iRepr, iNode, iMiter; - int i, fCompl, * piCopies, * pDepths; - Vec_IntClear( p->vXorNodes ); -// Gia_ManLevelNum( p->pAig ); - pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); - pNew->pName = Aig_UtilStrsav( p->pAig->pName ); - Gia_ManHashAlloc( pNew ); - piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); - piCopies[0] = 0; - Gia_ManForEachObj1( p->pAig, pObj, i ) - { - if ( Gia_ObjIsCi(pObj) ) - { - piCopies[i] = Gia_ManAppendCi( pNew ); - continue; - } - if ( Gia_ObjIsCo(pObj) ) - continue; - if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 || - piCopies[Gia_ObjFaninId1(pObj,i)] == -1 ) - continue; - iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); - iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); - iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); - pDepths[i] = AIG_MAX( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] ); - if ( Cec_ObjRepr(p, i) < 0 || Cec_ObjFailed(p, i) ) - continue; - assert( Cec_ObjRepr(p, i) < i ); - iRepr = piCopies[Cec_ObjRepr(p, i)]; - if ( iRepr == -1 ) - continue; - if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) - continue; - pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) ); - fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); - piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); - if ( Cec_ObjProved(p, i) ) - continue; -// if ( p->pPars->nLevelMax && -// (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax || -// Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) ) -// continue; - // produce speculative miter - iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); - Gia_ManAppendCo( pNew, iMiter ); - Vec_IntPush( p->vXorNodes, Cec_ObjRepr(p, i) ); - Vec_IntPush( p->vXorNodes, i ); - // add to the depth of this node - pDepths[i] = 1 + AIG_MAX( pDepths[i], pDepths[Cec_ObjRepr(p, i)] ); - if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax ) - piCopies[i] = -1; - } - ABC_FREE( piCopies ); - ABC_FREE( pDepths ); - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, 0 ); - pNew = Gia_ManCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Cec_ManCswSpecReductionProved( Cec_ManCsw_t * p ) -{ - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pRepr; - int iRes0, iRes1, iRepr, iNode, iMiter; - int i, fCompl, * piCopies; - Vec_IntClear( p->vXorNodes ); - Gia_ManLevelNum( p->pAig ); - pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); - pNew->pName = Aig_UtilStrsav( p->pAig->pName ); - Gia_ManHashAlloc( pNew ); - piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - piCopies[0] = 0; - Gia_ManForEachObj1( p->pAig, pObj, i ) + int w; + if ( p[0] & 1 ) { - if ( Gia_ObjIsCi(pObj) ) - { - piCopies[i] = Gia_ManAppendCi( pNew ); - continue; - } - if ( Gia_ObjIsCo(pObj) ) - continue; - iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); - iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); - iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); - if ( Cec_ObjRepr(p, i) < 0 || !Cec_ObjProved(p, i) ) - continue; - assert( Cec_ObjRepr(p, i) < i ); - iRepr = piCopies[Cec_ObjRepr(p, i)]; - if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) - continue; - pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) ); - fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); - piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); - // add speculative miter - iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); - Gia_ManAppendCo( pNew, iMiter ); + for ( w = 0; w < nWords; w++ ) + if ( p[w] != ~0 ) + return 0; + return 1; } - ABC_FREE( piCopies ); - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, 0 ); - pNew = Gia_ManCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cec_ManCswCountOne( Cec_ManCsw_t * p, int i ) -{ - int Ent, nLits = 1; - Cec_ClassForEachObj1( p, i, Ent ) + else { - assert( Cec_ObjRepr(p, Ent) == i ); - nLits++; + for ( w = 0; w < nWords; w++ ) + if ( p[w] != 0 ) + return 0; + return 1; } - return nLits; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cec_ManCswCountLitsAll( Cec_ManCsw_t * p ) -{ - int i, nLits = 0; - Cec_ManForEachObj( p, i ) - nLits += (Cec_ObjRepr(p, i) >= 0); - return nLits; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cec_ManCswPrintOne( Cec_ManCsw_t * p, int i, int Counter ) -{ - int Ent; - printf( "Class %4d : Num = %2d {", Counter, Cec_ManCswCountOne(p, i) ); - Cec_ClassForEachObj( p, i, Ent ) - printf(" %d", Ent ); - printf( " }\n" ); } /**Function************************************************************* - Synopsis [] + Synopsis [Compares simulation info of two nodes.] Description [] @@ -348,32 +74,28 @@ void Cec_ManCswPrintOne( Cec_ManCsw_t * p, int i, int Counter ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswPrintClasses( Cec_ManCsw_t * p, int fVerbose ) +int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords ) { - int i, Counter = 0, Counter1 = 0, CounterX = 0, nLits; - Cec_ManForEachObj1( p, i ) + int w; + if ( (p0[0] & 1) == (p1[0] & 1) ) { - if ( Cec_ObjIsHead(p, i) ) - Counter++; - else if ( Cec_ObjIsConst(p, i) ) - Counter1++; - else if ( Cec_ObjIsNone(p, i) ) - CounterX++; + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != p1[w] ) + return 0; + return 1; } - nLits = Cec_ManCswCountLitsAll( p ); - printf( "Class =%7d. Const =%7d. Unsed =%7d. Lits =%8d. All =%8d. Mem = %5.2f Mb\n", - Counter, Counter1, CounterX, nLits-Counter1, nLits, 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20) ); - if ( fVerbose ) + else { - Counter = 0; - Cec_ManForEachClass( p, i ) - Cec_ManCswPrintOne( p, i, ++Counter ); + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != ~p1[w] ) + return 0; + return 1; } } /**Function************************************************************* - Synopsis [] + Synopsis [Returns the number of the first non-equal bit.] Description [] @@ -382,28 +104,28 @@ void Cec_ManCswPrintClasses( Cec_ManCsw_t * p, int fVerbose ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswCompareEqual( unsigned * p0, unsigned * p1, int nWords ) +int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords ) { int w; - if ( (p0[0] & 1) == (p1[0] & 1) ) + if ( p[0] & 1 ) { for ( w = 0; w < nWords; w++ ) - if ( p0[w] != p1[w] ) - return 0; - return 1; + if ( p[w] != ~0 ) + return 32*w + Aig_WordFindFirstBit( ~p[w] ); + return -1; } else { for ( w = 0; w < nWords; w++ ) - if ( p0[w] != ~p1[w] ) - return 0; - return 1; + if ( p[w] != 0 ) + return 32*w + Aig_WordFindFirstBit( p[w] ); + return -1; } } /**Function************************************************************* - Synopsis [] + Synopsis [Compares simulation info of two nodes.] Description [] @@ -412,28 +134,28 @@ int Cec_ManCswCompareEqual( unsigned * p0, unsigned * p1, int nWords ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswCompareConst( unsigned * p, int nWords ) +int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords ) { int w; - if ( p[0] & 1 ) + if ( (p0[0] & 1) == (p1[0] & 1) ) { for ( w = 0; w < nWords; w++ ) - if ( p[w] != ~0 ) - return 0; - return 1; + if ( p0[w] != p1[w] ) + return 32*w + Aig_WordFindFirstBit( p0[w] ^ p1[w] ); + return -1; } else { for ( w = 0; w < nWords; w++ ) - if ( p[w] != 0 ) - return 0; - return 1; + if ( p0[w] != ~p1[w] ) + return 32*w + Aig_WordFindFirstBit( p0[w] ^ ~p1[w] ); + return -1; } } /**Function************************************************************* - Synopsis [] + Synopsis [Creates equivalence class.] Description [] @@ -442,31 +164,31 @@ int Cec_ManCswCompareConst( unsigned * p, int nWords ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswClassCreate( Cec_ManCsw_t * p, Vec_Int_t * vClass ) +void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass ) { - int Repr = -1, EntPrev = -1, Ent, i; + int Repr = GIA_VOID, EntPrev = -1, Ent, i; assert( Vec_IntSize(vClass) > 0 ); Vec_IntForEachEntry( vClass, Ent, i ) { if ( i == 0 ) { Repr = Ent; - Cec_ObjSetRepr( p, Ent, -1 ); + Gia_ObjSetRepr( p, Ent, GIA_VOID ); EntPrev = Ent; } else { - Cec_ObjSetRepr( p, Ent, Repr ); - Cec_ObjSetNext( p, EntPrev, Ent ); + Gia_ObjSetRepr( p, Ent, Repr ); + Gia_ObjSetNext( p, EntPrev, Ent ); EntPrev = Ent; } } - Cec_ObjSetNext( p, EntPrev, 0 ); + Gia_ObjSetNext( p, EntPrev, 0 ); } /**Function************************************************************* - Synopsis [] + Synopsis [Refines one equivalence class.] Description [] @@ -475,34 +197,34 @@ void Cec_ManCswClassCreate( Cec_ManCsw_t * p, Vec_Int_t * vClass ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassRefineOne( Cec_ManCsw_t * p, int i, int fFirst ) +int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i ) { unsigned * pSim0, * pSim1; int Ent; Vec_IntClear( p->vClassOld ); Vec_IntClear( p->vClassNew ); Vec_IntPush( p->vClassOld, i ); - pSim0 = fFirst? Cec_ObjSimP1(p, i) : Cec_ObjSimP(p, i); - Cec_ClassForEachObj1( p, i, Ent ) + pSim0 = Cec_ObjSim(p, i); + Gia_ClassForEachObj1( p->pAig, i, Ent ) { - pSim1 = fFirst? Cec_ObjSimP1(p, Ent) : Cec_ObjSimP(p, Ent); - if ( Cec_ManCswCompareEqual( pSim0, pSim1, p->nWords ) ) + pSim1 = Cec_ObjSim(p, Ent); + if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) ) Vec_IntPush( p->vClassOld, Ent ); else Vec_IntPush( p->vClassNew, Ent ); } if ( Vec_IntSize( p->vClassNew ) == 0 ) return 0; - Cec_ManCswClassCreate( p, p->vClassOld ); - Cec_ManCswClassCreate( p, p->vClassNew ); + Cec_ManSimClassCreate( p->pAig, p->vClassOld ); + Cec_ManSimClassCreate( p->pAig, p->vClassNew ); if ( Vec_IntSize(p->vClassNew) > 1 ) - return 1 + Cec_ManCswClassRefineOne( p, Vec_IntEntry(p->vClassNew,0), fFirst ); + return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) ); return 1; } /**Function************************************************************* - Synopsis [] + Synopsis [Computes hash key of the simuation info.] Description [] @@ -511,7 +233,7 @@ int Cec_ManCswClassRefineOne( Cec_ManCsw_t * p, int i, int fFirst ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize ) +int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize ) { static int s_Primes[16] = { 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, @@ -530,7 +252,7 @@ int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize ) /**Function************************************************************* - Synopsis [] + Synopsis [Resets pointers to the simulation memory.] Description [] @@ -539,90 +261,7 @@ int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswClassesCreate( Cec_ManCsw_t * p ) -{ - int * pTable, nTableSize, i, Key; - p->nWords = 1; - nTableSize = Aig_PrimeCudd( 100 + Gia_ManObjNum(p->pAig) / 10 ); - pTable = ABC_CALLOC( int, nTableSize ); - Cec_ObjSetRepr( p, 0, -1 ); - Cec_ManForEachObj1( p, i ) - { - if ( Gia_ObjIsCo(Gia_ManObj(p->pAig, i)) ) - { - Cec_ObjSetRepr( p, i, -1 ); - continue; - } - if ( Cec_ManCswCompareConst( Cec_ObjSimP1(p, i), p->nWords ) ) - { - Cec_ObjSetRepr( p, i, 0 ); - continue; - } - Key = Cec_ManCswHashKey( Cec_ObjSimP1(p, i), p->nWords, nTableSize ); - if ( pTable[Key] == 0 ) - Cec_ObjSetRepr( p, i, -1 ); - else - { - Cec_ObjSetNext( p, pTable[Key], i ); - Cec_ObjSetRepr( p, i, Cec_ObjRepr(p, pTable[Key]) ); - if ( Cec_ObjRepr(p, i) == -1 ) - Cec_ObjSetRepr( p, i, pTable[Key] ); - } - pTable[Key] = i; - } - ABC_FREE( pTable ); - if ( p->pPars->fVeryVerbose ) - Cec_ManCswPrintClasses( p, 0 ); - // refine classes - Cec_ManForEachClass( p, i ) - Cec_ManCswClassRefineOne( p, i, 1 ); - // clean memory - Cec_ManForEachObj( p, i ) - Cec_ObjSetSim( p, i, 0 ); - if ( p->pPars->fVeryVerbose ) - Cec_ManCswPrintClasses( p, 0 ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cec_ManCswSimulateSimple( Cec_ManCsw_t * p ) -{ - Gia_Obj_t * pObj; - unsigned Res0, Res1; - int i; - Gia_ManForEachCi( p->pAig, pObj, i ) - Cec_ObjSetSim( p, i, Aig_ManRandom(0) ); - Gia_ManForEachAnd( p->pAig, pObj, i ) - { - Res0 = Cec_ObjSim( p, Gia_ObjFaninId0(pObj, i) ); - Res1 = Cec_ObjSim( p, Gia_ObjFaninId1(pObj, i) ); - Cec_ObjSetSim( p, i, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & - (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); - } -} - -/**Function************************************************************* - - Synopsis [References simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p ) +void Cec_ManSimMemRelink( Cec_ManSim_t * p ) { unsigned * pPlace, Ent; pPlace = &p->MemFree; @@ -634,6 +273,7 @@ void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p ) pPlace = p->pMems + Ent; } *pPlace = 0; + p->nWordsOld = p->nWords; } /**Function************************************************************* @@ -647,10 +287,10 @@ void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p ) SeeAlso [] ***********************************************************************/ -unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) +unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i ) { unsigned * pSim; - assert( p->pObjs[i].SimNum == 0 ); + assert( p->pSimInfo[i] == 0 ); if ( p->MemFree == 0 ) { if ( p->nWordsAlloc == 0 ) @@ -661,9 +301,9 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) } p->nWordsAlloc *= 2; p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc ); - Cec_ManCswSimMemRelink( p ); + Cec_ManSimMemRelink( p ); } - p->pObjs[i].SimNum = p->MemFree; + p->pSimInfo[i] = p->MemFree; pSim = p->pMems + p->MemFree; p->MemFree = pSim[0]; pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) ); @@ -675,7 +315,7 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) /**Function************************************************************* - Synopsis [Dereference simulaton info.] + Synopsis [Dereferences simulaton info.] Description [] @@ -684,16 +324,16 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) SeeAlso [] ***********************************************************************/ -unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i ) +unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i ) { unsigned * pSim; - assert( p->pObjs[i].SimNum > 0 ); - pSim = p->pMems + p->pObjs[i].SimNum; + assert( p->pSimInfo[i] > 0 ); + pSim = p->pMems + p->pSimInfo[i]; if ( --pSim[0] == 0 ) { pSim[0] = p->MemFree; - p->MemFree = p->pObjs[i].SimNum; - p->pObjs[i].SimNum = 0; + p->MemFree = p->pSimInfo[i]; + p->pSimInfo[i] = 0; p->nMems--; } return pSim; @@ -701,7 +341,7 @@ unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i ) /**Function************************************************************* - Synopsis [] + Synopsis [Refines nodes belonging to candidate constant class.] Description [] @@ -710,52 +350,145 @@ unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswProcessRefined( Cec_ManCsw_t * p, Vec_Int_t * vRefined ) +void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined ) { unsigned * pSim; int * pTable, nTableSize, i, k, Key; if ( Vec_IntSize(vRefined) == 0 ) return; - nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 ); + nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 ); pTable = ABC_CALLOC( int, nTableSize ); Vec_IntForEachEntry( vRefined, i, k ) { - if ( i == 7720 ) - { - int s = 0; - } - pSim = Cec_ObjSimP( p, i ); - assert( !Cec_ManCswCompareConst( pSim, p->nWords ) ); - Key = Cec_ManCswHashKey( pSim, p->nWords, nTableSize ); + pSim = Cec_ObjSim( p, i ); + assert( !Cec_ManSimCompareConst( pSim, p->nWords ) ); + Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize ); if ( pTable[Key] == 0 ) { - assert( Cec_ObjRepr(p, i) == 0 ); - assert( Cec_ObjNext(p, i) == 0 ); - Cec_ObjSetRepr( p, i, -1 ); + assert( Gia_ObjRepr(p->pAig, i) == 0 ); + assert( Gia_ObjNext(p->pAig, i) == 0 ); + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); } else { - Cec_ObjSetNext( p, pTable[Key], i ); - Cec_ObjSetRepr( p, i, Cec_ObjRepr(p, pTable[Key]) ); - if ( Cec_ObjRepr(p, i) == -1 ) - Cec_ObjSetRepr( p, i, pTable[Key] ); - assert( Cec_ObjRepr(p, i) > 0 ); + Gia_ObjSetNext( p->pAig, pTable[Key], i ); + Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) ); + if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID ) + Gia_ObjSetRepr( p->pAig, i, pTable[Key] ); + assert( Gia_ObjRepr(p->pAig, i) > 0 ); } pTable[Key] = i; } Vec_IntForEachEntry( vRefined, i, k ) { - if ( Cec_ObjIsHead( p, i ) ) - Cec_ManCswClassRefineOne( p, i, 0 ); + if ( Gia_ObjIsHead( p->pAig, i ) ) + Cec_ManSimClassRefineOne( p, i ); } Vec_IntForEachEntry( vRefined, i, k ) - Cec_ManCswSimDeref( p, i ); + Cec_ManSimSimDeref( p, i ); ABC_FREE( pTable ); } /**Function************************************************************* + Synopsis [Saves the input pattern with the given number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat ) +{ + unsigned * pInfo; + int i; + assert( p->pCexComb == NULL ); + assert( iPat >= 0 && iPat < 32 * p->nWords ); + p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char, + sizeof(Gia_Cex_t) + sizeof(unsigned) * Aig_BitWordNum(Gia_ManCiNum(p->pAig)) ); + p->pCexComb->iPo = p->iOut; + p->pCexComb->nPis = Gia_ManCiNum(p->pAig); + p->pCexComb->nBits = Gia_ManCiNum(p->pAig); + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pInfo = Vec_PtrEntry( p->vCiSimInfo, i ); + if ( Aig_InfoHasBit( pInfo, iPat ) ) + Aig_InfoSetBit( p->pCexComb->pData, i ); + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if computation should stop.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p ) +{ + unsigned * pInfo, * pInfo2; + int i; + if ( p->vCoSimInfo == NULL ) + return 0; + // compare outputs with 0 + if ( p->pPars->fDoubleOuts ) + { + assert( (Gia_ManCoNum(p->pAig) & 1) == 0 ); + for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ ) + { + pInfo = Vec_PtrEntry( p->vCoSimInfo, i ); + pInfo2 = Vec_PtrEntry( p->vCoSimInfo, ++i ); + if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) ) + { + if ( p->iOut == -1 ) + { + p->iOut = i/2; + Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) ); + } + if ( p->pCexes == NULL ) + p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig)/2 ); + if ( p->pCexes[i/2] == NULL ) + { + p->nOuts++; + p->pCexes[i/2] = (void *)1; + } + } + } + } + else + { + for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ ) + { + pInfo = Vec_PtrEntry( p->vCoSimInfo, i ); + if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) ) + { + if ( p->iOut == -1 ) + { + p->iOut = i; + Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) ); + } + if ( p->pCexes == NULL ) + p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig) ); + if ( p->pCexes[i] == NULL ) + { + p->nOuts++; + p->pCexes[i] = (void *)1; + } + } + } + } + return p->pCexes != NULL && p->pPars->fFirstStop; +} + +/**Function************************************************************* + Synopsis [Simulates one round.] Description [Returns the number of PO entry if failed; 0 otherwise.] @@ -765,17 +498,20 @@ void Cec_ManCswProcessRefined( Cec_ManCsw_t * p, Vec_Int_t * vRefined ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos, int iSeries, int fRandomize ) +int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ) { - static int nCountRand = 0; Gia_Obj_t * pObj; unsigned * pRes0, * pRes1, * pRes; int i, k, w, Ent, iCiId = 0, iCoId = 0; + // prepare internal storage + if ( p->nWordsOld != p->nWords ) + Cec_ManSimMemRelink( p ); p->nMemsMax = 0; + // simulate nodes Vec_IntClear( p->vRefinedC ); if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) ) { - pRes = Cec_ManCswSimRef( p, 0 ); + pRes = Cec_ManSimSimRef( p, 0 ); for ( w = 1; w <= p->nWords; w++ ) pRes[w] = 0; } @@ -788,16 +524,12 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t iCiId++; continue; } - pRes = Cec_ManCswSimRef( p, i ); + pRes = Cec_ManSimSimRef( p, i ); if ( vInfoCis ) { pRes0 = Vec_PtrEntry( vInfoCis, iCiId++ ); for ( w = 1; w <= p->nWords; w++ ) - { - pRes[w] = pRes0[iSeries*p->nWords+w-1]; - if ( fRandomize ) - pRes[w] ^= (1 << (nCountRand++ & 0x1f)); - } + pRes[w] = pRes0[w-1]; } else { @@ -810,7 +542,7 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t } if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin { - pRes0 = Cec_ManCswSimDeref( p, Gia_ObjFaninId0(pObj,i) ); + pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); if ( vInfoCos ) { pRes = Vec_PtrEntry( vInfoCos, iCoId++ ); @@ -824,9 +556,9 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t continue; } assert( Gia_ObjValue(pObj) ); - pRes = Cec_ManCswSimRef( p, i ); - pRes0 = Cec_ManCswSimDeref( p, Gia_ObjFaninId0(pObj,i) ); - pRes1 = Cec_ManCswSimDeref( p, Gia_ObjFaninId1(pObj,i) ); + pRes = Cec_ManSimSimRef( p, i ); + pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); + pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) ); if ( Gia_ObjFaninC0(pObj) ) { if ( Gia_ObjFaninC1(pObj) ) @@ -847,47 +579,50 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t } references: // if this node is candidate constant, collect it - if ( Cec_ObjIsConst(p, i) && !Cec_ManCswCompareConst(pRes + 1, p->nWords) ) + if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) ) { pRes[0]++; Vec_IntPush( p->vRefinedC, i ); } // if the node belongs to a class, save it - if ( Cec_ObjIsClass(p, i) ) + if ( Gia_ObjIsClass(p->pAig, i) ) pRes[0]++; // if this is the last node of the class, process it - if ( Cec_ObjIsTail(p, i) ) + if ( Gia_ObjIsTail(p->pAig, i) ) { Vec_IntClear( p->vClassTemp ); - Cec_ClassForEachObj( p, Cec_ObjRepr(p, i), Ent ) + Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent ) Vec_IntPush( p->vClassTemp, Ent ); - Cec_ManCswClassRefineOne( p, Cec_ObjRepr(p, i), 0 ); + Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) ); Vec_IntForEachEntry( p->vClassTemp, Ent, k ) - Cec_ManCswSimDeref( p, Ent ); + Cec_ManSimSimDeref( p, Ent ); } } if ( Vec_IntSize(p->vRefinedC) > 0 ) - Cec_ManCswProcessRefined( p, p->vRefinedC ); + Cec_ManSimProcessRefined( p, p->vRefinedC ); assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) ); assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) ); assert( p->nMems == 1 ); + if ( p->nMems != 1 ) + printf( "Cec_ManSimSimulateRound(): Memory management error!\n" ); if ( p->pPars->fVeryVerbose ) - Cec_ManCswPrintClasses( p, 0 ); + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); /* - if ( p->nMems > 1 ) - { + if ( p->nMems > 1 ) { for ( i = 1; i < p->nObjs; i++ ) - if ( p->pSims[i] ) - { + if ( p->pSims[i] ) { int x = 0; } } */ + return Cec_ManSimAnalyzeOutputs( p ); } + + /**Function************************************************************* - Synopsis [] + Synopsis [Creates simulation info for this round.] Description [] @@ -896,28 +631,41 @@ references: SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p ) +void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ) { - int i; - Gia_ManSetRefs( p->pAig ); - Cec_ManCswSimulateSimple( p ); - Cec_ManCswClassesCreate( p ); - for ( i = 0; i < p->pPars->nRounds; i++ ) + unsigned * pRes0, * pRes1; + int i, w; + if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 ) { - p->nWords = i + 1; - Cec_ManCswSimMemRelink( p ); - Cec_ManCswSimulateRound( p, NULL, NULL, 0, 0 ); + assert( vInfoCis && vInfoCos ); + for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vInfoCis, i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = Aig_ManRandom( 0 ); + } + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i ); + pRes1 = Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = pRes1[w]; + } + } + else + { + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vInfoCis, i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = Aig_ManRandom( 0 ); + } } - p->nWords = p->pPars->nWords; - Cec_ManCswSimMemRelink( p ); - for ( i = 0; i < p->pPars->nRounds; i++ ) - Cec_ManCswSimulateRound( p, NULL, NULL, 0, 0 ); - return 1; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the bug is found.] Description [] @@ -926,21 +674,37 @@ int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassesUpdate_rec( Gia_Obj_t * pObj ) +int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ) { - int Result; - if ( pObj->fMark0 ) - return 1; - if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) - return 0; - Result = (Cec_ManCswClassesUpdate_rec( Gia_ObjFanin0(pObj) ) | - Cec_ManCswClassesUpdate_rec( Gia_ObjFanin1(pObj) )); - return pObj->fMark0 = Result; + Gia_Obj_t * pObj; + int i; + assert( p->pAig->pReprs == NULL ); + // allocate representation + p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) ); + p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj)) ? 0 : GIA_VOID ); + // perform simulation + Gia_ManSetRefs( p->pAig ); + p->nWords = 1; + do { + if ( p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + for ( i = 0; i < 4; i++ ) + { + Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo ); + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; + } + p->nWords = 2 * p->nWords + 1; + } + while ( p->nWords <= p->pPars->nWords ); + return 0; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the bug is found.] Description [] @@ -949,100 +713,23 @@ int Cec_ManCswClassesUpdate_rec( Gia_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassesUpdate( Cec_ManCsw_t * p, Cec_ManPat_t * pPat, Gia_Man_t * pNew ) +int Cec_ManSimClassesRefine( Cec_ManSim_t * p ) { - Vec_Ptr_t * vInfo; - Gia_Obj_t * pObj, * pObjOld, * pReprOld; - int i, k, iRepr, iNode; - vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), p->pPars->nWords ); - if ( vInfo != NULL ) - { - for ( i = 0; i < pPat->nSeries; i++ ) - Cec_ManCswSimulateRound( p, vInfo, NULL, i, 0 ); - Vec_PtrFree( vInfo ); - } - assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) ); - // mark the transitive fanout of failed nodes - if ( p->pPars->nDepthMax != 1 ) + int i; + Gia_ManSetRefs( p->pAig ); + p->nWords = p->pPars->nWords; + for ( i = 0; i < p->pPars->nRounds; i++ ) { - Gia_ManCleanMark0( p->pAig ); - Gia_ManCleanMark1( p->pAig ); - Gia_ManForEachCo( pNew, pObj, k ) - { - iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); - iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); - if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved - continue; -// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1; - Gia_ManObj(p->pAig, iNode)->fMark0 = 1; - } - // mark the nodes reachable through the failed nodes - Gia_ManForEachAnd( p->pAig, pObjOld, k ) - pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0); - // unmark the disproved nodes - Gia_ManForEachCo( pNew, pObj, k ) - { - iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); - iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); - if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved - continue; - pObjOld = Gia_ManObj(p->pAig, iNode); - assert( pObjOld->fMark0 == 1 ); - if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 ) - pObjOld->fMark1 = 1; - } - // clean marks - Gia_ManForEachAnd( p->pAig, pObjOld, k ) - if ( pObjOld->fMark1 ) - { - pObjOld->fMark0 = 0; - pObjOld->fMark1 = 0; - } + if ( (i % 4) == 0 && p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo ); + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; } - // set the results - Gia_ManForEachCo( pNew, pObj, k ) - { - iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); - iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); - pReprOld = Gia_ManObj(p->pAig, iRepr); - pObjOld = Gia_ManObj(p->pAig, iNode); - if ( pObj->fMark1 ) - { // proved - assert( pObj->fMark0 == 0 ); - assert( !Cec_ObjProved(p, iNode) ); - if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) -// if ( pObjOld->fMark0 == 0 ) - { - assert( iRepr == Cec_ObjRepr(p, iNode) ); - Cec_ObjSetProved( p, iNode ); - p->nAllProved++; - } - } - else if ( pObj->fMark0 ) - { // disproved - assert( pObj->fMark1 == 0 ); - if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) -// if ( pObjOld->fMark0 == 0 ) - { - if ( iRepr == Cec_ObjRepr(p, iNode) ) - printf( "Cec_ManCswClassesUpdate(): Error! Node is not refined!\n" ); - p->nAllDisproved++; - } - } - else - { // failed - assert( pObj->fMark0 == 0 ); - assert( pObj->fMark1 == 0 ); - assert( !Cec_ObjFailed(p, iNode) ); - assert( !Cec_ObjProved(p, iNode) ); - Cec_ObjSetFailed( p, iNode ); - p->nAllFailed++; - } - } + if ( p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); return 0; } - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c index ab8fd5cf..e25ddc90 100644 --- a/src/aig/cec/cecCore.c +++ b/src/aig/cec/cecCore.c @@ -44,11 +44,37 @@ void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ) memset( p, 0, sizeof(Cec_ParSat_t) ); p->nBTLimit = 10; // conflict limit at a node p->nSatVarMax = 2000; // the max number of SAT variables - p->nCallsRecycle = 100; // calls to perform before recycling SAT solver + p->nCallsRecycle = 200; // calls to perform before recycling SAT solver p->fPolarFlip = 1; // flops polarity of variables + p->fCheckMiter = 0; // the circuit is the miter p->fFirstStop = 0; // stop on the first sat output - p->fVerbose = 1; // verbose stats + p->fVerbose = 0; // verbose stats } + +/**Function************ ************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSim_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->TimeLimit = 0; // the runtime limit in seconds + p->fCheckMiter = 0; // the circuit is the miter + p->fFirstStop = 0; // stop on the first sat output + p->fDoubleOuts = 0; // miter with separate outputs + p->fSeqSimulate = 0; // performs sequential simulation + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} /**Function************ ************************************************* @@ -61,19 +87,21 @@ void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p ) +void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ) { - memset( p, 0, sizeof(Cec_ParCsw_t) ); - p->nWords = 20; // the number of simulation words - p->nRounds = 20; // the number of simulation rounds - p->nItersMax = 20; // the maximum number of iterations of SAT sweeping - p->nBTLimit = 10000; // conflict limit at a node - p->nSatVarMax = 2000; // the max number of SAT variables - p->nCallsRecycle = 100; // calls to perform before recycling SAT solver + memset( p, 0, sizeof(Cec_ParFra_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->TimeLimit = 0; // the runtime limit in seconds + p->nItersMax = 1000; // the maximum number of iterations of SAT sweeping + p->nBTLimit = 1000; // conflict limit at a node p->nLevelMax = 0; // restriction on the level of nodes to be swept p->nDepthMax = 1; // the depth in terms of steps of speculative reduction p->fRewriting = 0; // enables AIG rewriting + p->fCheckMiter = 0; // the circuit is the miter p->fFirstStop = 0; // stop on the first sat output + p->fDoubleOuts = 0; // miter with separate outputs + p->fColorDiff = 0; // miter with separate outputs p->fVeryVerbose = 0; // verbose stats p->fVerbose = 0; // verbose stats } @@ -92,14 +120,13 @@ void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p ) void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ) { memset( p, 0, sizeof(Cec_ParCec_t) ); - p->nIters = 1; // iterations of SAT solving/sweeping - p->nBTLimitBeg = 2; // starting backtrack limit - p->nBTlimitMulti = 8; // multiple of backtrack limiter + p->nBTLimit = 1000; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds + p->fFirstStop = 0; // stop on the first sat output p->fUseSmartCnf = 0; // use smart CNF computation p->fRewriting = 0; // enables AIG rewriting - p->fSatSweeping = 0; // enables SAT sweeping - p->fFirstStop = 0; // stop on the first sat output - p->fVerbose = 1; // verbose stats + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats } /**Function************************************************************* @@ -124,6 +151,35 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) return pNew; } +/**Function************************************************************* + + Synopsis [Core procedure for simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + Cec_ManSim_t * pSim; + int RetValue, clkTotal = clock(); + if ( pPars->fSeqSimulate ) + printf( "Performing sequential simulation of %d frames with %d words.\n", + pPars->nWords, pPars->nRounds ); + Aig_ManRandom( 1 ); + pSim = Cec_ManSimStart( pAig, pPars ); + if ( pAig->pReprs == NULL ) + RetValue = Cec_ManSimClassesPrepare( pSim ); + Cec_ManSimClassesRefine( pSim ); + if ( pPars->fCheckMiter ) + printf( "The number of failed outputs of the miter = %6d. (Words = %4d. Rounds = %4d.)\n", + pSim->iOut, pSim->nOuts, pPars->nWords, pPars->nRounds ); + ABC_PRT( "Time", clock() - clkTotal ); + Cec_ManSimStop( pSim ); +} /**Function************************************************************* @@ -136,96 +192,185 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ) +Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) { + int fOutputResult = 0; Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; - Gia_Man_t * pNew; - Cec_ManCsw_t * p; + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Gia_Man_t * pIni, * pSrm, * pTemp; + Cec_ManFra_t * p; + Cec_ManSim_t * pSim; Cec_ManPat_t * pPat; - int i, RetValue, clk, clk2, clkTotal = clock(); + int i, fTimeOut = 0, nMatches = 0, clk, clk2; + double clkTotal = clock(); + + // duplicate AIG and transfer equivalence classes Aig_ManRandom( 1 ); - Gia_ManSetPhase( pAig ); - Gia_ManCleanMark0( pAig ); - Gia_ManCleanMark1( pAig ); - p = Cec_ManCswStart( pAig, pPars ); -clk = clock(); - RetValue = Cec_ManCswClassesPrepare( p ); -p->timeSim += clock() - clk; + pIni = Gia_ManDup(pAig); + pIni->pReprs = pAig->pReprs; pAig->pReprs = NULL; + pIni->pNexts = pAig->pNexts; pAig->pNexts = NULL; + + // prepare the managers + // SAT sweeping + p = Cec_ManFraStart( pIni, pPars ); + if ( pPars->fDoubleOuts ) + pPars->fColorDiff = 1; + // simulation + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nRounds = pPars->nRounds; + pParsSim->fCheckMiter = pPars->fCheckMiter; + pParsSim->fFirstStop = pPars->fFirstStop; + pParsSim->fDoubleOuts = pPars->fDoubleOuts; + pParsSim->fVerbose = pPars->fVerbose; + pSim = Cec_ManSimStart( p->pAig, pParsSim ); + pSim->nWords = p->pPars->nWords; + // SAT solving Cec_ManSatSetDefaultParams( pParsSat ); pParsSat->nBTLimit = pPars->nBTLimit; pParsSat->fVerbose = pPars->fVeryVerbose; + // simulation patterns pPat = Cec_ManPatStart(); pPat->fVerbose = pPars->fVeryVerbose; + + // start equivalence classes +clk = clock(); + if ( p->pAig->pReprs == NULL ) + { + if ( Cec_ManSimClassesPrepare(pSim) || Cec_ManSimClassesRefine(pSim) ) + { + Gia_ManStop( p->pAig ); + p->pAig = NULL; + goto finalize; + } + } +p->timeSim += clock() - clk; + // perform solving for ( i = 1; i <= pPars->nItersMax; i++ ) { clk2 = clock(); - pNew = Cec_ManCswSpecReduction( p ); - if ( pPars->fVeryVerbose ) + nMatches = 0; + if ( pPars->fDoubleOuts ) { - Gia_ManPrintStats( p->pAig ); - Gia_ManPrintStats( pNew ); + nMatches = Gia_ManEquivSetColors( p->pAig, pPars->fVeryVerbose ); +// p->pAig->pIso = Cec_ManDetectIsomorphism( p->pAig ); +// Gia_ManEquivTransform( p->pAig, 1 ); } - if ( Gia_ManCoNum(pNew) == 0 ) + pSrm = Cec_ManFraSpecReduction( p ); + if ( pPars->fVeryVerbose ) + Gia_ManPrintStats( pSrm ); + if ( Gia_ManCoNum(pSrm) == 0 ) { - Gia_ManStop( pNew ); + Gia_ManStop( pSrm ); + if ( p->pPars->fVerbose ) + printf( "Considered all available candidate equivalences.\n" ); + if ( pPars->fDoubleOuts && Gia_ManAndNum(p->pAig) > 0 ) + { + if ( pPars->fColorDiff ) + { + if ( p->pPars->fVerbose ) + printf( "Switching into reduced mode.\n" ); + pPars->fColorDiff = 0; + } + else + { + if ( p->pPars->fVerbose ) + printf( "Switching into normal mode.\n" ); + pPars->fDoubleOuts = 0; + } + continue; + } break; } clk = clock(); - Cec_ManSatSolve( pPat, pNew, pParsSat ); + Cec_ManSatSolve( pPat, pSrm, pParsSat ); p->timeSat += clock() - clk; -clk = clock(); - Cec_ManCswClassesUpdate( p, pPat, pNew ); -p->timeSim += clock() - clk; - Gia_ManStop( pNew ); - pNew = Cec_ManCswDupWithClasses( p ); - Gia_WriteAiger( pNew, "gia_temp_new.aig", 0, 1 ); + if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) ) + { + Gia_ManStop( pSrm ); + Gia_ManStop( p->pAig ); + p->pAig = NULL; + goto finalize; + } + Gia_ManStop( pSrm ); + + // update the manager + pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDoubleOuts ); + Gia_ManStop( pTemp ); if ( p->pPars->fVerbose ) { - printf( "%3d : P =%7d. D =%7d. F =%6d. Lit =%8d. And =%8d. ", - i, p->nAllProved, p->nAllDisproved, p->nAllFailed, - Cec_ManCswCountLitsAll(p), Gia_ManAndNum(pNew) ); + printf( "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", + i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) ); ABC_PRT( "Time", clock() - clk2 ); } - if ( p->pPars->fVeryVerbose ) + if ( Gia_ManAndNum(p->pAig) == 0 ) { - ABC_PRTP( "Sim ", p->timeSim, clock() - clkTotal ); - ABC_PRTP( "Sat ", p->timeSat, clock() - clkTotal ); - ABC_PRT( "Time", clock() - clkTotal ); - printf( "****** Intermedate result %3d ******\n", i ); - Gia_ManPrintStats( p->pAig ); - Gia_ManPrintStats( pNew ); - printf("The result is written into file \"%s\".\n", "gia_temp.aig" ); - printf( "************************************\n" ); + if ( p->pPars->fVerbose ) + printf( "Network after reduction is empty.\n" ); + break; } - if ( Gia_ManAndNum(pNew) == 0 ) + // check resource limits + if ( p->pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= p->pPars->TimeLimit ) { - Gia_ManStop( pNew ); + fTimeOut = 1; break; } - Gia_ManStop( pNew ); +// if ( p->nAllFailed && !p->nAllProved && !p->nAllDisproved ) + if ( p->nAllFailed > p->nAllProved + p->nAllDisproved ) + { + if ( pParsSat->nBTLimit >= 10000 ) + break; + pParsSat->nBTLimit *= 10; + if ( p->pPars->fVerbose ) + { + if ( p->pPars->fVerbose ) + printf( "Increasing conflict limit to %d.\n", pParsSat->nBTLimit ); + if ( fOutputResult ) + { + Gia_WriteAiger( p->pAig, "gia_cec_temp.aig", 0, 0 ); + printf("The result is written into file \"%s\".\n", "gia_cec_temp.aig" ); + } + } + } + if ( pPars->fDoubleOuts && pPars->fColorDiff && Gia_ManAndNum(p->pAig) < 100000 ) + { + if ( p->pPars->fVerbose ) + printf( "Switching into reduced mode.\n" ); + pPars->fColorDiff = 0; + } + if ( pPars->fDoubleOuts && Gia_ManAndNum(p->pAig) < 20000 ) + { + if ( p->pPars->fVerbose ) + printf( "Switching into normal mode.\n" ); + pPars->fColorDiff = 0; + pPars->fDoubleOuts = 0; + } } - Gia_ManCleanMark0( pAig ); - Gia_ManCleanMark1( pAig ); - - // verify the result +finalize: if ( p->pPars->fVerbose ) { - printf( "Verifying the result:\n" ); - pNew = Cec_ManCswSpecReductionProved( p ); - pParsSat->nBTLimit = 1000000; - pParsSat->fVerbose = 1; - Cec_ManSatSolve( NULL, pNew, pParsSat ); - Gia_ManStop( pNew ); + ABC_PRTP( "Sim ", p->timeSim, clock() - (int)clkTotal ); + ABC_PRTP( "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal ); + ABC_PRTP( "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal ); + ABC_PRT( "Time", clock() - clkTotal ); } - // create the resulting miter - pAig->pReprs = Cec_ManCswDeriveReprs( p ); - pNew = Gia_ManDupDfsClasses( pAig ); - Cec_ManCswStop( p ); + pTemp = p->pAig; p->pAig = NULL; + if ( pTemp == NULL ) + printf( "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut ); + else if ( pSim->pCexes ) + printf( "Disproved %d outputs of the miter.\n", pSim->nOuts ); + if ( fTimeOut ) + printf( "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC ); + + pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL; + Cec_ManSimStop( pSim ); Cec_ManPatStop( pPat ); - return pNew; + Cec_ManFraStop( p ); + return pTemp; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecInt.h b/src/aig/cec/cecInt.h index 309f4292..1898b07c 100644 --- a/src/aig/cec/cecInt.h +++ b/src/aig/cec/cecInt.h @@ -65,6 +65,7 @@ struct Cec_ManPat_t_ int timeSort; // sorting literals int timePack; // packing into sim info structures int timeTotal; // total runtime + int timeTotalSave; // total runtime for saving }; // SAT solving manager @@ -100,38 +101,43 @@ struct Cec_ManSat_t_ int timeTotal; // total runtime }; -// combinational sweeping object -typedef struct Cec_ObjCsw_t_ Cec_ObjCsw_t; -struct Cec_ObjCsw_t_ -{ - int iRepr; // representative node - unsigned iNext : 30; // next node in the class - unsigned iProved : 1; // this node is proved - unsigned iFailed : 1; // this node is failed - unsigned SimNum; // simulation info number -}; - // combinational simulation manager -typedef struct Cec_ManCsw_t_ Cec_ManCsw_t; -struct Cec_ManCsw_t_ +typedef struct Cec_ManSim_t_ Cec_ManSim_t; +struct Cec_ManSim_t_ { // parameters Gia_Man_t * pAig; // the AIG to be used for simulation - Cec_ParCsw_t * pPars; // SAT sweeping parameters + Cec_ParSim_t * pPars; // simulation parameters int nWords; // the number of simulation words - // equivalence classes - Cec_ObjCsw_t * pObjs; // objects used for SAT sweeping // recycable memory + int * pSimInfo; // simulation information offsets unsigned * pMems; // allocated simulaton memory int nWordsAlloc; // the number of allocated entries int nMems; // the number of used entries int nMemsMax; // the max number of used entries int MemFree; // next free entry + int nWordsOld; // the number of simulation words after previous relink + // bug catcher + Vec_Ptr_t * vCiSimInfo; // CI simulation info + Vec_Ptr_t * vCoSimInfo; // CO simulation info + void ** pCexes; // counter-examples for each output + int iOut; // first failed output + int nOuts; // the number of failed outputs + Gia_Cex_t * pCexComb; // counter-example for the first failed output // temporaries Vec_Int_t * vClassOld; // old class numbers Vec_Int_t * vClassNew; // new class numbers Vec_Int_t * vClassTemp; // temporary storage Vec_Int_t * vRefinedC; // refined const reprs +}; + +// combinational simulation manager +typedef struct Cec_ManFra_t_ Cec_ManFra_t; +struct Cec_ManFra_t_ +{ + // parameters + Gia_Man_t * pAig; // the AIG to be used for simulation + Cec_ParFra_t * pPars; // SAT sweeping parameters // simulation patterns Vec_Int_t * vXorNodes; // nodes used in speculative reduction int nAllProved; // total number of proved nodes @@ -139,6 +145,7 @@ struct Cec_ManCsw_t_ int nAllFailed; // total number of failed nodes // runtime stats int timeSim; // unsat + int timePat; // unsat int timeSat; // sat int timeTotal; // total runtime }; @@ -153,29 +160,31 @@ struct Cec_ManCsw_t_ /*=== cecCore.c ============================================================*/ /*=== cecClass.c ============================================================*/ -extern int Cec_ManCswCountLitsAll( Cec_ManCsw_t * p ); -extern int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p ); -extern Gia_Man_t * Cec_ManCswSpecReduction( Cec_ManCsw_t * p ); -extern Gia_Man_t * Cec_ManCswSpecReductionProved( Cec_ManCsw_t * p ); -extern Gia_Man_t * Cec_ManCswDupWithClasses( Cec_ManCsw_t * p ); -extern int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p ); -extern int Cec_ManCswClassesUpdate( Cec_ManCsw_t * p, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); +extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ); +extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p ); +extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ); +/*=== cecIso.c ============================================================*/ +extern int * Cec_ManDetectIsomorphism( Gia_Man_t * p ); /*=== cecMan.c ============================================================*/ -extern Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ); -extern void Cec_ManCswStop( Cec_ManCsw_t * p ); -extern Cec_ManPat_t * Cec_ManPatStart(); -extern void Cec_ManPatPrintStats( Cec_ManPat_t * p ); -extern void Cec_ManPatStop( Cec_ManPat_t * p ); extern Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); extern void Cec_ManSatPrintStats( Cec_ManSat_t * p ); extern void Cec_ManSatStop( Cec_ManSat_t * p ); +extern Cec_ManPat_t * Cec_ManPatStart(); +extern void Cec_ManPatPrintStats( Cec_ManPat_t * p ); +extern void Cec_ManPatStop( Cec_ManPat_t * p ); +extern Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); +extern void Cec_ManSimStop( Cec_ManSim_t * p ); +extern Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars ); +extern void Cec_ManFraStop( Cec_ManFra_t * p ); /*=== cecPat.c ============================================================*/ extern void Cec_ManPatSavePattern( Cec_ManPat_t * pPat, Cec_ManSat_t * p, Gia_Obj_t * pObj ); extern Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWords ); /*=== cecSolve.c ============================================================*/ extern int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj ); extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars ); -/*=== cecUtil.c ============================================================*/ +/*=== ceFraeep.c ============================================================*/ +extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ); +extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); #ifdef __cplusplus } diff --git a/src/aig/cec/cecIso.c b/src/aig/cec/cecIso.c new file mode 100644 index 00000000..08d4b7ec --- /dev/null +++ b/src/aig/cec/cecIso.c @@ -0,0 +1,370 @@ +/**CFile**************************************************************** + + FileName [cecIso.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecIso.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline unsigned * Cec_ManIsoInfo( unsigned * pStore, int nWords, int Id ) { return pStore + nWords * Id; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes simulation info for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoSimulate( Gia_Obj_t * pObj, int Id, unsigned * pStore, int nWords ) +{ + unsigned * pInfo = Cec_ManIsoInfo( pStore, nWords, Id ); + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId0(pObj, Id) ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId1(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Copies simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoCopy( int IdDest, int IdSour, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, IdDest ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, IdSour ); + int w; + for ( w = 0; w < nWords; w++ ) + pInfo0[w] = pInfo1[w]; +} + +/**Function************************************************************* + + Synopsis [Compares simulation info of two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoEqual( int Id0, int Id1, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id0 ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Id1 ); + int w; + for ( w = 0; w < nWords; w++ ) + if ( pInfo0[w] != pInfo1[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Generates random simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoRandom( int Id, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id ); + int w; + for ( w = 0; w < nWords; w++ ) + pInfo0[w] = Aig_ManRandom( 0 ); +} + +/**Function************************************************************* + + Synopsis [Computes hash key of the simuation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoHashKey( int Id, unsigned * pStore, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id ); + unsigned uHash = 0; + int i; + for ( i = 0; i < nWords; i++ ) + uHash ^= pInfo0[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Adds node to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoTableAdd( Gia_Man_t * p, int Id, unsigned * pStore, int nWords, int * pTable, int nTableSize ) +{ + Gia_Obj_t * pTemp; + int Key, Ent, Counter = 0, Color = Gia_ObjColors( p, Id ); + assert( Color == 1 || Color == 2 ); + Key = Gia_ManIsoHashKey( Id, pStore, nWords, nTableSize ); + for ( Ent = pTable[Key], pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp; + Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) ) + { + if ( Gia_ObjColors( p, Ent ) != Color ) + continue; + if ( !Gia_ManIsoEqual( Id, Ent, pStore, nWords ) ) + continue; + // found node with the same color and signature - mark it and do not add new node + pTemp->fMark0 = 1; + return; + } + // did not find the node with the same color and signature - add new node + pTemp = Gia_ManObj( p, Id ); + assert( pTemp->Value == 0 ); + assert( pTemp->fMark0 == 0 ); + pTemp->Value = pTable[Key]; + pTable[Key] = Id; +} + +/**Function************************************************************* + + Synopsis [Extracts equivalence class candidates from one bin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoExtractClasses( Gia_Man_t * p, int Bin, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB ) +{ + Gia_Obj_t * pTemp; + int Ent; + Vec_IntClear( vNodesA ); + Vec_IntClear( vNodesB ); + for ( Ent = Bin, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp; + Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) ) + { + if ( pTemp->fMark0 ) + { + pTemp->fMark0 = 0; + continue; + } + if ( Gia_ObjColors( p, Ent ) == 1 ) + Vec_IntPush( vNodesA, Ent ); + else + Vec_IntPush( vNodesB, Ent ); + } + return Vec_IntSize(vNodesA) > 0 && Vec_IntSize(vNodesB) > 0; +} + +/**Function************************************************************* + + Synopsis [Matches nodes in the extacted classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoMatchNodes( int * pIso, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB ) +{ + int k0, k1, IdA, IdB; + Vec_IntForEachEntry( vNodesA, IdA, k0 ) + Vec_IntForEachEntry( vNodesB, IdB, k1 ) + { + if ( Gia_ManIsoEqual( IdA, IdB, pStore, nWords ) ) + { + assert( pIso[IdA] == 0 ); + assert( pIso[IdB] == 0 ); + assert( IdA != IdB ); + pIso[IdA] = IdB; + pIso[IdB] = IdA; + continue; + } + } +} + +/**Function************************************************************* + + Synopsis [Transforms iso into equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManTransformClasses( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts && p->pIso ); + memset( p->pReprs, 0, sizeof(int) * Gia_ManObjNum(p) ); + memset( p->pNexts, 0, sizeof(int) * Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( p->pIso[i] && p->pIso[i] < i ) + { + p->pReprs[i].iRepr = p->pIso[i]; + p->pNexts[p->pIso[i]] = i; + } + } +} + +/**Function************************************************************* + + Synopsis [Finds node correspondences in the miter.] + + Description [Assumes that the colors are assigned.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Cec_ManDetectIsomorphism( Gia_Man_t * p ) +{ + int nWords = 2; + Gia_Obj_t * pObj; + Vec_Int_t * vNodesA, * vNodesB; + unsigned * pStore, Counter; + int i, * pIso, * pTable, nTableSize; + // start equivalence classes + pIso = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjColors(p, i) == 0 ); + continue; + } + assert( Gia_ObjColors(p, i) ); + if ( Gia_ObjColors(p, i) == 3 ) + pIso[i] = i; + } + // start simulation info + pStore = ABC_ALLOC( unsigned, Gia_ManObjNum(p) * nWords ); + // simulate and create table + nTableSize = Aig_PrimeCudd( 100 + Gia_ManObjNum(p)/2 ); + pTable = ABC_CALLOC( int, nTableSize ); + Gia_ManCleanValue( p ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + continue; + if ( pIso[i] == 0 ) // simulate + Gia_ManIsoSimulate( pObj, i, pStore, nWords ); + else if ( pIso[i] < i ) // copy + Gia_ManIsoCopy( i, pIso[i], pStore, nWords ); + else // generate + Gia_ManIsoRandom( i, pStore, nWords ); + if ( pIso[i] == 0 ) + Gia_ManIsoTableAdd( p, i, pStore, nWords, pTable, nTableSize ); + } + // create equivalence classes + vNodesA = Vec_IntAlloc( 100 ); + vNodesB = Vec_IntAlloc( 100 ); + for ( i = 0; i < nTableSize; i++ ) + if ( Gia_ManIsoExtractClasses( p, pTable[i], pStore, nWords, vNodesA, vNodesB ) ) + Gia_ManIsoMatchNodes( pIso, pStore, nWords, vNodesA, vNodesB ); + Vec_IntFree( vNodesA ); + Vec_IntFree( vNodesB ); + // collect info + Counter = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + Counter += (pIso[i] && pIso[i] < i); +/* + if ( pIso[i] && pIso[i] < i ) + { + if ( (Gia_ObjIsHead(p,pIso[i]) && Gia_ObjRepr(p,i)==pIso[i]) || + (Gia_ObjIsClass(p,pIso[i]) && Gia_ObjRepr(p,i)==Gia_ObjRepr(p,pIso[i])) ) + printf( "1" ); + else + printf( "0" ); + } +*/ + } + printf( "Computed %d pairs of structurally equivalent nodes.\n", Counter ); +// p->pIso = pIso; +// Cec_ManTransformClasses( p ); + + ABC_FREE( pTable ); + ABC_FREE( pStore ); + return pIso; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecMan.c b/src/aig/cec/cecMan.c index b8ee75b2..1a94409f 100644 --- a/src/aig/cec/cecMan.c +++ b/src/aig/cec/cecMan.c @@ -30,7 +30,7 @@ /**Function************************************************************* - Synopsis [Creates AIG.] + Synopsis [Creates the manager.] Description [] @@ -39,26 +39,25 @@ SeeAlso [] ***********************************************************************/ -Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ) -{ - Cec_ManCsw_t * p; - p = ABC_ALLOC( Cec_ManCsw_t, 1 ); - memset( p, 0, sizeof(Cec_ManCsw_t) ); - p->pAig = pAig; - p->pPars = pPars; - p->pObjs = ABC_CALLOC( Cec_ObjCsw_t, Gia_ManObjNum(pAig) ); - // temporaries - p->vClassOld = Vec_IntAlloc( 1000 ); - p->vClassNew = Vec_IntAlloc( 1000 ); - p->vClassTemp = Vec_IntAlloc( 1000 ); - p->vRefinedC = Vec_IntAlloc( 10000 ); - p->vXorNodes = Vec_IntAlloc( 1000 ); +Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) +{ + Cec_ManSat_t * p; + // create interpolation manager + p = ABC_ALLOC( Cec_ManSat_t, 1 ); + memset( p, 0, sizeof(Cec_ManSat_t) ); + p->pPars = pPars; + p->pAig = pAig; + // SAT solving + p->nSatVars = 1; + p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); + p->vUsedNodes = Vec_PtrAlloc( 1000 ); + p->vFanins = Vec_PtrAlloc( 100 ); return p; } /**Function************************************************************* - Synopsis [Deletes AIG.] + Synopsis [Prints statistics of the manager.] Description [] @@ -67,19 +66,46 @@ Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswStop( Cec_ManCsw_t * p ) +void Cec_ManSatPrintStats( Cec_ManSat_t * p ) { - Vec_IntFree( p->vXorNodes ); - Vec_IntFree( p->vClassOld ); - Vec_IntFree( p->vClassNew ); - Vec_IntFree( p->vClassTemp ); - Vec_IntFree( p->vRefinedC ); - ABC_FREE( p->pMems ); - ABC_FREE( p->pObjs ); + printf( "CO = %6d ", Gia_ManCoNum(p->pAig) ); + printf( "Conf = %5d ", p->pPars->nBTLimit ); + printf( "MinVar = %5d ", p->pPars->nSatVarMax ); + printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Frees the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatStop( Cec_ManSat_t * p ) +{ + if ( p->pSat ) + sat_solver_delete( p->pSat ); + Vec_PtrFree( p->vUsedNodes ); + Vec_PtrFree( p->vFanins ); + ABC_FREE( p->pSatVars ); ABC_FREE( p ); } + /**Function************************************************************* Synopsis [Creates AIG.] @@ -147,9 +173,11 @@ void Cec_ManPatStop( Cec_ManPat_t * p ) ABC_FREE( p ); } + + /**Function************************************************************* - Synopsis [Creates the manager.] + Synopsis [Creates AIG.] Description [] @@ -158,25 +186,31 @@ void Cec_ManPatStop( Cec_ManPat_t * p ) SeeAlso [] ***********************************************************************/ -Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) -{ - Cec_ManSat_t * p; - // create interpolation manager - p = ABC_ALLOC( Cec_ManSat_t, 1 ); - memset( p, 0, sizeof(Cec_ManSat_t) ); - p->pPars = pPars; - p->pAig = pAig; - // SAT solving - p->nSatVars = 1; - p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); - p->vUsedNodes = Vec_PtrAlloc( 1000 ); - p->vFanins = Vec_PtrAlloc( 100 ); +Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + Cec_ManSim_t * p; + p = ABC_ALLOC( Cec_ManSim_t, 1 ); + memset( p, 0, sizeof(Cec_ManSim_t) ); + p->pAig = pAig; + p->pPars = pPars; + p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); + p->vClassOld = Vec_IntAlloc( 1000 ); + p->vClassNew = Vec_IntAlloc( 1000 ); + p->vClassTemp = Vec_IntAlloc( 1000 ); + p->vRefinedC = Vec_IntAlloc( 10000 ); + p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords ); + if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) ) + { + p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords ); + Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords ); + } + p->iOut = -1; return p; } /**Function************************************************************* - Synopsis [Prints statistics of the manager.] + Synopsis [Deletes AIG.] Description [] @@ -185,26 +219,27 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) SeeAlso [] ***********************************************************************/ -void Cec_ManSatPrintStats( Cec_ManSat_t * p ) +void Cec_ManSimStop( Cec_ManSim_t * p ) { - printf( "CO = %6d ", Gia_ManCoNum(p->pAig) ); - printf( "Conf = %5d ", p->pPars->nBTLimit ); - printf( "MinVar = %5d ", p->pPars->nSatVarMax ); - printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle ); - printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", - p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); - ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); - printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", - p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); - ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); - printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", - p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); - ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + Vec_IntFree( p->vClassOld ); + Vec_IntFree( p->vClassNew ); + Vec_IntFree( p->vClassTemp ); + Vec_IntFree( p->vRefinedC ); + if ( p->vCiSimInfo ) + Vec_PtrFree( p->vCiSimInfo ); + if ( p->vCoSimInfo ) + Vec_PtrFree( p->vCoSimInfo ); + ABC_FREE( p->pCexComb ); + ABC_FREE( p->pCexes ); + ABC_FREE( p->pMems ); + ABC_FREE( p->pSimInfo ); + ABC_FREE( p ); } + /**Function************************************************************* - Synopsis [Frees the manager.] + Synopsis [Creates AIG.] Description [] @@ -213,16 +248,35 @@ void Cec_ManSatPrintStats( Cec_ManSat_t * p ) SeeAlso [] ***********************************************************************/ -void Cec_ManSatStop( Cec_ManSat_t * p ) +Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) +{ + Cec_ManFra_t * p; + p = ABC_ALLOC( Cec_ManFra_t, 1 ); + memset( p, 0, sizeof(Cec_ManFra_t) ); + p->pAig = pAig; + p->pPars = pPars; + p->vXorNodes = Vec_IntAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraStop( Cec_ManFra_t * p ) { - if ( p->pSat ) - sat_solver_delete( p->pSat ); - Vec_PtrFree( p->vUsedNodes ); - Vec_PtrFree( p->vFanins ); - ABC_FREE( p->pSatVars ); + Vec_IntFree( p->vXorNodes ); ABC_FREE( p ); } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecPat.c b/src/aig/cec/cecPat.c index 1af4f333..b80f1e44 100644 --- a/src/aig/cec/cecPat.c +++ b/src/aig/cec/cecPat.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [cec.c] + FileName [cecPat.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Combinatinoal equivalence checking.] - Synopsis [] + Synopsis [Simulation pattern manager.] Author [Alan Mishchenko] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: cec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ diff --git a/src/aig/cec/cecSim.c b/src/aig/cec/cecSim.c new file mode 100644 index 00000000..dbd3bd5e --- /dev/null +++ b/src/aig/cec/cecSim.c @@ -0,0 +1,48 @@ +/**CFile**************************************************************** + + FileName [cecSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Simulation manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecSolve.c b/src/aig/cec/cecSolve.c index e4daf719..ba4b0477 100644 --- a/src/aig/cec/cecSolve.c +++ b/src/aig/cec/cecSolve.c @@ -390,6 +390,70 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p ) /**Function************************************************************* + Synopsis [Sets variable activities in the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_SetActivityFactors_rec( Cec_ManSat_t * p, Gia_Obj_t * pObj, int LevelMin, int LevelMax ) +{ + float dActConeBumpMax = 20.0; + int iVar; + // skip visited variables + if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p->pAig, pObj); + // add the PI to the list + if ( Gia_ObjLevel(p->pAig, pObj) <= LevelMin || Gia_ObjIsCi(pObj) ) + return; + // set the factor of this variable + // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pPars->dActConeBumpMax / ThisBump + if ( (iVar = Cec_ObjSatNum(p,pObj)) ) + { + p->pSat->factors[iVar] = dActConeBumpMax * (Gia_ObjLevel(p->pAig, pObj) - LevelMin)/(LevelMax - LevelMin); + veci_push(&p->pSat->act_vars, iVar); + } + // explore the fanins + Cec_SetActivityFactors_rec( p, Gia_ObjFanin0(pObj), LevelMin, LevelMax ); + Cec_SetActivityFactors_rec( p, Gia_ObjFanin1(pObj), LevelMin, LevelMax ); +} + +/**Function************************************************************* + + Synopsis [Sets variable activities in the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SetActivityFactors( Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + float dActConeRatio = 0.5; + int LevelMin, LevelMax; + // reset the active variables + veci_resize(&p->pSat->act_vars, 0); + // prepare for traversal + Gia_ManIncrementTravId( p->pAig ); + // determine the min and max level to visit + assert( dActConeRatio > 0 && dActConeRatio < 1 ); + LevelMax = Gia_ObjLevel(p->pAig,pObj); + LevelMin = (int)(LevelMax * (1.0 - dActConeRatio)); + // traverse + Cec_SetActivityFactors_rec( p, pObj, LevelMin, LevelMax ); +//Cec_PrintActivity( p ); + return 1; +} + + +/**Function************************************************************* + Synopsis [Runs equivalence test for the two nodes.] Description [] @@ -402,7 +466,7 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p ) int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) { int nBTLimit = p->pPars->nBTLimit; - int Lit, RetValue, status, clk, nConflicts; + int Lit, RetValue, status, clk, clk2, nConflicts; p->nCallsSince++; // experiment with this!!! p->nSatTotal++; @@ -415,7 +479,14 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) Cec_ManSatSolverRecycle( p ); // if the nodes do not have SAT variables, allocate them +clk2 = clock(); Cec_CnfNodeAddToSolver( p, Gia_ObjFanin0(pObj) ); +//ABC_PRT( "cnf", clock() - clk2 ); +//printf( "%d \n", p->pSat->size ); + +clk2 = clock(); +// Cec_SetActivityFactors( p, Gia_ObjFanin0(pObj) ); +//ABC_PRT( "act", clock() - clk2 ); // propage unit clauses if ( p->pSat->qtail != p->pSat->qhead ) @@ -435,8 +506,12 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) //Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); clk = clock(); nConflicts = p->pSat->stats.conflicts; + +clk2 = clock(); RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); +//ABC_PRT( "sat", clock() - clk2 ); + if ( RetValue == l_False ) { p->timeSatUnsat += clock() - clk; @@ -466,6 +541,7 @@ p->timeSatUndec += clock() - clk; } } + /**Function************************************************************* Synopsis [Performs one round of solving for the POs of the AIG.] @@ -486,7 +562,7 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar Bar_Progress_t * pProgress = NULL; Cec_ManSat_t * p; Gia_Obj_t * pObj; - int i, status, clk = clock(); + int i, status, clk = clock(), clk2; // sprintf( Buffer, "gia%03d.aig", Counter++ ); //Gia_WriteAiger( pAig, Buffer, 0, 0 ); @@ -499,8 +575,9 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar pPat->nPats = 0; pPat->nPatLits = 0; pPat->nPatLitsMin = 0; - } + } Gia_ManSetPhase( pAig ); + Gia_ManLevelNum( pAig ); Gia_ManResetTravId( pAig ); p = Cec_ManSatCreate( pAig, pPars ); pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); @@ -512,13 +589,19 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar pObj->fMark1 = 1; continue; } -//printf( "Output %6d : ", i ); - Bar_ProgressUpdate( pProgress, i, "SAT..." ); +clk2 = clock(); status = Cec_ManSatCheckNode( p, pObj ); pObj->fMark0 = (status == 0); pObj->fMark1 = (status == 1); /* +printf( "Output %6d : ", i ); +printf( "conf = %6d ", p->pSat->stats.conflicts ); +printf( "prop = %6d ", p->pSat->stats.propagations ); +ABC_PRT( "time", clock() - clk2 ); +*/ + +/* if ( status == -1 ) { Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj ); @@ -531,7 +614,11 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar continue; // save the pattern if ( pPat ) + { + int clk3 = clock(); Cec_ManPatSavePattern( pPat, p, pObj ); + pPat->timeTotalSave += clock() - clk3; + } // quit if one of them is solved if ( pPars->fFirstStop ) break; diff --git a/src/aig/cec/cecSweep.c b/src/aig/cec/cecSweep.c new file mode 100644 index 00000000..20a668bd --- /dev/null +++ b/src/aig/cec/cecSweep.c @@ -0,0 +1,294 @@ +/**CFile**************************************************************** + + FileName [ceFraeep.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [SAT sweeping manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ceFraeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs limited speculative reduction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + int iRes0, iRes1, iRepr, iNode, iMiter; + int i, fCompl, * piCopies, * pDepths; + Gia_ManSetPhase( p->pAig ); + Vec_IntClear( p->vXorNodes ); + if ( p->pPars->nLevelMax ) + Gia_ManLevelNum( p->pAig ); + pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); + pNew->pName = Aig_UtilStrsav( p->pAig->pName ); + Gia_ManHashAlloc( pNew ); + piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); + pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); + piCopies[0] = 0; + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + piCopies[i] = Gia_ManAppendCi( pNew ); + continue; + } + if ( Gia_ObjIsCo(pObj) ) + continue; + if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 || + piCopies[Gia_ObjFaninId1(pObj,i)] == -1 ) + continue; + iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); + iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); + iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); + pDepths[i] = AIG_MAX( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] ); + if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID || Gia_ObjFailed(p->pAig, i) ) + continue; + assert( Gia_ObjRepr(p->pAig, i) < i ); + iRepr = piCopies[Gia_ObjRepr(p->pAig, i)]; + if ( iRepr == -1 ) + continue; + if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) + continue; + if ( p->pPars->nLevelMax && + (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax || + Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) ) + continue; + if ( p->pPars->fDoubleOuts ) + { +// if ( i % 1000 == 0 && Gia_ObjRepr(p->pAig, i) ) +// Gia_ManEquivPrintOne( p->pAig, Gia_ObjRepr(p->pAig, i), 0 ); + if ( p->pPars->fColorDiff ) + { + if ( !Gia_ObjDiffColors( p->pAig, Gia_ObjRepr(p->pAig, i), i ) ) + continue; + } + else + { + if ( !Gia_ObjDiffColors2( p->pAig, Gia_ObjRepr(p->pAig, i), i ) ) + continue; + } + } + pRepr = Gia_ManObj( p->pAig, Gia_ObjRepr(p->pAig, i) ); + fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); + piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); + if ( Gia_ObjProved(p->pAig, i) ) + continue; + // produce speculative miter + iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); + Gia_ManAppendCo( pNew, iMiter ); + Vec_IntPush( p->vXorNodes, Gia_ObjRepr(p->pAig, i) ); + Vec_IntPush( p->vXorNodes, i ); + // add to the depth of this node + pDepths[i] = 1 + AIG_MAX( pDepths[i], pDepths[Gia_ObjRepr(p->pAig, i)] ); + if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax ) + piCopies[i] = -1; + } + ABC_FREE( piCopies ); + ABC_FREE( pDepths ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManFraClassesUpdate_rec( Gia_Obj_t * pObj ) +{ + int Result; + if ( pObj->fMark0 ) + return 1; + if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) + return 0; + Result = (Cec_ManFraClassesUpdate_rec( Gia_ObjFanin0(pObj) ) | + Cec_ManFraClassesUpdate_rec( Gia_ObjFanin1(pObj) )); + return pObj->fMark0 = Result; +} + +/**Function************************************************************* + + Synopsis [Creates simulation info for this round.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vCiInfo, Vec_Ptr_t * vInfo, int nSeries ) +{ + unsigned * pRes0, * pRes1; + int i, w; + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vCiInfo, i ); + pRes1 = Vec_PtrEntry( vInfo, i ); + pRes1 += p->nWords * nSeries; + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = pRes1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Updates equivalence classes using the patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ) +{ + Vec_Ptr_t * vInfo; + Gia_Obj_t * pObj, * pObjOld, * pReprOld; + int i, k, iRepr, iNode, clk; +clk = clock(); + vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), pSim->nWords ); +p->timePat += clock() - clk; +clk = clock(); + if ( vInfo != NULL ) + { + Gia_ManSetRefs( p->pAig ); + for ( i = 0; i < pPat->nSeries; i++ ) + { + Cec_ManFraCreateInfo( pSim, pSim->vCiSimInfo, vInfo, i ); + if ( Cec_ManSimSimulateRound( pSim, pSim->vCiSimInfo, pSim->vCoSimInfo ) ) + { + Vec_PtrFree( vInfo ); + return 1; + } + } + Vec_PtrFree( vInfo ); + } +p->timeSim += clock() - clk; + assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) ); + // mark the transitive fanout of failed nodes + if ( p->pPars->nDepthMax != 1 ) + { + Gia_ManCleanMark0( p->pAig ); + Gia_ManCleanMark1( p->pAig ); + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved + continue; +// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1; + Gia_ManObj(p->pAig, iNode)->fMark0 = 1; + } + // mark the nodes reachable through the failed nodes + Gia_ManForEachAnd( p->pAig, pObjOld, k ) + pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0); + // unmark the disproved nodes + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved + continue; + pObjOld = Gia_ManObj(p->pAig, iNode); + assert( pObjOld->fMark0 == 1 ); + if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 ) + pObjOld->fMark1 = 1; + } + // clean marks + Gia_ManForEachAnd( p->pAig, pObjOld, k ) + if ( pObjOld->fMark1 ) + { + pObjOld->fMark0 = 0; + pObjOld->fMark1 = 0; + } + } + // set the results + p->nAllProved = p->nAllDisproved = p->nAllFailed = 0; + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + pReprOld = Gia_ManObj(p->pAig, iRepr); + pObjOld = Gia_ManObj(p->pAig, iNode); + if ( pObj->fMark1 ) + { // proved + assert( pObj->fMark0 == 0 ); + assert( !Gia_ObjProved(p->pAig, iNode) ); + if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) +// if ( pObjOld->fMark0 == 0 ) + { + assert( iRepr == Gia_ObjRepr(p->pAig, iNode) ); + Gia_ObjSetProved( p->pAig, iNode ); + p->nAllProved++; + } + } + else if ( pObj->fMark0 ) + { // disproved + assert( pObj->fMark1 == 0 ); + if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) +// if ( pObjOld->fMark0 == 0 ) + { + if ( iRepr == Gia_ObjRepr(p->pAig, iNode) ) + printf( "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" ); + p->nAllDisproved++; + } + } + else + { // failed + assert( pObj->fMark0 == 0 ); + assert( pObj->fMark1 == 0 ); + assert( !Gia_ObjFailed(p->pAig, iNode) ); + assert( !Gia_ObjProved(p->pAig, iNode) ); + Gia_ObjSetFailed( p->pAig, iNode ); + p->nAllFailed++; + } + } + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/module.make b/src/aig/cec/module.make index f8e2602a..4618c424 100644 --- a/src/aig/cec/module.make +++ b/src/aig/cec/module.make @@ -1,5 +1,9 @@ -SRC += src/aig/cec/cecClass.c \ +SRC += src/aig/cec/cecCec.c \ + src/aig/cec/cecClass.c \ src/aig/cec/cecCore.c \ + src/aig/cec/cecIso.c \ src/aig/cec/cecMan.c \ src/aig/cec/cecPat.c \ - src/aig/cec/cecSolve.c + src/aig/cec/cecSim.c \ + src/aig/cec/cecSolve.c \ + src/aig/cec/cecSweep.c diff --git a/src/aig/dar/darRefact.c b/src/aig/dar/darRefact.c index f0173a3c..f64564fa 100644 --- a/src/aig/dar/darRefact.c +++ b/src/aig/dar/darRefact.c @@ -113,7 +113,7 @@ Ref_Man_t * Dar_ManRefStart( Aig_Man_t * pAig, Dar_RefPar_t * pPars ) // other data p->vCuts = Vec_VecStart( pPars->nCutsMax ); p->vTruthElem = Vec_PtrAllocTruthTables( pPars->nLeafMax ); - p->vTruthStore = Vec_PtrAllocSimInfo( 256, Kit_TruthWordNum(pPars->nLeafMax) ); + p->vTruthStore = Vec_PtrAllocSimInfo( 1024, Kit_TruthWordNum(pPars->nLeafMax) ); p->vMemory = Vec_IntAlloc( 1 << 16 ); p->vCutNodes = Vec_PtrAlloc( 256 ); p->vLeavesBest = Vec_PtrAlloc( pPars->nLeafMax ); diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index b77dd76f..91507947 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -36,27 +36,50 @@ extern "C" { #endif #define GIA_NONE 0x1FFFFFFF +#define GIA_VOID 0x0FFFFFFF //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Gia_Rpr_t_ Gia_Rpr_t; +struct Gia_Rpr_t_ +{ + unsigned iRepr : 28; // representative node + unsigned fProved : 1; // marks the proved equivalence + unsigned fFailed : 1; // marks the failed equivalence + unsigned fColorA : 1; // marks cone of A + unsigned fColorB : 1; // marks cone of B +}; + typedef struct Gia_Obj_t_ Gia_Obj_t; struct Gia_Obj_t_ { - unsigned iDiff0 : 29; // the diff of the first fanin - unsigned fCompl0: 1; // the complemented attribute - unsigned fMark0 : 1; // first user-controlled mark - unsigned fTerm : 1; // terminal node (CI/CO) + unsigned iDiff0 : 29; // the diff of the first fanin + unsigned fCompl0: 1; // the complemented attribute + unsigned fMark0 : 1; // first user-controlled mark + unsigned fTerm : 1; // terminal node (CI/CO) - unsigned iDiff1 : 29; // the diff of the second fanin - unsigned fCompl1: 1; // the complemented attribute - unsigned fMark1 : 1; // second user-controlled mark - unsigned fPhase : 1; // value under 000 pattern + unsigned iDiff1 : 29; // the diff of the second fanin + unsigned fCompl1: 1; // the complemented attribute + unsigned fMark1 : 1; // second user-controlled mark + unsigned fPhase : 1; // value under 000 pattern unsigned Value; // application-specific value }; +// sequential counter-example +typedef struct Gia_Cex_t_ Gia_Cex_t; +struct Gia_Cex_t_ +{ + int iPo; // the zero-based number of PO, for which verification failed + int iFrame; // the zero-based number of the time-frame, for which verificaiton failed + int nRegs; // the number of registers in the miter + int nPis; // the number of primary inputs in the miter + int nBits; // the number of words of bit data used + unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) +}; + typedef struct Gia_Man_t_ Gia_Man_t; struct Gia_Man_t_ { @@ -76,23 +99,42 @@ struct Gia_Man_t_ int nLevels; // the mamixum level int nTravIds; // the current traversal ID int nFront; // frontier size - int * pReprs; // representatives (for CIs and ANDs) + int * pReprsOld; // representatives (for CIs and ANDs) + Gia_Rpr_t * pReprs; // representatives (for CIs and ANDs) + int * pNexts; // next nodes in the equivalence classes + int * pIso; // pairs of structurally isomorphic nodes int nTerLoop; // the state where loop begins int nTerStates; // the total number of ternary states int * pFanData; // the database to store fanout information int nFansAlloc; // the size of fanout representation + int * pMapping; // mapping for each node + Gia_Cex_t * pCexComb; // combinational counter-example }; +typedef struct Emb_Par_t_ Emb_Par_t; +struct Emb_Par_t_ +{ + int nDims; // the number of dimension + int nSols; // the number of solutions (typically, 2) + int nIters; // the number of iterations of FORCE + int fRefine; // use refinement by FORCE + int fCluster; // use clustered representation + int fDump; // dump Gnuplot file + int fDumpLarge; // dump Gnuplot file for large benchmarks + int fShowImage; // shows image if Gnuplot is installed + int fVerbose; // verbose flag +}; + // frames parameters typedef struct Gia_ParFra_t_ Gia_ParFra_t; struct Gia_ParFra_t_ { - int nFrames; // the number of frames to unroll - int fInit; // initialize the timeframes - int fVerbose; // enables verbose output + int nFrames; // the number of frames to unroll + int fInit; // initialize the timeframes + int fVerbose; // enables verbose output }; @@ -180,17 +222,17 @@ static inline int Gia_ObjFaninId0p( Gia_Man_t * p, Gia_Obj_t * pObj ) { static inline int Gia_ObjFaninId1p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId1( pObj, Gia_ObjId(p, pObj) ); } static inline int Gia_ObjFaninLit0( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninC0(pObj) ); } static inline int Gia_ObjFaninLit1( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId1(pObj, ObjId), Gia_ObjFaninC1(pObj) ); } -static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); } -static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); } +static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); } static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); pObj->fCompl0 ^= 1; } static inline int Gia_ObjWhatFanin( Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { return Gia_ObjFanin0(pObj) == pFanin ? 0 : (Gia_ObjFanin1(pObj) == pFanin ? 1 : -1); } -static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); } -static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); } +static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); } static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { return Gia_NotCond( Gia_ManObj(p, Gia_Lit2Var(iLit)), Gia_LitIsCompl(iLit) ); } -static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); } -static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } +static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); } +static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(p->pLevels);return p->pLevels[Gia_ObjId(p, pObj)]; } @@ -204,12 +246,12 @@ static inline void Gia_ObjRefFanin0Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ static inline void Gia_ObjRefFanin1Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin1(pObj)); } static inline void Gia_ManResetTravId( Gia_Man_t * p ) { extern void Gia_ManCleanValue( Gia_Man_t * p ); Gia_ManCleanValue( p ); p->nTravIds = 1; } -static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; } -static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } -static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; } -static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } -static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } -static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } +static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; } +static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } +static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; } +static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } +static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } +static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } // AIG construction extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); @@ -293,6 +335,54 @@ static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCom return GIA_ONE; } +static inline Gia_Obj_t * Gia_ObjReprObj( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr == GIA_VOID ? NULL : Gia_ManObj( p, p->pReprs[Id].iRepr ); } +static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; } +static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { p->pReprs[Id].iRepr = Num; } + +static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; } +static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; } + +static inline int Gia_ObjFailed( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fFailed; } +static inline void Gia_ObjSetFailed( Gia_Man_t * p, int Id ) { p->pReprs[Id].fFailed = 1; } + +static inline int Gia_ObjColor( Gia_Man_t * p, int Id, int c ) { return c? p->pReprs[Id].fColorB : p->pReprs[Id].fColorA; } +static inline int Gia_ObjColors( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fColorB * 2 + p->pReprs[Id].fColorA; } +static inline void Gia_ObjSetColor( Gia_Man_t * p, int Id, int c ) { if (c) p->pReprs[Id].fColorB = 1; else p->pReprs[Id].fColorA = 1; } +static inline void Gia_ObjSetColors( Gia_Man_t * p, int Id ) { p->pReprs[Id].fColorB = p->pReprs[Id].fColorA = 1; } +static inline int Gia_ObjVisitColor( Gia_Man_t * p, int Id, int c ) { int x; if (c) { x = p->pReprs[Id].fColorB; p->pReprs[Id].fColorB = 1; } else { x = p->pReprs[Id].fColorA; p->pReprs[Id].fColorA = 1; } return x; } +static inline int Gia_ObjDiffColors( Gia_Man_t * p, int i, int j ) { return (p->pReprs[i].fColorA ^ p->pReprs[j].fColorA) && (p->pReprs[i].fColorB ^ p->pReprs[j].fColorB); } +static inline int Gia_ObjDiffColors2( Gia_Man_t * p, int i, int j ) { return (p->pReprs[i].fColorA ^ p->pReprs[j].fColorA) || (p->pReprs[i].fColorB ^ p->pReprs[j].fColorB); } + +static inline int Gia_ObjNext( Gia_Man_t * p, int Id ) { return p->pNexts[Id]; } +static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p->pNexts[Id] = Num; } + +static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; } +static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; } +static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; } + +#define Gia_ManForEachConst( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else +#define Gia_ManForEachClass( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ManForEachClassReverse( p, i ) \ + for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ClassForEachObj( p, i, iObj ) \ + for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) ) +#define Gia_ClassForEachObj1( p, i, iObj ) \ + for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) + + +static inline int Gia_ObjIsGate( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; } +static inline int Gia_ObjGateSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; } +static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; } + +#define Gia_ManForEachGate( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsGate(p, i) ) {} else +#define Gia_GateForEachFanin( p, i, iFan, k ) \ + for ( k = 0; k < Gia_ObjGateSize(p,i) && ((iFan = Gia_ObjGateFanins(p,i)[k]),1); k++ ) + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -351,18 +441,30 @@ extern Gia_Man_t * Gia_ManDupDfsSkip( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj ); extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ); -extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ); -extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar ); +extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ); +extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan ); extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); +extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fXorOuts, int fComb, int fVerbose ); +extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ); +/*=== giaEnable.c ==========================================================*/ +extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset ); +/*=== giaEquiv.c ==========================================================*/ +extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); +extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter ); +extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ); +extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ); +extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ); +extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p ); +extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ); /*=== giaFanout.c =========================================================*/ extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); extern void Gia_ManFanoutStart( Gia_Man_t * p ); extern void Gia_ManFanoutStop( Gia_Man_t * p ); /*=== giaForce.c =========================================================*/ -extern void For_ManExperiment( Gia_Man_t * pGia ); +extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose ); /*=== giaFrames.c =========================================================*/ extern void Gia_ManFraSetDefaultParams( Gia_ParFra_t * p ); extern Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars ); @@ -380,7 +482,7 @@ extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p ); /*=== giaLogic.c ===========================================================*/ extern void Gia_ManTestDistance( Gia_Man_t * p ); -extern void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, int fDump, int fVerbose ); +extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ); /*=== giaMan.c ===========================================================*/ extern Gia_Man_t * Gia_ManStart( int nObjsMax ); extern void Gia_ManStop( Gia_Man_t * p ); @@ -388,13 +490,18 @@ extern void Gia_ManPrintStats( Gia_Man_t * p ); extern void Gia_ManPrintStatsShort( Gia_Man_t * p ); extern void Gia_ManPrintMiterStatus( Gia_Man_t * p ); extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); +/*=== giaMap.c ===========================================================*/ +extern void Gia_ManPrintMappingStats( Gia_Man_t * p ); /*=== giaSat.c ============================================================*/ extern int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax ); /*=== giaScl.c ============================================================*/ +extern int Gia_ManSeqMarkUsed( Gia_Man_t * p ); extern int Gia_ManCombMarkUsed( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); +/*=== giaSort.c ============================================================*/ +extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ); /*=== giaSim.c ============================================================*/ extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); /*=== giaTsim.c ============================================================*/ @@ -411,6 +518,7 @@ extern void Gia_ManFillValue( Gia_Man_t * p ); extern void Gia_ManSetPhase( Gia_Man_t * p ); extern int Gia_ManLevelNum( Gia_Man_t * p ); extern void Gia_ManSetRefs( Gia_Man_t * p ); +extern int * Gia_ManCreateMuxRefs( Gia_Man_t * p ); extern void Gia_ManCreateRefs( Gia_Man_t * p ); extern int Gia_ManCrossCut( Gia_Man_t * p ); extern int Gia_ManIsNormalized( Gia_Man_t * p ); @@ -418,6 +526,7 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ); extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode ); extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ); extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ); +extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDoubleOuts ); #ifdef __cplusplus } diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index 8b59341a..544cfe0d 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -92,10 +92,9 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ) } // add logic for the POs Aig_ManForEachPo( p, pObj, i ) - { Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Aig_ManForEachPo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); - } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; } @@ -133,10 +132,9 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) } // add logic for the POs Aig_ManForEachPo( p, pObj, i ) - { Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Aig_ManForEachPo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); - } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; } diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 40c5329d..cfd2dc73 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -175,6 +175,120 @@ char * Gia_TimeStamp() /**Function************************************************************* + Synopsis [Read integer from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadInt( unsigned char * pPos ) +{ + int i, Value = 0; + for ( i = 0; i < 4; i++ ) + Value = (Value << 8) | *pPos++; + return Value; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, Item, fProved, iRepr, iNode; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + pReprs = ABC_CALLOC( Gia_Rpr_t, nSize ); + for ( i = 0; i < nSize; i++ ) + pReprs[i].iRepr = GIA_VOID; + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + { + iRepr += (Item >> 1); + iNode = iRepr; +//printf( "\nRepr = %d ", iRepr ); + continue; + } + Item >>= 1; + fProved = (Item & 1); + Item >>= 1; + iNode += Item; + pReprs[iNode].fProved = fProved; + pReprs[iNode].iRepr = iRepr; +//printf( "Node = %d ", iNode ); + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) +{ + int * pMapping; + unsigned char * pStop; + int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + nAlloc = nSize + pStop - *ppPos; + pMapping = ABC_CALLOC( int, nAlloc ); + while ( *ppPos < pStop ) + { + k = iOffset; + pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos ); + for ( j = 0; j <= nFanins; j++ ) + pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode ); + pMapping[iNode] = iOffset; + iOffset = k; + } + assert( iOffset <= nAlloc ); + return pMapping; +} + +/**Function************************************************************* + Synopsis [Reads the AIG in the binary AIGER format.] Description [] @@ -328,6 +442,38 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) // create the latches Gia_ManSetRegNum( pNew, nLatches ); + // check if there are other types of information to read + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + pCur++; + if ( *pCur == 'e' ) + { + pCur++; + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + } + if ( *pCur == 'm' ) + { + pCur++; + // read mapping + pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'p' ) + { + pCur++; + // read placement + } + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Aig_UtilStrsav( pCur ); + } + } + // skipping the comments ABC_FREE( pContents ); Vec_IntFree( vNodes ); @@ -443,6 +589,144 @@ Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits ) /**Function************************************************************* + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteInt( unsigned char * pPos, int Value ) +{ + int i; + for ( i = 3; i >= 0; i-- ) + *pPos++ = (Value >> (8*i)) & 255; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos; + assert( p->pReprs && p->pNexts ); + // count the number of entries to be written + nItems = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write constant class + iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); +//printf( "\nRepr = %d ", 0 ); + iPrevNode = 0; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { +//printf( "Node = %d ", iNode ); + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { +//printf( "\nRepr = %d ", iRepr ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) ); + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { +//printf( "Node = %d ", iNode ); + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + } + Gia_WriteInt( pBuffer, iPos ); + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +{ + if ( iPrev < iThis ) + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) ); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) +{ + unsigned char * pBuffer; + int i, k, iPrev, iFan, nItems, iPos = 4; + assert( p->pMapping ); + // count the number of entries to be written + nItems = 0; + Gia_ManForEachGate( p, i ) + nItems += 2 + Gia_ObjGateSize( p, i ); + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write non-constant classes + iPrev = 0; + Gia_ManForEachGate( p, i ) + { +//printf( "\nSize = %d ", Gia_ObjGateSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjGateSize(p, i) ); + Gia_GateForEachFanin( p, i, iFan, k ) + { +//printf( "Fan = %d ", iFan ); + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); + iPrev = iFan; + } + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i ); + iPrev = i; +//printf( "Node = %d ", i ); + } +//printf( "\n" ); + Gia_WriteInt( pBuffer, iPos ); + *pMapSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + Synopsis [Writes the AIG in the binary AIGER format.] Description [] @@ -536,10 +820,29 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int ABC_FREE( pBuffer ); // write the comment - fprintf( pFile, "c\n" ); + fprintf( pFile, "c" ); + // write equivalences + if ( p->pReprs && p->pNexts ) + { + int nEquivSize; + unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize ); + fprintf( pFile, "e" ); + fwrite( pEquivs, 1, nEquivSize, pFile ); + ABC_FREE( pEquivs ); + } + // write mapping + if ( p->pMapping ) + { + int nMapSize; + unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize ); + fprintf( pFile, "m" ); + fwrite( pMaps, 1, nMapSize, pFile ); + ABC_FREE( pMaps ); + } + // write placement if ( p->pName ) - fprintf( pFile, ".model %s\n", p->pName ); - fprintf( pFile, "This file was produced by the AIG package on %s\n", Gia_TimeStamp() ); + fprintf( pFile, "n%s%c", p->pName, '\0' ); + fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); fclose( pFile ); if ( p != pInit ) diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index d58429cd..735aca72 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -41,6 +41,7 @@ struct Cof_Obj_t_ unsigned fMark1 : 1; // second user-controlled mark unsigned nFanins : 4; // the number of fanins unsigned nFanouts : 24; // total number of fanouts + unsigned nFanoutsM; // total number of MUX ctrl fanouts unsigned Value; // application specific data int Id; // ID of the node int iNext; // next one in the linked list @@ -124,6 +125,7 @@ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia ) Cof_Man_t * p; Cof_Obj_t * pObjLog, * pFanLog; Gia_Obj_t * pObj; + int * pMuxRefs; int i, iHandle = 0; p = ABC_CALLOC( Cof_Man_t, 1 ); p->pGia = pGia; @@ -173,11 +175,14 @@ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia ) p->nObjs++; } assert( iHandle == p->nObjData ); + pMuxRefs = Gia_ManCreateMuxRefs( pGia ); Gia_ManForEachObj( pGia, pObj, i ) { pObjLog = Cof_ManObj( p, Gia_ObjHandle(pObj) ); assert( pObjLog->nFanouts == pObjLog->Value ); + pObjLog->nFanoutsM = pMuxRefs[i]; } + ABC_FREE( pMuxRefs ); return p; } @@ -509,8 +514,7 @@ int Cof_ManCountRemoved( Cof_Man_t * p, Cof_Obj_t * pRoot, int fConst1 ) void Cof_ManPrintHighFanoutOne( Cof_Man_t * p, Cof_Obj_t * pObj ) { printf( "%7d : ", pObj->Id ); - printf( "fi =%2d ", Cof_ObjFaninNum(pObj) ); - printf( "fo =%5d ", Cof_ObjFanoutNum(pObj) ); + printf( "i/o/c =%2d %5d %5d ", Cof_ObjFaninNum(pObj), Cof_ObjFanoutNum(pObj), 2*pObj->nFanoutsM ); printf( "l =%4d ", Cof_ObjLevel(p, pObj) ); printf( "s =%5d ", Cof_ManSuppSize(p, &pObj, 1) ); printf( "TFI =%7d ", Cof_ManTfiSize(p, &pObj, 1) ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index d5c0862f..4821dba9 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -196,11 +196,11 @@ int Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( ~pObj->Value ) return pObj->Value; - if ( p->pReprs && ~p->pReprs[Gia_ObjId(p, pObj)] ) + if ( p->pReprsOld && ~p->pReprsOld[Gia_ObjId(p, pObj)] ) { - Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprs[Gia_ObjId(p, pObj)] ); - pObj->Value = Gia_ManDupDfs_rec( pNew, p, pRepr ); - return pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprsOld[Gia_ObjId(p, pObj)] ); + pRepr->Value = Gia_ManDupDfs_rec( pNew, p, pRepr ); + return pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); } if ( Gia_ObjIsCi(pObj) ) return pObj->Value = Gia_ManAppendCi(pNew); @@ -380,7 +380,7 @@ Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) +Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; @@ -391,12 +391,12 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) Gia_ManSetRefs( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) - if ( pObj->Value > 0 || Gia_ObjIsRo(p, pObj) ) + if ( !fTrimCis || pObj->Value > 0 || Gia_ObjIsRo(p, pObj) ) pObj->Value = Gia_ManAppendCi(pNew); Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, i ) - if ( !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) ) + if ( !fTrimCos || !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); return pNew; @@ -413,11 +413,16 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar ) +Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pPivot; int i, iCofVar = -1; + if ( nLimFan > 0 ) + { + printf( "This feature is not implemented.\n" ); + return NULL; + } if ( !(iVar > 0 && iVar < Gia_ManObjNum(p)) ) { printf( "Gia_ManDupCofactored(): Variable %d is out of range (%d; %d).\n", iVar, 0, Gia_ManObjNum(p) ); @@ -502,7 +507,7 @@ void Gia_ManPrintRepr( Gia_Man_t * p ) Gia_Obj_t * pObj; int i; Gia_ManForEachObj( p, pObj, i ) - if ( ~p->pReprs[i] ) + if ( ~p->pReprsOld[i] ) printf( "%d->%d ", i, p->pReprs[i] ); printf( "\n" ); } @@ -569,7 +574,7 @@ Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ) Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; - assert( p->pReprs != NULL ); + assert( p->pReprsOld != NULL ); Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); @@ -719,6 +724,195 @@ Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ) } +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Creates miter of two designs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManMiter( Gia_Man_t * p0, Gia_Man_t * p1, int fXorOuts, int fComb, int fVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, iLit; + if ( fComb ) + { + if ( Gia_ManCiNum(p0) != Gia_ManCiNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of CIs.\n" ); + return NULL; + } + if ( Gia_ManCoNum(p0) != Gia_ManCoNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of COs.\n" ); + return NULL; + } + } + else + { + if ( Gia_ManPiNum(p0) != Gia_ManPiNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of PIs.\n" ); + return NULL; + } + if ( Gia_ManPoNum(p0) != Gia_ManPoNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of POs.\n" ); + return NULL; + } + if ( Gia_ManRegNum(p0) == 0 || Gia_ManRegNum(p1) == 0 ) + { + printf( "Gia_ManMiter(): At least one of the designs has no registers.\n" ); + return NULL; + } + } + // start the manager + pNew = Gia_ManStart( Gia_ManObjNum(p0) + Gia_ManObjNum(p1) ); + pNew->pName = Aig_UtilStrsav( "miter" ); + // map combinational inputs + Gia_ManFillValue( p0 ); + Gia_ManFillValue( p1 ); + Gia_ManConst0(p0)->Value = 0; + Gia_ManConst0(p1)->Value = 0; + // map internal nodes and outputs + Gia_ManHashAlloc( pNew ); + if ( fComb ) + { + // create combinational inputs + Gia_ManForEachCi( p0, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachCi( p1, pObj, i ) + pObj->Value = Gia_ObjToLit( pNew, Gia_ManCi(pNew, i) ); + // create combinational outputs + Gia_ManForEachCo( p0, pObj, i ) + { + Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) ); + Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(Gia_ManCo(p1,i)) ); + if ( fXorOuts ) + { + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(Gia_ManCo(p1,i)) ); + Gia_ManAppendCo( pNew, iLit ); + } + else + { + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p1,i)) ); + } + } + } + else + { + // create primary inputs + Gia_ManForEachPi( p0, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachPi( p1, pObj, i ) + pObj->Value = Gia_ObjToLit( pNew, Gia_ManPi(pNew, i) ); + // create latch outputs + Gia_ManForEachRo( p0, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachRo( p1, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // create primary outputs + Gia_ManForEachPo( p0, pObj, i ) + { + Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) ); + Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(Gia_ManPo(p1,i)) ); + if ( fXorOuts ) + { + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(Gia_ManPo(p1,i)) ); + Gia_ManAppendCo( pNew, iLit ); + } + else + { + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManPo(p1,i)) ); + } + } + // create register inputs + Gia_ManForEachRi( p0, pObj, i ) + { + Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManForEachRi( p1, pObj, i ) + { + Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p0) + Gia_ManRegNum(p1) ); + } + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transforms the circuit into a regular miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pObj2; + int i, iLit; + assert( (Gia_ManPoNum(p) & 1) == 0 ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + { + pObj2 = Gia_ManPo( p, ++i ); + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(pObj2) ); + Gia_ManAppendCo( pNew, iLit ); + } + Gia_ManForEachRi( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index 0469d1a4..6c2f00df 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -25,12 +25,18 @@ The code is based on the paper by D. Harel and Y. Koren, "Graph drawing by high-dimensional embedding", J. Graph Algs & Apps, Vol 8(2), pp. 195-217 (2004). + http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf + + Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah. + "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// + typedef float Emb_Dat_t; typedef struct Emb_Obj_t_ Emb_Obj_t; @@ -90,10 +96,10 @@ static inline Emb_Obj_t * Emb_ManCo( Emb_Man_t * p, int i ) static inline int Emb_ObjIsTerm( Emb_Obj_t * pObj ) { return pObj->fCi || pObj->fCo; } static inline int Emb_ObjIsCi( Emb_Obj_t * pObj ) { return pObj->fCi; } static inline int Emb_ObjIsCo( Emb_Obj_t * pObj ) { return pObj->fCo; } -static inline int Emb_ObjIsPi( Emb_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; } -static inline int Emb_ObjIsPo( Emb_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; } +//static inline int Emb_ObjIsPi( Emb_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; } +//static inline int Emb_ObjIsPo( Emb_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; } static inline int Emb_ObjIsNode( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins > 0; } -static inline int Emb_ObjIsConst0( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins == 0; } +//static inline int Emb_ObjIsConst0( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins == 0; } static inline int Emb_ObjSize( Emb_Obj_t * pObj ) { return sizeof(Emb_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } static inline int Emb_ObjFaninNum( Emb_Obj_t * pObj ) { return pObj->nFanins; } @@ -109,8 +115,8 @@ static inline void Emb_ObjSetTravIdPrevious( Emb_Man_t * p, Emb_Obj_t * p static inline int Emb_ObjIsTravIdCurrent( Emb_Man_t * p, Emb_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds); } static inline int Emb_ObjIsTravIdPrevious( Emb_Man_t * p, Emb_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds - 1); } -static inline Emb_Dat_t * Emb_ManVec( Emb_Man_t * p, int v ) { return p->pVecs + v * p->nObjs; } -static inline float * Emb_ManSol( Emb_Man_t * p, int v ) { return p->pSols + v * p->nObjs; } +static inline Emb_Dat_t * Emb_ManVec( Emb_Man_t * p, int v ) { return p->pVecs + v * p->nObjs; } +static inline float * Emb_ManSol( Emb_Man_t * p, int v ) { return p->pSols + v * p->nObjs; } #define Emb_ManForEachObj( p, pObj, i ) \ for ( i = 0; (i < p->nObjData) && (pObj = Emb_ManObj(p,i)); i += Emb_ObjSize(pObj) ) @@ -171,13 +177,13 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) p->nRegs = Gia_ManRegNum(pGia); p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); - p->nObjData = (sizeof(Emb_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia) + Gia_ManRegNum(pGia)); + p->nObjData = (sizeof(Emb_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia) + Gia_ManRegNum(pGia) + Gia_ManCoNum(pGia)); p->pObjData = ABC_CALLOC( int, p->nObjData ); // create constant node Gia_ManConst0(pGia)->Value = hHandle; pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; - pObjLog->nFanins = 0; + pObjLog->nFanins = Gia_ManCoNum(pGia); //0; pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); // count objects hHandle += Emb_ObjSize( pObjLog ); @@ -227,7 +233,7 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; pObjLog->nFanins = 1; - pObjLog->nFanouts = Gia_ObjIsRi( pGia, pObj ); + pObjLog->nFanouts = 1 + Gia_ObjIsRi( pGia, pObj ); pObjLog->fCo = 1; // add fanins pFanLog = Emb_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); @@ -249,8 +255,8 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) if ( !~Gia_ObjValue(pObj) ) continue; pObjLog = Emb_ManObj( p, Gia_ObjValue(pObj) ); - assert( pObjLog->nFanins == pObjLog->iFanin ); - assert( pObjLog->nFanouts == pObjLog->iFanout ); + assert( pObjLog->nFanins == pObjLog->iFanin || Gia_ObjIsConst0(pObj) ); + assert( pObjLog->nFanouts == pObjLog->iFanout || Gia_ObjIsCo(pObj) ); pObjLog->iFanin = pObjLog->iFanout = 0; } ABC_FREE( pGia->pRefs ); @@ -496,13 +502,13 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia ) p->nRegs = Gia_ManRegNum(pGia); p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); - p->nObjData = (sizeof(Emb_Obj_t) / 4) * nObjs + 2 * (nFanios + Gia_ManRegNum(pGia)); + p->nObjData = (sizeof(Emb_Obj_t) / 4) * nObjs + 2 * (nFanios + Gia_ManRegNum(pGia) + Gia_ManCoNum(pGia)); p->pObjData = ABC_CALLOC( int, p->nObjData ); // create constant node Gia_ManConst0(pGia)->Value = hHandle; pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; - pObjLog->nFanins = 0; + pObjLog->nFanins = Gia_ManCoNum(pGia); //0; pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); // count objects hHandle += Emb_ObjSize( pObjLog ); @@ -563,7 +569,7 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia ) pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; pObjLog->nFanins = 1; - pObjLog->nFanouts = Gia_ObjIsRi( pGia, pObj ); + pObjLog->nFanouts = 1 + Gia_ObjIsRi( pGia, pObj ); pObjLog->fCo = 1; // add fanins pFanLog = Emb_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); @@ -587,8 +593,8 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia ) if ( !~Gia_ObjValue(pObj) ) continue; pObjLog = Emb_ManObj( p, Gia_ObjValue(pObj) ); - assert( pObjLog->nFanins == pObjLog->iFanin ); - assert( pObjLog->nFanouts == pObjLog->iFanout ); + assert( pObjLog->nFanins == pObjLog->iFanin || Gia_ObjIsConst0(pObj) ); + assert( pObjLog->nFanouts == pObjLog->iFanout || Gia_ObjIsCo(pObj) ); pObjLog->iFanin = pObjLog->iFanout = 0; } ABC_FREE( pGia->pRefs ); @@ -904,7 +910,7 @@ ABC_PRT( "Time", clock() - clk ); /**Function************************************************************* - Synopsis [Computes the distances from the given set of objects.] + Synopsis [Perform BFS from the set of nodes.] Description [Returns one of the most distant objects.] @@ -913,20 +919,11 @@ ABC_PRT( "Time", clock() - clk ); SeeAlso [] ***********************************************************************/ -Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * pDist ) +Emb_Obj_t * Emb_ManPerformBfs( Emb_Man_t * p, Vec_Int_t * vThis, Vec_Int_t * vNext, Emb_Dat_t * pDist ) { - Vec_Int_t * vThis, * vNext, * vTemp; + Vec_Int_t * vTemp; Emb_Obj_t * pThis, * pNext, * pResult; int i, k; - p->nReached = p->nDistMax = 0; - vThis = Vec_IntAlloc( 1000 ); - vNext = Vec_IntAlloc( 1000 ); - Emb_ManIncrementTravId( p ); - Emb_ManForEachObjVec( vStart, p, pThis, i ) - { - Emb_ObjSetTravIdCurrent( p, pThis ); - Vec_IntPush( vThis, pThis->hHandle ); - } assert( Vec_IntSize(vThis) > 0 ); for ( p->nDistMax = 0; Vec_IntSize(vThis) > 0; p->nDistMax++ ) { @@ -955,6 +952,74 @@ Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * assert( Vec_IntSize(vNext) > 0 ); pResult = Emb_ManObj( p, Vec_IntEntry(vNext, 0) ); assert( pDist == NULL || pDist[pResult->Value] == p->nDistMax - 1 ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Computes the distances from the given set of objects.] + + Description [Returns one of the most distant objects.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Emb_ManConnectedComponents( Emb_Man_t * p ) +{ + Gia_Obj_t * pObj; + Vec_Int_t * vThis, * vNext, * vResult; + Emb_Obj_t * pThis; + int i; + vResult = Vec_IntAlloc( 1000 ); + vThis = Vec_IntAlloc( 1000 ); + vNext = Vec_IntAlloc( 1000 ); + p->nReached = 0; + Emb_ManIncrementTravId( p ); + Gia_ManForEachCo( p->pGia, pObj, i ) + { + pThis = Emb_ManObj( p, Gia_ObjValue(pObj) ); + if ( Emb_ObjIsTravIdCurrent(p, pThis) ) + continue; + Emb_ObjSetTravIdCurrent( p, pThis ); + Vec_IntPush( vResult, pThis->hHandle ); + // perform BFS from this node + Vec_IntClear( vThis ); + Vec_IntPush( vThis, pThis->hHandle ); + Emb_ManPerformBfs( p, vThis, vNext, NULL ); + } + Vec_IntFree( vThis ); + Vec_IntFree( vNext ); + return vResult; +} + +/**Function************************************************************* + + Synopsis [Computes the distances from the given set of objects.] + + Description [Returns one of the most distant objects.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * pDist ) +{ + Vec_Int_t * vThis, * vNext; + Emb_Obj_t * pThis, * pResult; + int i; + p->nReached = p->nDistMax = 0; + vThis = Vec_IntAlloc( 1000 ); + vNext = Vec_IntAlloc( 1000 ); + Emb_ManIncrementTravId( p ); + Emb_ManForEachObjVec( vStart, p, pThis, i ) + { + Emb_ObjSetTravIdCurrent( p, pThis ); + Vec_IntPush( vThis, pThis->hHandle ); + } + pResult = Emb_ManPerformBfs( p, vThis, vNext, pDist ); Vec_IntFree( vThis ); Vec_IntFree( vNext ); return pResult; @@ -1029,13 +1094,28 @@ void Emb_DumpGraphIntoFile( Emb_Man_t * p ) void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims ) { Emb_Obj_t * pRandom, * pPivot; - Vec_Int_t * vStart; + Vec_Int_t * vStart, * vComps; int d, nReached; - int i, Counter; + int i;//, Counter; + // connect unconnected components + vComps = Emb_ManConnectedComponents( p ); +// printf( "Components = %d. Considered %d objects (out of %d).\n", Vec_IntSize(vComps), p->nReached, Emb_ManObjNum(p) ); + if ( Vec_IntSize(vComps) > 1 ) + { + Emb_Obj_t * pFanin, * pObj = Emb_ManObj( p, 0 ); + Emb_ManForEachObjVec( vComps, p, pFanin, i ) + { + assert( Emb_ObjIsCo(pFanin) ); + pFanin->Fanios[pFanin->nFanins + pFanin->nFanouts-1] = + pObj->Fanios[i] = pObj->hHandle - pFanin->hHandle; + } + } + Vec_IntFree( vComps ); + // allocate memory for vectors assert( p->pVecs == NULL ); - p->pVecs = ABC_ALLOC( Emb_Dat_t, p->nObjs * nDims ); - for ( i = 0; i < p->nObjs * nDims; i++ ) - p->pVecs[i] = ABC_INFINITY; + p->pVecs = ABC_CALLOC( Emb_Dat_t, p->nObjs * nDims ); +// for ( i = 0; i < p->nObjs * nDims; i++ ) +// p->pVecs[i] = ABC_INFINITY; vStart = Vec_IntAlloc( nDims ); // get the pivot vertex pRandom = Emb_ManRandomVertex( p ); @@ -1046,7 +1126,7 @@ void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims ) nReached = p->nReached; if ( nReached < Emb_ManObjNum(p) ) { - printf( "Considering a connected component with %d objects (out of %d).\n", p->nReached, Emb_ManObjNum(p) ); +// printf( "Considering a connected component with %d objects (out of %d).\n", p->nReached, Emb_ManObjNum(p) ); } // start dimensions with this vertex Vec_IntClear( vStart ); @@ -1061,11 +1141,11 @@ void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims ) } Vec_IntFree( vStart ); // make sure the number of reached objects is correct - Counter = 0; - for ( i = 0; i < p->nObjs; i++ ) - if ( p->pVecs[i] < ABC_INFINITY ) - Counter++; - assert( Counter == nReached ); +// Counter = 0; +// for ( i = 0; i < p->nObjs; i++ ) +// if ( p->pVecs[i] < ABC_INFINITY ) +// Counter++; +// assert( Counter == nReached ); } /**Function************************************************************* @@ -1338,7 +1418,6 @@ void Emb_ManComputeSolutions( Emb_Man_t * p, int nDims, int nSols ) ***********************************************************************/ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) { - extern int * Gia_SortFloats( float * pArray, int nSize ); float * pY0, * pY1, Max0, Max1, Min0, Min1, Str0, Str1; int * pPerm0, * pPerm1; int k; @@ -1373,10 +1452,10 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) pY1[k] = (pY1[k] != 0.0) ? ((pY1[k] - Min1) * Str1) : 0.0; // derive the order of these numbers - pPerm0 = Gia_SortFloats( pY0, p->nObjs ); - pPerm1 = Gia_SortFloats( pY1, p->nObjs ); + pPerm0 = Gia_SortFloats( pY0, NULL, p->nObjs ); + pPerm1 = Gia_SortFloats( pY1, NULL, p->nObjs ); - // average solutions and project them into 32K by 32K square + // average solutions and project them into square [0;0xffff] x [0;0xffff] p->pPlacement = ABC_ALLOC( unsigned short, 2 * p->nObjs ); for ( k = 0; k < p->nObjs; k++ ) { @@ -1387,6 +1466,127 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) ABC_FREE( pPerm1 ); } + +/**Function************************************************************* + + Synopsis [Computes wire-length.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Emb_ManComputeHPWL( Emb_Man_t * p ) +{ + double Result = 0.0; + Emb_Obj_t * pThis, * pNext; + int i, k, iMinX, iMaxX, iMinY, iMaxY; + if ( p->pPlacement == NULL ) + return 0.0; + Emb_ManForEachObj( p, pThis, i ) + { + iMinX = iMaxX = p->pPlacement[2*pThis->Value+0]; + iMinY = iMaxY = p->pPlacement[2*pThis->Value+1]; + Emb_ObjForEachFanout( pThis, pNext, k ) + { + iMinX = ABC_MIN( iMinX, p->pPlacement[2*pNext->Value+0] ); + iMaxX = ABC_MAX( iMaxX, p->pPlacement[2*pNext->Value+0] ); + iMinY = ABC_MIN( iMinY, p->pPlacement[2*pNext->Value+1] ); + iMaxY = ABC_MAX( iMaxY, p->pPlacement[2*pNext->Value+1] ); + } + Result += (iMaxX - iMinX) + (iMaxY - iMinY); + } + return Result; +} + + +/**Function************************************************************* + + Synopsis [Performs iterative refinement of the given placement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Emb_ManPlacementRefine( Emb_Man_t * p, int nIters, int fVerbose ) +{ + Emb_Obj_t * pThis, * pNext; + double CostThis, CostPrev; + float * pEdgeX, * pEdgeY; + float * pVertX, * pVertY; + float VertX, VertY; + int * pPermX, * pPermY; + int i, k, Iter, iMinX, iMaxX, iMinY, iMaxY; + int clk = clock(); + if ( p->pPlacement == NULL ) + return; + pEdgeX = ABC_ALLOC( float, p->nObjs ); + pEdgeY = ABC_ALLOC( float, p->nObjs ); + pVertX = ABC_ALLOC( float, p->nObjs ); + pVertY = ABC_ALLOC( float, p->nObjs ); + // refine placement + CostPrev = 0.0; + for ( Iter = 0; Iter < nIters; Iter++ ) + { + // compute centers of hyperedges + CostThis = 0.0; + Emb_ManForEachObj( p, pThis, i ) + { + iMinX = iMaxX = p->pPlacement[2*pThis->Value+0]; + iMinY = iMaxY = p->pPlacement[2*pThis->Value+1]; + Emb_ObjForEachFanout( pThis, pNext, k ) + { + iMinX = ABC_MIN( iMinX, p->pPlacement[2*pNext->Value+0] ); + iMaxX = ABC_MAX( iMaxX, p->pPlacement[2*pNext->Value+0] ); + iMinY = ABC_MIN( iMinY, p->pPlacement[2*pNext->Value+1] ); + iMaxY = ABC_MAX( iMaxY, p->pPlacement[2*pNext->Value+1] ); + } + pEdgeX[pThis->Value] = 0.5 * (iMaxX + iMinX); + pEdgeY[pThis->Value] = 0.5 * (iMaxY + iMinY); + CostThis += (iMaxX - iMinX) + (iMaxY - iMinY); + } + // compute new centers of objects + Emb_ManForEachObj( p, pThis, i ) + { + VertX = pEdgeX[pThis->Value]; + VertY = pEdgeY[pThis->Value]; + Emb_ObjForEachFanin( pThis, pNext, k ) + { + VertX += pEdgeX[pNext->Value]; + VertY += pEdgeY[pNext->Value]; + } + pVertX[pThis->Value] = VertX / (Emb_ObjFaninNum(pThis) + 1); + pVertY[pThis->Value] = VertY / (Emb_ObjFaninNum(pThis) + 1); + } + // sort these numbers + pPermX = Gia_SortFloats( pVertX, NULL, p->nObjs ); + pPermY = Gia_SortFloats( pVertY, NULL, p->nObjs ); + for ( k = 0; k < p->nObjs; k++ ) + { + p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); + p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); + } + ABC_FREE( pPermX ); + ABC_FREE( pPermY ); + // evaluate cost + if ( fVerbose ) + { + printf( "%2d : HPWL = %e ", Iter+1, CostThis ); + ABC_PRT( "Time", clock() - clk ); + } + } + ABC_FREE( pEdgeX ); + ABC_FREE( pEdgeY ); + ABC_FREE( pVertX ); + ABC_FREE( pVertY ); +} + + /**Function************************************************************* Synopsis [Derives solutions from original vectors and eigenvectors.] @@ -1413,6 +1613,68 @@ void Emb_ManPrintSolutions( Emb_Man_t * p, int nSols ) /**Function************************************************************* + Synopsis [Prepares image for dumping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Emb_ManDumpGnuplotPrepare( Emb_Man_t * p ) +{ +// int nRows = 496; +// int nCols = 710; + int nRows = 500; + int nCols = 700; + Vec_Int_t * vLines; + Emb_Obj_t * pThis; + char * pBuffer, ** ppRows; + int i, k, placeX, placeY; + int fStart; + // alloc memory + pBuffer = ABC_CALLOC( char, nRows * (nCols+1) ); + ppRows = ABC_ALLOC( char *, nRows ); + for ( i = 0; i < nRows; i++ ) + ppRows[i] = pBuffer + i*(nCols+1); + // put data into them + Emb_ManForEachObj( p, pThis, i ) + { + placeX = p->pPlacement[2*pThis->Value+0] * nCols / (1<<16); + placeY = p->pPlacement[2*pThis->Value+1] * nRows / (1<<16); + assert( placeX < nCols && placeY < nRows ); + ppRows[placeY][placeX] = 1; + } + // select lines + vLines = Vec_IntAlloc( 1000 ); + for ( i = 0; i < nRows; i++ ) + { + fStart = 0; + for ( k = 0; k <= nCols; k++ ) + { + if ( ppRows[i][k] && !fStart ) + { + Vec_IntPush( vLines, k ); + Vec_IntPush( vLines, i ); + fStart = 1; + } + if ( !ppRows[i][k] && fStart ) + { + Vec_IntPush( vLines, k-1 ); + Vec_IntPush( vLines, i ); + fStart = 0; + } + } + assert( fStart == 0 ); + } + ABC_FREE( pBuffer ); + ABC_FREE( ppRows ); + return vLines; +} + +/**Function************************************************************* + Synopsis [Derives solutions from original vectors and eigenvectors.] Description [] @@ -1422,71 +1684,89 @@ void Emb_ManPrintSolutions( Emb_Man_t * p, int nSols ) SeeAlso [] ***********************************************************************/ -void Emb_ManDumpGnuplot( Emb_Man_t * p, int nSols, char * pName ) +void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowImage ) { - int fDumpImage = 1; + extern void Gia_ManGnuplotShow( char * pPlotFileName ); // char * pDirectory = "place\\"; char * pDirectory = ""; extern char * Ioa_TimeStamp(); FILE * pFile; char Buffer[1000]; Emb_Obj_t * pThis, * pNext; - float * pSol0, * pSol1; int i, k; - if ( nSols < 2 ) - return; if ( p->pPlacement == NULL ) { printf( "Emb_ManDumpGnuplot(): Placement is not available.\n" ); return; } - pSol0 = Emb_ManSol( p, 0 ); - pSol1 = Emb_ManSol( p, 1 ); sprintf( Buffer, "%s%s", pDirectory, Aig_FileNameGenericAppend(pName, ".plt") ); pFile = fopen( Buffer, "w" ); fprintf( pFile, "# This Gnuplot file was produced by ABC on %s\n", Ioa_TimeStamp() ); fprintf( pFile, "\n" ); - if ( fDumpImage ) - { fprintf( pFile, "set nokey\n" ); + fprintf( pFile, "\n" ); + if ( !fShowImage ) + { // fprintf( pFile, "set terminal postscript\n" ); -// fprintf( pFile, "set output \'%s\'\n", Aig_FileNameGenericAppend(pName, ".ps") ); fprintf( pFile, "set terminal gif font \'arial\' 10 size 800,600 xffffff x000000 x000000 x000000\n" ); fprintf( pFile, "set output \'%s\'\n", Aig_FileNameGenericAppend(pName, ".gif") ); fprintf( pFile, "\n" ); } - fprintf( pFile, "set title \"%s : PI = %d PO = %d FF = %d Node = %d Obj = %d\\n", - pName, Emb_ManPiNum(p), Emb_ManPoNum(p), Emb_ManRegNum(p), Emb_ManNodeNum(p), Emb_ManObjNum(p) ); + fprintf( pFile, "set title \"%s : PI = %d PO = %d FF = %d Node = %d Obj = %d HPWL = %.2e\\n", + pName, Emb_ManPiNum(p), Emb_ManPoNum(p), Emb_ManRegNum(p), Emb_ManNodeNum(p), Emb_ManObjNum(p), Emb_ManComputeHPWL(p) ); fprintf( pFile, "(image generated by ABC and Gnuplot on %s)\"", Ioa_TimeStamp() ); fprintf( pFile, "font \"Times, 12\"\n" ); fprintf( pFile, "\n" ); fprintf( pFile, "plot [:] '-' w l\n" ); fprintf( pFile, "\n" ); - Emb_ManForEachObj( p, pThis, i ) + if ( fDumpLarge ) { - if ( !Emb_ObjIsTravIdCurrent(p, pThis) ) - continue; - Emb_ObjForEachFanout( pThis, pNext, k ) + int begX, begY, endX, endY; + Vec_Int_t * vLines = Emb_ManDumpGnuplotPrepare( p ); + Vec_IntForEachEntry( vLines, begX, i ) { - assert( Emb_ObjIsTravIdCurrent(p, pNext) ); -// fprintf( pFile, "%d %d\n", (int)pSol0[pThis->Value], (int)pSol1[pThis->Value] ); -// fprintf( pFile, "%d %d\n", (int)pSol0[pNext->Value], (int)pSol1[pNext->Value] ); -// fprintf( pFile, "%5.2f %5.2f\n", pSol0[pThis->Value], pSol1[pThis->Value] ); -// fprintf( pFile, "%5.2f %5.2f\n", pSol0[pNext->Value], pSol1[pNext->Value] ); - fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pThis->Value+0], p->pPlacement[2*pThis->Value+1] ); - fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pNext->Value+0], p->pPlacement[2*pNext->Value+1] ); + begY = Vec_IntEntry( vLines, i+1 ); + endX = Vec_IntEntry( vLines, i+2 ); + endY = Vec_IntEntry( vLines, i+3 ); + i += 3; + fprintf( pFile, "%5d %5d\n", begX, begY ); + fprintf( pFile, "%5d %5d\n", endX, endY ); fprintf( pFile, "\n" ); } + Vec_IntFree( vLines ); + } + else + { + Emb_ManForEachObj( p, pThis, i ) + { + if ( !Emb_ObjIsTravIdCurrent(p, pThis) ) + continue; + Emb_ObjForEachFanout( pThis, pNext, k ) + { + assert( Emb_ObjIsTravIdCurrent(p, pNext) ); + fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pThis->Value+0], p->pPlacement[2*pThis->Value+1] ); + fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pNext->Value+0], p->pPlacement[2*pNext->Value+1] ); + fprintf( pFile, "\n" ); + } + } } fprintf( pFile, "EOF\n" ); fprintf( pFile, "\n" ); - if ( !fDumpImage ) + if ( fShowImage ) { - fprintf( pFile, "pause -1 \"Hit return to continue\"\n" ); + fprintf( pFile, "pause -1 \"Close window\"\n" ); // Hit return to continue fprintf( pFile, "reset\n" ); fprintf( pFile, "\n" ); } + else + { + fprintf( pFile, "# pause -1 \"Close window\"\n" ); // Hit return to continue + fprintf( pFile, "# reset\n" ); + fprintf( pFile, "\n" ); + } fclose( pFile ); + if ( fShowImage ) + Gia_ManGnuplotShow( Buffer ); } /**Function************************************************************* @@ -1500,7 +1780,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, int nSols, char * pName ) SeeAlso [] ***********************************************************************/ -void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, int fDump, int fVerbose ) +void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ) { Emb_Man_t * p; int clk, clkSetup; @@ -1508,18 +1788,18 @@ void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, // transform AIG into internal data-structure clk = clock(); - if ( fCluster ) + if ( pPars->fCluster ) { p = Emb_ManStart( pGia ); - if ( fVerbose ) + if ( pPars->fVerbose ) { - printf( "After clustering: " ); + printf( "Clustered: " ); Emb_ManPrintStats( p ); } } else p = Emb_ManStartSimple( pGia ); - p->fVerbose = fVerbose; + p->fVerbose = pPars->fVerbose; // Emb_ManPrintFanio( p ); // prepare data-structure @@ -1529,26 +1809,40 @@ clk = clock(); clkSetup = clock() - clk; clk = clock(); - Emb_ManComputeDimensions( p, nDims ); -if ( fVerbose ) + Emb_ManComputeDimensions( p, pPars->nDims ); +if ( pPars->fVerbose ) ABC_PRT( "Setup ", clkSetup ); -if ( fVerbose ) +if ( pPars->fVerbose ) ABC_PRT( "Dimensions", clock() - clk ); clk = clock(); - Emb_ManComputeCovariance( p, nDims ); -if ( fVerbose ) + Emb_ManComputeCovariance( p, pPars->nDims ); +if ( pPars->fVerbose ) ABC_PRT( "Matrix ", clock() - clk ); clk = clock(); - Emb_ManComputeEigenvectors( p, nDims, nSols ); - Emb_ManComputeSolutions( p, nDims, nSols ); - Emb_ManDerivePlacement( p, nSols ); -if ( fVerbose ) + Emb_ManComputeEigenvectors( p, pPars->nDims, pPars->nSols ); + Emb_ManComputeSolutions( p, pPars->nDims, pPars->nSols ); + Emb_ManDerivePlacement( p, pPars->nSols ); +if ( pPars->fVerbose ) ABC_PRT( "Eigenvecs ", clock() - clk ); - if ( fDump ) - Emb_ManDumpGnuplot( p, nSols, pGia->pName ); + if ( pPars->fRefine ) + { +clk = clock(); + Emb_ManPlacementRefine( p, pPars->nIters, pPars->fVerbose ); +if ( pPars->fVerbose ) +ABC_PRT( "Refinement", clock() - clk ); + } + + if ( (pPars->fDump || pPars->fDumpLarge) && pPars->nSols == 2 ) + { +clk = clock(); + Emb_ManDumpGnuplot( p, pGia->pName, pPars->fDumpLarge, pPars->fShowImage ); +if ( pPars->fVerbose ) +ABC_PRT( "Image dump", clock() - clk ); + } + Emb_ManStop( p ); } diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c new file mode 100644 index 00000000..d05dc5a9 --- /dev/null +++ b/src/aig/gia/giaEnable.c @@ -0,0 +1,210 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Structural detection of enables, sets and resets.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_CollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ) + { + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + // go through the branches + Gia_CollectSuper_rec( p, Gia_ObjChild0(pObj), vSuper ); + Gia_CollectSuper_rec( p, Gia_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_CollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + Vec_IntClear( vSuper ); +// Gia_CollectSuper_rec( p, pObj, vSuper ); + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin1(pObj)) ); + } + else + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) ); + +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintSignals( Gia_Man_t * p, int * pFreq, char * pStr ) +{ + Vec_Int_t * vObjs; + int i, Counter = 0, nTotal = 0; + vObjs = Vec_IntAlloc( 100 ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( pFreq[i] > 1 ) + { + nTotal += pFreq[i]; + Counter++; + } + printf( "%s (total = %d driven = %d)\n", pStr, Counter, nTotal ); + Counter = 0; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( pFreq[i] > 1 ) + { + printf( "%3d : Obj = %6d Refs = %6d Freq = %6d\n", + ++Counter, i, Gia_ObjRefs(p, Gia_ManObj(p,i)), pFreq[i] ); + Vec_IntPush( vObjs, i ); + } + Vec_IntFree( vObjs ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset ) +{ + Vec_Int_t * vSuper; + Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp; + int i, k, Ent, * pSets, * pResets, * pEnables; + int nHaveSetReset = 0, nHaveEnable = 0; + assert( Gia_ManRegNum(p) > 0 ); + pSets = ABC_CALLOC( int, Gia_ManObjNum(p) ); + pResets = ABC_CALLOC( int, Gia_ManObjNum(p) ); + pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) ); + vSuper = Vec_IntAlloc( 100 ); + Gia_ManForEachRi( p, pFlop, i ) + { + pNode = Gia_ObjFanin0(pFlop); + if ( !Gia_ObjIsAnd(pNode) ) + continue; + // detect sets/resets + Gia_CollectSuper( p, pNode, vSuper ); + if ( Gia_ObjFaninC0(pFlop) ) + Vec_IntForEachEntry( vSuper, Ent, k ) + pSets[Ent]++; + else + Vec_IntForEachEntry( vSuper, Ent, k ) + pResets[Ent]++; + // detect enables + if ( !Gia_ObjIsMuxType(pNode) ) + continue; + pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 ); + pTemp = Gia_ObjRiToRo( p, pFlop ); + if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp ) + continue; + if ( !Gia_ObjFaninC0(pFlop) ) + { + pObj0 = Gia_Not(pObj0); + pObj1 = Gia_Not(pObj1); + } + if ( Gia_IsComplement(pObjC) ) + { + pObjC = Gia_Not(pObjC); + pTemp = pObj0; + pObj0 = pObj1; + pObj1 = pTemp; + } + // detect controls +// Gia_CollectSuper( p, pObjC, vSuper ); +// Vec_IntForEachEntry( vSuper, Ent, k ) +// pEnables[Ent]++; + pEnables[Gia_ObjId(p, pObjC)]++; + nHaveEnable++; + } + Gia_ManForEachRi( p, pFlop, i ) + { + pNode = Gia_ObjFanin0(pFlop); + if ( !Gia_ObjIsAnd(pNode) ) + continue; + // detect sets/resets + Gia_CollectSuper( p, pNode, vSuper ); + Vec_IntForEachEntry( vSuper, Ent, k ) + if ( pSets[Ent] > 1 || pResets[Ent] > 1 ) + { + nHaveSetReset++; + break; + } + } + Vec_IntFree( vSuper ); + Gia_ManCreateRefs( p ); + printf( "Flops with set/reset = %6d. Flops with enable = %6d.\n", nHaveSetReset, nHaveEnable ); + if ( fSetReset ) + { + Gia_ManPrintSignals( p, pSets, "Set signals" ); + Gia_ManPrintSignals( p, pResets, "Reset signals" ); + } + Gia_ManPrintSignals( p, pEnables, "Enable signals" ); + ABC_FREE( p->pRefs ); + ABC_FREE( pSets ); + ABC_FREE( pResets ); + ABC_FREE( pEnables ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c new file mode 100644 index 00000000..9e190da3 --- /dev/null +++ b/src/aig/gia/giaEquiv.c @@ -0,0 +1,618 @@ +/**CFile**************************************************************** + + FileName [giaEquiv.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Manipulation of equivalence classes.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaEquiv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Given representatives, derives pointers to the next objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManDeriveNexts( Gia_Man_t * p ) +{ + unsigned * pNexts, * pTails; + int i; + assert( p->pReprs ); + pNexts = ABC_CALLOC( unsigned, Gia_ManObjNum(p) ); + pTails = ABC_ALLOC( unsigned, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + pTails[i] = i; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID ) + continue; + pNexts[ pTails[p->pReprs[i].iRepr] ] = i; + pTails[p->pReprs[i].iRepr] = i; + } + ABC_FREE( pTails ); + return (int *)pNexts; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivCountOne( Gia_Man_t * p, int i ) +{ + int Ent, nLits = 1; + Gia_ClassForEachObj1( p, i, Ent ) + { + assert( Gia_ObjRepr(p, Ent) == i ); + nLits++; + } + return nLits; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter ) +{ + int Ent; + printf( "Class %4d : Num = %2d {", Counter, Gia_ManEquivCountOne(p, i) ); + Gia_ClassForEachObj( p, i, Ent ) + { + printf(" %d", Ent ); + if ( p->pReprs[Ent].fColorA || p->pReprs[Ent].fColorB ) + printf(" <%d%d>", p->pReprs[Ent].fColorA, p->pReprs[Ent].fColorB ); + } + printf( " }\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivCountLitsAll( Gia_Man_t * p ) +{ + int i, nLits = 0; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + nLits += (Gia_ObjRepr(p, i) != GIA_VOID); + return nLits; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivCheckLits( Gia_Man_t * p, int nLits ) +{ + int nLitsReal = Gia_ManEquivCountLitsAll( p ); + if ( nLitsReal != nLits ) + printf( "Detected a mismatch in counting equivalence classes (%d).\n", nLitsReal - nLits ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) +{ + int i, Counter = 0, Counter1 = 0, CounterX = 0, Proved = 0, nLits; + for ( i = 1; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjIsHead(p, i) ) + Counter++; + else if ( Gia_ObjIsConst(p, i) ) + Counter1++; + else if ( Gia_ObjIsNone(p, i) ) + CounterX++; + if ( Gia_ObjProved(p, i) ) + Proved++; + } + CounterX -= Gia_ManCoNum(p); + nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; + printf( "cls =%7d cst =%8d lit =%8d unused =%8d proof =%6d mem =%5.2f Mb\n", + Counter, Counter1, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem ); + assert( Gia_ManEquivCheckLits( p, nLits ) ); + if ( fVerbose ) + { + Counter = 0; + Gia_ManForEachClass( p, i ) + Gia_ManEquivPrintOne( p, i, ++Counter ); + } +} + +/**Function************************************************************* + + Synopsis [Returns representative node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) + return NULL; + return Gia_ManObj( p, Gia_ObjRepr(p, Gia_ObjId(p,pObj)) ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + if ( (pRepr = Gia_ManEquivRepr(p, pObj)) ) + { + Gia_ManEquivReduce_rec( pNew, p, pRepr ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRepr; + int i; + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + { + pObj->Value = Gia_ManAppendCi(pNew); + if ( (pRepr = Gia_ManEquivRepr(p, pObj)) ) + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + } + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj0, * pObj1; + int i; + assert( (Gia_ManPoNum(p) & 1) == 0 ); + Gia_ManForEachPo( p, pObj0, i ) + { + pObj1 = Gia_ManPo( p, ++i ); + if ( Gia_ObjChild0(pObj0) != Gia_ObjChild0(pObj1) ) + continue; + pObj0->iDiff0 = Gia_ObjId(p, pObj0); + pObj0->fCompl0 = 0; + pObj1->iDiff0 = Gia_ObjId(p, pObj1); + pObj1->fCompl0 = 0; + } +} + +/**Function************************************************************* + + Synopsis [Removes pointers to the unmarked nodes..] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivUpdatePointers( Gia_Man_t * p, Gia_Man_t * pNew ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + if ( !~pObj->Value ) + continue; + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + if ( pObjNew->fMark0 ) + pObj->Value = ~0; + } +} + +/**Function************************************************************* + + Synopsis [Removes pointers to the unmarked nodes..] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivDeriveReprs( Gia_Man_t * p, Gia_Man_t * pNew, Gia_Man_t * pFinal ) +{ + Vec_Int_t * vClass; + Gia_Obj_t * pObj, * pObjNew; + int i, k, iNode, iRepr, iPrev; + // start representatives + pFinal->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pFinal) ); + for ( i = 0; i < Gia_ManObjNum(pFinal); i++ ) + Gia_ObjSetRepr( pFinal, i, GIA_VOID ); + // iterate over constant candidates + Gia_ManForEachConst( p, i ) + { + pObj = Gia_ManObj( p, i ); + if ( !~pObj->Value ) + continue; + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_Lit2Var(pObjNew->Value) == 0 ) + continue; + Gia_ObjSetRepr( pFinal, Gia_Lit2Var(pObjNew->Value), 0 ); + } + // iterate over class candidates + vClass = Vec_IntAlloc( 100 ); + Gia_ManForEachClass( p, i ) + { + Vec_IntClear( vClass ); + Gia_ClassForEachObj( p, i, k ) + { + pObj = Gia_ManObj( p, k ); + if ( !~pObj->Value ) + continue; + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + Vec_IntPushUnique( vClass, Gia_Lit2Var(pObjNew->Value) ); + } + if ( Vec_IntSize( vClass ) < 2 ) + continue; + Vec_IntSort( vClass, 0 ); + iRepr = iPrev = Vec_IntEntry( vClass, 0 ); + Vec_IntForEachEntryStart( vClass, iNode, k, 1 ) + { + Gia_ObjSetRepr( pFinal, iNode, iRepr ); + assert( iPrev < iNode ); + iPrev = iNode; + } + } + Vec_IntFree( vClass ); + pFinal->pNexts = Gia_ManDeriveNexts( pFinal ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG while remapping equivalence classes.] + + Description [Drops the pairs of outputs if they are proved equivalent.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ) +{ + Gia_Man_t * pNew, * pFinal; + pNew = Gia_ManEquivReduce( p ); + if ( fMiterPairs ) + Gia_ManEquivFixOutputPairs( pNew ); + if ( fSeq ) + Gia_ManSeqMarkUsed( pNew ); + else + Gia_ManCombMarkUsed( pNew ); + Gia_ManEquivUpdatePointers( p, pNew ); + pFinal = Gia_ManDupMarked( pNew ); + Gia_ManEquivDeriveReprs( p, pNew, pFinal ); + Gia_ManStop( pNew ); + return pFinal; +} + +/**Function************************************************************* + + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivSetColor_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fOdds ) +{ + if ( Gia_ObjVisitColor( p, Gia_ObjId(p,pObj), fOdds ) ) + return 0; + if ( Gia_ObjIsRo(p, pObj) ) + return 1 + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj)), fOdds ); + assert( Gia_ObjIsAnd(pObj) ); + return 1 + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), fOdds ) + + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin1(pObj), fOdds ); +} + +/**Function************************************************************* + + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ) +{ + Gia_Obj_t * pObj; + int i, nNodes[2] = {0,0}, nDiffs[2]; + assert( (Gia_ManPoNum(p) & 1) == 0 ); + Gia_ObjSetColors( p, 0 ); + Gia_ManForEachPi( p, pObj, i ) + Gia_ObjSetColors( p, Gia_ObjId(p,pObj) ); + Gia_ManForEachPo( p, pObj, i ) + nNodes[i&1] += Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), i&1 ); +// Gia_ManForEachObj( p, pObj, i ) +// if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ) +// assert( Gia_ObjColors(p, i) ); + nDiffs[0] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[0]); + nDiffs[1] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[1]); + if ( fVerbose ) + { + printf( "CI+AND = %7d A = %7d B = %7d Ad = %7d Bd = %7d AB = %7d.\n", + Gia_ManCiNum(p) + Gia_ManAndNum(p), + Gia_ManPiNum(p) + nNodes[0], Gia_ManPiNum(p) + nNodes[1], + nDiffs[0], nDiffs[1], + Gia_ManCiNum(p) + Gia_ManAndNum(p) - nDiffs[0] - nDiffs[1] ); + } + return (nDiffs[0] + nDiffs[1]) / 2; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits ) +{ + Gia_Obj_t * pRepr; + int iLitNew; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + return; + iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + if ( pObj->Value != (unsigned)iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) + Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) ); + pObj->Value = iLitNew; +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + Vec_Int_t * vXorLits; + int i, iLitNew; + if ( !p->pReprs ) + return NULL; + vXorLits = Vec_IntAlloc( 1000 ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + if ( pObj->Value != (unsigned)iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) + Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) ); + pObj->Value = iLitNew; + } + Gia_ManForEachCo( p, pObj, i ) + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits ); + Vec_IntForEachEntry( vXorLits, iLitNew, i ) + Gia_ManAppendCo( pNew, iLitNew ); + if ( Vec_IntSize(vXorLits) == 0 ) + { + printf( "Speculatively reduced model has no primary outputs.\n" ); + Gia_ManAppendCo( pNew, 0 ); + } + Gia_ManForEachRi( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntFree( vXorLits ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transforms equiv classes by removing the AB nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ) +{ + extern void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass ); + Vec_Int_t * vClass, * vClassNew; + int iRepr, iNode, Ent, k; + int nRemovedLits = 0, nRemovedClas = 0; + int nTotalLits = 0, nTotalClas = 0; + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts ); + vClass = Vec_IntAlloc( 100 ); + vClassNew = Vec_IntAlloc( 100 ); + Gia_ManForEachObj( p, pObj, i ) + if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ) + assert( Gia_ObjColors(p, i) ); + Gia_ManForEachClassReverse( p, iRepr ) + { + nTotalClas++; + Vec_IntClear( vClass ); + Vec_IntClear( vClassNew ); + Gia_ClassForEachObj( p, iRepr, iNode ) + { + nTotalLits++; + Vec_IntPush( vClass, iNode ); + assert( Gia_ObjColors(p, iNode) ); + if ( Gia_ObjColors(p, iNode) != 3 ) + Vec_IntPush( vClassNew, iNode ); + else + nRemovedLits++; + } + Vec_IntForEachEntry( vClass, Ent, k ) + { + p->pReprs[Ent].fFailed = p->pReprs[Ent].fProved = 0; + p->pReprs[Ent].iRepr = GIA_VOID; + p->pNexts[Ent] = 0; + } + if ( Vec_IntSize(vClassNew) < 2 ) + { + nRemovedClas++; + continue; + } + Cec_ManSimClassCreate( p, vClassNew ); + } + Vec_IntFree( vClass ); + Vec_IntFree( vClassNew ); + if ( fVerbose ) + printf( "Removed classes = %6d (out of %6d). Removed literals = %6d (out of %6d).\n", + nRemovedClas, nTotalClas, nRemovedLits, nTotalLits ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c index c2d2d33f..cf4c4aa5 100644 --- a/src/aig/gia/giaForce.c +++ b/src/aig/gia/giaForce.c @@ -23,47 +23,100 @@ /* The code is based on the paper by F. A. Aloul, I. L. Markov, and K. A. Sakallah. "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct For_Obj_t_ For_Obj_t; -struct For_Obj_t_ +typedef struct Frc_Obj_t_ Frc_Obj_t; +struct Frc_Obj_t_ { - int iObj; - float lNode; + unsigned fCi : 1; // terminal node CI + unsigned fCo : 1; // terminal node CO + unsigned fMark0 : 1; // first user-controlled mark + unsigned fMark1 : 1; // second user-controlled mark + unsigned nFanins : 28; // the number of fanins + unsigned nFanouts; // the number of fanouts + unsigned iFanout; // the current number of fanouts + int hHandle; // the handle of the node + int pPlace; // the placement of each node + union { + float fEdgeCenter; // center-of-gravity of the edge + unsigned iFanin; + }; + int Fanios[0]; // the array of fanins/fanouts }; -typedef struct For_Man_t_ For_Man_t; -struct For_Man_t_ +typedef struct Frc_Man_t_ Frc_Man_t; +struct Frc_Man_t_ { Gia_Man_t * pGia; // the original AIG manager + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) int nObjs; // the number of objects - int iObj; // the last added object - int * pPlace; // coordinates of objects - int * piNext; // array of next pointers - int * piRoot; // array of root pointers - float * plEdge; // edge coordinates - For_Obj_t * pNodes; // the array of nodes + int nRegs; // the number of registers + int * pObjData; // the array containing data for objects + int nObjData; // the size of array to store the logic network + int fVerbose; // verbose output flag + int nCutCur; // current cut + int nCutMax; // max cut seen }; -static inline int Gia_ObjPlace( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjId(p->pGia, pObj)]; } -static inline int Gia_ObjPlaceFanin0( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjFaninId0p(p->pGia, pObj)]; } -static inline int Gia_ObjPlaceFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjFaninId1p(p->pGia, pObj)]; } - -static inline int Gia_ObjEdge( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjId(p->pGia, pObj)]; } -static inline int Gia_ObjEdgeFanin0( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)]; } -static inline int Gia_ObjEdgeFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjFaninId1p(p->pGia, pObj)]; } +static inline int Frc_ManRegNum( Frc_Man_t * p ) { return p->nRegs; } +static inline int Frc_ManCiNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCis); } +static inline int Frc_ManCoNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCos); } +static inline int Frc_ManPiNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCis) - p->nRegs; } +static inline int Frc_ManPoNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCos) - p->nRegs; } +static inline int Frc_ManObjNum( Frc_Man_t * p ) { return p->nObjs; } +static inline int Frc_ManNodeNum( Frc_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos); } + +static inline Frc_Obj_t * Frc_ManObj( Frc_Man_t * p, int hHandle ) { return (Frc_Obj_t *)(p->pObjData + hHandle); } +static inline Frc_Obj_t * Frc_ManCi( Frc_Man_t * p, int i ) { return Frc_ManObj( p, Vec_IntEntry(p->vCis,i) ); } +static inline Frc_Obj_t * Frc_ManCo( Frc_Man_t * p, int i ) { return Frc_ManObj( p, Vec_IntEntry(p->vCos,i) ); } + +static inline int Frc_ObjIsTerm( Frc_Obj_t * pObj ) { return pObj->fCi || pObj->fCo; } +static inline int Frc_ObjIsCi( Frc_Obj_t * pObj ) { return pObj->fCi; } +static inline int Frc_ObjIsCo( Frc_Obj_t * pObj ) { return pObj->fCo; } +static inline int Frc_ObjIsPi( Frc_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; } +static inline int Frc_ObjIsPo( Frc_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; } +static inline int Frc_ObjIsNode( Frc_Obj_t * pObj ) { return!Frc_ObjIsTerm(pObj) && pObj->nFanins > 0; } +static inline int Frc_ObjIsConst0( Frc_Obj_t * pObj ) { return!Frc_ObjIsTerm(pObj) && pObj->nFanins == 0; } + +static inline int Frc_ObjSize( Frc_Obj_t * pObj ) { return sizeof(Frc_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } +static inline int Frc_ObjFaninNum( Frc_Obj_t * pObj ) { return pObj->nFanins; } +static inline int Frc_ObjFanoutNum( Frc_Obj_t * pObj ) { return pObj->nFanouts; } +static inline Frc_Obj_t * Frc_ObjFanin( Frc_Obj_t * pObj, int i ) { return (Frc_Obj_t *)(((int *)pObj) - pObj->Fanios[i]); } +static inline Frc_Obj_t * Frc_ObjFanout( Frc_Obj_t * pObj, int i ) { return (Frc_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); } + +#define Frc_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Frc_ManObj(p,i)); i += Frc_ObjSize(pObj) ) +#define Frc_ManForEachObjVec( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Frc_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) + +#define Frc_ManForEachNode( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Frc_ManObj(p,i)); i += Frc_ObjSize(pObj) ) if ( Frc_ObjIsTerm(pObj) ) {} else +#define Frc_ManForEachCi( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCis)) && (pObj = Frc_ManObj(p,Vec_IntEntry(p->vCis,i))); i++ ) +#define Frc_ManForEachCo( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCos)) && (pObj = Frc_ManObj(p,Vec_IntEntry(p->vCos,i))); i++ ) + +#define Frc_ObjForEachFanin( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Frc_ObjFanin(pObj,i)); i++ ) +#define Frc_ObjForEachFaninReverse( pObj, pNext, i ) \ + for ( i = (int)pObj->nFanins - 1; (i >= 0) && (pNext = Frc_ObjFanin(pObj,i)); i-- ) +#define Frc_ObjForEachFanout( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Frc_ObjFanout(pObj,i)); i++ ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// + /**Function************************************************************* - Synopsis [] + Synopsis [Creates fanin/fanout pair.] Description [] @@ -72,23 +125,128 @@ static inline int Gia_ObjEdgeFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { retu SeeAlso [] ***********************************************************************/ -For_Man_t * For_ManStart( Gia_Man_t * pGia ) +void Frc_ObjAddFanin( Frc_Obj_t * pObj, Frc_Obj_t * pFanin ) +{ + assert( pObj->iFanin < pObj->nFanins ); + assert( pFanin->iFanout < pFanin->nFanouts ); + pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] = + pObj->Fanios[pObj->iFanin++] = pObj->hHandle - pFanin->hHandle; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Frc_Man_t * Frc_ManStartSimple( Gia_Man_t * pGia ) { - For_Man_t * p; - p = ABC_CALLOC( For_Man_t, 1 ); - p->pGia = pGia; - p->nObjs = Gia_ManObjNum(pGia); - p->pPlace = ABC_ALLOC( int, p->nObjs ); - p->piNext = ABC_ALLOC( int, p->nObjs ); - p->piRoot = ABC_ALLOC( int, p->nObjs ); - p->plEdge = ABC_ALLOC( float, p->nObjs ); - p->pNodes = ABC_ALLOC( For_Obj_t, p->nObjs ); + Frc_Man_t * p; + Frc_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj;//, * pObjRi, * pObjRo; + int i, nNodes, hHandle = 0; + // prepare the AIG + Gia_ManCreateRefs( pGia ); + // create logic network + p = ABC_CALLOC( Frc_Man_t, 1 ); + p->pGia = pGia; + p->nRegs = Gia_ManRegNum(pGia); + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Frc_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia)); + p->pObjData = ABC_CALLOC( int, p->nObjData ); + // create constant node + Gia_ManConst0(pGia)->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes = 1; + p->nObjs++; + // create the PIs + Gia_ManForEachCi( pGia, pObj, i ) + { + // create PI object + pObj->Value = hHandle; + Vec_IntPush( p->vCis, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->fCi = 0; + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; + } + // create internal nodes + Gia_ManForEachAnd( pGia, pObj, i ) + { + assert( Gia_ObjRefs( pGia, pObj ) > 0 ); + // create node object + pObj->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 2; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + // add fanins + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin1(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes++; + p->nObjs++; + } + // create the POs + Gia_ManForEachCo( pGia, pObj, i ) + { + // create PO object + pObj->Value = hHandle; + Vec_IntPush( p->vCos, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 1; + pObjLog->nFanouts = 0; + pObjLog->fCo = 1; + // add fanins + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; + } + // connect registers +// Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, i ) +// Frc_ObjAddFanin( Frc_ManObj(p,Gia_ObjValue(pObjRo)), Frc_ManObj(p,Gia_ObjValue(pObjRi)) ); + assert( nNodes == Frc_ManNodeNum(p) ); + assert( hHandle == p->nObjData ); + if ( hHandle != p->nObjData ) + printf( "Frc_ManStartSimple(): Fatal error in internal representation.\n" ); + // make sure the fanin/fanout counters are correct + Gia_ManForEachObj( pGia, pObj, i ) + { + if ( !~Gia_ObjValue(pObj) ) + continue; + pObjLog = Frc_ManObj( p, Gia_ObjValue(pObj) ); + assert( pObjLog->nFanins == pObjLog->iFanin ); + assert( pObjLog->nFanouts == pObjLog->iFanout ); + pObjLog->iFanin = pObjLog->iFanout = 0; + } + ABC_FREE( pGia->pRefs ); return p; } /**Function************************************************************* - Synopsis [] + Synopsis [Collect the fanin IDs.] Description [] @@ -97,19 +255,50 @@ For_Man_t * For_ManStart( Gia_Man_t * pGia ) SeeAlso [] ***********************************************************************/ -void For_ManStop( For_Man_t * p ) +void Frc_ManCollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper, Vec_Int_t * vVisit ) { - ABC_FREE( p->pPlace ); - ABC_FREE( p->piNext ); - ABC_FREE( p->piRoot ); - ABC_FREE( p->plEdge ); - ABC_FREE( p->pNodes ); - ABC_FREE( p ); + if ( pObj->fMark1 ) + return; + pObj->fMark1 = 1; + Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); + if ( pObj->fMark0 ) + { + Vec_IntPush( vSuper, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Frc_ManCollectSuper_rec( p, Gia_ObjFanin0(pObj), vSuper, vVisit ); + Frc_ManCollectSuper_rec( p, Gia_ObjFanin1(pObj), vSuper, vVisit ); + } /**Function************************************************************* - Synopsis [Derives random ordering of nodes.] + Synopsis [Collect the fanin IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper, Vec_Int_t * vVisit ) +{ + int Entry, i; + Vec_IntClear( vSuper ); + Vec_IntClear( vVisit ); + assert( pObj->fMark0 == 1 ); + pObj->fMark0 = 0; + Frc_ManCollectSuper_rec( p, pObj, vSuper, vVisit ); + pObj->fMark0 = 1; + Vec_IntForEachEntry( vVisit, Entry, i ) + Gia_ManObj(p, Entry)->fMark1 = 0; +} + +/**Function************************************************************* + + Synopsis [Assigns references while removing the MUX/XOR ones.] Description [] @@ -118,24 +307,44 @@ void For_ManStop( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManSetInitPlaceRandom( For_Man_t * p ) +void Frc_ManCreateRefsSpecial( Gia_Man_t * p ) { - int i, Temp, iNext; - Aig_ManRandom( 1 ); - for ( i = 0; i < p->nObjs; i++ ) - p->pPlace[i] = i; - for ( i = 0; i < p->nObjs; i++ ) + Gia_Obj_t * pObj, * pFan0, * pFan1; + Gia_Obj_t * pObjC, * pObjD0, * pObjD1; + int i; + assert( p->pRefs == NULL ); + Gia_ManCleanMark0( p ); + Gia_ManCreateRefs( p ); + Gia_ManForEachAnd( p, pObj, i ) { - iNext = Aig_ManRandom( 0 ) % p->nObjs; - Temp = p->pPlace[i]; - p->pPlace[i] = p->pPlace[iNext]; - p->pPlace[iNext] = Temp; + assert( pObj->fMark0 == 0 ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + // skip nodes whose fanins are PIs or are already marked + if ( Gia_ObjIsCi(pFan0) || pFan0->fMark0 || + Gia_ObjIsCi(pFan1) || pFan1->fMark0 ) + continue; + // skip nodes that are not MUX type + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + // the node is MUX type, mark it and its fanins + pObj->fMark0 = 1; + pFan0->fMark0 = 1; + pFan1->fMark0 = 1; + // deref the control + pObjC = Gia_ObjRecognizeMux( pObj, &pObjD1, &pObjD0 ); + Gia_ObjRefDec( p, Gia_Regular(pObjC) ); + if ( Gia_Regular(pObjD0) == Gia_Regular(pObjD1) ) + Gia_ObjRefDec( p, Gia_Regular(pObjD0) ); } + Gia_ManForEachAnd( p, pObj, i ) + assert( Gia_ObjRefs(p, pObj) > 0 ); + Gia_ManCleanMark0( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Assigns references while removing the MUX/XOR ones.] Description [] @@ -144,39 +353,196 @@ void For_ManSetInitPlaceRandom( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManSetInitPlaceDfs_rec( For_Man_t * p, Gia_Obj_t * pObj, int fRev ) +void Frc_ManTransformRefs( Gia_Man_t * p, int * pnObjs, int * pnFanios ) { - if ( pObj->fMark0 ) - return; - pObj->fMark0 = 1; - if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) + Vec_Int_t * vSuper, * vVisit; + Gia_Obj_t * pObj, * pFanin; + int i, k, Counter; + assert( p->pRefs != NULL ); + + // mark nodes to be used in the logic network + Gia_ManCleanMark0( p ); + Gia_ManConst0(p)->fMark0 = 1; + // mark the inputs + Gia_ManForEachCi( p, pObj, i ) + pObj->fMark0 = 1; + // mark those nodes that have ref count more than 1 + Gia_ManForEachAnd( p, pObj, i ) + pObj->fMark0 = (Gia_ObjRefs(p, pObj) > 1); + // mark the output drivers + Gia_ManForEachCoDriver( p, pObj, i ) + pObj->fMark0 = 1; + + // count the number of nodes + Counter = 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += pObj->fMark0; + *pnObjs = Counter + Gia_ManCoNum(p); + + // reset the references + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + // reference from internal nodes + Counter = 0; + vSuper = Vec_IntAlloc( 100 ); + vVisit = Vec_IntAlloc( 100 ); + Gia_ManCleanMark1( p ); + Gia_ManForEachAnd( p, pObj, i ) { - p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++; - return; + if ( pObj->fMark0 == 0 ) + continue; + Frc_ManCollectSuper( p, pObj, vSuper, vVisit ); + Gia_ManForEachObjVec( vSuper, p, pFanin, k ) + { + assert( pFanin->fMark0 ); + Gia_ObjRefInc( p, pFanin ); + } + Counter += Vec_IntSize( vSuper ); } - if ( Gia_ObjIsCo(pObj) ) + Gia_ManCheckMark1( p ); + Vec_IntFree( vSuper ); + Vec_IntFree( vVisit ); + // reference from outputs + Gia_ManForEachCoDriver( p, pObj, i ) { - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev ); - p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++; - return; + assert( pObj->fMark0 ); + Gia_ObjRefInc( p, pObj ); } - assert( Gia_ObjIsAnd(pObj) ); - if ( fRev ) + *pnFanios = Counter + Gia_ManCoNum(p); +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Frc_Man_t * Frc_ManStart( Gia_Man_t * pGia ) +{ + Frc_Man_t * p; + Frc_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj, * pFanin;//, * pObjRi, * pObjRo; + Vec_Int_t * vSuper, * vVisit; + int nObjs, nFanios, nNodes = 0; + int i, k, hHandle = 0; + // prepare the AIG +// Gia_ManCreateRefs( pGia ); + Frc_ManCreateRefsSpecial( pGia ); + Frc_ManTransformRefs( pGia, &nObjs, &nFanios ); + Gia_ManFillValue( pGia ); + // create logic network + p = ABC_CALLOC( Frc_Man_t, 1 ); + p->pGia = pGia; + p->nRegs = Gia_ManRegNum(pGia); + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Frc_Obj_t) / 4) * nObjs + 2 * nFanios; + p->pObjData = ABC_CALLOC( int, p->nObjData ); + // create constant node + Gia_ManConst0(pGia)->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes++; + p->nObjs++; + // create the PIs + Gia_ManForEachCi( pGia, pObj, i ) { - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin1(pObj), fRev ); - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev ); + // create PI object + pObj->Value = hHandle; + Vec_IntPush( p->vCis, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->fCi = 1; + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; } - else + // create internal nodes + vSuper = Vec_IntAlloc( 100 ); + vVisit = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( pGia, pObj, i ) { - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev ); - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin1(pObj), fRev ); + if ( pObj->fMark0 == 0 ) + { + assert( Gia_ObjRefs( pGia, pObj ) == 0 ); + continue; + } + assert( Gia_ObjRefs( pGia, pObj ) > 0 ); + Frc_ManCollectSuper( pGia, pObj, vSuper, vVisit ); + // create node object + pObj->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = Vec_IntSize( vSuper ); + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + // add fanins + Gia_ManForEachObjVec( vSuper, pGia, pFanin, k ) + { + pFanLog = Frc_ManObj( p, Gia_ObjValue(pFanin) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + } + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes++; + p->nObjs++; + } + Vec_IntFree( vSuper ); + Vec_IntFree( vVisit ); + // create the POs + Gia_ManForEachCo( pGia, pObj, i ) + { + // create PO object + pObj->Value = hHandle; + Vec_IntPush( p->vCos, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 1; + pObjLog->nFanouts = 0; + pObjLog->fCo = 1; + // add fanins + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; } - p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++; + // connect registers +// Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, i ) +// Frc_ObjAddFanin( Frc_ManObj(p,Gia_ObjValue(pObjRo)), Frc_ManObj(p,Gia_ObjValue(pObjRi)) ); + Gia_ManCleanMark0( pGia ); + assert( nNodes == Frc_ManNodeNum(p) ); + assert( nObjs == p->nObjs ); + assert( hHandle == p->nObjData ); + if ( hHandle != p->nObjData ) + printf( "Frc_ManStart(): Fatal error in internal representation.\n" ); + // make sure the fanin/fanout counters are correct + Gia_ManForEachObj( pGia, pObj, i ) + { + if ( !~Gia_ObjValue(pObj) ) + continue; + pObjLog = Frc_ManObj( p, Gia_ObjValue(pObj) ); + assert( pObjLog->nFanins == pObjLog->iFanin ); + assert( pObjLog->nFanouts == pObjLog->iFanout ); + pObjLog->iFanin = pObjLog->iFanout = 0; + } + ABC_FREE( pGia->pRefs ); + return p; } /**Function************************************************************* - Synopsis [Derives DFS ordering of nodes.] + Synopsis [Creates logic network isomorphic to the given AIG.] Description [] @@ -185,25 +551,25 @@ void For_ManSetInitPlaceDfs_rec( For_Man_t * p, Gia_Obj_t * pObj, int fRev ) SeeAlso [] ***********************************************************************/ -void For_ManSetInitPlaceDfs( For_Man_t * p, int fRev ) +void Frc_ManPrintStats( Frc_Man_t * p ) { - Gia_Obj_t * pObj; - int i; - p->iObj = 0; - Gia_ManCleanMark0( p->pGia ); - For_ManSetInitPlaceDfs_rec( p, Gia_ManConst0(p->pGia), fRev ); - Gia_ManForEachCo( p->pGia, pObj, i ) - For_ManSetInitPlaceDfs_rec( p, pObj, fRev ); - Gia_ManForEachCi( p->pGia, pObj, i ) - if ( pObj->fMark0 == 0 ) - For_ManSetInitPlaceDfs_rec( p, pObj, fRev ); - assert( p->iObj == p->nObjs ); - Gia_ManCleanMark0( p->pGia ); +// if ( p->pName ) +// printf( "%8s : ", p->pName ); + printf( "i/o =%7d/%7d ", Frc_ManPiNum(p), Frc_ManPoNum(p) ); + if ( Frc_ManRegNum(p) ) + printf( "ff =%7d ", Frc_ManRegNum(p) ); + printf( "node =%8d ", Frc_ManNodeNum(p) ); + printf( "obj =%8d ", Frc_ManObjNum(p) ); +// printf( "lev =%5d ", Frc_ManLevelNum(p) ); +// printf( "cut =%5d ", Frc_ManCrossCut(p) ); + printf( "mem =%5.2f Mb", 4.0*p->nObjData/(1<<20) ); +// printf( "obj =%5d ", Frc_ManObjNum(p) ); + printf( "\n" ); } /**Function************************************************************* - Synopsis [Computes span for the given placement.] + Synopsis [Creates logic network isomorphic to the given AIG.] Description [] @@ -212,29 +578,72 @@ void For_ManSetInitPlaceDfs( For_Man_t * p, int fRev ) SeeAlso [] ***********************************************************************/ -double For_ManGetEdgeSpan( For_Man_t * p ) +void Frc_ManStop( Frc_Man_t * p ) { - double Result = 0.0; - Gia_Obj_t * pObj; - int i, Diff; - Gia_ManForEachAnd( p->pGia, pObj, i ) + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + ABC_FREE( p->pObjData ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Computes cross cut size for the given order of POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Frc_ManCrossCut_rec( Frc_Man_t * p, Frc_Obj_t * pObj ) +{ + assert( pObj->iFanout > 0 ); + if ( pObj->iFanout-- == pObj->nFanouts ) { - Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin0(p, pObj); - Result += (double)ABC_ABS(Diff); - Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin1(p, pObj); - Result += (double)ABC_ABS(Diff); + Frc_Obj_t * pFanin; + int i; + p->nCutCur++; + p->nCutMax = ABC_MAX( p->nCutMax, p->nCutCur ); + if ( !Frc_ObjIsCi(pObj) ) + Frc_ObjForEachFanin( pObj, pFanin, i ) + p->nCutCur -= Frc_ManCrossCut_rec( p, pFanin ); } - Gia_ManForEachCo( p->pGia, pObj, i ) + return pObj->iFanout == 0; +} + +/**Function************************************************************* + + Synopsis [Computes cross cut size for the given order of POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Frc_ManCrossCut2_rec( Frc_Man_t * p, Frc_Obj_t * pObj ) +{ + assert( pObj->iFanout > 0 ); + if ( pObj->iFanout-- == pObj->nFanouts ) { - Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin0(p, pObj); - Result += (double)ABC_ABS(Diff); + Frc_Obj_t * pFanin; + int i; + p->nCutCur++; + p->nCutMax = ABC_MAX( p->nCutMax, p->nCutCur ); + if ( !Frc_ObjIsCi(pObj) ) + Frc_ObjForEachFaninReverse( pObj, pFanin, i ) + p->nCutCur -= Frc_ManCrossCut2_rec( p, pFanin ); } - return Result; + return pObj->iFanout == 0; } /**Function************************************************************* - Synopsis [Computes max cut of the given placement.] + Synopsis [Computes cross cut size for the given order of POs.] Description [] @@ -243,68 +652,138 @@ double For_ManGetEdgeSpan( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -int For_ManGetMaxCut( For_Man_t * p ) +int Frc_ManCrossCut( Frc_Man_t * p, Vec_Int_t * vOrder, int fReverse ) { - Gia_Obj_t * pObj; - int i, iObj, iFan, * pTemp; - int nCutCut, nCutMax; - pTemp = ABC_CALLOC( int, p->nObjs ); - Gia_ManForEachAnd( p->pGia, pObj, i ) + Frc_Obj_t * pObj; + int i; + assert( Vec_IntSize(vOrder) == Frc_ManCoNum(p) ); + p->nCutCur = 0; + p->nCutMax = 0; + Frc_ManForEachObj( p, pObj, i ) + pObj->iFanout = pObj->nFanouts; + Frc_ManForEachObjVec( vOrder, p, pObj, i ) { - iObj = Gia_ObjPlace(p, pObj); - iFan = Gia_ObjPlaceFanin0(p, pObj); - if ( iObj < iFan ) - { - pTemp[iObj]++; - pTemp[iFan]--; - } - else - { - pTemp[iObj]--; - pTemp[iFan]++; - } - iObj = Gia_ObjPlace(p, pObj); - iFan = Gia_ObjPlaceFanin1(p, pObj); - if ( iObj < iFan ) - { - pTemp[iObj]++; - pTemp[iFan]--; - } + assert( Frc_ObjIsCo(pObj) ); + if ( fReverse ) + p->nCutCur -= Frc_ManCrossCut2_rec( p, Frc_ObjFanin(pObj,0) ); else - { - pTemp[iObj]--; - pTemp[iFan]++; - } + p->nCutCur -= Frc_ManCrossCut_rec( p, Frc_ObjFanin(pObj,0) ); } - Gia_ManForEachCo( p->pGia, pObj, i ) + assert( p->nCutCur == 0 ); +// Frc_ManForEachObj( p, pObj, i ) +// assert( pObj->iFanout == 0 ); + return p->nCutMax; +} + +/**Function************************************************************* + + Synopsis [Collects CO handles.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Frc_ManCollectCos( Frc_Man_t * p ) +{ + Vec_Int_t * vCoOrder; + Frc_Obj_t * pObj; + int i; + vCoOrder = Vec_IntAlloc( Frc_ManCoNum(p) ); + Frc_ManForEachCo( p, pObj, i ) + Vec_IntPush( vCoOrder, pObj->hHandle ); + return vCoOrder; +} + +/**Function************************************************************* + + Synopsis [Computes cross cut size for the given order of POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManCrossCutTest( Frc_Man_t * p, Vec_Int_t * vOrderInit ) +{ + Vec_Int_t * vOrder; + int clk = clock(); + vOrder = vOrderInit? vOrderInit : Frc_ManCollectCos( p ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 0 ) ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 1 ) ); + Vec_IntReverseOrder( vOrder ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 0 ) ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 1 ) ); + Vec_IntReverseOrder( vOrder ); + if ( vOrder != vOrderInit ) + Vec_IntFree( vOrder ); +// ABC_PRT( "Time", clock() - clk ); +} + + + +/**Function************************************************************* + + Synopsis [Generates random placement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManPlaceRandom( Frc_Man_t * p ) +{ + Frc_Obj_t * pThis; + int * pPlacement; + int i, h, Temp, iNext, Counter; + pPlacement = ABC_ALLOC( int, p->nObjs ); + for ( i = 0; i < p->nObjs; i++ ) + pPlacement[i] = i; + for ( i = 0; i < p->nObjs; i++ ) { - iObj = Gia_ObjPlace(p, pObj); - iFan = Gia_ObjPlaceFanin0(p, pObj); - if ( iObj < iFan ) - { - pTemp[iObj]++; - pTemp[iFan]--; - } - else - { - pTemp[iObj]--; - pTemp[iFan]++; - } + iNext = Aig_ManRandom( 0 ) % p->nObjs; + Temp = pPlacement[i]; + pPlacement[i] = pPlacement[iNext]; + pPlacement[iNext] = Temp; } - nCutCut = nCutMax = 0; - for ( i = 0; i < p->nObjs; i++ ) + Counter = 0; + Frc_ManForEachObj( p, pThis, h ) + pThis->pPlace = pPlacement[Counter++]; + ABC_FREE( pPlacement ); +} + +/**Function************************************************************* + + Synopsis [Shuffles array of random integers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManArrayShuffle( Vec_Int_t * vArray ) +{ + int i, iNext, Temp; + for ( i = 0; i < vArray->nSize; i++ ) { - nCutCut += pTemp[i]; - nCutMax = ABC_MAX( nCutCut, nCutMax ); + iNext = Aig_ManRandom( 0 ) % vArray->nSize; + Temp = vArray->pArray[i]; + vArray->pArray[i] = vArray->pArray[iNext]; + vArray->pArray[iNext] = Temp; } - ABC_FREE( pTemp ); - assert( nCutCut == 0 ); - return nCutMax; } /**Function************************************************************* - Synopsis [Computes hyper-edge centers.] + Synopsis [Computes cross cut size for the given order of POs.] Description [] @@ -313,31 +792,23 @@ int For_ManGetMaxCut( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManEdgeCenters( For_Man_t * p ) +void Frc_ManPlaceDfs_rec( Frc_Man_t * p, Frc_Obj_t * pObj, int * piPlace ) { - Gia_Obj_t * pObj; - int i; - memset( p->plEdge, 0, sizeof(float) * p->nObjs ); - Gia_ManForEachObj( p->pGia, pObj, i ) + assert( pObj->iFanout > 0 ); + if ( pObj->iFanout-- == pObj->nFanouts ) { - p->plEdge[i] = Gia_ObjPlace(p, pObj); - if ( Gia_ObjIsAnd(pObj) ) - { - p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj); - p->plEdge[Gia_ObjFaninId1p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj); - } - else if ( Gia_ObjIsCo(pObj) ) - { - p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj); - } + Frc_Obj_t * pFanin; + int i; + if ( !Frc_ObjIsCi(pObj) ) + Frc_ObjForEachFanin( pObj, pFanin, i ) + Frc_ManPlaceDfs_rec( p, pFanin, piPlace ); + pObj->pPlace = (*piPlace)++; } - Gia_ManForEachObj( p->pGia, pObj, i ) - p->plEdge[i] /= 1.0 + Gia_ObjRefs( p->pGia, pObj ); } /**Function************************************************************* - Synopsis [Computes object centers.] + Synopsis [Generates DFS placement.] Description [] @@ -346,30 +817,156 @@ void For_ManEdgeCenters( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManObjCenters( For_Man_t * p ) +void Frc_ManPlaceDfs( Frc_Man_t * p, Vec_Int_t * vCoOrder ) { - Gia_Obj_t * pObj; - int i; - Gia_ManForEachObj( p->pGia, pObj, i ) + Frc_Obj_t * pObj; + int i, nPlaces = 0; + Frc_ManForEachObj( p, pObj, i ) { - p->pNodes[i].lNode = Gia_ObjEdge(p, pObj); - if ( Gia_ObjIsAnd(pObj) ) + pObj->iFanout = pObj->nFanouts; + if ( pObj->nFanouts == 0 && !Frc_ObjIsCo(pObj) ) + pObj->pPlace = nPlaces++; + } + Frc_ManForEachObjVec( vCoOrder, p, pObj, i ) + { + assert( Frc_ObjIsCo(pObj) ); + Frc_ManPlaceDfs_rec( p, Frc_ObjFanin(pObj,0), &nPlaces ); + pObj->pPlace = nPlaces++; + } + assert( nPlaces == p->nObjs ); +} + +/**Function************************************************************* + + Synopsis [Generates DFS placement by trying both orders.] + + Description [Returns the cross cut size of the best order. ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Frc_ManPlaceDfsBoth( Frc_Man_t * p, Vec_Int_t * vCoOrder, int * piCutSize2 ) +{ + int nCutStart1, nCutStart2; + nCutStart1 = Frc_ManCrossCut( p, vCoOrder, 0 ); + Vec_IntReverseOrder( vCoOrder ); + nCutStart2 = Frc_ManCrossCut( p, vCoOrder, 0 ); + if ( nCutStart1 <= nCutStart2 ) + { + Vec_IntReverseOrder( vCoOrder ); // undo + Frc_ManPlaceDfs( p, vCoOrder ); + *piCutSize2 = nCutStart2; + return nCutStart1; + } + else + { + Frc_ManPlaceDfs( p, vCoOrder ); + Vec_IntReverseOrder( vCoOrder ); // undo + *piCutSize2 = nCutStart1; + return nCutStart2; + } +} + +/**Function************************************************************* + + Synopsis [Performs iterative refinement of the given placement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManPlacementRefine( Frc_Man_t * p, int nIters, int fVerbose ) +{ + int fRandomize = 0; + Vec_Int_t * vCoOrder; + Frc_Obj_t * pThis, * pNext; + double CostThis, CostPrev; + float * pVertX, VertX; + int * pPermX, * pHandles; + int k, h, Iter, iMinX, iMaxX, Counter, nCutStart, nCutCur, nCutCur2, nCutPrev; + int clk = clock(), clk2, clk2Total = 0; + // create starting one-dimensional placement + vCoOrder = Frc_ManCollectCos( p ); + if ( fRandomize ) + Frc_ManArrayShuffle( vCoOrder ); + nCutStart = Frc_ManPlaceDfsBoth( p, vCoOrder, &nCutCur2 ); + // refine placement + CostPrev = 0.0; + nCutPrev = nCutStart; + pHandles = ABC_ALLOC( int, p->nObjs ); + pVertX = ABC_ALLOC( float, p->nObjs ); + for ( Iter = 0; Iter < nIters; Iter++ ) + { + // compute centers of hyperedges + CostThis = 0.0; + Frc_ManForEachObj( p, pThis, h ) + { + iMinX = iMaxX = pThis->pPlace; + Frc_ObjForEachFanout( pThis, pNext, k ) + { + iMinX = ABC_MIN( iMinX, pNext->pPlace ); + iMaxX = ABC_MAX( iMaxX, pNext->pPlace ); + } + pThis->fEdgeCenter = 0.5 * (iMaxX + iMinX); + CostThis += (iMaxX - iMinX); + } + // compute new centers of objects + Counter = 0; + Frc_ManForEachObj( p, pThis, h ) { - p->pNodes[i].lNode += Gia_ObjEdgeFanin0(p, pObj); - p->pNodes[i].lNode += Gia_ObjEdgeFanin1(p, pObj); - p->pNodes[i].lNode /= 3.0; + VertX = pThis->fEdgeCenter; + Frc_ObjForEachFanin( pThis, pNext, k ) + VertX += pNext->fEdgeCenter; + pVertX[Counter] = VertX / (Frc_ObjFaninNum(pThis) + 1); + pHandles[Counter++] = h; } - else if ( Gia_ObjIsCo(pObj) ) + assert( Counter == Frc_ManObjNum(p) ); + // sort these numbers + clk2 = clock(); + pPermX = Gia_SortFloats( pVertX, pHandles, p->nObjs ); + clk2Total += clock() - clk2; + assert( pPermX == pHandles ); + Vec_IntClear( vCoOrder ); + for ( k = 0; k < p->nObjs; k++ ) { - p->pNodes[i].lNode += Gia_ObjEdgeFanin0(p, pObj); - p->pNodes[i].lNode /= 2.0; + pThis = Frc_ManObj( p, pPermX[k] ); + pThis->pPlace = k; + if ( Frc_ObjIsCo(pThis) ) + Vec_IntPush( vCoOrder, pThis->hHandle ); } +/* + printf( "Ordering of PIs:\n" ); + Frc_ManForEachCi( p, pThis, k ) + printf( "PI number = %7d. Object handle = %7d, Coordinate = %7d.\n", + k, pThis->hHandle, pThis->pPlace ); +*/ + nCutCur = Frc_ManPlaceDfsBoth( p, vCoOrder, &nCutCur2 ); + // evaluate cost + if ( fVerbose ) + { + printf( "%2d : Span = %e ", Iter+1, CostThis ); + printf( "Cut = %6d (%5.2f %%) CutR = %6d ", nCutCur, 100.0*(nCutStart-nCutCur)/nCutStart, nCutCur2 ); + ABC_PRTn( "Total", clock() - clk ); + ABC_PRT( "Sort", clk2Total ); +// Frc_ManCrossCutTest( p, vCoOrder ); + } +// if ( 1.0 * nCutPrev / nCutCur < 1.001 ) +// break; + nCutPrev = nCutCur; } + ABC_FREE( pHandles ); + ABC_FREE( pVertX ); + Vec_IntFree( vCoOrder ); } /**Function************************************************************* - Synopsis [Sorts objects by their new centers.] + Synopsis [Returns 1 if all fanouts are COsw.] Description [] @@ -378,65 +975,56 @@ void For_ManObjCenters( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -int For_ObjCompare( For_Obj_t ** pp0, For_Obj_t ** pp1 ) +int Frc_ObjFanoutsAreCos( Frc_Obj_t * pThis ) { - if ( (*pp0)->lNode < (*pp1)->lNode ) - return -1; - if ( (*pp0)->lNode > (*pp1)->lNode ) - return 1; - return 0; + Frc_Obj_t * pNext; + int i; + Frc_ObjForEachFanout( pThis, pNext, i ) + if ( !Frc_ObjIsCo(pNext) ) + return 0; + return 1; } /**Function************************************************************* - Synopsis [Sorts objects by their new centers.] + Synopsis [Computes the distances from the given set of objects.] - Description [] + Description [Returns one of the most distant objects.] SideEffects [] SeeAlso [] - + ***********************************************************************/ -void For_ManSortObjects( For_Man_t * p ) +void Frc_DumpGraphIntoFile( Frc_Man_t * p ) { - For_Obj_t * pNode, * pPrev; - Vec_Ptr_t * vArray; - int i, k, iPlace; - // link the nodes into lists by cost - memset( p->piRoot, 0xff, sizeof(int) * p->nObjs ); - for ( i = 0; i < p->nObjs; i++ ) + FILE * pFile; + Frc_Obj_t * pThis, * pNext; + int i, k, Counter = 0; + // assign numbers to CIs and internal nodes + Frc_ManForEachObj( p, pThis, i ) { - p->pNodes[i].iObj = i; - iPlace = (int)p->pNodes[i].lNode; - assert( iPlace >= 0 && iPlace < p->nObjs ); - p->piNext[i] = p->piRoot[iPlace]; - p->piRoot[iPlace] = i; + if ( i && ((Frc_ObjIsCi(pThis) && !Frc_ObjFanoutsAreCos(pThis)) || Frc_ObjIsNode(pThis)) ) + pThis->iFanin = Counter++; + else + pThis->iFanin = ~0; } - // reconstruct the order - p->iObj = 0; - pPrev = NULL; - vArray = Vec_PtrAlloc( 100 ); - for ( i = 0; i < p->nObjs; i++ ) + // assign numbers to all other nodes + pFile = fopen( "x\\large\\aig\\dg1.g", "w" ); + Frc_ManForEachObj( p, pThis, i ) { - Vec_PtrClear( vArray ); - for ( k = p->piRoot[i]; ~((unsigned)k); k = p->piNext[k] ) - Vec_PtrPush( vArray, p->pNodes + k ); - Vec_PtrSort( vArray, (int (*)())For_ObjCompare ); - Vec_PtrForEachEntry( vArray, pNode, k ) + Frc_ObjForEachFanout( pThis, pNext, k ) { - p->pPlace[ pNode->iObj ] = p->iObj++; - assert( !pPrev || pPrev->lNode <= pNode->lNode ); - pPrev = pNode; + if ( ~pThis->iFanin && ~pNext->iFanin ) + fprintf( pFile, "%d %d\n", pThis->iFanin, pNext->iFanin ); } } - Vec_PtrFree( vArray ); - assert( p->iObj == p->nObjs ); + fclose( pFile ); } /**Function************************************************************* - Synopsis [] + Synopsis [Experiment with the FORCE algorithm.] Description [] @@ -445,33 +1033,25 @@ void For_ManSortObjects( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManPlaceByForce( For_Man_t * p ) +void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose ) { - int clk, Iter, fUseCut = 1; - double iCostThis, iCostPrev; - iCostThis = fUseCut? For_ManGetMaxCut(p) : For_ManGetEdgeSpan(p); - printf( "Init = %12.0f. \n", iCostThis ); - Iter = 0; - do { - Iter++; - iCostPrev = iCostThis; -clk = clock(); - For_ManEdgeCenters( p ); -//ABC_PRT( "Time", clock() - clk ); -clk = clock(); - For_ManObjCenters( p ); -//ABC_PRT( "Time", clock() - clk ); -clk = clock(); - For_ManSortObjects( p ); -//ABC_PRT( "Time", clock() - clk ); - iCostThis = fUseCut? For_ManGetMaxCut(p) : For_ManGetEdgeSpan(p); - printf( "%4d = %12.0f. \n", Iter, iCostThis ); - } while ( iCostPrev > iCostThis ); + Frc_Man_t * p; + Aig_ManRandom( 1 ); + if ( fClustered ) + p = Frc_ManStart( pGia ); + else + p = Frc_ManStartSimple( pGia ); +// Frc_DumpGraphIntoFile( p ); + if ( fVerbose ) + Frc_ManPrintStats( p ); +// Frc_ManCrossCutTest( p, NULL ); + Frc_ManPlacementRefine( p, nIters, fVerbose ); + Frc_ManStop( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Experiment with the FORCE algorithm.] Description [] @@ -480,51 +1060,40 @@ clk = clock(); SeeAlso [] ***********************************************************************/ -void For_ManExperiment( Gia_Man_t * pGia ) +void For_ManFileExperiment() { - For_Man_t * p; + FILE * pFile; + int * pBuffer; + int i, Size, Exp = 25; int clk = clock(); - p = For_ManStart( pGia ); - Gia_ManCreateRefs( pGia ); - - // use DSF order -clk = clock(); - For_ManSetInitPlaceDfs( p, 0 ); - printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) ); - printf( "Max span = %8d ", For_ManGetMaxCut(p) ); -ABC_PRT( "Time", clock() - clk ); - -clk = clock(); - For_ManPlaceByForce( p ); -ABC_PRT( "Time", clock() - clk ); - // use modified DFS order -clk = clock(); - For_ManSetInitPlaceDfs( p, 1 ); - printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) ); - printf( "Max span = %8d ", For_ManGetMaxCut(p) ); -ABC_PRT( "Time", clock() - clk ); + Size = (1 << Exp); + printf( "2^%d machine words (%d bytes).\n", Exp, sizeof(int) * Size ); -clk = clock(); - For_ManPlaceByForce( p ); -ABC_PRT( "Time", clock() - clk ); + pBuffer = ABC_ALLOC( int, Size ); + for ( i = 0; i < Size; i++ ) + pBuffer[i] = i; +ABC_PRT( "Fillup", clock() - clk ); - // use random order clk = clock(); - For_ManSetInitPlaceRandom( p ); - printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) ); - printf( "Max span = %8d ", For_ManGetMaxCut(p) ); -ABC_PRT( "Time", clock() - clk ); + pFile = fopen( "test.txt", "rb" ); + fread( pBuffer, 1, sizeof(int) * Size, pFile ); + fclose( pFile ); +ABC_PRT( "Read ", clock() - clk ); clk = clock(); - For_ManPlaceByForce( p ); -ABC_PRT( "Time", clock() - clk ); - - For_ManStop( p ); + pFile = fopen( "test.txt", "wb" ); + fwrite( pBuffer, 1, sizeof(int) * Size, pFile ); + fclose( pFile ); +ABC_PRT( "Write ", clock() - clk ); +/* +2^25 machine words (134217728 bytes). +Fillup = 0.06 sec +Read = 0.08 sec +Write = 1.81 sec +*/ } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - +////////////////////////////////////////////////////////////////////////
\ No newline at end of file diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index e6e45cb5..95bffee8 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -68,8 +68,13 @@ void Gia_ManStop( Gia_Man_t * p ) { Vec_IntFree( p->vCis ); Vec_IntFree( p->vCos ); + ABC_FREE( p->pCexComb ); + ABC_FREE( p->pIso ); + ABC_FREE( p->pMapping ); ABC_FREE( p->pFanData ); + ABC_FREE( p->pReprsOld ); ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); ABC_FREE( p->pName ); ABC_FREE( p->pRefs ); ABC_FREE( p->pLevels ); @@ -98,12 +103,16 @@ void Gia_ManPrintStats( Gia_Man_t * p ) printf( "ff =%7d ", Gia_ManRegNum(p) ); printf( "and =%8d ", Gia_ManAndNum(p) ); printf( "lev =%5d ", Gia_ManLevelNum(p) ); -// printf( "cut =%5d ", Gia_ManCrossCut(p) ); + printf( "cut =%5d ", Gia_ManCrossCut(p) ); printf( "mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); // printf( "obj =%5d ", Gia_ManObjNum(p) ); printf( "\n" ); // Gia_ManSatExperiment( p ); + if ( p->pReprs && p->pNexts ) + Gia_ManEquivPrintClasses( p, 0, 0.0 ); + if ( p->pMapping ) + Gia_ManPrintMappingStats( p ); } /**Function************************************************************* diff --git a/src/aig/gia/giaMap.c b/src/aig/gia/giaMap.c new file mode 100644 index 00000000..72bdb001 --- /dev/null +++ b/src/aig/gia/giaMap.c @@ -0,0 +1,305 @@ +/**CFile**************************************************************** + + FileName [giaMap.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Manipulation of mapping associated with the AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "if.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetIfParsDefault( If_Par_t * pPars ) +{ +// extern void * Abc_FrameReadLibLut(); + // set defaults + memset( pPars, 0, sizeof(If_Par_t) ); + // user-controlable paramters +// pPars->nLutSize = -1; + pPars->nLutSize = 6; + pPars->nCutsMax = 8; + pPars->nFlowIters = 1; + pPars->nAreaIters = 2; + pPars->DelayTarget = -1; + pPars->Epsilon = (float)0.005; + pPars->fPreprocess = 1; + pPars->fArea = 0; + pPars->fFancy = 0; + pPars->fExpRed = 1; //// + pPars->fLatchPaths = 0; + pPars->fEdge = 1; + pPars->fPower = 0; + pPars->fCutMin = 0; + pPars->fSeqMap = 0; + pPars->fVerbose = 0; + // internal parameters + pPars->fTruth = 0; + pPars->nLatches = 0; + pPars->fLiftLeaves = 0; +// pPars->pLutLib = Abc_FrameReadLibLut(); + pPars->pLutLib = NULL; + pPars->pTimesArr = NULL; + pPars->pTimesArr = NULL; + pPars->pFuncCost = NULL; +} + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) +{ +// extern Vec_Int_t * SGia_ManComputeSwitchProbs( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ); +// Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL; +// float * pSwitching, * pSwitching2; + If_Man_t * pIfMan; + If_Obj_t * pIfObj; + Gia_Obj_t * pNode; + int i, clk = clock(); + Gia_ManLevelNum( p ); +/* + // set the number of registers (switch activity will be combinational) + Gia_ManSetRegNum( p, 0 ); + if ( pPars->fPower ) + { + vSwitching = SGia_ManComputeSwitchProbs( p, 48, 16, 0 ); + if ( pPars->fVerbose ) + { + ABC_PRT( "Computing switching activity", clock() - clk ); + } + pSwitching = (float *)vSwitching->pArray; + vSwitching2 = Vec_IntStart( Gia_ManObjNumMax(p) ); + pSwitching2 = (float *)vSwitching2->pArray; + } +*/ + // start the mapping manager and set its parameters + pIfMan = If_ManStart( pPars ); +// pIfMan->vSwitching = vSwitching2; + // load the AIG into the mapper + Gia_ManForEachObj( p, pNode, i ) + { + if ( Gia_ObjIsAnd(pNode) ) + pIfObj = If_ManCreateAnd( pIfMan, + If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), + If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); + else if ( Gia_ObjIsCi(pNode) ) + { + pIfObj = If_ManCreateCi( pIfMan ); + If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) ); +// printf( "pi=%d ", pIfObj->Level ); + if ( pIfMan->nLevelMax < (int)pIfObj->Level ) + pIfMan->nLevelMax = (int)pIfObj->Level; + } + else if ( Gia_ObjIsCo(pNode) ) + { + pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); +// printf( "po=%d ", pIfObj->Level ); + } + else if ( Gia_ObjIsConst0(pNode) ) + pIfObj = If_Not(If_ManConst1( pIfMan )); + else // add the node to the mapper + assert( 0 ); + // save the result + assert( Vec_PtrEntry(vAigToIf, i) == NULL ); + Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); +// if ( vSwitching2 ) +// pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; +/* // set up the choice node + if ( Gia_ObjIsChoice( p, pNode ) ) + { + pIfMan->nChoices++; + for ( pPrev = pNode, pFanin = Gia_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Gia_ObjEquiv(p, pFanin) ) + If_ObjSetChoice( pPrev->pData, pFanin->pData ); + If_ManCreateChoice( pIfMan, pNode->pData ); + } +// assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) ); +*/ + } +// if ( vSwitching ) +// Vec_IntFree( vSwitching ); + return pIfMan; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) +{ + int * pMapping, iOffset; + Vec_Ptr_t * vIfToAig; + Gia_Obj_t * pObj, * pObjRepr; + If_Obj_t * pIfObj; + If_Cut_t * pCutBest; + int i, k, j, nLeaves, * ppLeaves; + int nItems = 0; + assert( Gia_ManCiNum(p) == If_ManCiNum(pIfMan) ); + assert( Gia_ManCoNum(p) == If_ManCoNum(pIfMan) ); + assert( Gia_ManAndNum(p) == If_ManAndNum(pIfMan) ); + // create mapping of IF to AIG + vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) ); + Gia_ManForEachObj( p, pObj, i ) + { + pIfObj = Vec_PtrEntry( vAigToIf, i ); + Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj ); + if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) + continue; + nItems += 2 + If_CutLeaveNum( If_ObjCutBest(pIfObj) ); + } + // construct the network + pMapping = ABC_CALLOC( int, Gia_ManObjNum(p) + nItems ); + iOffset = Gia_ManObjNum(p); + Gia_ManForEachObj( p, pObj, i ) + { + pIfObj = Vec_PtrEntry( vAigToIf, i ); + if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) + continue; + pCutBest = If_ObjCutBest( pIfObj ); + nLeaves = If_CutLeaveNum( pCutBest ); + ppLeaves = If_CutLeaves( pCutBest ); + // create node + k = iOffset; + pMapping[k++] = nLeaves; + for ( j = 0; j < nLeaves; j++ ) + { + pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[j] ); + pMapping[k++] = Gia_ObjId( p, pObjRepr ); + } + pMapping[k++] = i; + pMapping[i] = iOffset; + iOffset = k; + } + assert( iOffset <= Gia_ManObjNum(p) + nItems ); + Vec_PtrFree( vIfToAig ); +// pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Interface with the FPGA mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars ) +{ + If_Man_t * pIfMan; + Vec_Ptr_t * vAigToIf; + // set the arrival times + pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) ); + memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) ); + // translate into the mapper + vAigToIf = Vec_PtrStart( Gia_ManObjNum(p) ); + pIfMan = Gia_ManToIf( p, pPars, vAigToIf ); + if ( pIfMan == NULL ) + return 0; +// pIfMan->pManTim = Tim_ManDup( pManTime, 0 ); + if ( !If_ManPerformMapping( pIfMan ) ) + { + If_ManStop( pIfMan ); + return 0; + } + // transform the result of mapping into the new network + ABC_FREE( p->pMapping ); + p->pMapping = Gia_ManFromIf( pIfMan, p, vAigToIf ); +// if ( pPars->fBidec && pPars->nLutSize <= 8 ) +// Gia_ManBidecResyn( pNtk, 0 ); + If_ManStop( pIfMan ); + Vec_PtrFree( vAigToIf ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintMappingStats( Gia_Man_t * p ) +{ + int * pLevels; + int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0; + if ( !p->pMapping ) + return; + pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachGate( p, i ) + { + nLuts++; + nFanins += Gia_ObjGateSize(p, i); + nLutSize = ABC_MAX( nLutSize, Gia_ObjGateSize(p, i) ); + Gia_GateForEachFanin( p, i, iFan, k ) + pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] ); + pLevels[i]++; + LevelMax = ABC_MAX( LevelMax, pLevels[i] ); + } + ABC_FREE( pLevels ); + printf( "mapping : " ); + printf( "%d=lut =%7d ", nLutSize, nLuts ); + printf( "edge =%8d ", nFanins ); + printf( "lev =%5d ", LevelMax ); + printf( "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); + printf( "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c index 3f72b0b9..9058af7d 100644 --- a/src/aig/gia/giaScl.c +++ b/src/aig/gia/giaScl.c @@ -30,7 +30,7 @@ /**Function************************************************************* - Synopsis [Returns the number of unmarked nodes.] + Synopsis [Marks unreachable internal nodes and returned their number.] Description [] @@ -45,13 +45,13 @@ int Gia_ManCombMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) return 0; pObj->fMark0 = 0; assert( Gia_ObjIsAnd(pObj) ); - return Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) + - Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ) + 1; + return 1 + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ); } /**Function************************************************************* - Synopsis [Returns the number of unused nodes.] + Synopsis [Marks unreachable internal nodes and returned their number.] Description [] @@ -90,7 +90,7 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ) /**Function************************************************************* - Synopsis [Marks CIs/COs reachable from POs.] + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] Description [] @@ -99,29 +99,26 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) +int Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) { if ( !pObj->fMark0 ) - return; + return 0; pObj->fMark0 = 0; if ( Gia_ObjIsCo(pObj) ) - { - Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); - return; - } + return Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); if ( Gia_ObjIsRo(p, pObj) ) { Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ObjRoToRi(p, pObj)) ); - return; + return 0; } assert( Gia_ObjIsAnd(pObj) ); - Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); - Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots ); + return 1 + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ) + + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots ); } /**Function************************************************************* - Synopsis [Performs sequential cleanup.] + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] Description [] @@ -130,19 +127,38 @@ void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ) +int Gia_ManSeqMarkUsed( Gia_Man_t * p ) { Vec_Int_t * vRoots; Gia_Obj_t * pObj; - int i; + int i, nNodes = 0; Gia_ManSetMark0( p ); Gia_ManConst0(p)->fMark0 = 0; Gia_ManForEachPi( p, pObj, i ) pObj->fMark0 = 0; + Gia_ManForEachPo( p, pObj, i ) + pObj->fMark0 = 0; vRoots = Gia_ManCollectPoIds( p ); Gia_ManForEachObjVec( vRoots, p, pObj, i ) - Gia_ManSeqMarkUsed_rec( p, pObj, vRoots ); + nNodes += Gia_ManSeqMarkUsed_rec( p, pObj, vRoots ); Vec_IntFree( vRoots ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs sequential cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ) +{ + Gia_ManSeqMarkUsed( p ); return Gia_ManDupMarked( p ); } diff --git a/src/aig/gia/giaSort.c b/src/aig/gia/giaSort.c index aec98fd8..8574297d 100644 --- a/src/aig/gia/giaSort.c +++ b/src/aig/gia/giaSort.c @@ -245,12 +245,15 @@ void minisat_sort3(float* array, int* perm, int size) SeeAlso [] ***********************************************************************/ -int * Gia_SortFloats( float * pArray, int nSize ) +int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ) { - int i, * pPerm; - pPerm = ABC_ALLOC( int, nSize ); - for ( i = 0; i < nSize; i++ ) - pPerm[i] = i; + int i; + if ( pPerm == NULL ) + { + pPerm = ABC_ALLOC( int, nSize ); + for ( i = 0; i < nSize; i++ ) + pPerm[i] = i; + } minisat_sort3( pArray, pPerm, nSize ); // for ( i = 1; i < nSize; i++ ) // assert( pArray[i-1] <= pArray[i] ); diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 64f191f1..cc1a3861 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -300,6 +300,34 @@ void Gia_ManCreateRefs( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Assigns references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManCreateMuxRefs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pCtrl, * pFan0, * pFan1; + int i, * pMuxRefs; + pMuxRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + continue; + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_ObjRecognizeMux( pObj, &pFan0, &pFan1 ); + pMuxRefs[ Gia_ObjId(p, Gia_Regular(pCtrl)) ]++; + } + return pMuxRefs; +} + +/**Function************************************************************* + Synopsis [Computes the maximum frontier size.] Description [] @@ -549,6 +577,45 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob return NULL; } + +/**Function************************************************************* + + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDoubleOuts ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = Aig_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Aig_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + if ( fDoubleOuts ) + RetValue = Gia_ManPo(pAig, 2*p->iPo)->fMark0 ^ Gia_ManPo(pAig, 2*p->iPo+1)->fMark0; + else + RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; + Gia_ManCleanMark0(pAig); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 7a68b554..4410b497 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -5,6 +5,8 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaDfs.c \ src/aig/gia/giaDup.c \ src/aig/gia/giaEmbed.c \ + src/aig/gia/giaEnable.c \ + src/aig/gia/giaEquiv.c \ src/aig/gia/giaFanout.c \ src/aig/gia/giaForce.c \ src/aig/gia/giaFrames.c \ @@ -12,6 +14,7 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaGlitch.c \ src/aig/gia/giaHash.c \ src/aig/gia/giaMan.c \ + src/aig/gia/giaMap.c \ src/aig/gia/giaScl.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSort.c \ diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c index 11c866f4..b81414a5 100644 --- a/src/aig/ioa/ioaReadAig.c +++ b/src/aig/ioa/ioaReadAig.c @@ -341,6 +341,18 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck ) Aig_ManShortNames( pNew ); } */ + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + pCur++; + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Aig_UtilStrsav( pCur ); + } + } // skipping the comments ABC_FREE( pContents ); diff --git a/src/aig/ioa/ioaWriteAig.c b/src/aig/ioa/ioaWriteAig.c index 3d37c0a7..42aa42db 100644 --- a/src/aig/ioa/ioaWriteAig.c +++ b/src/aig/ioa/ioaWriteAig.c @@ -375,10 +375,10 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int } */ // write the comment - fprintf( pFile, "c\n" ); + fprintf( pFile, "c" ); if ( pMan->pName ) - fprintf( pFile, ".model %s\n", pMan->pName ); - fprintf( pFile, "This file was produced by the AIG package on %s\n", Ioa_TimeStamp() ); + fprintf( pFile, "n%s%c", pMan->pName, '\0' ); + fprintf( pFile, "\nThis file was produced by the IOA package in ABC on %s\n", Ioa_TimeStamp() ); fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); fclose( pFile ); } diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 174a3e97..71bdadf6 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -568,13 +568,17 @@ int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** printf( "The output number %d of the miter is constant 1.\n", i ); Counter++; continue; - } + } if ( !Aig_ObjIsNode(pFanin) || !Aig_ObjRecognizeExor( pFanin, &pObj0, &pObj1 ) ) { +/* printf( "The miter cannot be demitered.\n" ); Vec_PtrFree( vSet0 ); Vec_PtrFree( vSet1 ); return 0; +*/ + printf( "The output number %d cannot be demitered.\n", i ); + continue; } if ( Aig_ObjFaninC0(pObj) ) pObj0 = Aig_Not(pObj0); diff --git a/src/aig/ssw/sswCore.c b/src/aig/ssw/sswCore.c index 16430ace..9d09d4e7 100644 --- a/src/aig/ssw/sswCore.c +++ b/src/aig/ssw/sswCore.c @@ -179,7 +179,8 @@ clk = clock(); printf( "Cex =%5d. ", p->nSatCallsSat-nSatCallsSat ); printf( "R =%4d. ", p->nRecycles-nRecycles ); } - printf( "F =%5d. ", p->nSatFailsReal-nSatFailsReal ); + printf( "F =%5d. %s ", p->nSatFailsReal-nSatFailsReal, + (Saig_ManPoNum(p->pAig)==1 && Ssw_ObjIsConst1Cand(p->pAig,Aig_ObjFanin0(Aig_ManPo(p->pAig,0))))? "+" : "-" ); ABC_PRT( "T", clock() - clk ); } // if ( p->pPars->fDynamic && p->nSatCallsSat-nSatCallsSat < 100 ) |