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 | |
parent | c03f9b516bed2c06ec2bfc78617eba5fc9a11c32 (diff) | |
download | abc-32314347bae6ddcd841a268e797ec4da45726abb.tar.gz abc-32314347bae6ddcd841a268e797ec4da45726abb.tar.bz2 abc-32314347bae6ddcd841a268e797ec4da45726abb.zip |
Version abc90310
Diffstat (limited to 'src')
66 files changed, 8677 insertions, 1793 deletions
diff --git a/src/aig/bbl/bblif.c b/src/aig/bbl/bblif.c new file mode 100644 index 00000000..adc10b28 --- /dev/null +++ b/src/aig/bbl/bblif.c @@ -0,0 +1,1511 @@ +/**CFile**************************************************************** + + FileName [bblif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Binary BLIF representation for logic networks.] + + Synopsis [Main implementation module.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 28, 2009.] + + Revision [$Id: bblif.c,v 1.00 2009/02/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <time.h> + +#include "bblif.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// vector of integers +typedef struct Vec_Int_t_ Vec_Int_t; +struct Vec_Int_t_ +{ + int nCap; + int nSize; + int * pArray; +}; + +// vector of characters +typedef struct Vec_Str_t_ Vec_Str_t; +struct Vec_Str_t_ +{ + int nCap; + int nSize; + char * pArray; +}; + +// network object +struct Bbl_Obj_t_ +{ + int Id; // user ID + int Fnc; // functionality + unsigned fCi : 1; // combinational input + unsigned fCo : 1; // combinational output + unsigned fBox : 1; // subcircuit + unsigned fMark : 1; // temporary mark + unsigned nFanins : 28; // fanin number + int pFanins[0]; // fanin array +}; + +// object function +typedef struct Bbl_Fnc_t_ Bbl_Fnc_t; +struct Bbl_Fnc_t_ +{ + int nWords; // word number + int pWords[0]; // word array +}; + +// object function +typedef struct Bbl_Ent_t_ Bbl_Ent_t; +struct Bbl_Ent_t_ +{ + int iFunc; // function handle + int iNext; // next entry handle +}; + +// data manager +struct Bbl_Man_t_ +{ + // data pool + Vec_Str_t * pName; // design name + Vec_Str_t * pObjs; // vector of objects + Vec_Str_t * pFncs; // vector of functions + // construction + Vec_Int_t * vId2Obj; // mapping user IDs into objects + Vec_Int_t * vObj2Id; // mapping objects into user IDs + Vec_Int_t * vFaninNums; // mapping user IDs into fanin number + // file contents + int nFileSize; // file size + char * pFileData; // file contents + // other data + Vec_Str_t * pEnts; // vector of entries + int SopMap[17][17]; // mapping vars x cubes into entry handles +}; + +static inline int Bbl_ObjIsCi( Bbl_Obj_t * pObj ) { return pObj->fCi; } +static inline int Bbl_ObjIsCo( Bbl_Obj_t * pObj ) { return pObj->fCo; } +static inline int Bbl_ObjIsNode( Bbl_Obj_t * pObj ) { return!pObj->fCi && !pObj->fCo; } + +static inline int Bbl_ObjFaninNum( Bbl_Obj_t * pObj ) { return pObj->nFanins; } +static inline Bbl_Obj_t * Bbl_ObjFanin( Bbl_Obj_t * pObj, int i ) { return (Bbl_Obj_t *)(((char *)pObj) - pObj->pFanins[i]); } + +static inline int Bbl_ObjSize( Bbl_Obj_t * pObj ) { return sizeof(Bbl_Obj_t) + sizeof(int) * pObj->nFanins; } +static inline int Bbl_FncSize( Bbl_Fnc_t * pFnc ) { return sizeof(Bbl_Fnc_t) + sizeof(int) * pFnc->nWords; } + +static inline Bbl_Obj_t * Bbl_VecObj( Vec_Str_t * p, int h ) { return (Bbl_Obj_t *)(p->pArray + h); } +static inline Bbl_Fnc_t * Bbl_VecFnc( Vec_Str_t * p, int h ) { return (Bbl_Fnc_t *)(p->pArray + h); } +static inline Bbl_Ent_t * Bbl_VecEnt( Vec_Str_t * p, int h ) { return (Bbl_Ent_t *)(p->pArray + h); } + +static inline char * Bbl_ManSop( Bbl_Man_t * p, int h ) { return (char *)Bbl_VecFnc(p->pFncs, h)->pWords; } +static inline Bbl_Obj_t * Bbl_ManObj( Bbl_Man_t * p, int Id ) { return Bbl_VecObj(p->pObjs, p->vId2Obj->pArray[Id]); } + +#define Bbl_ManForEachObj_int( p, pObj, h ) \ + for ( h = 0; (h < p->nSize) && (pObj = Bbl_VecObj(p,h)); h += Bbl_ObjSize(pObj) ) +#define Bbl_ManForEachFnc_int( p, pObj, h ) \ + for ( h = 0; (h < p->nSize) && (pObj = Bbl_VecFnc(p,h)); h += Bbl_FncSize(pObj) ) +#define Bbl_ObjForEachFanin_int( pObj, pFanin, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pFanin = Bbl_ObjFanin(pObj,i)); i++ ) + +#define BBLIF_ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) +#define BBLIF_CALLOC(type, num) ((type *) calloc((num), sizeof(type))) +#define BBLIF_FALLOC(type, num) ((type *) memset(malloc(sizeof(type) * (num)), 0xff, sizeof(type) * (num))) +#define BBLIF_FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#define BBLIF_REALLOC(type, obj, num) \ + ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num)))) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAlloc( int nCap ) +{ + Vec_Int_t * p; + p = BBLIF_ALLOC( Vec_Int_t, 1 ); + if ( nCap > 0 && nCap < 16 ) + nCap = 16; + p->nSize = 0; + p->nCap = nCap; + p->pArray = p->nCap? BBLIF_ALLOC( int, p->nCap ) : NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntStart( int nSize ) +{ + Vec_Int_t * p; + p = Vec_IntAlloc( nSize ); + p->nSize = nSize; + memset( p->pArray, 0, sizeof(int) * nSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntStartNatural( int nSize ) +{ + Vec_Int_t * p; + int i; + p = Vec_IntAlloc( nSize ); + p->nSize = nSize; + for ( i = 0; i < nSize; i++ ) + p->pArray[i] = i; + return p; +} + +/**Function************************************************************* + + Synopsis [Creates the vector from an integer array of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize ) +{ + Vec_Int_t * p; + p = BBLIF_ALLOC( Vec_Int_t, 1 ); + p->nSize = nSize; + p->nCap = nSize; + p->pArray = pArray; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntFree( Vec_Int_t * p ) +{ + BBLIF_FREE( p->pArray ); + BBLIF_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntSize( Vec_Int_t * p ) +{ + return p->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntEntry( Vec_Int_t * p, int i ) +{ + assert( i >= 0 && i < p->nSize ); + return p->pArray[i]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry ) +{ + assert( i >= 0 && i < p->nSize ); + p->pArray[i] = Entry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition ) +{ + assert( i >= 0 && i < p->nSize ); + p->pArray[i] += Addition; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntEntryLast( Vec_Int_t * p ) +{ + assert( p->nSize > 0 ); + return p->pArray[p->nSize-1]; +} + +/**Function************************************************************* + + Synopsis [Resizes the vector to the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin ) +{ + if ( p->nCap >= nCapMin ) + return; + p->pArray = BBLIF_REALLOC( int, p->pArray, nCapMin ); + assert( p->pArray ); + p->nCap = nCapMin; +} + +/**Function************************************************************* + + Synopsis [Fills the vector with given number of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Fill ) +{ + int i; + Vec_IntGrow( p, nSize ); + for ( i = 0; i < nSize; i++ ) + p->pArray[i] = Fill; + p->nSize = nSize; +} + +/**Function************************************************************* + + Synopsis [Fills the vector with given number of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill ) +{ + int i; + if ( p->nSize >= nSize ) + return; + if ( nSize < 2 * p->nSize ) + nSize = 2 * p->nSize; + Vec_IntGrow( p, nSize ); + for ( i = p->nSize; i < nSize; i++ ) + p->pArray[i] = Fill; + p->nSize = nSize; +} + +/**Function************************************************************* + + Synopsis [Returns the entry even if the place not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntGetEntry( Vec_Int_t * p, int i ) +{ + Vec_IntFillExtra( p, i + 1, 0 ); + return Vec_IntEntry( p, i ); +} + +/**Function************************************************************* + + Synopsis [Inserts the entry even if the place does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntSetEntry( Vec_Int_t * p, int i, int Entry ) +{ + Vec_IntFillExtra( p, i + 1, 0 ); + Vec_IntWriteEntry( p, i, Entry ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew ) +{ + assert( p->nSize >= nSizeNew ); + p->nSize = nSizeNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntClear( Vec_Int_t * p ) +{ + p->nSize = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntPush( Vec_Int_t * p, int Entry ) +{ + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_IntGrow( p, 16 ); + else + Vec_IntGrow( p, 2 * p->nCap ); + } + p->pArray[p->nSize++] = Entry; +} + + + + + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAlloc( int nCap ) +{ + Vec_Str_t * p; + p = BBLIF_ALLOC( Vec_Str_t, 1 ); + if ( nCap > 0 && nCap < 16 ) + nCap = 16; + p->nSize = 0; + p->nCap = nCap; + p->pArray = p->nCap? BBLIF_ALLOC( char, p->nCap ) : NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [Creates the vector from an array of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize ) +{ + Vec_Str_t * p; + p = BBLIF_ALLOC( Vec_Str_t, 1 ); + p->nSize = nSize; + p->nCap = nSize; + p->pArray = pArray; + return p; +} + +/**Fnction************************************************************* + + Synopsis [Returns a piece of memory.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Vec_StrFetch( Vec_Str_t * p, int nBytes ) +{ + while ( p->nSize + nBytes > p->nCap ) + { + p->pArray = BBLIF_REALLOC( char, p->pArray, 3 * p->nCap ); + p->nCap *= 3; + } + p->nSize += nBytes; + return p->pArray + p->nSize - nBytes; +} + +/**Fnction************************************************************* + + Synopsis [Write vector into file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vec_StrWrite( FILE * pFile, Vec_Str_t * p ) +{ + fwrite( &p->nSize, sizeof(int), 1, pFile ); + fwrite( p->pArray, sizeof(char), p->nSize, pFile ); +} + +/**Fnction************************************************************* + + Synopsis [Write vector into file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Vec_StrRead( char ** ppStr ) +{ + Vec_Str_t * p; + char * pStr = *ppStr; + p = Vec_StrAlloc( 0 ); + p->nSize = *(int *)pStr; + p->pArray = pStr + sizeof(int); + *ppStr = pStr + sizeof(int) + p->nSize * sizeof(char); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_StrSize( Vec_Str_t * p ) +{ + return p->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_StrFree( Vec_Str_t * p ) +{ + BBLIF_FREE( p->pArray ); + BBLIF_FREE( p ); +} + + + + + +/**Fnction************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManFileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Bbl_ManFileSize(): The file is unavailable (absent or open).\n" ); + return 0; + } + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + fclose( pFile ); + return nFileSize; +} + +/**Fnction************************************************************* + + Synopsis [Read data from file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManFileRead( char * pFileName ) +{ + FILE * pFile; + char * pContents; + int nFileSize; + nFileSize = Bbl_ManFileSize( pFileName ); + pFile = fopen( pFileName, "rb" ); + pContents = BBLIF_ALLOC( char, nFileSize ); + fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + return pContents; +} + + + +/**Fnction************************************************************* + + Synopsis [Writes data into file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName ) +{ + FILE * pFile; + pFile = fopen( pFileName, "wb" ); + Vec_StrWrite( pFile, p->pName ); + Vec_StrWrite( pFile, p->pObjs ); + Vec_StrWrite( pFile, p->pFncs ); + fclose( pFile ); +} + +/**Fnction************************************************************* + + Synopsis [Creates manager after reading.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName ) +{ + Bbl_Man_t * p; + Bbl_Obj_t * pObj; + char * pBuffer; + int h; + p = BBLIF_ALLOC( Bbl_Man_t, 1 ); + memset( p, 0, sizeof(Bbl_Man_t) ); + p->nFileSize = Bbl_ManFileSize( pFileName ); + p->pFileData = Bbl_ManFileRead( pFileName ); + // extract three managers + pBuffer = p->pFileData; + p->pName = Vec_StrRead( &pBuffer ); + p->pObjs = Vec_StrRead( &pBuffer ); + p->pFncs = Vec_StrRead( &pBuffer ); + assert( pBuffer - p->pFileData == p->nFileSize ); + // remember original IDs in the objects + p->vObj2Id = Vec_IntAlloc( 1000 ); + Bbl_ManForEachObj_int( p->pObjs, pObj, h ) + { + Vec_IntPush( p->vObj2Id, pObj->Id ); + pObj->Id = Vec_IntSize(p->vObj2Id) - 1; + } + return p; +} + +/**Fnction************************************************************* + + Synopsis [Prints stats of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManPrintStats( Bbl_Man_t * p ) +{ + Bbl_Obj_t * pObj; + Bbl_Fnc_t * pFnc; + int h, nFuncs = 0, nNodes = 0, nObjs = 0; + Bbl_ManForEachObj_int( p->pObjs, pObj, h ) + nObjs++, nNodes += Bbl_ObjIsNode(pObj); + Bbl_ManForEachFnc_int( p->pFncs, pFnc, h ) + nFuncs++; + printf( "Total objects = %7d. Total nodes = %7d. Unique functions = %7d.\n", nObjs, nNodes, nFuncs ); + printf( "Name manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pName)/(1 << 20) ); + printf( "Objs manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pObjs)/(1 << 20) ); + printf( "Fncs manager = %5.2f Mb\n", 1.0*Vec_StrSize(p->pFncs)/(1 << 20) ); +} + +/**Fnction************************************************************* + + Synopsis [Deletes the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManStop( Bbl_Man_t * p ) +{ + if ( p->vId2Obj ) Vec_IntFree( p->vId2Obj ); + if ( p->vObj2Id ) Vec_IntFree( p->vObj2Id ); + if ( p->vFaninNums ) Vec_IntFree( p->vFaninNums ); + if ( p->pFileData ) + { + BBLIF_FREE( p->pFileData ); + p->pName->pArray = NULL; + p->pObjs->pArray = NULL; + p->pFncs->pArray = NULL; + } + if ( p->pEnts ) + Vec_StrFree( p->pEnts ); + Vec_StrFree( p->pName ); + Vec_StrFree( p->pObjs ); + Vec_StrFree( p->pFncs ); + BBLIF_FREE( p ); +} + +/**Fnction************************************************************* + + Synopsis [Creates manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Man_t * Bbl_ManStart( char * pName ) +{ + Bbl_Man_t * p; + int nLength; + p = BBLIF_ALLOC( Bbl_Man_t, 1 ); + memset( p, 0, sizeof(Bbl_Man_t) ); + nLength = pName? 4 * ((strlen(pName) + 1) / 4 + 1) : 0; + p->pName = Vec_StrAlloc( nLength ); + p->pName->nSize = p->pName->nCap; + if ( pName ) + strcpy( p->pName->pArray, pName ); + p->pObjs = Vec_StrAlloc( 1 << 16 ); + p->pFncs = Vec_StrAlloc( 1 << 16 ); + p->pEnts = Vec_StrAlloc( 1 << 16 ); p->pEnts->nSize = 1; + p->vId2Obj = Vec_IntStart( 1 << 10 ); + p->vFaninNums = Vec_IntStart( 1 << 10 ); + return p; +} + + + + +/**Function************************************************************* + + Synopsis [Performs selection sort on the array of cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManSortCubes( char ** pCubes, int nCubes, int nVars ) +{ + char * pTemp; + int i, j, best_i; + for ( i = 0; i < nCubes-1; i++ ) + { + best_i = i; + for (j = i+1; j < nCubes; j++) + if ( memcmp( pCubes[j], pCubes[best_i], nVars ) < 0 ) + best_i = j; + pTemp = pCubes[i]; pCubes[i] = pCubes[best_i]; pCubes[best_i] = pTemp; + } +} + +/**Function************************************************************* + + Synopsis [Sorts the cubes in the SOP to uniqify them to some extent.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManSortSop( char * pSop, int nVars ) +{ + char ** pCubes, * pSopNew; + int c, Length, nCubes; + Length = strlen(pSop); + assert( Length % (nVars + 3) == 0 ); + nCubes = Length / (nVars + 3); + if ( nCubes < 2 ) + { + pSopNew = BBLIF_ALLOC( char, Length + 1 ); + memcpy( pSopNew, pSop, Length + 1 ); + return pSopNew; + } + pCubes = BBLIF_ALLOC( char *, nCubes ); + for ( c = 0; c < nCubes; c++ ) + pCubes[c] = pSop + c * (nVars + 3); + if ( nCubes < 300 ) + Bbl_ManSortCubes( pCubes, nCubes, nVars ); + pSopNew = BBLIF_ALLOC( char, Length + 1 ); + for ( c = 0; c < nCubes; c++ ) + memcpy( pSopNew + c * (nVars + 3), pCubes[c], nVars + 3 ); + BBLIF_FREE( pCubes ); + pSopNew[nCubes * (nVars + 3)] = 0; + return pSopNew; +} + +/**Fnction************************************************************* + + Synopsis [Saves one entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManCreateEntry( Bbl_Man_t * p, int iFunc, int iNext ) +{ + Bbl_Ent_t * pEnt; + pEnt = (Bbl_Ent_t *)Vec_StrFetch( p->pEnts, 2 * sizeof(int) ); + pEnt->iFunc = iFunc; + pEnt->iNext = iNext; + return (char *)pEnt - p->pEnts->pArray; +} + +/**Function************************************************************* + + Synopsis [Sorts the cubes in the SOP to uniqify them to some extent.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManSopCheckUnique( Bbl_Man_t * p, char * pSop, int nVars, int nCubes, int iFunc ) +{ + Bbl_Fnc_t * pFnc; + Bbl_Ent_t * pEnt; + int h, Length = strlen(pSop) + 1; + int nWords = (Length / 4 + (Length % 4 > 0)); + if ( nVars > 16 ) nVars = 16; + if ( nCubes > 16 ) nCubes = 16; +// if ( nVars == 16 && nCubes == 16 ) +// return iFunc; + for ( h = p->SopMap[nVars][nCubes]; h; h = pEnt->iNext ) + { + pEnt = Bbl_VecEnt( p->pEnts, h ); + pFnc = Bbl_VecFnc( p->pFncs, pEnt->iFunc ); + assert( nVars == 16 || nCubes == 16 || pFnc->nWords == nWords ); + if ( pFnc->nWords == nWords && memcmp( pFnc->pWords, pSop, Length ) == 0 ) + return pEnt->iFunc; + } + p->SopMap[nVars][nCubes] = Bbl_ManCreateEntry( p, iFunc, p->SopMap[nVars][nCubes] ); + return iFunc; +} + +/**Fnction************************************************************* + + Synopsis [Saves one SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManSaveSop( Bbl_Man_t * p, char * pSop, int nVars ) +{ + Bbl_Fnc_t * pFnc; + char * pSopNew; + int iFunc, Length = strlen(pSop) + 1; + int nWords = Length / 4 + (Length % 4 > 0); + // reorder cubes to semi-canicize SOPs + pSopNew = Bbl_ManSortSop( pSop, nVars ); + // get the candidate location + iFunc = Bbl_ManSopCheckUnique( p, pSopNew, nVars, Length / (nVars + 3), Vec_StrSize(p->pFncs) ); +// iFunc = Vec_StrSize(p->pFncs); + if ( iFunc == Vec_StrSize(p->pFncs) ) + { // store this SOP + pFnc = (Bbl_Fnc_t *)Vec_StrFetch( p->pFncs, sizeof(Bbl_Fnc_t) + nWords * sizeof(int) ); + pFnc->pWords[nWords-1] = 0; + pFnc->nWords = nWords; + strcpy( (char *)pFnc->pWords, pSopNew ); + assert( iFunc == (char *)pFnc - p->pFncs->pArray ); + } + BBLIF_FREE( pSopNew ); + return iFunc; +} + +/**Fnction************************************************************* + + Synopsis [Adds one object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop ) +{ + Bbl_Obj_t * pObj; + if ( Type == BBL_OBJ_CI && nFanins != 0 ) + { + printf( "Attempting to create a combinational input with %d fanins (should be 0).\n", nFanins ); + return; + } + if ( Type == BBL_OBJ_CO && nFanins != 1 ) + { + printf( "Attempting to create a combinational output with %d fanins (should be 1).\n", nFanins ); + return; + } + pObj = (Bbl_Obj_t *)Vec_StrFetch( p->pObjs, sizeof(Bbl_Obj_t) + nFanins * sizeof(int) ); + memset( pObj, 0, sizeof(Bbl_Obj_t) ); + Vec_IntSetEntry( p->vId2Obj, ObjId, (char *)pObj - p->pObjs->pArray ); + Vec_IntSetEntry( p->vFaninNums, ObjId, 0 ); + pObj->fCi = (Type == BBL_OBJ_CI); + pObj->fCo = (Type == BBL_OBJ_CO); + pObj->Id = ObjId; + pObj->Fnc = pSop? Bbl_ManSaveSop(p, pSop, nFanins) : -1; + pObj->nFanins = nFanins; +} + +/**Fnction************************************************************* + + Synopsis [Creates fanin/fanout relationship between two objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId ) +{ + Bbl_Obj_t * pObj, * pFanin; + int iFanin; + pObj = Bbl_ManObj( p, ObjId ); + if ( Bbl_ObjIsCi(pObj) ) + { + printf( "Bbl_ManAddFanin(): Cannot add fanin of the combinational input (Id = %d).\n", ObjId ); + return; + } + pFanin = Bbl_ManObj( p, FaninId ); + if ( Bbl_ObjIsCo(pFanin) ) + { + printf( "Bbl_ManAddFanin(): Cannot add fanout of the combinational output (Id = %d).\n", FaninId ); + return; + } + iFanin = Vec_IntEntry( p->vFaninNums, ObjId ); + if ( iFanin >= (int)pObj->nFanins ) + { + printf( "Bbl_ManAddFanin(): Trying to add more fanins to object (Id = %d) than declared (%d).\n", ObjId, pObj->nFanins ); + return; + } + assert( iFanin < (int)pObj->nFanins ); + Vec_IntWriteEntry( p->vFaninNums, ObjId, iFanin+1 ); + pObj->pFanins[iFanin] = (char *)pObj - (char *)pFanin; +} + + +/**Fnction************************************************************* + + Synopsis [Returns 1 if the manager was created correctly.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManCheck( Bbl_Man_t * p ) +{ + Bbl_Obj_t * pObj; + int h, RetValue = 1; + Bbl_ManForEachObj_int( p->pObjs, pObj, h ) + { + if ( Bbl_ObjIsNode(pObj) && pObj->Fnc == -1 ) + RetValue = 0, printf( "Bbl_ManCheck(): Node %d does not have function specified.\n", pObj->Id ); + if ( Bbl_ObjIsCi(pObj) && pObj->Fnc != -1 ) + RetValue = 0, printf( "Bbl_ManCheck(): CI with %d has function specified.\n", pObj->Id ); + if ( Bbl_ObjIsCo(pObj) && pObj->Fnc != -1 ) + RetValue = 0, printf( "Bbl_ManCheck(): CO with %d has function specified.\n", pObj->Id ); + if ( Vec_IntEntry(p->vFaninNums, pObj->Id) != (int)pObj->nFanins ) + RetValue = 0, printf( "Bbl_ManCheck(): Object %d has less fanins (%d) than declared (%d).\n", + pObj->Id, Vec_IntEntry(p->vFaninNums, pObj->Id), pObj->nFanins ); + } + return RetValue; +} + + +/**Fnction************************************************************* + + Synopsis [Misc APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ObjIsInput( Bbl_Obj_t * p ) { return Bbl_ObjIsCi(p); } +int Bbl_ObjIsOutput( Bbl_Obj_t * p ) { return Bbl_ObjIsCo(p); } +int Bbl_ObjIsLut( Bbl_Obj_t * p ) { return Bbl_ObjIsNode(p); } +int Bbl_ObjId( Bbl_Obj_t * p ) { return p->Id; } +int Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p ) { assert(0); return Vec_IntEntry(pMan->vObj2Id, p->Id); } +int Bbl_ObjFaninNumber( Bbl_Obj_t * p ) { return Bbl_ObjFaninNum(p); } +char * Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p ) { return Bbl_ManSop(pMan, p->Fnc); } +int Bbl_ObjIsMarked( Bbl_Obj_t * p ) { return p->fMark; } +void Bbl_ObjMark( Bbl_Obj_t * p ) { p->fMark = 1; } +int Bbl_ObjFncHandle( Bbl_Obj_t * p ) { return p->Fnc; } + +/**Fnction************************************************************* + + Synopsis [Returns the name of the design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManName( Bbl_Man_t * p ) +{ + return p->pName->pArray; +} + +/**Fnction************************************************************* + + Synopsis [Returns the maximum handle of the SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bbl_ManFncSize( Bbl_Man_t * p ) +{ + return p->pFncs->nSize; +} + +/**Fnction************************************************************* + + Synopsis [Returns the first object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p ) +{ + return Bbl_VecObj( p->pObjs, 0 ); +} + +/**Fnction************************************************************* + + Synopsis [Returns the next object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj ) +{ + char * pNext = (char *)pObj + Bbl_ObjSize(pObj); + char * pEdge = p->pObjs->pArray + p->pObjs->nSize; + return (Bbl_Obj_t *)(pNext < pEdge ? pNext : NULL); +} + +/**Fnction************************************************************* + + Synopsis [Returns the first fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p ) +{ + return Bbl_ObjFaninNum(p) ? Bbl_ObjFanin( p, 0 ) : NULL; +} + +/**Fnction************************************************************* + + Synopsis [Returns the next fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev ) +{ + Bbl_Obj_t * pFanin; + int i; + Bbl_ObjForEachFanin_int( p, pFanin, i ) + if ( pFanin == pPrev ) + break; + return i < Bbl_ObjFaninNum(p) - 1 ? Bbl_ObjFanin( p, i+1 ) : NULL; +} + +/**Fnction************************************************************* + + Synopsis [Drives text BLIF file for debugging.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName ) +{ + FILE * pFile; + Bbl_Obj_t * pObj, * pFanin; + pFile = fopen( pFileName, "w" ); + fprintf( pFile, "# Test file written by Bbl_ManDumpBlif() in ABC.\n" ); + fprintf( pFile, ".model %s\n", Bbl_ManName(p) ); + // write objects + Bbl_ManForEachObj( p, pObj ) + { + if ( Bbl_ObjIsInput(pObj) ) + fprintf( pFile, ".inputs %d\n", Bbl_ObjId(pObj) ); + else if ( Bbl_ObjIsOutput(pObj) ) + fprintf( pFile, ".outputs %d\n", Bbl_ObjId(pObj) ); + else if ( Bbl_ObjIsLut(pObj) ) + { + fprintf( pFile, ".names" ); + Bbl_ObjForEachFanin( pObj, pFanin ) + fprintf( pFile, " %d", Bbl_ObjId(pFanin) ); + fprintf( pFile, " %d\n", Bbl_ObjId(pObj) ); + fprintf( pFile, "%s", Bbl_ObjSop(p, pObj) ); + } + else assert( 0 ); + } + // write output drivers + Bbl_ManForEachObj( p, pObj ) + { + if ( !Bbl_ObjIsOutput(pObj) ) + continue; + fprintf( pFile, ".names" ); + Bbl_ObjForEachFanin( pObj, pFanin ) + fprintf( pFile, " %d", Bbl_ObjId(pFanin) ); + fprintf( pFile, " %d\n", Bbl_ObjId(pObj) ); + fprintf( pFile, "1 1\n" ); + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +/**Fnction************************************************************* + + Synopsis [Converting truth table into an SOP.] + + Description [The truth table is given as a bit-string pTruth + composed of 2^nVars bits. The result is an SOP derived by + collecting minterms appearing in the truth table. The SOP is + represented as a C-string, as documented in file "bblif.h". + It is recommended to limit the use of this procedure to Boolean + functions up to 6 inputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Bbl_ManTruthToSop( unsigned * pTruth, int nVars ) +{ + char * pResult, * pTemp; + int nMints, nOnes, b, v; + assert( nVars >= 0 && nVars <= 16 ); + nMints = (1 << nVars); + // count the number of ones + nOnes = 0; + for ( b = 0; b < nMints; b++ ) + nOnes += ((pTruth[b>>5] >> (b&31)) & 1); + // handle constants + if ( nOnes == 0 || nOnes == nMints ) + { + pResult = pTemp = BBLIF_ALLOC( char, nVars + 4 ); + for ( v = 0; v < nVars; v++ ) + *pTemp++ = '-'; + *pTemp++ = ' '; + *pTemp++ = nOnes? '1' : '0'; + *pTemp++ = '\n'; + *pTemp++ = 0; + assert( pTemp - pResult == nVars + 4 ); + return pResult; + } + pResult = pTemp = BBLIF_ALLOC( char, nOnes * (nVars + 3) + 1 ); + for ( b = 0; b < nMints; b++ ) + { + if ( ((pTruth[b>>5] >> (b&31)) & 1) == 0 ) + continue; + for ( v = 0; v < nVars; v++ ) + *pTemp++ = ((b >> v) & 1)? '1' : '0'; + *pTemp++ = ' '; + *pTemp++ = '1'; + *pTemp++ = '\n'; + } + *pTemp++ = 0; + assert( pTemp - pResult == nOnes * (nVars + 3) + 1 ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Allocates the array of truth tables for the given number of vars.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Bbl_ManSopToTruthElem( int nVars, unsigned ** pVars ) +{ + unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; + int i, k, nWords; + nWords = (nVars <= 5 ? 1 : (1 << (nVars - 5))); + for ( i = 0; i < nVars; i++ ) + { + if ( i < 5 ) + { + for ( k = 0; k < nWords; k++ ) + pVars[i][k] = Masks[i]; + } + else + { + for ( k = 0; k < nWords; k++ ) + if ( k & (1 << (i-5)) ) + pVars[i][k] = ~(unsigned)0; + else + pVars[i][k] = 0; + } + } +} + +/**Fnction************************************************************* + + Synopsis [Converting SOP into a truth table.] + + Description [The SOP is represented as a C-string, as documented in + file "bblif.h". The truth table is returned as a bit-string composed + of 2^nVars bits. For functions of less than 6 variables, the full + machine word is returned. (The truth table looks as if the function + had 5 variables.) The use of this procedure should be limited to + Boolean functions with no more than 16 inputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Bbl_ManSopToTruth( char * pSop, int nVars ) +{ + unsigned * pTruth, * pCube, * pVars[16]; + int nWords = nVars <= 5 ? 1 : (1 << (nVars - 5)); + int v, c, w, nCubes, fCompl = 0; + if ( pSop == NULL ) + return NULL; + if ( strlen(pSop) % (nVars + 3) != 0 ) + { + printf( "Bbl_ManSopToTruth(): SOP is represented incorrectly.\n" ); + return NULL; + } + // create storage for TTs of the result, elementary variables and the temp cube + pTruth = BBLIF_ALLOC( unsigned, nWords ); + pVars[0] = BBLIF_ALLOC( unsigned, nWords * (nVars+1) ); + for ( v = 1; v < nVars; v++ ) + pVars[v] = pVars[v-1] + nWords; + pCube = pVars[v-1] + nWords; + Bbl_ManSopToTruthElem( nVars, pVars ); + // iterate through the cubes + memset( pTruth, 0, sizeof(unsigned) * nWords ); + nCubes = strlen(pSop) / (nVars + 3); + for ( c = 0; c < nCubes; c++ ) + { + fCompl = (pSop[nVars+1] == '0'); + memset( pCube, 0xff, sizeof(unsigned) * nWords ); + // iterate through the literals of the cube + for ( v = 0; v < nVars; v++ ) + if ( pSop[v] == '1' ) + for ( w = 0; w < nWords; w++ ) + pCube[w] &= pVars[v][w]; + else if ( pSop[v] == '0' ) + for ( w = 0; w < nWords; w++ ) + pCube[w] &= ~pVars[v][w]; + // add cube to storage + for ( w = 0; w < nWords; w++ ) + pTruth[w] |= pCube[w]; + // go to the next cube + pSop += (nVars + 3); + } + BBLIF_FREE( pVars[0] ); + if ( fCompl ) + for ( w = 0; w < nWords; w++ ) + pTruth[w] = ~pTruth[w]; + return pTruth; +} + + +/**Fnction************************************************************* + + Synopsis [Checks the truth table computation.] + + Description [We construct the logic network for the half-adder represnted + using the BLIF file below] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManTestTruth( char * pSop, int nVars ) +{ + unsigned * pTruth; + char * pSopNew; + pTruth = Bbl_ManSopToTruth( pSop, nVars ); + pSopNew = Bbl_ManTruthToSop( pTruth, nVars ); + printf( "Old SOP:\n%s\n", pSop ); + printf( "New SOP:\n%s\n", pSopNew ); + BBLIF_FREE( pSopNew ); + BBLIF_FREE( pTruth ); +} + +/**Fnction************************************************************* + + Synopsis [This demo shows using the internal to construct a half-adder.] + + Description [We construct the logic network for the half-adder represnted + using the BLIF file below] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManSimpleDemo() +{ +/* + # There are contents of a BLIF file representing a half-adder: + .model hadder + .inputs a // ID = 1 + .inputs b // ID = 2 + .inputs cin // ID = 3 + .outputs s // ID = 4 + .outputs cout // ID = 5 + .names a b cin s_driver // ID = 6 + 100 1 + 010 1 + 001 1 + 111 1 + .names a b cin cout_driver // ID = 7 + -11 1 + 1-1 1 + 11- 1 + .names s_driver s + 1 1 + .names cout_driver cout + 1 1 + .end +*/ + Bbl_Man_t * p; + // start the data manager + p = Bbl_ManStart( "hadder" ); + // create CIs + Bbl_ManCreateObject( p, BBL_OBJ_CI, 1, 0, NULL ); // a + Bbl_ManCreateObject( p, BBL_OBJ_CI, 2, 0, NULL ); // b + Bbl_ManCreateObject( p, BBL_OBJ_CI, 3, 0, NULL ); // cin + // create COs + Bbl_ManCreateObject( p, BBL_OBJ_CO, 4, 1, NULL ); // s + Bbl_ManCreateObject( p, BBL_OBJ_CO, 5, 1, NULL ); // cout + // create internal nodes + Bbl_ManCreateObject( p, BBL_OBJ_NODE, 6, 3, "100 1\n010 1\n001 1\n111 1\n" ); // s_driver + Bbl_ManCreateObject( p, BBL_OBJ_NODE, 7, 3, "-11 1\n1-1 1\n11- 1\n" ); // cout_driver + // add fanins of node 6 + Bbl_ManAddFanin( p, 6, 1 ); // s_driver <- a + Bbl_ManAddFanin( p, 6, 2 ); // s_driver <- b + Bbl_ManAddFanin( p, 6, 3 ); // s_driver <- cin + // add fanins of node 7 + Bbl_ManAddFanin( p, 7, 1 ); // cout_driver <- a + Bbl_ManAddFanin( p, 7, 2 ); // cout_driver <- b + Bbl_ManAddFanin( p, 7, 3 ); // cout_driver <- cin + // add fanins of COs + Bbl_ManAddFanin( p, 4, 6 ); // s <- s_driver + Bbl_ManAddFanin( p, 5, 7 ); // cout <- cout_driver + // sanity check + Bbl_ManCheck( p ); + // write BLIF file as a sanity check + Bbl_ManDumpBlif( p, "hadder.blif" ); + // write binary BLIF file + Bbl_ManDumpBinaryBlif( p, "hadder.bblif" ); + // remove the manager + Bbl_ManStop( p ); + + +// Bbl_ManTestTruth( "100 1\n010 1\n001 1\n111 1\n", 3 ); +// Bbl_ManTestTruth( "-11 0\n1-1 0\n11- 0\n", 3 ); +// Bbl_ManTestTruth( "--- 1\n", 3 ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/bbl/bblif.h b/src/aig/bbl/bblif.h new file mode 100644 index 00000000..db3eb2f5 --- /dev/null +++ b/src/aig/bbl/bblif.h @@ -0,0 +1,273 @@ +/**CFile**************************************************************** + + FileName [bblif.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Binary BLIF representation for logic networks.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 28, 2009.] + + Revision [$Id: bblif.h,v 1.00 2009/02/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __BBLIF_H__ +#define __BBLIF_H__ + +/* + This file (taken together with "bblif.c") implements a stand-alone + interface between ABC and an application that uses ABC. + + The interface is designed to pass a combinational logic network + from the calling application to ABC using a binary BLIF format (BBLIF) + and return the network after synthesis/mapping/verification in ABC + back to the caller. + + The interface can do the following: + (1) accept a combinational logic network via a set of APIs + (2) write the logic network into a binary BLIF file readable by ABC + (3) read a binary BLIF file with a mapped network produced by ABC + (4) return the mapped network to the caller through a set of APIs + + Here these steps are described in more detail: + + (1) The BBLIF manager is allocated by calling Bbl_ManStart() and + deallocated by calling Bbl_ManStop(). + + The combinational network is composed of three types of objects: + (a) combinational inputs (CIs), (b) combinational outputs (COs), + (c) internal logic nodes represented using Sum-of-Products (SOPs) + similar to the way logic nodes are represented in SIS. Sequential + elements (flops) are currently not supported. A CI has no fanins. + A CO has exactly one fanin and no fanouts. Internal nodes can + have any number of fanins and fanouts. Only an internal node can + have a logic function. + + Before constructing the BBLIF manager, each object should be + assigned a unique non-negative (0-based) integer ID. The sequence + of ID numbers may have gaps in it (for example, 0, 1, 2, 5, 6, etc) + but care should be taken that the ID numbers do not grow too large + because internally they are used to index the objects. So if + the largest given ID has value N, an array of 4*N bytes will be + allocated internally by the BBLIF manager. Obviously if N = 1M, + the array will use 4Mb, but if N = 100M, it will use 0.4Gb. + + This object ID (called also "the original ID of the object") is + given to Bbl_ManCreateObject(), which construct the BBLIF objects + and to the procedure Bbl_ManAddFanin(), which creates fanin/fanout + relations between two objects. The exact number of fanins of an + object should be declared when calling Bbl_ManCreateObject(). + Later on, each node should be assigned as many fanins using + Bbl_ManAddFanin(). The order/number of fanins corresponds to the + order/number of variables in the SOP of the logic function of the + node. The declared and actual number of fanins should be the same. + otherwise the interface will not function correctly. This is checked + by the procedure Bbl_ManCheck(), which should be called when + constructing all objects and their fanins is finished. + + The SOP representation of the logic function should be given to + every internal node. It is given as a C-string, showing the SOP + as it would appear in a BLIF or PLA file. Each cube is composed + of characters '0', '1', and '-', and ended by a seqence of three + characters: space ' ', followed by '0' or '1' (depending on whether + on- or off-set is used), followed by the new line character '\n'. + For example, a two-input OR has the following SOP representation: + "1- 1\n-1 1\n", or equivalently, "00 0\n". The SOP for a constant + function with no fanins is represented as " 0\n" (constant 0) and + " 1\n" (constant 1). SOP for a constant node with some fanins + may also be represented. For example, constant 0 node with three + fanins will have SOP representation as follows: "--- 0\n". + + The objects can be added to the BBLIF manager in any order, but + by the time the fanin/fanout connections are created, corresponding + objects should be already created. + + The number of objects is limited by 2^31. The number of fanins + of one object is restricted to 2^28. The SOP representation can + have arbitrary many products (cubes), as long as memory is enough + to represent them in the C-string form, as described above. + + (2) To write the manager into a file, call procedure Bbl_ManDumpBinaryBlif(). + It is recommended to use files with extension ".bblif" because it + will allow ABC to call the approapriate reader in command "read". + + (3) To read the network from file, call procedure Bbl_ManReadBinaryBlif(). + + (4) It is assumed that ABC will return the network after mapping. + This network will arrive in a BBLIF file, from which the BBLIF + manager is created by the call to Bbl_ManReadBinaryBlif(). The + following APIs are useful to extract the mapped network from the manager: + + Iterator Bbl_ManForEachObj() iterates through the pointers to the + BBLIF objects, which are guaranteed to be in a topological order. + + For each object, the following APIs can be used: + Bbl_ObjIsInput() returns 1 if the object is a CI + Bbl_ObjIsOutput() returns 1 if the object is a CO + Bbl_ObjIsLut() returns 1 if the object is a logic node (lookup table) + Bbl_ObjFaninNumber() returns the number of fanins of the node + Bbl_ObjSop() returns the SOP representation of the node, as described above. + + A special attention should be given to the representation of object IDs + after mapping. Recall that when the outgoing BBLIF network is constructed, + the IDs of objects are assigned by the calling application and given to + the BBLIF manager when procedure Bbl_ManCreateObject() is called. + We refer to these object IDs as "original IDs of the objects". + + When the network has been given to ABC, mapped, and returned to the + calling application in the incoming BBLIF file, only CIs and COs are + guaranteed to preserve their "original IDs". Other objects may be created + during synthesis/mapping. The original IDs of these objects are set to -1. + + The following two APIs are used to return the IDs of objects after mapping: + Bbl_ObjId() returns the new ID (useful to construct network after mapping) + Bbl_ObjIdOriginal() returns the original ID (or -1 if this is a new object). + + !!!***!!! + Note: The original ID currently cannot be returned by Bbl_ObjIdOriginal(). + It is recommended to use the work-around described below. + !!!***!!! + + The original ID is useful to map CIs/COs after mapping into CIs/COs before + mapping. However, the order of CIs/COs after mapping in the incoming network + is the same as the order of their creation by the calling application + in the outgoing network. This allows for a workaround that does not have + the need for the original IDs. We can simply iterate through the objects + after mapping, and create CIs and COs in the order of their appearance, + and this order is guaranteed to be the same as the order of their + construction by the calling application. + + It is also worth noting that currently the internal node names are not + preserved by ABC during synthesis. This may change in the future. and then + some of the internal nodes will preserve their IDs, which may allow the + calling application to reconstruct the names of some of the nodes after + synthesis/mapping in ABC using their original IDs whenever available. + + Finally, iterator Bbl_ObjForEachFanin() can be used to iterate through + the fanins of each mapped object. For CIs, there will be no fanins. + For COs, there will be exactly one fanin. For the internal nodes (LUTs) + the number of fanins is the number of inputs of these nodes. + + A demo of using this interface is included at the bottom of file "bblif.c" in + procedure Bbl_ManSimpleDemo(). Additional examples can be found in the files + "abc\src\base\io\ioReadBblif.c" and "abc\src\base\io\ioWriteBblif.c". These + files illustrate how an ABC network is created from the BBLIF data manager + and how the data manager is created from the ABC network. + + Note that only the files "bblif.h" and "bblif.c" are needed for interfacing + the user's application with ABC, while other files should not be compiled + as part of the application code. + + Finally, a warning regarding endianness. The interface may not work + if the BBLIF file is produced on a machine whose engianness is different + from the machine, which is reading this file. +*/ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +#define inline __inline +#endif + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// object types +typedef enum { + BBL_OBJ_NONE, // 0: non-existent object + BBL_OBJ_CI, // 1: primary input + BBL_OBJ_CO, // 2: primary output + BBL_OBJ_NODE, // 3: buffer node + BBL_OBJ_VOID // 4: unused object +} Bbl_Type_t; + +// data manager +typedef struct Bbl_Man_t_ Bbl_Man_t; + +// data object +typedef struct Bbl_Obj_t_ Bbl_Obj_t; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// (1) creating the data manager in the application code +extern Bbl_Man_t * Bbl_ManStart( char * pName ); +extern void Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop ); +extern void Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId ); +extern int Bbl_ManCheck( Bbl_Man_t * p ); +extern void Bbl_ManPrintStats( Bbl_Man_t * p ); +extern void Bbl_ManStop( Bbl_Man_t * p ); + +// (2) writing the data manager into file +extern void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName ); + +// (3) reading the data manager from file +extern Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName ); + +// (4) returning the mapped network after reading the data manaager from file +extern char * Bbl_ManName( Bbl_Man_t * p ); +extern int Bbl_ObjIsInput( Bbl_Obj_t * p ); +extern int Bbl_ObjIsOutput( Bbl_Obj_t * p ); +extern int Bbl_ObjIsLut( Bbl_Obj_t * p ); +extern int Bbl_ObjId( Bbl_Obj_t * p ); +extern int Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p ); +extern int Bbl_ObjFaninNumber( Bbl_Obj_t * p ); +extern char * Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p ); + +// for the use in iterators only +extern Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p ); +extern Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj ); +extern Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p ); +extern Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev ); + +// iterator through the objects +#define Bbl_ManForEachObj( p, pObj ) \ + for ( pObj = Bbl_ManObjFirst(p); pObj; pObj = Bbl_ManObjNext(p, pObj) ) +// iterator through the fanins fo the an object +#define Bbl_ObjForEachFanin( pObj, pFanin ) \ + for ( pFanin = Bbl_ObjFaninFirst(pObj); pFanin; pFanin = Bbl_ObjFaninNext(pObj, pFanin) ) + +// these additional procedures are provided to transform truth tables into SOPs, and vice versa +extern char * Bbl_ManTruthToSop( unsigned * pTruth, int nVars ); +extern unsigned * Bbl_ManSopToTruth( char * pSop, int nVars ); + +// write text BLIF file for debugging +extern void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName ); + +// a simple demo procedure +extern void Bbl_ManSimpleDemo(); + + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/bbl/module.make b/src/aig/bbl/module.make new file mode 100644 index 00000000..89ed2fa3 --- /dev/null +++ b/src/aig/bbl/module.make @@ -0,0 +1 @@ +SRC += src/aig/bbl/bblif.c diff --git a/src/aig/cec/cec.h b/src/aig/cec/cec.h index fa7c5dbc..16748233 100644 --- a/src/aig/cec/cec.h +++ b/src/aig/cec/cec.h @@ -45,24 +45,42 @@ struct Cec_ParSat_t_ int nSatVarMax; // the max number of SAT variables int nCallsRecycle; // calls to perform before recycling SAT solver int fPolarFlip; // flops polarity of variables + int fCheckMiter; // the circuit is the miter int fFirstStop; // stop on the first sat output int fVerbose; // verbose stats }; +// simulation parameters +typedef struct Cec_ParSim_t_ Cec_ParSim_t; +struct Cec_ParSim_t_ +{ + int nWords; // the number of simulation words + int nRounds; // the number of simulation rounds + int TimeLimit; // the runtime limit in seconds + int fDoubleOuts; // miter with separate outputs + int fCheckMiter; // the circuit is the miter + int fFirstStop; // stop on the first sat output + int fSeqSimulate; // performs sequential simulation + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + // combinational SAT sweeping parameters -typedef struct Cec_ParCsw_t_ Cec_ParCsw_t; -struct Cec_ParCsw_t_ +typedef struct Cec_ParFra_t_ Cec_ParFra_t; +struct Cec_ParFra_t_ { int nWords; // the number of simulation words int nRounds; // the number of simulation rounds int nItersMax; // the maximum number of iterations of SAT sweeping int nBTLimit; // conflict limit at a node - int nSatVarMax; // the max number of SAT variables - int nCallsRecycle; // calls to perform before recycling SAT solver + int TimeLimit; // the runtime limit in seconds int nLevelMax; // restriction on the level nodes to be swept int nDepthMax; // the depth in terms of steps of speculative reduction int fRewriting; // enables AIG rewriting + int fCheckMiter; // the circuit is the miter int fFirstStop; // stop on the first sat output + int fDoubleOuts; // miter with separate outputs + int fColorDiff; // miter with separate outputs int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -71,13 +89,12 @@ struct Cec_ParCsw_t_ typedef struct Cec_ParCec_t_ Cec_ParCec_t; struct Cec_ParCec_t_ { - int nIters; // iterations of SAT solving/sweeping - int nBTLimitBeg; // starting backtrack limit - int nBTlimitMulti; // multiple of backtrack limit + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int fFirstStop; // stop on the first sat output int fUseSmartCnf; // use smart CNF computation int fRewriting; // enables AIG rewriting - int fSatSweeping; // enables SAT sweeping - int fFirstStop; // stop on the first sat output + int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -89,12 +106,17 @@ struct Cec_ParCec_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== cecCec.c ==========================================================*/ +extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ); +extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); /*=== cecCore.c ==========================================================*/ extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ); -extern void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p ); +extern void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p ); +extern void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ); extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ); -extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ); +extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); +extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); #ifdef __cplusplus } diff --git a/src/aig/cec/cecCec.c b/src/aig/cec/cecCec.c new file mode 100644 index 00000000..ea730693 --- /dev/null +++ b/src/aig/cec/cecCec.c @@ -0,0 +1,241 @@ +/**CFile**************************************************************** + + FileName [cecCec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Integrated combinatinal equivalence checker.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecCec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Saves the input pattern with the given number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues ) +{ + int i; + assert( p->pCexComb == NULL ); + p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char, + sizeof(Gia_Cex_t) + sizeof(unsigned) * Aig_BitWordNum(Gia_ManCiNum(p)) ); + p->pCexComb->iPo = iOut; + p->pCexComb->nPis = Gia_ManCiNum(p); + p->pCexComb->nBits = Gia_ManCiNum(p); + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + if ( pValues[i] ) + Aig_InfoSetBit( p->pCexComb->pData, i ); +} + +/**Function************************************************************* + + Synopsis [Interface to the old CEC engine] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose ) +{ + extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); + extern int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs ); + Gia_Man_t * pTemp = Gia_ManTransformMiter( pMiter ); + Aig_Man_t * pMiterCec = Gia_ManToAig( pTemp ); + int RetValue, iOut, nOuts, clkTotal = clock(); + Gia_ManStop( pTemp ); + // run CEC on this miter + RetValue = Fra_FraigCec( &pMiterCec, 100000, fVerbose ); + // report the miter + if ( RetValue == 1 ) + { + printf( "Networks are equivalent. " ); +ABC_PRT( "Time", clock() - clkTotal ); + } + else if ( RetValue == 0 ) + { + printf( "Networks are NOT EQUIVALENT. " ); +ABC_PRT( "Time", clock() - clkTotal ); + if ( pMiterCec->pData == NULL ) + printf( "Counter-example is not available.\n" ); + else + { + iOut = Ssw_SecCexResimulate( pMiterCec, pMiterCec->pData, &nOuts ); + if ( iOut == -1 ) + printf( "Counter-example verification has failed.\n" ); + else + { + printf( "Primary output %d has failed in frame %d.\n", iOut ); + printf( "The counter-example detected %d incorrect outputs.\n", nOuts ); + } + Cec_ManTransformPattern( pMiter, iOut, pMiterCec->pData ); + } + } + else + { + printf( "Networks are UNDECIDED. " ); +ABC_PRT( "Time", clock() - clkTotal ); + } + fflush( stdout ); + Aig_ManStop( pMiterCec ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ) +{ + int fDumpUndecided = 1; + Cec_ParFra_t ParsFra, * pParsFra = &ParsFra; + Gia_Man_t * pNew; + int RetValue, clk = clock(); + double clkTotal = clock(); + // sweep for equivalences + Cec_ManFraSetDefaultParams( pParsFra ); + pParsFra->nBTLimit = pPars->nBTLimit; + pParsFra->TimeLimit = pPars->TimeLimit; + pParsFra->fVerbose = pPars->fVerbose; + pParsFra->fCheckMiter = 1; + pParsFra->fFirstStop = 1; + pParsFra->fDoubleOuts = 1; + pNew = Cec_ManSatSweeping( p, pParsFra ); + if ( pNew == NULL ) + { + if ( !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + printf( "Counter-example simulation has failed.\n" ); + printf( "Networks are NOT EQUIVALENT. " ); + ABC_PRT( "Time", clock() - clk ); + return 0; + } + if ( Gia_ManAndNum(pNew) == 0 ) + { + printf( "Networks are equivalent. " ); + ABC_PRT( "Time", clock() - clk ); + Gia_ManStop( pNew ); + return 1; + } + printf( "Networks are UNDECIDED after the new CEC engine. " ); + ABC_PRT( "Time", clock() - clk ); + if ( fDumpUndecided ) + { + Gia_WriteAiger( pNew, "gia_cec_undecided.aig", 0, 0 ); + printf( "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" ); + } + if ( pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) + { + Gia_ManStop( pNew ); + return -1; + } + // call other solver + printf( "Calling the old CEC engine.\n" ); + fflush( stdout ); + RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose ); + p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL; + if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + printf( "Counter-example simulation has failed.\n" ); + Gia_ManStop( pNew ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine applied to two circuits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + Gia_Man_t * pMiter; + int RetValue; + Cec_ManCecSetDefaultParams( pPars ); + pPars->fVerbose = fVerbose; + pMiter = Gia_ManMiter( p0, p1, 0, 1, pPars->fVerbose ); + if ( pMiter == NULL ) + return -1; + RetValue = Cec_ManVerify( pMiter, pPars ); + p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL; + Gia_ManStop( pMiter ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine applied to two circuits.] + + Description [Returns 1 if equivalent, 0 if counter-example, -1 if undecided. + Counter-example is returned in the first manager as pAig0->pSeqModel. + The format is given in Gia_Cex_t (file "abc\src\aig\gia\gia.h").] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose ) +{ + Gia_Man_t * p0, * p1, * pTemp; + int RetValue; + + p0 = Gia_ManFromAig( pAig0 ); + p0 = Gia_ManCleanup( pTemp = p0 ); + Gia_ManStop( pTemp ); + + p1 = Gia_ManFromAig( pAig1 ); + p1 = Gia_ManCleanup( pTemp = p1 ); + Gia_ManStop( pTemp ); + + RetValue = Cec_ManVerifyTwo( p0, p1, fVerbose ); + pAig0->pSeqModel = p0->pCexComb; p0->pCexComb = NULL; + Gia_ManStop( p0 ); + Gia_ManStop( p1 ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecClass.c b/src/aig/cec/cecClass.c index 65fa2e9b..aaa85ffa 100644 --- a/src/aig/cec/cecClass.c +++ b/src/aig/cec/cecClass.c @@ -24,39 +24,10 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Cec_ObjRepr( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iRepr; } -static inline void Cec_ObjSetRepr( Cec_ManCsw_t * p, int Id, int Num ) { p->pObjs[Id].iRepr = Num; } - -static inline int Cec_ObjProved( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iProved; } -static inline void Cec_ObjSetProved( Cec_ManCsw_t * p, int Id ) { p->pObjs[Id].iProved = 1; } - -static inline int Cec_ObjFailed( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iFailed; } -static inline void Cec_ObjSetFailed( Cec_ManCsw_t * p, int Id ) { p->pObjs[Id].iFailed = 1; } - -static inline int Cec_ObjNext( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].iNext; } -static inline void Cec_ObjSetNext( Cec_ManCsw_t * p, int Id, int Num ) { p->pObjs[Id].iNext = Num; } - -static inline unsigned Cec_ObjSim( Cec_ManCsw_t * p, int Id ) { return p->pObjs[Id].SimNum; } -static inline unsigned * Cec_ObjSimP1( Cec_ManCsw_t * p, int Id ) { return &p->pObjs[Id].SimNum; } -static inline unsigned * Cec_ObjSimP( Cec_ManCsw_t * p, int Id ) { return p->pMems + Cec_ObjSim(p, Id) + 1; } -static inline void Cec_ObjSetSim( Cec_ManCsw_t * p, int Id, unsigned n ) { p->pObjs[Id].SimNum = n; } - -static inline int Cec_ObjIsConst( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) == 0; } -static inline int Cec_ObjIsHead( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) < 0 && Cec_ObjNext(p, Id) > 0; } -static inline int Cec_ObjIsNone( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) < 0 && Cec_ObjNext(p, Id) == 0; } -static inline int Cec_ObjIsTail( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) > 0 && Cec_ObjNext(p, Id) == 0; } -static inline int Cec_ObjIsClass( Cec_ManCsw_t * p, int Id ) { return Cec_ObjRepr(p, Id) > 0 || Cec_ObjNext(p, Id) > 0; } - -#define Cec_ManForEachObj( p, i ) \ - for ( i = 0; i < Gia_ManObjNum(p->pAig); i++ ) -#define Cec_ManForEachObj1( p, i ) \ - for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) -#define Cec_ManForEachClass( p, i ) \ - for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) if ( !Cec_ObjIsHead(p, i) ) {} else -#define Cec_ClassForEachObj( p, i, iObj ) \ - for ( assert(Cec_ObjIsHead(p, i)), iObj = i; iObj; iObj = Cec_ObjNext(p, iObj) ) -#define Cec_ClassForEachObj1( p, i, iObj ) \ - for ( assert(Cec_ObjIsHead(p, i)), iObj = Cec_ObjNext(p, i); iObj; iObj = Cec_ObjNext(p, iObj) ) +static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id ) { return p->pMems + p->pSimInfo[Id] + 1; } +static inline void Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n ) { p->pSimInfo[Id] = n; } + +static inline float Cec_MemUsage( Cec_ManSim_t * p ) { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -64,30 +35,7 @@ static inline int Cec_ObjIsClass( Cec_ManCsw_t * p, int Id ) { /**Function************************************************************* - Synopsis [Creates the set of representatives.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p ) -{ - int i, * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) - if ( Cec_ObjProved(p, i) ) - { - assert( Cec_ObjRepr(p, i) >= 0 ); - pReprs[i] = Cec_ObjRepr(p, i); - } - return pReprs; -} - -/**Function************************************************************* - - Synopsis [] + Synopsis [Compares simulation info of one node with constant 0.] Description [] @@ -96,250 +44,28 @@ int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Cec_ManCswDupWithClasses( Cec_ManCsw_t * p ) +int Cec_ManSimCompareConst( unsigned * p, int nWords ) { - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pRepr; - int iRes0, iRes1, iRepr, iNode; - int i, fCompl, * piCopies; - Vec_IntClear( p->vXorNodes ); - Gia_ManLevelNum( p->pAig ); - pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); - pNew->pName = Aig_UtilStrsav( p->pAig->pName ); - Gia_ManHashAlloc( pNew ); - piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - piCopies[0] = 0; - Gia_ManForEachObj1( p->pAig, pObj, i ) - { - if ( Gia_ObjIsCi(pObj) ) - { - piCopies[i] = Gia_ManAppendCi( pNew ); - continue; - } - iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); - if ( Gia_ObjIsCo(pObj) ) - { - Gia_ManAppendCo( pNew, iRes0 ); - continue; - } - iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); - iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); - if ( Cec_ObjRepr(p, i) < 0 || !Cec_ObjProved(p, i) ) - continue; - assert( Cec_ObjRepr(p, i) < i ); - iRepr = piCopies[Cec_ObjRepr(p, i)]; - if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) - continue; - pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) ); - fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); - piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); - } - ABC_FREE( piCopies ); - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, 0 ); - pNew = Gia_ManCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Cec_ManCswSpecReduction( Cec_ManCsw_t * p ) -{ - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pRepr; - int iRes0, iRes1, iRepr, iNode, iMiter; - int i, fCompl, * piCopies, * pDepths; - Vec_IntClear( p->vXorNodes ); -// Gia_ManLevelNum( p->pAig ); - pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); - pNew->pName = Aig_UtilStrsav( p->pAig->pName ); - Gia_ManHashAlloc( pNew ); - piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); - piCopies[0] = 0; - Gia_ManForEachObj1( p->pAig, pObj, i ) - { - if ( Gia_ObjIsCi(pObj) ) - { - piCopies[i] = Gia_ManAppendCi( pNew ); - continue; - } - if ( Gia_ObjIsCo(pObj) ) - continue; - if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 || - piCopies[Gia_ObjFaninId1(pObj,i)] == -1 ) - continue; - iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); - iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); - iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); - pDepths[i] = AIG_MAX( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] ); - if ( Cec_ObjRepr(p, i) < 0 || Cec_ObjFailed(p, i) ) - continue; - assert( Cec_ObjRepr(p, i) < i ); - iRepr = piCopies[Cec_ObjRepr(p, i)]; - if ( iRepr == -1 ) - continue; - if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) - continue; - pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) ); - fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); - piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); - if ( Cec_ObjProved(p, i) ) - continue; -// if ( p->pPars->nLevelMax && -// (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax || -// Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) ) -// continue; - // produce speculative miter - iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); - Gia_ManAppendCo( pNew, iMiter ); - Vec_IntPush( p->vXorNodes, Cec_ObjRepr(p, i) ); - Vec_IntPush( p->vXorNodes, i ); - // add to the depth of this node - pDepths[i] = 1 + AIG_MAX( pDepths[i], pDepths[Cec_ObjRepr(p, i)] ); - if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax ) - piCopies[i] = -1; - } - ABC_FREE( piCopies ); - ABC_FREE( pDepths ); - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, 0 ); - pNew = Gia_ManCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Cec_ManCswSpecReductionProved( Cec_ManCsw_t * p ) -{ - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pRepr; - int iRes0, iRes1, iRepr, iNode, iMiter; - int i, fCompl, * piCopies; - Vec_IntClear( p->vXorNodes ); - Gia_ManLevelNum( p->pAig ); - pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); - pNew->pName = Aig_UtilStrsav( p->pAig->pName ); - Gia_ManHashAlloc( pNew ); - piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); - piCopies[0] = 0; - Gia_ManForEachObj1( p->pAig, pObj, i ) + int w; + if ( p[0] & 1 ) { - if ( Gia_ObjIsCi(pObj) ) - { - piCopies[i] = Gia_ManAppendCi( pNew ); - continue; - } - if ( Gia_ObjIsCo(pObj) ) - continue; - iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); - iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); - iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); - if ( Cec_ObjRepr(p, i) < 0 || !Cec_ObjProved(p, i) ) - continue; - assert( Cec_ObjRepr(p, i) < i ); - iRepr = piCopies[Cec_ObjRepr(p, i)]; - if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) - continue; - pRepr = Gia_ManObj( p->pAig, Cec_ObjRepr(p, i) ); - fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); - piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); - // add speculative miter - iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); - Gia_ManAppendCo( pNew, iMiter ); + for ( w = 0; w < nWords; w++ ) + if ( p[w] != ~0 ) + return 0; + return 1; } - ABC_FREE( piCopies ); - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, 0 ); - pNew = Gia_ManCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cec_ManCswCountOne( Cec_ManCsw_t * p, int i ) -{ - int Ent, nLits = 1; - Cec_ClassForEachObj1( p, i, Ent ) + else { - assert( Cec_ObjRepr(p, Ent) == i ); - nLits++; + for ( w = 0; w < nWords; w++ ) + if ( p[w] != 0 ) + return 0; + return 1; } - return nLits; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cec_ManCswCountLitsAll( Cec_ManCsw_t * p ) -{ - int i, nLits = 0; - Cec_ManForEachObj( p, i ) - nLits += (Cec_ObjRepr(p, i) >= 0); - return nLits; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cec_ManCswPrintOne( Cec_ManCsw_t * p, int i, int Counter ) -{ - int Ent; - printf( "Class %4d : Num = %2d {", Counter, Cec_ManCswCountOne(p, i) ); - Cec_ClassForEachObj( p, i, Ent ) - printf(" %d", Ent ); - printf( " }\n" ); } /**Function************************************************************* - Synopsis [] + Synopsis [Compares simulation info of two nodes.] Description [] @@ -348,32 +74,28 @@ void Cec_ManCswPrintOne( Cec_ManCsw_t * p, int i, int Counter ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswPrintClasses( Cec_ManCsw_t * p, int fVerbose ) +int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords ) { - int i, Counter = 0, Counter1 = 0, CounterX = 0, nLits; - Cec_ManForEachObj1( p, i ) + int w; + if ( (p0[0] & 1) == (p1[0] & 1) ) { - if ( Cec_ObjIsHead(p, i) ) - Counter++; - else if ( Cec_ObjIsConst(p, i) ) - Counter1++; - else if ( Cec_ObjIsNone(p, i) ) - CounterX++; + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != p1[w] ) + return 0; + return 1; } - nLits = Cec_ManCswCountLitsAll( p ); - printf( "Class =%7d. Const =%7d. Unsed =%7d. Lits =%8d. All =%8d. Mem = %5.2f Mb\n", - Counter, Counter1, CounterX, nLits-Counter1, nLits, 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20) ); - if ( fVerbose ) + else { - Counter = 0; - Cec_ManForEachClass( p, i ) - Cec_ManCswPrintOne( p, i, ++Counter ); + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != ~p1[w] ) + return 0; + return 1; } } /**Function************************************************************* - Synopsis [] + Synopsis [Returns the number of the first non-equal bit.] Description [] @@ -382,28 +104,28 @@ void Cec_ManCswPrintClasses( Cec_ManCsw_t * p, int fVerbose ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswCompareEqual( unsigned * p0, unsigned * p1, int nWords ) +int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords ) { int w; - if ( (p0[0] & 1) == (p1[0] & 1) ) + if ( p[0] & 1 ) { for ( w = 0; w < nWords; w++ ) - if ( p0[w] != p1[w] ) - return 0; - return 1; + if ( p[w] != ~0 ) + return 32*w + Aig_WordFindFirstBit( ~p[w] ); + return -1; } else { for ( w = 0; w < nWords; w++ ) - if ( p0[w] != ~p1[w] ) - return 0; - return 1; + if ( p[w] != 0 ) + return 32*w + Aig_WordFindFirstBit( p[w] ); + return -1; } } /**Function************************************************************* - Synopsis [] + Synopsis [Compares simulation info of two nodes.] Description [] @@ -412,28 +134,28 @@ int Cec_ManCswCompareEqual( unsigned * p0, unsigned * p1, int nWords ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswCompareConst( unsigned * p, int nWords ) +int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords ) { int w; - if ( p[0] & 1 ) + if ( (p0[0] & 1) == (p1[0] & 1) ) { for ( w = 0; w < nWords; w++ ) - if ( p[w] != ~0 ) - return 0; - return 1; + if ( p0[w] != p1[w] ) + return 32*w + Aig_WordFindFirstBit( p0[w] ^ p1[w] ); + return -1; } else { for ( w = 0; w < nWords; w++ ) - if ( p[w] != 0 ) - return 0; - return 1; + if ( p0[w] != ~p1[w] ) + return 32*w + Aig_WordFindFirstBit( p0[w] ^ ~p1[w] ); + return -1; } } /**Function************************************************************* - Synopsis [] + Synopsis [Creates equivalence class.] Description [] @@ -442,31 +164,31 @@ int Cec_ManCswCompareConst( unsigned * p, int nWords ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswClassCreate( Cec_ManCsw_t * p, Vec_Int_t * vClass ) +void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass ) { - int Repr = -1, EntPrev = -1, Ent, i; + int Repr = GIA_VOID, EntPrev = -1, Ent, i; assert( Vec_IntSize(vClass) > 0 ); Vec_IntForEachEntry( vClass, Ent, i ) { if ( i == 0 ) { Repr = Ent; - Cec_ObjSetRepr( p, Ent, -1 ); + Gia_ObjSetRepr( p, Ent, GIA_VOID ); EntPrev = Ent; } else { - Cec_ObjSetRepr( p, Ent, Repr ); - Cec_ObjSetNext( p, EntPrev, Ent ); + Gia_ObjSetRepr( p, Ent, Repr ); + Gia_ObjSetNext( p, EntPrev, Ent ); EntPrev = Ent; } } - Cec_ObjSetNext( p, EntPrev, 0 ); + Gia_ObjSetNext( p, EntPrev, 0 ); } /**Function************************************************************* - Synopsis [] + Synopsis [Refines one equivalence class.] Description [] @@ -475,34 +197,34 @@ void Cec_ManCswClassCreate( Cec_ManCsw_t * p, Vec_Int_t * vClass ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassRefineOne( Cec_ManCsw_t * p, int i, int fFirst ) +int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i ) { unsigned * pSim0, * pSim1; int Ent; Vec_IntClear( p->vClassOld ); Vec_IntClear( p->vClassNew ); Vec_IntPush( p->vClassOld, i ); - pSim0 = fFirst? Cec_ObjSimP1(p, i) : Cec_ObjSimP(p, i); - Cec_ClassForEachObj1( p, i, Ent ) + pSim0 = Cec_ObjSim(p, i); + Gia_ClassForEachObj1( p->pAig, i, Ent ) { - pSim1 = fFirst? Cec_ObjSimP1(p, Ent) : Cec_ObjSimP(p, Ent); - if ( Cec_ManCswCompareEqual( pSim0, pSim1, p->nWords ) ) + pSim1 = Cec_ObjSim(p, Ent); + if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) ) Vec_IntPush( p->vClassOld, Ent ); else Vec_IntPush( p->vClassNew, Ent ); } if ( Vec_IntSize( p->vClassNew ) == 0 ) return 0; - Cec_ManCswClassCreate( p, p->vClassOld ); - Cec_ManCswClassCreate( p, p->vClassNew ); + Cec_ManSimClassCreate( p->pAig, p->vClassOld ); + Cec_ManSimClassCreate( p->pAig, p->vClassNew ); if ( Vec_IntSize(p->vClassNew) > 1 ) - return 1 + Cec_ManCswClassRefineOne( p, Vec_IntEntry(p->vClassNew,0), fFirst ); + return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) ); return 1; } /**Function************************************************************* - Synopsis [] + Synopsis [Computes hash key of the simuation info.] Description [] @@ -511,7 +233,7 @@ int Cec_ManCswClassRefineOne( Cec_ManCsw_t * p, int i, int fFirst ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize ) +int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize ) { static int s_Primes[16] = { 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, @@ -530,7 +252,7 @@ int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize ) /**Function************************************************************* - Synopsis [] + Synopsis [Resets pointers to the simulation memory.] Description [] @@ -539,90 +261,7 @@ int Cec_ManCswHashKey( unsigned * pSim, int nWords, int nTableSize ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswClassesCreate( Cec_ManCsw_t * p ) -{ - int * pTable, nTableSize, i, Key; - p->nWords = 1; - nTableSize = Aig_PrimeCudd( 100 + Gia_ManObjNum(p->pAig) / 10 ); - pTable = ABC_CALLOC( int, nTableSize ); - Cec_ObjSetRepr( p, 0, -1 ); - Cec_ManForEachObj1( p, i ) - { - if ( Gia_ObjIsCo(Gia_ManObj(p->pAig, i)) ) - { - Cec_ObjSetRepr( p, i, -1 ); - continue; - } - if ( Cec_ManCswCompareConst( Cec_ObjSimP1(p, i), p->nWords ) ) - { - Cec_ObjSetRepr( p, i, 0 ); - continue; - } - Key = Cec_ManCswHashKey( Cec_ObjSimP1(p, i), p->nWords, nTableSize ); - if ( pTable[Key] == 0 ) - Cec_ObjSetRepr( p, i, -1 ); - else - { - Cec_ObjSetNext( p, pTable[Key], i ); - Cec_ObjSetRepr( p, i, Cec_ObjRepr(p, pTable[Key]) ); - if ( Cec_ObjRepr(p, i) == -1 ) - Cec_ObjSetRepr( p, i, pTable[Key] ); - } - pTable[Key] = i; - } - ABC_FREE( pTable ); - if ( p->pPars->fVeryVerbose ) - Cec_ManCswPrintClasses( p, 0 ); - // refine classes - Cec_ManForEachClass( p, i ) - Cec_ManCswClassRefineOne( p, i, 1 ); - // clean memory - Cec_ManForEachObj( p, i ) - Cec_ObjSetSim( p, i, 0 ); - if ( p->pPars->fVeryVerbose ) - Cec_ManCswPrintClasses( p, 0 ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cec_ManCswSimulateSimple( Cec_ManCsw_t * p ) -{ - Gia_Obj_t * pObj; - unsigned Res0, Res1; - int i; - Gia_ManForEachCi( p->pAig, pObj, i ) - Cec_ObjSetSim( p, i, Aig_ManRandom(0) ); - Gia_ManForEachAnd( p->pAig, pObj, i ) - { - Res0 = Cec_ObjSim( p, Gia_ObjFaninId0(pObj, i) ); - Res1 = Cec_ObjSim( p, Gia_ObjFaninId1(pObj, i) ); - Cec_ObjSetSim( p, i, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & - (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); - } -} - -/**Function************************************************************* - - Synopsis [References simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p ) +void Cec_ManSimMemRelink( Cec_ManSim_t * p ) { unsigned * pPlace, Ent; pPlace = &p->MemFree; @@ -634,6 +273,7 @@ void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p ) pPlace = p->pMems + Ent; } *pPlace = 0; + p->nWordsOld = p->nWords; } /**Function************************************************************* @@ -647,10 +287,10 @@ void Cec_ManCswSimMemRelink( Cec_ManCsw_t * p ) SeeAlso [] ***********************************************************************/ -unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) +unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i ) { unsigned * pSim; - assert( p->pObjs[i].SimNum == 0 ); + assert( p->pSimInfo[i] == 0 ); if ( p->MemFree == 0 ) { if ( p->nWordsAlloc == 0 ) @@ -661,9 +301,9 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) } p->nWordsAlloc *= 2; p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc ); - Cec_ManCswSimMemRelink( p ); + Cec_ManSimMemRelink( p ); } - p->pObjs[i].SimNum = p->MemFree; + p->pSimInfo[i] = p->MemFree; pSim = p->pMems + p->MemFree; p->MemFree = pSim[0]; pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) ); @@ -675,7 +315,7 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) /**Function************************************************************* - Synopsis [Dereference simulaton info.] + Synopsis [Dereferences simulaton info.] Description [] @@ -684,16 +324,16 @@ unsigned * Cec_ManCswSimRef( Cec_ManCsw_t * p, int i ) SeeAlso [] ***********************************************************************/ -unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i ) +unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i ) { unsigned * pSim; - assert( p->pObjs[i].SimNum > 0 ); - pSim = p->pMems + p->pObjs[i].SimNum; + assert( p->pSimInfo[i] > 0 ); + pSim = p->pMems + p->pSimInfo[i]; if ( --pSim[0] == 0 ) { pSim[0] = p->MemFree; - p->MemFree = p->pObjs[i].SimNum; - p->pObjs[i].SimNum = 0; + p->MemFree = p->pSimInfo[i]; + p->pSimInfo[i] = 0; p->nMems--; } return pSim; @@ -701,7 +341,7 @@ unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i ) /**Function************************************************************* - Synopsis [] + Synopsis [Refines nodes belonging to candidate constant class.] Description [] @@ -710,52 +350,145 @@ unsigned * Cec_ManCswSimDeref( Cec_ManCsw_t * p, int i ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswProcessRefined( Cec_ManCsw_t * p, Vec_Int_t * vRefined ) +void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined ) { unsigned * pSim; int * pTable, nTableSize, i, k, Key; if ( Vec_IntSize(vRefined) == 0 ) return; - nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 ); + nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 ); pTable = ABC_CALLOC( int, nTableSize ); Vec_IntForEachEntry( vRefined, i, k ) { - if ( i == 7720 ) - { - int s = 0; - } - pSim = Cec_ObjSimP( p, i ); - assert( !Cec_ManCswCompareConst( pSim, p->nWords ) ); - Key = Cec_ManCswHashKey( pSim, p->nWords, nTableSize ); + pSim = Cec_ObjSim( p, i ); + assert( !Cec_ManSimCompareConst( pSim, p->nWords ) ); + Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize ); if ( pTable[Key] == 0 ) { - assert( Cec_ObjRepr(p, i) == 0 ); - assert( Cec_ObjNext(p, i) == 0 ); - Cec_ObjSetRepr( p, i, -1 ); + assert( Gia_ObjRepr(p->pAig, i) == 0 ); + assert( Gia_ObjNext(p->pAig, i) == 0 ); + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); } else { - Cec_ObjSetNext( p, pTable[Key], i ); - Cec_ObjSetRepr( p, i, Cec_ObjRepr(p, pTable[Key]) ); - if ( Cec_ObjRepr(p, i) == -1 ) - Cec_ObjSetRepr( p, i, pTable[Key] ); - assert( Cec_ObjRepr(p, i) > 0 ); + Gia_ObjSetNext( p->pAig, pTable[Key], i ); + Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) ); + if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID ) + Gia_ObjSetRepr( p->pAig, i, pTable[Key] ); + assert( Gia_ObjRepr(p->pAig, i) > 0 ); } pTable[Key] = i; } Vec_IntForEachEntry( vRefined, i, k ) { - if ( Cec_ObjIsHead( p, i ) ) - Cec_ManCswClassRefineOne( p, i, 0 ); + if ( Gia_ObjIsHead( p->pAig, i ) ) + Cec_ManSimClassRefineOne( p, i ); } Vec_IntForEachEntry( vRefined, i, k ) - Cec_ManCswSimDeref( p, i ); + Cec_ManSimSimDeref( p, i ); ABC_FREE( pTable ); } /**Function************************************************************* + Synopsis [Saves the input pattern with the given number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat ) +{ + unsigned * pInfo; + int i; + assert( p->pCexComb == NULL ); + assert( iPat >= 0 && iPat < 32 * p->nWords ); + p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char, + sizeof(Gia_Cex_t) + sizeof(unsigned) * Aig_BitWordNum(Gia_ManCiNum(p->pAig)) ); + p->pCexComb->iPo = p->iOut; + p->pCexComb->nPis = Gia_ManCiNum(p->pAig); + p->pCexComb->nBits = Gia_ManCiNum(p->pAig); + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pInfo = Vec_PtrEntry( p->vCiSimInfo, i ); + if ( Aig_InfoHasBit( pInfo, iPat ) ) + Aig_InfoSetBit( p->pCexComb->pData, i ); + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if computation should stop.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p ) +{ + unsigned * pInfo, * pInfo2; + int i; + if ( p->vCoSimInfo == NULL ) + return 0; + // compare outputs with 0 + if ( p->pPars->fDoubleOuts ) + { + assert( (Gia_ManCoNum(p->pAig) & 1) == 0 ); + for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ ) + { + pInfo = Vec_PtrEntry( p->vCoSimInfo, i ); + pInfo2 = Vec_PtrEntry( p->vCoSimInfo, ++i ); + if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) ) + { + if ( p->iOut == -1 ) + { + p->iOut = i/2; + Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) ); + } + if ( p->pCexes == NULL ) + p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig)/2 ); + if ( p->pCexes[i/2] == NULL ) + { + p->nOuts++; + p->pCexes[i/2] = (void *)1; + } + } + } + } + else + { + for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ ) + { + pInfo = Vec_PtrEntry( p->vCoSimInfo, i ); + if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) ) + { + if ( p->iOut == -1 ) + { + p->iOut = i; + Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) ); + } + if ( p->pCexes == NULL ) + p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig) ); + if ( p->pCexes[i] == NULL ) + { + p->nOuts++; + p->pCexes[i] = (void *)1; + } + } + } + } + return p->pCexes != NULL && p->pPars->fFirstStop; +} + +/**Function************************************************************* + Synopsis [Simulates one round.] Description [Returns the number of PO entry if failed; 0 otherwise.] @@ -765,17 +498,20 @@ void Cec_ManCswProcessRefined( Cec_ManCsw_t * p, Vec_Int_t * vRefined ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos, int iSeries, int fRandomize ) +int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ) { - static int nCountRand = 0; Gia_Obj_t * pObj; unsigned * pRes0, * pRes1, * pRes; int i, k, w, Ent, iCiId = 0, iCoId = 0; + // prepare internal storage + if ( p->nWordsOld != p->nWords ) + Cec_ManSimMemRelink( p ); p->nMemsMax = 0; + // simulate nodes Vec_IntClear( p->vRefinedC ); if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) ) { - pRes = Cec_ManCswSimRef( p, 0 ); + pRes = Cec_ManSimSimRef( p, 0 ); for ( w = 1; w <= p->nWords; w++ ) pRes[w] = 0; } @@ -788,16 +524,12 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t iCiId++; continue; } - pRes = Cec_ManCswSimRef( p, i ); + pRes = Cec_ManSimSimRef( p, i ); if ( vInfoCis ) { pRes0 = Vec_PtrEntry( vInfoCis, iCiId++ ); for ( w = 1; w <= p->nWords; w++ ) - { - pRes[w] = pRes0[iSeries*p->nWords+w-1]; - if ( fRandomize ) - pRes[w] ^= (1 << (nCountRand++ & 0x1f)); - } + pRes[w] = pRes0[w-1]; } else { @@ -810,7 +542,7 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t } if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin { - pRes0 = Cec_ManCswSimDeref( p, Gia_ObjFaninId0(pObj,i) ); + pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); if ( vInfoCos ) { pRes = Vec_PtrEntry( vInfoCos, iCoId++ ); @@ -824,9 +556,9 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t continue; } assert( Gia_ObjValue(pObj) ); - pRes = Cec_ManCswSimRef( p, i ); - pRes0 = Cec_ManCswSimDeref( p, Gia_ObjFaninId0(pObj,i) ); - pRes1 = Cec_ManCswSimDeref( p, Gia_ObjFaninId1(pObj,i) ); + pRes = Cec_ManSimSimRef( p, i ); + pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); + pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) ); if ( Gia_ObjFaninC0(pObj) ) { if ( Gia_ObjFaninC1(pObj) ) @@ -847,47 +579,50 @@ void Cec_ManCswSimulateRound( Cec_ManCsw_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t } references: // if this node is candidate constant, collect it - if ( Cec_ObjIsConst(p, i) && !Cec_ManCswCompareConst(pRes + 1, p->nWords) ) + if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) ) { pRes[0]++; Vec_IntPush( p->vRefinedC, i ); } // if the node belongs to a class, save it - if ( Cec_ObjIsClass(p, i) ) + if ( Gia_ObjIsClass(p->pAig, i) ) pRes[0]++; // if this is the last node of the class, process it - if ( Cec_ObjIsTail(p, i) ) + if ( Gia_ObjIsTail(p->pAig, i) ) { Vec_IntClear( p->vClassTemp ); - Cec_ClassForEachObj( p, Cec_ObjRepr(p, i), Ent ) + Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent ) Vec_IntPush( p->vClassTemp, Ent ); - Cec_ManCswClassRefineOne( p, Cec_ObjRepr(p, i), 0 ); + Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) ); Vec_IntForEachEntry( p->vClassTemp, Ent, k ) - Cec_ManCswSimDeref( p, Ent ); + Cec_ManSimSimDeref( p, Ent ); } } if ( Vec_IntSize(p->vRefinedC) > 0 ) - Cec_ManCswProcessRefined( p, p->vRefinedC ); + Cec_ManSimProcessRefined( p, p->vRefinedC ); assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) ); assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) ); assert( p->nMems == 1 ); + if ( p->nMems != 1 ) + printf( "Cec_ManSimSimulateRound(): Memory management error!\n" ); if ( p->pPars->fVeryVerbose ) - Cec_ManCswPrintClasses( p, 0 ); + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); /* - if ( p->nMems > 1 ) - { + if ( p->nMems > 1 ) { for ( i = 1; i < p->nObjs; i++ ) - if ( p->pSims[i] ) - { + if ( p->pSims[i] ) { int x = 0; } } */ + return Cec_ManSimAnalyzeOutputs( p ); } + + /**Function************************************************************* - Synopsis [] + Synopsis [Creates simulation info for this round.] Description [] @@ -896,28 +631,41 @@ references: SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p ) +void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ) { - int i; - Gia_ManSetRefs( p->pAig ); - Cec_ManCswSimulateSimple( p ); - Cec_ManCswClassesCreate( p ); - for ( i = 0; i < p->pPars->nRounds; i++ ) + unsigned * pRes0, * pRes1; + int i, w; + if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 ) { - p->nWords = i + 1; - Cec_ManCswSimMemRelink( p ); - Cec_ManCswSimulateRound( p, NULL, NULL, 0, 0 ); + assert( vInfoCis && vInfoCos ); + for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vInfoCis, i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = Aig_ManRandom( 0 ); + } + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i ); + pRes1 = Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = pRes1[w]; + } + } + else + { + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vInfoCis, i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = Aig_ManRandom( 0 ); + } } - p->nWords = p->pPars->nWords; - Cec_ManCswSimMemRelink( p ); - for ( i = 0; i < p->pPars->nRounds; i++ ) - Cec_ManCswSimulateRound( p, NULL, NULL, 0, 0 ); - return 1; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the bug is found.] Description [] @@ -926,21 +674,37 @@ int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassesUpdate_rec( Gia_Obj_t * pObj ) +int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ) { - int Result; - if ( pObj->fMark0 ) - return 1; - if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) - return 0; - Result = (Cec_ManCswClassesUpdate_rec( Gia_ObjFanin0(pObj) ) | - Cec_ManCswClassesUpdate_rec( Gia_ObjFanin1(pObj) )); - return pObj->fMark0 = Result; + Gia_Obj_t * pObj; + int i; + assert( p->pAig->pReprs == NULL ); + // allocate representation + p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) ); + p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj)) ? 0 : GIA_VOID ); + // perform simulation + Gia_ManSetRefs( p->pAig ); + p->nWords = 1; + do { + if ( p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + for ( i = 0; i < 4; i++ ) + { + Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo ); + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; + } + p->nWords = 2 * p->nWords + 1; + } + while ( p->nWords <= p->pPars->nWords ); + return 0; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the bug is found.] Description [] @@ -949,100 +713,23 @@ int Cec_ManCswClassesUpdate_rec( Gia_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -int Cec_ManCswClassesUpdate( Cec_ManCsw_t * p, Cec_ManPat_t * pPat, Gia_Man_t * pNew ) +int Cec_ManSimClassesRefine( Cec_ManSim_t * p ) { - Vec_Ptr_t * vInfo; - Gia_Obj_t * pObj, * pObjOld, * pReprOld; - int i, k, iRepr, iNode; - vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), p->pPars->nWords ); - if ( vInfo != NULL ) - { - for ( i = 0; i < pPat->nSeries; i++ ) - Cec_ManCswSimulateRound( p, vInfo, NULL, i, 0 ); - Vec_PtrFree( vInfo ); - } - assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) ); - // mark the transitive fanout of failed nodes - if ( p->pPars->nDepthMax != 1 ) + int i; + Gia_ManSetRefs( p->pAig ); + p->nWords = p->pPars->nWords; + for ( i = 0; i < p->pPars->nRounds; i++ ) { - Gia_ManCleanMark0( p->pAig ); - Gia_ManCleanMark1( p->pAig ); - Gia_ManForEachCo( pNew, pObj, k ) - { - iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); - iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); - if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved - continue; -// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1; - Gia_ManObj(p->pAig, iNode)->fMark0 = 1; - } - // mark the nodes reachable through the failed nodes - Gia_ManForEachAnd( p->pAig, pObjOld, k ) - pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0); - // unmark the disproved nodes - Gia_ManForEachCo( pNew, pObj, k ) - { - iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); - iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); - if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved - continue; - pObjOld = Gia_ManObj(p->pAig, iNode); - assert( pObjOld->fMark0 == 1 ); - if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 ) - pObjOld->fMark1 = 1; - } - // clean marks - Gia_ManForEachAnd( p->pAig, pObjOld, k ) - if ( pObjOld->fMark1 ) - { - pObjOld->fMark0 = 0; - pObjOld->fMark1 = 0; - } + if ( (i % 4) == 0 && p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo ); + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; } - // set the results - Gia_ManForEachCo( pNew, pObj, k ) - { - iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); - iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); - pReprOld = Gia_ManObj(p->pAig, iRepr); - pObjOld = Gia_ManObj(p->pAig, iNode); - if ( pObj->fMark1 ) - { // proved - assert( pObj->fMark0 == 0 ); - assert( !Cec_ObjProved(p, iNode) ); - if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) -// if ( pObjOld->fMark0 == 0 ) - { - assert( iRepr == Cec_ObjRepr(p, iNode) ); - Cec_ObjSetProved( p, iNode ); - p->nAllProved++; - } - } - else if ( pObj->fMark0 ) - { // disproved - assert( pObj->fMark1 == 0 ); - if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) -// if ( pObjOld->fMark0 == 0 ) - { - if ( iRepr == Cec_ObjRepr(p, iNode) ) - printf( "Cec_ManCswClassesUpdate(): Error! Node is not refined!\n" ); - p->nAllDisproved++; - } - } - else - { // failed - assert( pObj->fMark0 == 0 ); - assert( pObj->fMark1 == 0 ); - assert( !Cec_ObjFailed(p, iNode) ); - assert( !Cec_ObjProved(p, iNode) ); - Cec_ObjSetFailed( p, iNode ); - p->nAllFailed++; - } - } + if ( p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); return 0; } - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c index ab8fd5cf..e25ddc90 100644 --- a/src/aig/cec/cecCore.c +++ b/src/aig/cec/cecCore.c @@ -44,11 +44,37 @@ void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ) memset( p, 0, sizeof(Cec_ParSat_t) ); p->nBTLimit = 10; // conflict limit at a node p->nSatVarMax = 2000; // the max number of SAT variables - p->nCallsRecycle = 100; // calls to perform before recycling SAT solver + p->nCallsRecycle = 200; // calls to perform before recycling SAT solver p->fPolarFlip = 1; // flops polarity of variables + p->fCheckMiter = 0; // the circuit is the miter p->fFirstStop = 0; // stop on the first sat output - p->fVerbose = 1; // verbose stats + p->fVerbose = 0; // verbose stats } + +/**Function************ ************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSim_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->TimeLimit = 0; // the runtime limit in seconds + p->fCheckMiter = 0; // the circuit is the miter + p->fFirstStop = 0; // stop on the first sat output + p->fDoubleOuts = 0; // miter with separate outputs + p->fSeqSimulate = 0; // performs sequential simulation + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} /**Function************ ************************************************* @@ -61,19 +87,21 @@ void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p ) +void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ) { - memset( p, 0, sizeof(Cec_ParCsw_t) ); - p->nWords = 20; // the number of simulation words - p->nRounds = 20; // the number of simulation rounds - p->nItersMax = 20; // the maximum number of iterations of SAT sweeping - p->nBTLimit = 10000; // conflict limit at a node - p->nSatVarMax = 2000; // the max number of SAT variables - p->nCallsRecycle = 100; // calls to perform before recycling SAT solver + memset( p, 0, sizeof(Cec_ParFra_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->TimeLimit = 0; // the runtime limit in seconds + p->nItersMax = 1000; // the maximum number of iterations of SAT sweeping + p->nBTLimit = 1000; // conflict limit at a node p->nLevelMax = 0; // restriction on the level of nodes to be swept p->nDepthMax = 1; // the depth in terms of steps of speculative reduction p->fRewriting = 0; // enables AIG rewriting + p->fCheckMiter = 0; // the circuit is the miter p->fFirstStop = 0; // stop on the first sat output + p->fDoubleOuts = 0; // miter with separate outputs + p->fColorDiff = 0; // miter with separate outputs p->fVeryVerbose = 0; // verbose stats p->fVerbose = 0; // verbose stats } @@ -92,14 +120,13 @@ void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p ) void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ) { memset( p, 0, sizeof(Cec_ParCec_t) ); - p->nIters = 1; // iterations of SAT solving/sweeping - p->nBTLimitBeg = 2; // starting backtrack limit - p->nBTlimitMulti = 8; // multiple of backtrack limiter + p->nBTLimit = 1000; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds + p->fFirstStop = 0; // stop on the first sat output p->fUseSmartCnf = 0; // use smart CNF computation p->fRewriting = 0; // enables AIG rewriting - p->fSatSweeping = 0; // enables SAT sweeping - p->fFirstStop = 0; // stop on the first sat output - p->fVerbose = 1; // verbose stats + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats } /**Function************************************************************* @@ -124,6 +151,35 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) return pNew; } +/**Function************************************************************* + + Synopsis [Core procedure for simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + Cec_ManSim_t * pSim; + int RetValue, clkTotal = clock(); + if ( pPars->fSeqSimulate ) + printf( "Performing sequential simulation of %d frames with %d words.\n", + pPars->nWords, pPars->nRounds ); + Aig_ManRandom( 1 ); + pSim = Cec_ManSimStart( pAig, pPars ); + if ( pAig->pReprs == NULL ) + RetValue = Cec_ManSimClassesPrepare( pSim ); + Cec_ManSimClassesRefine( pSim ); + if ( pPars->fCheckMiter ) + printf( "The number of failed outputs of the miter = %6d. (Words = %4d. Rounds = %4d.)\n", + pSim->iOut, pSim->nOuts, pPars->nWords, pPars->nRounds ); + ABC_PRT( "Time", clock() - clkTotal ); + Cec_ManSimStop( pSim ); +} /**Function************************************************************* @@ -136,96 +192,185 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ) +Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) { + int fOutputResult = 0; Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; - Gia_Man_t * pNew; - Cec_ManCsw_t * p; + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Gia_Man_t * pIni, * pSrm, * pTemp; + Cec_ManFra_t * p; + Cec_ManSim_t * pSim; Cec_ManPat_t * pPat; - int i, RetValue, clk, clk2, clkTotal = clock(); + int i, fTimeOut = 0, nMatches = 0, clk, clk2; + double clkTotal = clock(); + + // duplicate AIG and transfer equivalence classes Aig_ManRandom( 1 ); - Gia_ManSetPhase( pAig ); - Gia_ManCleanMark0( pAig ); - Gia_ManCleanMark1( pAig ); - p = Cec_ManCswStart( pAig, pPars ); -clk = clock(); - RetValue = Cec_ManCswClassesPrepare( p ); -p->timeSim += clock() - clk; + pIni = Gia_ManDup(pAig); + pIni->pReprs = pAig->pReprs; pAig->pReprs = NULL; + pIni->pNexts = pAig->pNexts; pAig->pNexts = NULL; + + // prepare the managers + // SAT sweeping + p = Cec_ManFraStart( pIni, pPars ); + if ( pPars->fDoubleOuts ) + pPars->fColorDiff = 1; + // simulation + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nRounds = pPars->nRounds; + pParsSim->fCheckMiter = pPars->fCheckMiter; + pParsSim->fFirstStop = pPars->fFirstStop; + pParsSim->fDoubleOuts = pPars->fDoubleOuts; + pParsSim->fVerbose = pPars->fVerbose; + pSim = Cec_ManSimStart( p->pAig, pParsSim ); + pSim->nWords = p->pPars->nWords; + // SAT solving Cec_ManSatSetDefaultParams( pParsSat ); pParsSat->nBTLimit = pPars->nBTLimit; pParsSat->fVerbose = pPars->fVeryVerbose; + // simulation patterns pPat = Cec_ManPatStart(); pPat->fVerbose = pPars->fVeryVerbose; + + // start equivalence classes +clk = clock(); + if ( p->pAig->pReprs == NULL ) + { + if ( Cec_ManSimClassesPrepare(pSim) || Cec_ManSimClassesRefine(pSim) ) + { + Gia_ManStop( p->pAig ); + p->pAig = NULL; + goto finalize; + } + } +p->timeSim += clock() - clk; + // perform solving for ( i = 1; i <= pPars->nItersMax; i++ ) { clk2 = clock(); - pNew = Cec_ManCswSpecReduction( p ); - if ( pPars->fVeryVerbose ) + nMatches = 0; + if ( pPars->fDoubleOuts ) { - Gia_ManPrintStats( p->pAig ); - Gia_ManPrintStats( pNew ); + nMatches = Gia_ManEquivSetColors( p->pAig, pPars->fVeryVerbose ); +// p->pAig->pIso = Cec_ManDetectIsomorphism( p->pAig ); +// Gia_ManEquivTransform( p->pAig, 1 ); } - if ( Gia_ManCoNum(pNew) == 0 ) + pSrm = Cec_ManFraSpecReduction( p ); + if ( pPars->fVeryVerbose ) + Gia_ManPrintStats( pSrm ); + if ( Gia_ManCoNum(pSrm) == 0 ) { - Gia_ManStop( pNew ); + Gia_ManStop( pSrm ); + if ( p->pPars->fVerbose ) + printf( "Considered all available candidate equivalences.\n" ); + if ( pPars->fDoubleOuts && Gia_ManAndNum(p->pAig) > 0 ) + { + if ( pPars->fColorDiff ) + { + if ( p->pPars->fVerbose ) + printf( "Switching into reduced mode.\n" ); + pPars->fColorDiff = 0; + } + else + { + if ( p->pPars->fVerbose ) + printf( "Switching into normal mode.\n" ); + pPars->fDoubleOuts = 0; + } + continue; + } break; } clk = clock(); - Cec_ManSatSolve( pPat, pNew, pParsSat ); + Cec_ManSatSolve( pPat, pSrm, pParsSat ); p->timeSat += clock() - clk; -clk = clock(); - Cec_ManCswClassesUpdate( p, pPat, pNew ); -p->timeSim += clock() - clk; - Gia_ManStop( pNew ); - pNew = Cec_ManCswDupWithClasses( p ); - Gia_WriteAiger( pNew, "gia_temp_new.aig", 0, 1 ); + if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) ) + { + Gia_ManStop( pSrm ); + Gia_ManStop( p->pAig ); + p->pAig = NULL; + goto finalize; + } + Gia_ManStop( pSrm ); + + // update the manager + pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDoubleOuts ); + Gia_ManStop( pTemp ); if ( p->pPars->fVerbose ) { - printf( "%3d : P =%7d. D =%7d. F =%6d. Lit =%8d. And =%8d. ", - i, p->nAllProved, p->nAllDisproved, p->nAllFailed, - Cec_ManCswCountLitsAll(p), Gia_ManAndNum(pNew) ); + printf( "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", + i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) ); ABC_PRT( "Time", clock() - clk2 ); } - if ( p->pPars->fVeryVerbose ) + if ( Gia_ManAndNum(p->pAig) == 0 ) { - ABC_PRTP( "Sim ", p->timeSim, clock() - clkTotal ); - ABC_PRTP( "Sat ", p->timeSat, clock() - clkTotal ); - ABC_PRT( "Time", clock() - clkTotal ); - printf( "****** Intermedate result %3d ******\n", i ); - Gia_ManPrintStats( p->pAig ); - Gia_ManPrintStats( pNew ); - printf("The result is written into file \"%s\".\n", "gia_temp.aig" ); - printf( "************************************\n" ); + if ( p->pPars->fVerbose ) + printf( "Network after reduction is empty.\n" ); + break; } - if ( Gia_ManAndNum(pNew) == 0 ) + // check resource limits + if ( p->pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= p->pPars->TimeLimit ) { - Gia_ManStop( pNew ); + fTimeOut = 1; break; } - Gia_ManStop( pNew ); +// if ( p->nAllFailed && !p->nAllProved && !p->nAllDisproved ) + if ( p->nAllFailed > p->nAllProved + p->nAllDisproved ) + { + if ( pParsSat->nBTLimit >= 10000 ) + break; + pParsSat->nBTLimit *= 10; + if ( p->pPars->fVerbose ) + { + if ( p->pPars->fVerbose ) + printf( "Increasing conflict limit to %d.\n", pParsSat->nBTLimit ); + if ( fOutputResult ) + { + Gia_WriteAiger( p->pAig, "gia_cec_temp.aig", 0, 0 ); + printf("The result is written into file \"%s\".\n", "gia_cec_temp.aig" ); + } + } + } + if ( pPars->fDoubleOuts && pPars->fColorDiff && Gia_ManAndNum(p->pAig) < 100000 ) + { + if ( p->pPars->fVerbose ) + printf( "Switching into reduced mode.\n" ); + pPars->fColorDiff = 0; + } + if ( pPars->fDoubleOuts && Gia_ManAndNum(p->pAig) < 20000 ) + { + if ( p->pPars->fVerbose ) + printf( "Switching into normal mode.\n" ); + pPars->fColorDiff = 0; + pPars->fDoubleOuts = 0; + } } - Gia_ManCleanMark0( pAig ); - Gia_ManCleanMark1( pAig ); - - // verify the result +finalize: if ( p->pPars->fVerbose ) { - printf( "Verifying the result:\n" ); - pNew = Cec_ManCswSpecReductionProved( p ); - pParsSat->nBTLimit = 1000000; - pParsSat->fVerbose = 1; - Cec_ManSatSolve( NULL, pNew, pParsSat ); - Gia_ManStop( pNew ); + ABC_PRTP( "Sim ", p->timeSim, clock() - (int)clkTotal ); + ABC_PRTP( "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal ); + ABC_PRTP( "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal ); + ABC_PRT( "Time", clock() - clkTotal ); } - // create the resulting miter - pAig->pReprs = Cec_ManCswDeriveReprs( p ); - pNew = Gia_ManDupDfsClasses( pAig ); - Cec_ManCswStop( p ); + pTemp = p->pAig; p->pAig = NULL; + if ( pTemp == NULL ) + printf( "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut ); + else if ( pSim->pCexes ) + printf( "Disproved %d outputs of the miter.\n", pSim->nOuts ); + if ( fTimeOut ) + printf( "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC ); + + pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL; + Cec_ManSimStop( pSim ); Cec_ManPatStop( pPat ); - return pNew; + Cec_ManFraStop( p ); + return pTemp; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecInt.h b/src/aig/cec/cecInt.h index 309f4292..1898b07c 100644 --- a/src/aig/cec/cecInt.h +++ b/src/aig/cec/cecInt.h @@ -65,6 +65,7 @@ struct Cec_ManPat_t_ int timeSort; // sorting literals int timePack; // packing into sim info structures int timeTotal; // total runtime + int timeTotalSave; // total runtime for saving }; // SAT solving manager @@ -100,38 +101,43 @@ struct Cec_ManSat_t_ int timeTotal; // total runtime }; -// combinational sweeping object -typedef struct Cec_ObjCsw_t_ Cec_ObjCsw_t; -struct Cec_ObjCsw_t_ -{ - int iRepr; // representative node - unsigned iNext : 30; // next node in the class - unsigned iProved : 1; // this node is proved - unsigned iFailed : 1; // this node is failed - unsigned SimNum; // simulation info number -}; - // combinational simulation manager -typedef struct Cec_ManCsw_t_ Cec_ManCsw_t; -struct Cec_ManCsw_t_ +typedef struct Cec_ManSim_t_ Cec_ManSim_t; +struct Cec_ManSim_t_ { // parameters Gia_Man_t * pAig; // the AIG to be used for simulation - Cec_ParCsw_t * pPars; // SAT sweeping parameters + Cec_ParSim_t * pPars; // simulation parameters int nWords; // the number of simulation words - // equivalence classes - Cec_ObjCsw_t * pObjs; // objects used for SAT sweeping // recycable memory + int * pSimInfo; // simulation information offsets unsigned * pMems; // allocated simulaton memory int nWordsAlloc; // the number of allocated entries int nMems; // the number of used entries int nMemsMax; // the max number of used entries int MemFree; // next free entry + int nWordsOld; // the number of simulation words after previous relink + // bug catcher + Vec_Ptr_t * vCiSimInfo; // CI simulation info + Vec_Ptr_t * vCoSimInfo; // CO simulation info + void ** pCexes; // counter-examples for each output + int iOut; // first failed output + int nOuts; // the number of failed outputs + Gia_Cex_t * pCexComb; // counter-example for the first failed output // temporaries Vec_Int_t * vClassOld; // old class numbers Vec_Int_t * vClassNew; // new class numbers Vec_Int_t * vClassTemp; // temporary storage Vec_Int_t * vRefinedC; // refined const reprs +}; + +// combinational simulation manager +typedef struct Cec_ManFra_t_ Cec_ManFra_t; +struct Cec_ManFra_t_ +{ + // parameters + Gia_Man_t * pAig; // the AIG to be used for simulation + Cec_ParFra_t * pPars; // SAT sweeping parameters // simulation patterns Vec_Int_t * vXorNodes; // nodes used in speculative reduction int nAllProved; // total number of proved nodes @@ -139,6 +145,7 @@ struct Cec_ManCsw_t_ int nAllFailed; // total number of failed nodes // runtime stats int timeSim; // unsat + int timePat; // unsat int timeSat; // sat int timeTotal; // total runtime }; @@ -153,29 +160,31 @@ struct Cec_ManCsw_t_ /*=== cecCore.c ============================================================*/ /*=== cecClass.c ============================================================*/ -extern int Cec_ManCswCountLitsAll( Cec_ManCsw_t * p ); -extern int * Cec_ManCswDeriveReprs( Cec_ManCsw_t * p ); -extern Gia_Man_t * Cec_ManCswSpecReduction( Cec_ManCsw_t * p ); -extern Gia_Man_t * Cec_ManCswSpecReductionProved( Cec_ManCsw_t * p ); -extern Gia_Man_t * Cec_ManCswDupWithClasses( Cec_ManCsw_t * p ); -extern int Cec_ManCswClassesPrepare( Cec_ManCsw_t * p ); -extern int Cec_ManCswClassesUpdate( Cec_ManCsw_t * p, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); +extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ); +extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p ); +extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ); +/*=== cecIso.c ============================================================*/ +extern int * Cec_ManDetectIsomorphism( Gia_Man_t * p ); /*=== cecMan.c ============================================================*/ -extern Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ); -extern void Cec_ManCswStop( Cec_ManCsw_t * p ); -extern Cec_ManPat_t * Cec_ManPatStart(); -extern void Cec_ManPatPrintStats( Cec_ManPat_t * p ); -extern void Cec_ManPatStop( Cec_ManPat_t * p ); extern Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); extern void Cec_ManSatPrintStats( Cec_ManSat_t * p ); extern void Cec_ManSatStop( Cec_ManSat_t * p ); +extern Cec_ManPat_t * Cec_ManPatStart(); +extern void Cec_ManPatPrintStats( Cec_ManPat_t * p ); +extern void Cec_ManPatStop( Cec_ManPat_t * p ); +extern Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); +extern void Cec_ManSimStop( Cec_ManSim_t * p ); +extern Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars ); +extern void Cec_ManFraStop( Cec_ManFra_t * p ); /*=== cecPat.c ============================================================*/ extern void Cec_ManPatSavePattern( Cec_ManPat_t * pPat, Cec_ManSat_t * p, Gia_Obj_t * pObj ); extern Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWords ); /*=== cecSolve.c ============================================================*/ extern int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj ); extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars ); -/*=== cecUtil.c ============================================================*/ +/*=== ceFraeep.c ============================================================*/ +extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ); +extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); #ifdef __cplusplus } diff --git a/src/aig/cec/cecIso.c b/src/aig/cec/cecIso.c new file mode 100644 index 00000000..08d4b7ec --- /dev/null +++ b/src/aig/cec/cecIso.c @@ -0,0 +1,370 @@ +/**CFile**************************************************************** + + FileName [cecIso.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecIso.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline unsigned * Cec_ManIsoInfo( unsigned * pStore, int nWords, int Id ) { return pStore + nWords * Id; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes simulation info for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoSimulate( Gia_Obj_t * pObj, int Id, unsigned * pStore, int nWords ) +{ + unsigned * pInfo = Cec_ManIsoInfo( pStore, nWords, Id ); + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId0(pObj, Id) ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId1(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Copies simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoCopy( int IdDest, int IdSour, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, IdDest ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, IdSour ); + int w; + for ( w = 0; w < nWords; w++ ) + pInfo0[w] = pInfo1[w]; +} + +/**Function************************************************************* + + Synopsis [Compares simulation info of two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoEqual( int Id0, int Id1, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id0 ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Id1 ); + int w; + for ( w = 0; w < nWords; w++ ) + if ( pInfo0[w] != pInfo1[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Generates random simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoRandom( int Id, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id ); + int w; + for ( w = 0; w < nWords; w++ ) + pInfo0[w] = Aig_ManRandom( 0 ); +} + +/**Function************************************************************* + + Synopsis [Computes hash key of the simuation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoHashKey( int Id, unsigned * pStore, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id ); + unsigned uHash = 0; + int i; + for ( i = 0; i < nWords; i++ ) + uHash ^= pInfo0[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Adds node to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoTableAdd( Gia_Man_t * p, int Id, unsigned * pStore, int nWords, int * pTable, int nTableSize ) +{ + Gia_Obj_t * pTemp; + int Key, Ent, Counter = 0, Color = Gia_ObjColors( p, Id ); + assert( Color == 1 || Color == 2 ); + Key = Gia_ManIsoHashKey( Id, pStore, nWords, nTableSize ); + for ( Ent = pTable[Key], pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp; + Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) ) + { + if ( Gia_ObjColors( p, Ent ) != Color ) + continue; + if ( !Gia_ManIsoEqual( Id, Ent, pStore, nWords ) ) + continue; + // found node with the same color and signature - mark it and do not add new node + pTemp->fMark0 = 1; + return; + } + // did not find the node with the same color and signature - add new node + pTemp = Gia_ManObj( p, Id ); + assert( pTemp->Value == 0 ); + assert( pTemp->fMark0 == 0 ); + pTemp->Value = pTable[Key]; + pTable[Key] = Id; +} + +/**Function************************************************************* + + Synopsis [Extracts equivalence class candidates from one bin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoExtractClasses( Gia_Man_t * p, int Bin, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB ) +{ + Gia_Obj_t * pTemp; + int Ent; + Vec_IntClear( vNodesA ); + Vec_IntClear( vNodesB ); + for ( Ent = Bin, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp; + Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) ) + { + if ( pTemp->fMark0 ) + { + pTemp->fMark0 = 0; + continue; + } + if ( Gia_ObjColors( p, Ent ) == 1 ) + Vec_IntPush( vNodesA, Ent ); + else + Vec_IntPush( vNodesB, Ent ); + } + return Vec_IntSize(vNodesA) > 0 && Vec_IntSize(vNodesB) > 0; +} + +/**Function************************************************************* + + Synopsis [Matches nodes in the extacted classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoMatchNodes( int * pIso, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB ) +{ + int k0, k1, IdA, IdB; + Vec_IntForEachEntry( vNodesA, IdA, k0 ) + Vec_IntForEachEntry( vNodesB, IdB, k1 ) + { + if ( Gia_ManIsoEqual( IdA, IdB, pStore, nWords ) ) + { + assert( pIso[IdA] == 0 ); + assert( pIso[IdB] == 0 ); + assert( IdA != IdB ); + pIso[IdA] = IdB; + pIso[IdB] = IdA; + continue; + } + } +} + +/**Function************************************************************* + + Synopsis [Transforms iso into equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManTransformClasses( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts && p->pIso ); + memset( p->pReprs, 0, sizeof(int) * Gia_ManObjNum(p) ); + memset( p->pNexts, 0, sizeof(int) * Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( p->pIso[i] && p->pIso[i] < i ) + { + p->pReprs[i].iRepr = p->pIso[i]; + p->pNexts[p->pIso[i]] = i; + } + } +} + +/**Function************************************************************* + + Synopsis [Finds node correspondences in the miter.] + + Description [Assumes that the colors are assigned.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Cec_ManDetectIsomorphism( Gia_Man_t * p ) +{ + int nWords = 2; + Gia_Obj_t * pObj; + Vec_Int_t * vNodesA, * vNodesB; + unsigned * pStore, Counter; + int i, * pIso, * pTable, nTableSize; + // start equivalence classes + pIso = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjColors(p, i) == 0 ); + continue; + } + assert( Gia_ObjColors(p, i) ); + if ( Gia_ObjColors(p, i) == 3 ) + pIso[i] = i; + } + // start simulation info + pStore = ABC_ALLOC( unsigned, Gia_ManObjNum(p) * nWords ); + // simulate and create table + nTableSize = Aig_PrimeCudd( 100 + Gia_ManObjNum(p)/2 ); + pTable = ABC_CALLOC( int, nTableSize ); + Gia_ManCleanValue( p ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + continue; + if ( pIso[i] == 0 ) // simulate + Gia_ManIsoSimulate( pObj, i, pStore, nWords ); + else if ( pIso[i] < i ) // copy + Gia_ManIsoCopy( i, pIso[i], pStore, nWords ); + else // generate + Gia_ManIsoRandom( i, pStore, nWords ); + if ( pIso[i] == 0 ) + Gia_ManIsoTableAdd( p, i, pStore, nWords, pTable, nTableSize ); + } + // create equivalence classes + vNodesA = Vec_IntAlloc( 100 ); + vNodesB = Vec_IntAlloc( 100 ); + for ( i = 0; i < nTableSize; i++ ) + if ( Gia_ManIsoExtractClasses( p, pTable[i], pStore, nWords, vNodesA, vNodesB ) ) + Gia_ManIsoMatchNodes( pIso, pStore, nWords, vNodesA, vNodesB ); + Vec_IntFree( vNodesA ); + Vec_IntFree( vNodesB ); + // collect info + Counter = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + Counter += (pIso[i] && pIso[i] < i); +/* + if ( pIso[i] && pIso[i] < i ) + { + if ( (Gia_ObjIsHead(p,pIso[i]) && Gia_ObjRepr(p,i)==pIso[i]) || + (Gia_ObjIsClass(p,pIso[i]) && Gia_ObjRepr(p,i)==Gia_ObjRepr(p,pIso[i])) ) + printf( "1" ); + else + printf( "0" ); + } +*/ + } + printf( "Computed %d pairs of structurally equivalent nodes.\n", Counter ); +// p->pIso = pIso; +// Cec_ManTransformClasses( p ); + + ABC_FREE( pTable ); + ABC_FREE( pStore ); + return pIso; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecMan.c b/src/aig/cec/cecMan.c index b8ee75b2..1a94409f 100644 --- a/src/aig/cec/cecMan.c +++ b/src/aig/cec/cecMan.c @@ -30,7 +30,7 @@ /**Function************************************************************* - Synopsis [Creates AIG.] + Synopsis [Creates the manager.] Description [] @@ -39,26 +39,25 @@ SeeAlso [] ***********************************************************************/ -Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ) -{ - Cec_ManCsw_t * p; - p = ABC_ALLOC( Cec_ManCsw_t, 1 ); - memset( p, 0, sizeof(Cec_ManCsw_t) ); - p->pAig = pAig; - p->pPars = pPars; - p->pObjs = ABC_CALLOC( Cec_ObjCsw_t, Gia_ManObjNum(pAig) ); - // temporaries - p->vClassOld = Vec_IntAlloc( 1000 ); - p->vClassNew = Vec_IntAlloc( 1000 ); - p->vClassTemp = Vec_IntAlloc( 1000 ); - p->vRefinedC = Vec_IntAlloc( 10000 ); - p->vXorNodes = Vec_IntAlloc( 1000 ); +Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) +{ + Cec_ManSat_t * p; + // create interpolation manager + p = ABC_ALLOC( Cec_ManSat_t, 1 ); + memset( p, 0, sizeof(Cec_ManSat_t) ); + p->pPars = pPars; + p->pAig = pAig; + // SAT solving + p->nSatVars = 1; + p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); + p->vUsedNodes = Vec_PtrAlloc( 1000 ); + p->vFanins = Vec_PtrAlloc( 100 ); return p; } /**Function************************************************************* - Synopsis [Deletes AIG.] + Synopsis [Prints statistics of the manager.] Description [] @@ -67,19 +66,46 @@ Cec_ManCsw_t * Cec_ManCswStart( Gia_Man_t * pAig, Cec_ParCsw_t * pPars ) SeeAlso [] ***********************************************************************/ -void Cec_ManCswStop( Cec_ManCsw_t * p ) +void Cec_ManSatPrintStats( Cec_ManSat_t * p ) { - Vec_IntFree( p->vXorNodes ); - Vec_IntFree( p->vClassOld ); - Vec_IntFree( p->vClassNew ); - Vec_IntFree( p->vClassTemp ); - Vec_IntFree( p->vRefinedC ); - ABC_FREE( p->pMems ); - ABC_FREE( p->pObjs ); + printf( "CO = %6d ", Gia_ManCoNum(p->pAig) ); + printf( "Conf = %5d ", p->pPars->nBTLimit ); + printf( "MinVar = %5d ", p->pPars->nSatVarMax ); + printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Frees the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatStop( Cec_ManSat_t * p ) +{ + if ( p->pSat ) + sat_solver_delete( p->pSat ); + Vec_PtrFree( p->vUsedNodes ); + Vec_PtrFree( p->vFanins ); + ABC_FREE( p->pSatVars ); ABC_FREE( p ); } + /**Function************************************************************* Synopsis [Creates AIG.] @@ -147,9 +173,11 @@ void Cec_ManPatStop( Cec_ManPat_t * p ) ABC_FREE( p ); } + + /**Function************************************************************* - Synopsis [Creates the manager.] + Synopsis [Creates AIG.] Description [] @@ -158,25 +186,31 @@ void Cec_ManPatStop( Cec_ManPat_t * p ) SeeAlso [] ***********************************************************************/ -Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) -{ - Cec_ManSat_t * p; - // create interpolation manager - p = ABC_ALLOC( Cec_ManSat_t, 1 ); - memset( p, 0, sizeof(Cec_ManSat_t) ); - p->pPars = pPars; - p->pAig = pAig; - // SAT solving - p->nSatVars = 1; - p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); - p->vUsedNodes = Vec_PtrAlloc( 1000 ); - p->vFanins = Vec_PtrAlloc( 100 ); +Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + Cec_ManSim_t * p; + p = ABC_ALLOC( Cec_ManSim_t, 1 ); + memset( p, 0, sizeof(Cec_ManSim_t) ); + p->pAig = pAig; + p->pPars = pPars; + p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); + p->vClassOld = Vec_IntAlloc( 1000 ); + p->vClassNew = Vec_IntAlloc( 1000 ); + p->vClassTemp = Vec_IntAlloc( 1000 ); + p->vRefinedC = Vec_IntAlloc( 10000 ); + p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords ); + if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) ) + { + p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords ); + Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords ); + } + p->iOut = -1; return p; } /**Function************************************************************* - Synopsis [Prints statistics of the manager.] + Synopsis [Deletes AIG.] Description [] @@ -185,26 +219,27 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) SeeAlso [] ***********************************************************************/ -void Cec_ManSatPrintStats( Cec_ManSat_t * p ) +void Cec_ManSimStop( Cec_ManSim_t * p ) { - printf( "CO = %6d ", Gia_ManCoNum(p->pAig) ); - printf( "Conf = %5d ", p->pPars->nBTLimit ); - printf( "MinVar = %5d ", p->pPars->nSatVarMax ); - printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle ); - printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", - p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); - ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); - printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", - p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); - ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); - printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", - p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); - ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + Vec_IntFree( p->vClassOld ); + Vec_IntFree( p->vClassNew ); + Vec_IntFree( p->vClassTemp ); + Vec_IntFree( p->vRefinedC ); + if ( p->vCiSimInfo ) + Vec_PtrFree( p->vCiSimInfo ); + if ( p->vCoSimInfo ) + Vec_PtrFree( p->vCoSimInfo ); + ABC_FREE( p->pCexComb ); + ABC_FREE( p->pCexes ); + ABC_FREE( p->pMems ); + ABC_FREE( p->pSimInfo ); + ABC_FREE( p ); } + /**Function************************************************************* - Synopsis [Frees the manager.] + Synopsis [Creates AIG.] Description [] @@ -213,16 +248,35 @@ void Cec_ManSatPrintStats( Cec_ManSat_t * p ) SeeAlso [] ***********************************************************************/ -void Cec_ManSatStop( Cec_ManSat_t * p ) +Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) +{ + Cec_ManFra_t * p; + p = ABC_ALLOC( Cec_ManFra_t, 1 ); + memset( p, 0, sizeof(Cec_ManFra_t) ); + p->pAig = pAig; + p->pPars = pPars; + p->vXorNodes = Vec_IntAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraStop( Cec_ManFra_t * p ) { - if ( p->pSat ) - sat_solver_delete( p->pSat ); - Vec_PtrFree( p->vUsedNodes ); - Vec_PtrFree( p->vFanins ); - ABC_FREE( p->pSatVars ); + Vec_IntFree( p->vXorNodes ); ABC_FREE( p ); } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecPat.c b/src/aig/cec/cecPat.c index 1af4f333..b80f1e44 100644 --- a/src/aig/cec/cecPat.c +++ b/src/aig/cec/cecPat.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [cec.c] + FileName [cecPat.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Combinatinoal equivalence checking.] - Synopsis [] + Synopsis [Simulation pattern manager.] Author [Alan Mishchenko] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: cec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ diff --git a/src/aig/cec/cecSim.c b/src/aig/cec/cecSim.c new file mode 100644 index 00000000..dbd3bd5e --- /dev/null +++ b/src/aig/cec/cecSim.c @@ -0,0 +1,48 @@ +/**CFile**************************************************************** + + FileName [cecSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Simulation manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecSolve.c b/src/aig/cec/cecSolve.c index e4daf719..ba4b0477 100644 --- a/src/aig/cec/cecSolve.c +++ b/src/aig/cec/cecSolve.c @@ -390,6 +390,70 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p ) /**Function************************************************************* + Synopsis [Sets variable activities in the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_SetActivityFactors_rec( Cec_ManSat_t * p, Gia_Obj_t * pObj, int LevelMin, int LevelMax ) +{ + float dActConeBumpMax = 20.0; + int iVar; + // skip visited variables + if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p->pAig, pObj); + // add the PI to the list + if ( Gia_ObjLevel(p->pAig, pObj) <= LevelMin || Gia_ObjIsCi(pObj) ) + return; + // set the factor of this variable + // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pPars->dActConeBumpMax / ThisBump + if ( (iVar = Cec_ObjSatNum(p,pObj)) ) + { + p->pSat->factors[iVar] = dActConeBumpMax * (Gia_ObjLevel(p->pAig, pObj) - LevelMin)/(LevelMax - LevelMin); + veci_push(&p->pSat->act_vars, iVar); + } + // explore the fanins + Cec_SetActivityFactors_rec( p, Gia_ObjFanin0(pObj), LevelMin, LevelMax ); + Cec_SetActivityFactors_rec( p, Gia_ObjFanin1(pObj), LevelMin, LevelMax ); +} + +/**Function************************************************************* + + Synopsis [Sets variable activities in the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SetActivityFactors( Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + float dActConeRatio = 0.5; + int LevelMin, LevelMax; + // reset the active variables + veci_resize(&p->pSat->act_vars, 0); + // prepare for traversal + Gia_ManIncrementTravId( p->pAig ); + // determine the min and max level to visit + assert( dActConeRatio > 0 && dActConeRatio < 1 ); + LevelMax = Gia_ObjLevel(p->pAig,pObj); + LevelMin = (int)(LevelMax * (1.0 - dActConeRatio)); + // traverse + Cec_SetActivityFactors_rec( p, pObj, LevelMin, LevelMax ); +//Cec_PrintActivity( p ); + return 1; +} + + +/**Function************************************************************* + Synopsis [Runs equivalence test for the two nodes.] Description [] @@ -402,7 +466,7 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p ) int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) { int nBTLimit = p->pPars->nBTLimit; - int Lit, RetValue, status, clk, nConflicts; + int Lit, RetValue, status, clk, clk2, nConflicts; p->nCallsSince++; // experiment with this!!! p->nSatTotal++; @@ -415,7 +479,14 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) Cec_ManSatSolverRecycle( p ); // if the nodes do not have SAT variables, allocate them +clk2 = clock(); Cec_CnfNodeAddToSolver( p, Gia_ObjFanin0(pObj) ); +//ABC_PRT( "cnf", clock() - clk2 ); +//printf( "%d \n", p->pSat->size ); + +clk2 = clock(); +// Cec_SetActivityFactors( p, Gia_ObjFanin0(pObj) ); +//ABC_PRT( "act", clock() - clk2 ); // propage unit clauses if ( p->pSat->qtail != p->pSat->qhead ) @@ -435,8 +506,12 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) //Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); clk = clock(); nConflicts = p->pSat->stats.conflicts; + +clk2 = clock(); RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); +//ABC_PRT( "sat", clock() - clk2 ); + if ( RetValue == l_False ) { p->timeSatUnsat += clock() - clk; @@ -466,6 +541,7 @@ p->timeSatUndec += clock() - clk; } } + /**Function************************************************************* Synopsis [Performs one round of solving for the POs of the AIG.] @@ -486,7 +562,7 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar Bar_Progress_t * pProgress = NULL; Cec_ManSat_t * p; Gia_Obj_t * pObj; - int i, status, clk = clock(); + int i, status, clk = clock(), clk2; // sprintf( Buffer, "gia%03d.aig", Counter++ ); //Gia_WriteAiger( pAig, Buffer, 0, 0 ); @@ -499,8 +575,9 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar pPat->nPats = 0; pPat->nPatLits = 0; pPat->nPatLitsMin = 0; - } + } Gia_ManSetPhase( pAig ); + Gia_ManLevelNum( pAig ); Gia_ManResetTravId( pAig ); p = Cec_ManSatCreate( pAig, pPars ); pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); @@ -512,13 +589,19 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar pObj->fMark1 = 1; continue; } -//printf( "Output %6d : ", i ); - Bar_ProgressUpdate( pProgress, i, "SAT..." ); +clk2 = clock(); status = Cec_ManSatCheckNode( p, pObj ); pObj->fMark0 = (status == 0); pObj->fMark1 = (status == 1); /* +printf( "Output %6d : ", i ); +printf( "conf = %6d ", p->pSat->stats.conflicts ); +printf( "prop = %6d ", p->pSat->stats.propagations ); +ABC_PRT( "time", clock() - clk2 ); +*/ + +/* if ( status == -1 ) { Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj ); @@ -531,7 +614,11 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar continue; // save the pattern if ( pPat ) + { + int clk3 = clock(); Cec_ManPatSavePattern( pPat, p, pObj ); + pPat->timeTotalSave += clock() - clk3; + } // quit if one of them is solved if ( pPars->fFirstStop ) break; diff --git a/src/aig/cec/cecSweep.c b/src/aig/cec/cecSweep.c new file mode 100644 index 00000000..20a668bd --- /dev/null +++ b/src/aig/cec/cecSweep.c @@ -0,0 +1,294 @@ +/**CFile**************************************************************** + + FileName [ceFraeep.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [SAT sweeping manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ceFraeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs limited speculative reduction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + int iRes0, iRes1, iRepr, iNode, iMiter; + int i, fCompl, * piCopies, * pDepths; + Gia_ManSetPhase( p->pAig ); + Vec_IntClear( p->vXorNodes ); + if ( p->pPars->nLevelMax ) + Gia_ManLevelNum( p->pAig ); + pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); + pNew->pName = Aig_UtilStrsav( p->pAig->pName ); + Gia_ManHashAlloc( pNew ); + piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); + pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); + piCopies[0] = 0; + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + piCopies[i] = Gia_ManAppendCi( pNew ); + continue; + } + if ( Gia_ObjIsCo(pObj) ) + continue; + if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 || + piCopies[Gia_ObjFaninId1(pObj,i)] == -1 ) + continue; + iRes0 = Gia_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); + iRes1 = Gia_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); + iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); + pDepths[i] = AIG_MAX( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] ); + if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID || Gia_ObjFailed(p->pAig, i) ) + continue; + assert( Gia_ObjRepr(p->pAig, i) < i ); + iRepr = piCopies[Gia_ObjRepr(p->pAig, i)]; + if ( iRepr == -1 ) + continue; + if ( Gia_LitRegular(iNode) == Gia_LitRegular(iRepr) ) + continue; + if ( p->pPars->nLevelMax && + (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax || + Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) ) + continue; + if ( p->pPars->fDoubleOuts ) + { +// if ( i % 1000 == 0 && Gia_ObjRepr(p->pAig, i) ) +// Gia_ManEquivPrintOne( p->pAig, Gia_ObjRepr(p->pAig, i), 0 ); + if ( p->pPars->fColorDiff ) + { + if ( !Gia_ObjDiffColors( p->pAig, Gia_ObjRepr(p->pAig, i), i ) ) + continue; + } + else + { + if ( !Gia_ObjDiffColors2( p->pAig, Gia_ObjRepr(p->pAig, i), i ) ) + continue; + } + } + pRepr = Gia_ManObj( p->pAig, Gia_ObjRepr(p->pAig, i) ); + fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); + piCopies[i] = Gia_LitNotCond( iRepr, fCompl ); + if ( Gia_ObjProved(p->pAig, i) ) + continue; + // produce speculative miter + iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); + Gia_ManAppendCo( pNew, iMiter ); + Vec_IntPush( p->vXorNodes, Gia_ObjRepr(p->pAig, i) ); + Vec_IntPush( p->vXorNodes, i ); + // add to the depth of this node + pDepths[i] = 1 + AIG_MAX( pDepths[i], pDepths[Gia_ObjRepr(p->pAig, i)] ); + if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax ) + piCopies[i] = -1; + } + ABC_FREE( piCopies ); + ABC_FREE( pDepths ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManFraClassesUpdate_rec( Gia_Obj_t * pObj ) +{ + int Result; + if ( pObj->fMark0 ) + return 1; + if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) + return 0; + Result = (Cec_ManFraClassesUpdate_rec( Gia_ObjFanin0(pObj) ) | + Cec_ManFraClassesUpdate_rec( Gia_ObjFanin1(pObj) )); + return pObj->fMark0 = Result; +} + +/**Function************************************************************* + + Synopsis [Creates simulation info for this round.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vCiInfo, Vec_Ptr_t * vInfo, int nSeries ) +{ + unsigned * pRes0, * pRes1; + int i, w; + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pRes0 = Vec_PtrEntry( vCiInfo, i ); + pRes1 = Vec_PtrEntry( vInfo, i ); + pRes1 += p->nWords * nSeries; + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = pRes1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Updates equivalence classes using the patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ) +{ + Vec_Ptr_t * vInfo; + Gia_Obj_t * pObj, * pObjOld, * pReprOld; + int i, k, iRepr, iNode, clk; +clk = clock(); + vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), pSim->nWords ); +p->timePat += clock() - clk; +clk = clock(); + if ( vInfo != NULL ) + { + Gia_ManSetRefs( p->pAig ); + for ( i = 0; i < pPat->nSeries; i++ ) + { + Cec_ManFraCreateInfo( pSim, pSim->vCiSimInfo, vInfo, i ); + if ( Cec_ManSimSimulateRound( pSim, pSim->vCiSimInfo, pSim->vCoSimInfo ) ) + { + Vec_PtrFree( vInfo ); + return 1; + } + } + Vec_PtrFree( vInfo ); + } +p->timeSim += clock() - clk; + assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) ); + // mark the transitive fanout of failed nodes + if ( p->pPars->nDepthMax != 1 ) + { + Gia_ManCleanMark0( p->pAig ); + Gia_ManCleanMark1( p->pAig ); + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved + continue; +// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1; + Gia_ManObj(p->pAig, iNode)->fMark0 = 1; + } + // mark the nodes reachable through the failed nodes + Gia_ManForEachAnd( p->pAig, pObjOld, k ) + pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0); + // unmark the disproved nodes + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved + continue; + pObjOld = Gia_ManObj(p->pAig, iNode); + assert( pObjOld->fMark0 == 1 ); + if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 ) + pObjOld->fMark1 = 1; + } + // clean marks + Gia_ManForEachAnd( p->pAig, pObjOld, k ) + if ( pObjOld->fMark1 ) + { + pObjOld->fMark0 = 0; + pObjOld->fMark1 = 0; + } + } + // set the results + p->nAllProved = p->nAllDisproved = p->nAllFailed = 0; + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + pReprOld = Gia_ManObj(p->pAig, iRepr); + pObjOld = Gia_ManObj(p->pAig, iNode); + if ( pObj->fMark1 ) + { // proved + assert( pObj->fMark0 == 0 ); + assert( !Gia_ObjProved(p->pAig, iNode) ); + if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) +// if ( pObjOld->fMark0 == 0 ) + { + assert( iRepr == Gia_ObjRepr(p->pAig, iNode) ); + Gia_ObjSetProved( p->pAig, iNode ); + p->nAllProved++; + } + } + else if ( pObj->fMark0 ) + { // disproved + assert( pObj->fMark1 == 0 ); + if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) +// if ( pObjOld->fMark0 == 0 ) + { + if ( iRepr == Gia_ObjRepr(p->pAig, iNode) ) + printf( "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" ); + p->nAllDisproved++; + } + } + else + { // failed + assert( pObj->fMark0 == 0 ); + assert( pObj->fMark1 == 0 ); + assert( !Gia_ObjFailed(p->pAig, iNode) ); + assert( !Gia_ObjProved(p->pAig, iNode) ); + Gia_ObjSetFailed( p->pAig, iNode ); + p->nAllFailed++; + } + } + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/module.make b/src/aig/cec/module.make index f8e2602a..4618c424 100644 --- a/src/aig/cec/module.make +++ b/src/aig/cec/module.make @@ -1,5 +1,9 @@ -SRC += src/aig/cec/cecClass.c \ +SRC += src/aig/cec/cecCec.c \ + src/aig/cec/cecClass.c \ src/aig/cec/cecCore.c \ + src/aig/cec/cecIso.c \ src/aig/cec/cecMan.c \ src/aig/cec/cecPat.c \ - src/aig/cec/cecSolve.c + src/aig/cec/cecSim.c \ + src/aig/cec/cecSolve.c \ + src/aig/cec/cecSweep.c diff --git a/src/aig/dar/darRefact.c b/src/aig/dar/darRefact.c index f0173a3c..f64564fa 100644 --- a/src/aig/dar/darRefact.c +++ b/src/aig/dar/darRefact.c @@ -113,7 +113,7 @@ Ref_Man_t * Dar_ManRefStart( Aig_Man_t * pAig, Dar_RefPar_t * pPars ) // other data p->vCuts = Vec_VecStart( pPars->nCutsMax ); p->vTruthElem = Vec_PtrAllocTruthTables( pPars->nLeafMax ); - p->vTruthStore = Vec_PtrAllocSimInfo( 256, Kit_TruthWordNum(pPars->nLeafMax) ); + p->vTruthStore = Vec_PtrAllocSimInfo( 1024, Kit_TruthWordNum(pPars->nLeafMax) ); p->vMemory = Vec_IntAlloc( 1 << 16 ); p->vCutNodes = Vec_PtrAlloc( 256 ); p->vLeavesBest = Vec_PtrAlloc( pPars->nLeafMax ); diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index b77dd76f..91507947 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -36,27 +36,50 @@ extern "C" { #endif #define GIA_NONE 0x1FFFFFFF +#define GIA_VOID 0x0FFFFFFF //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Gia_Rpr_t_ Gia_Rpr_t; +struct Gia_Rpr_t_ +{ + unsigned iRepr : 28; // representative node + unsigned fProved : 1; // marks the proved equivalence + unsigned fFailed : 1; // marks the failed equivalence + unsigned fColorA : 1; // marks cone of A + unsigned fColorB : 1; // marks cone of B +}; + typedef struct Gia_Obj_t_ Gia_Obj_t; struct Gia_Obj_t_ { - unsigned iDiff0 : 29; // the diff of the first fanin - unsigned fCompl0: 1; // the complemented attribute - unsigned fMark0 : 1; // first user-controlled mark - unsigned fTerm : 1; // terminal node (CI/CO) + unsigned iDiff0 : 29; // the diff of the first fanin + unsigned fCompl0: 1; // the complemented attribute + unsigned fMark0 : 1; // first user-controlled mark + unsigned fTerm : 1; // terminal node (CI/CO) - unsigned iDiff1 : 29; // the diff of the second fanin - unsigned fCompl1: 1; // the complemented attribute - unsigned fMark1 : 1; // second user-controlled mark - unsigned fPhase : 1; // value under 000 pattern + unsigned iDiff1 : 29; // the diff of the second fanin + unsigned fCompl1: 1; // the complemented attribute + unsigned fMark1 : 1; // second user-controlled mark + unsigned fPhase : 1; // value under 000 pattern unsigned Value; // application-specific value }; +// sequential counter-example +typedef struct Gia_Cex_t_ Gia_Cex_t; +struct Gia_Cex_t_ +{ + int iPo; // the zero-based number of PO, for which verification failed + int iFrame; // the zero-based number of the time-frame, for which verificaiton failed + int nRegs; // the number of registers in the miter + int nPis; // the number of primary inputs in the miter + int nBits; // the number of words of bit data used + unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) +}; + typedef struct Gia_Man_t_ Gia_Man_t; struct Gia_Man_t_ { @@ -76,23 +99,42 @@ struct Gia_Man_t_ int nLevels; // the mamixum level int nTravIds; // the current traversal ID int nFront; // frontier size - int * pReprs; // representatives (for CIs and ANDs) + int * pReprsOld; // representatives (for CIs and ANDs) + Gia_Rpr_t * pReprs; // representatives (for CIs and ANDs) + int * pNexts; // next nodes in the equivalence classes + int * pIso; // pairs of structurally isomorphic nodes int nTerLoop; // the state where loop begins int nTerStates; // the total number of ternary states int * pFanData; // the database to store fanout information int nFansAlloc; // the size of fanout representation + int * pMapping; // mapping for each node + Gia_Cex_t * pCexComb; // combinational counter-example }; +typedef struct Emb_Par_t_ Emb_Par_t; +struct Emb_Par_t_ +{ + int nDims; // the number of dimension + int nSols; // the number of solutions (typically, 2) + int nIters; // the number of iterations of FORCE + int fRefine; // use refinement by FORCE + int fCluster; // use clustered representation + int fDump; // dump Gnuplot file + int fDumpLarge; // dump Gnuplot file for large benchmarks + int fShowImage; // shows image if Gnuplot is installed + int fVerbose; // verbose flag +}; + // frames parameters typedef struct Gia_ParFra_t_ Gia_ParFra_t; struct Gia_ParFra_t_ { - int nFrames; // the number of frames to unroll - int fInit; // initialize the timeframes - int fVerbose; // enables verbose output + int nFrames; // the number of frames to unroll + int fInit; // initialize the timeframes + int fVerbose; // enables verbose output }; @@ -180,17 +222,17 @@ static inline int Gia_ObjFaninId0p( Gia_Man_t * p, Gia_Obj_t * pObj ) { static inline int Gia_ObjFaninId1p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId1( pObj, Gia_ObjId(p, pObj) ); } static inline int Gia_ObjFaninLit0( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninC0(pObj) ); } static inline int Gia_ObjFaninLit1( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId1(pObj, ObjId), Gia_ObjFaninC1(pObj) ); } -static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); } -static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); } +static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); } static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); pObj->fCompl0 ^= 1; } static inline int Gia_ObjWhatFanin( Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { return Gia_ObjFanin0(pObj) == pFanin ? 0 : (Gia_ObjFanin1(pObj) == pFanin ? 1 : -1); } -static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); } -static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); } +static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); } static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { return Gia_NotCond( Gia_ManObj(p, Gia_Lit2Var(iLit)), Gia_LitIsCompl(iLit) ); } -static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); } -static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } +static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); } +static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(p->pLevels);return p->pLevels[Gia_ObjId(p, pObj)]; } @@ -204,12 +246,12 @@ static inline void Gia_ObjRefFanin0Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ static inline void Gia_ObjRefFanin1Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin1(pObj)); } static inline void Gia_ManResetTravId( Gia_Man_t * p ) { extern void Gia_ManCleanValue( Gia_Man_t * p ); Gia_ManCleanValue( p ); p->nTravIds = 1; } -static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; } -static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } -static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; } -static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } -static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } -static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } +static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; } +static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } +static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; } +static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } +static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } +static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } // AIG construction extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); @@ -293,6 +335,54 @@ static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCom return GIA_ONE; } +static inline Gia_Obj_t * Gia_ObjReprObj( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr == GIA_VOID ? NULL : Gia_ManObj( p, p->pReprs[Id].iRepr ); } +static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; } +static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { p->pReprs[Id].iRepr = Num; } + +static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; } +static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; } + +static inline int Gia_ObjFailed( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fFailed; } +static inline void Gia_ObjSetFailed( Gia_Man_t * p, int Id ) { p->pReprs[Id].fFailed = 1; } + +static inline int Gia_ObjColor( Gia_Man_t * p, int Id, int c ) { return c? p->pReprs[Id].fColorB : p->pReprs[Id].fColorA; } +static inline int Gia_ObjColors( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fColorB * 2 + p->pReprs[Id].fColorA; } +static inline void Gia_ObjSetColor( Gia_Man_t * p, int Id, int c ) { if (c) p->pReprs[Id].fColorB = 1; else p->pReprs[Id].fColorA = 1; } +static inline void Gia_ObjSetColors( Gia_Man_t * p, int Id ) { p->pReprs[Id].fColorB = p->pReprs[Id].fColorA = 1; } +static inline int Gia_ObjVisitColor( Gia_Man_t * p, int Id, int c ) { int x; if (c) { x = p->pReprs[Id].fColorB; p->pReprs[Id].fColorB = 1; } else { x = p->pReprs[Id].fColorA; p->pReprs[Id].fColorA = 1; } return x; } +static inline int Gia_ObjDiffColors( Gia_Man_t * p, int i, int j ) { return (p->pReprs[i].fColorA ^ p->pReprs[j].fColorA) && (p->pReprs[i].fColorB ^ p->pReprs[j].fColorB); } +static inline int Gia_ObjDiffColors2( Gia_Man_t * p, int i, int j ) { return (p->pReprs[i].fColorA ^ p->pReprs[j].fColorA) || (p->pReprs[i].fColorB ^ p->pReprs[j].fColorB); } + +static inline int Gia_ObjNext( Gia_Man_t * p, int Id ) { return p->pNexts[Id]; } +static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p->pNexts[Id] = Num; } + +static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; } +static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; } +static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; } + +#define Gia_ManForEachConst( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else +#define Gia_ManForEachClass( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ManForEachClassReverse( p, i ) \ + for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ClassForEachObj( p, i, iObj ) \ + for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) ) +#define Gia_ClassForEachObj1( p, i, iObj ) \ + for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) + + +static inline int Gia_ObjIsGate( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; } +static inline int Gia_ObjGateSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; } +static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; } + +#define Gia_ManForEachGate( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsGate(p, i) ) {} else +#define Gia_GateForEachFanin( p, i, iFan, k ) \ + for ( k = 0; k < Gia_ObjGateSize(p,i) && ((iFan = Gia_ObjGateFanins(p,i)[k]),1); k++ ) + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -351,18 +441,30 @@ extern Gia_Man_t * Gia_ManDupDfsSkip( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj ); extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ); -extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ); -extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar ); +extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ); +extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan ); extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); +extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fXorOuts, int fComb, int fVerbose ); +extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ); +/*=== giaEnable.c ==========================================================*/ +extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset ); +/*=== giaEquiv.c ==========================================================*/ +extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); +extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter ); +extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ); +extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ); +extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ); +extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p ); +extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ); /*=== giaFanout.c =========================================================*/ extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); extern void Gia_ManFanoutStart( Gia_Man_t * p ); extern void Gia_ManFanoutStop( Gia_Man_t * p ); /*=== giaForce.c =========================================================*/ -extern void For_ManExperiment( Gia_Man_t * pGia ); +extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose ); /*=== giaFrames.c =========================================================*/ extern void Gia_ManFraSetDefaultParams( Gia_ParFra_t * p ); extern Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars ); @@ -380,7 +482,7 @@ extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p ); /*=== giaLogic.c ===========================================================*/ extern void Gia_ManTestDistance( Gia_Man_t * p ); -extern void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, int fDump, int fVerbose ); +extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ); /*=== giaMan.c ===========================================================*/ extern Gia_Man_t * Gia_ManStart( int nObjsMax ); extern void Gia_ManStop( Gia_Man_t * p ); @@ -388,13 +490,18 @@ extern void Gia_ManPrintStats( Gia_Man_t * p ); extern void Gia_ManPrintStatsShort( Gia_Man_t * p ); extern void Gia_ManPrintMiterStatus( Gia_Man_t * p ); extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); +/*=== giaMap.c ===========================================================*/ +extern void Gia_ManPrintMappingStats( Gia_Man_t * p ); /*=== giaSat.c ============================================================*/ extern int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax ); /*=== giaScl.c ============================================================*/ +extern int Gia_ManSeqMarkUsed( Gia_Man_t * p ); extern int Gia_ManCombMarkUsed( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); +/*=== giaSort.c ============================================================*/ +extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ); /*=== giaSim.c ============================================================*/ extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); /*=== giaTsim.c ============================================================*/ @@ -411,6 +518,7 @@ extern void Gia_ManFillValue( Gia_Man_t * p ); extern void Gia_ManSetPhase( Gia_Man_t * p ); extern int Gia_ManLevelNum( Gia_Man_t * p ); extern void Gia_ManSetRefs( Gia_Man_t * p ); +extern int * Gia_ManCreateMuxRefs( Gia_Man_t * p ); extern void Gia_ManCreateRefs( Gia_Man_t * p ); extern int Gia_ManCrossCut( Gia_Man_t * p ); extern int Gia_ManIsNormalized( Gia_Man_t * p ); @@ -418,6 +526,7 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ); extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode ); extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ); extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ); +extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDoubleOuts ); #ifdef __cplusplus } diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index 8b59341a..544cfe0d 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -92,10 +92,9 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ) } // add logic for the POs Aig_ManForEachPo( p, pObj, i ) - { Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Aig_ManForEachPo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); - } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; } @@ -133,10 +132,9 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) } // add logic for the POs Aig_ManForEachPo( p, pObj, i ) - { Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Aig_ManForEachPo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); - } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; } diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 40c5329d..cfd2dc73 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -175,6 +175,120 @@ char * Gia_TimeStamp() /**Function************************************************************* + Synopsis [Read integer from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadInt( unsigned char * pPos ) +{ + int i, Value = 0; + for ( i = 0; i < 4; i++ ) + Value = (Value << 8) | *pPos++; + return Value; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, Item, fProved, iRepr, iNode; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + pReprs = ABC_CALLOC( Gia_Rpr_t, nSize ); + for ( i = 0; i < nSize; i++ ) + pReprs[i].iRepr = GIA_VOID; + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + { + iRepr += (Item >> 1); + iNode = iRepr; +//printf( "\nRepr = %d ", iRepr ); + continue; + } + Item >>= 1; + fProved = (Item & 1); + Item >>= 1; + iNode += Item; + pReprs[iNode].fProved = fProved; + pReprs[iNode].iRepr = iRepr; +//printf( "Node = %d ", iNode ); + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) +{ + int * pMapping; + unsigned char * pStop; + int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + nAlloc = nSize + pStop - *ppPos; + pMapping = ABC_CALLOC( int, nAlloc ); + while ( *ppPos < pStop ) + { + k = iOffset; + pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos ); + for ( j = 0; j <= nFanins; j++ ) + pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode ); + pMapping[iNode] = iOffset; + iOffset = k; + } + assert( iOffset <= nAlloc ); + return pMapping; +} + +/**Function************************************************************* + Synopsis [Reads the AIG in the binary AIGER format.] Description [] @@ -328,6 +442,38 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) // create the latches Gia_ManSetRegNum( pNew, nLatches ); + // check if there are other types of information to read + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + pCur++; + if ( *pCur == 'e' ) + { + pCur++; + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + } + if ( *pCur == 'm' ) + { + pCur++; + // read mapping + pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'p' ) + { + pCur++; + // read placement + } + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Aig_UtilStrsav( pCur ); + } + } + // skipping the comments ABC_FREE( pContents ); Vec_IntFree( vNodes ); @@ -443,6 +589,144 @@ Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits ) /**Function************************************************************* + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteInt( unsigned char * pPos, int Value ) +{ + int i; + for ( i = 3; i >= 0; i-- ) + *pPos++ = (Value >> (8*i)) & 255; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos; + assert( p->pReprs && p->pNexts ); + // count the number of entries to be written + nItems = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write constant class + iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); +//printf( "\nRepr = %d ", 0 ); + iPrevNode = 0; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { +//printf( "Node = %d ", iNode ); + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { +//printf( "\nRepr = %d ", iRepr ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) ); + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { +//printf( "Node = %d ", iNode ); + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + } + Gia_WriteInt( pBuffer, iPos ); + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +{ + if ( iPrev < iThis ) + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) ); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) +{ + unsigned char * pBuffer; + int i, k, iPrev, iFan, nItems, iPos = 4; + assert( p->pMapping ); + // count the number of entries to be written + nItems = 0; + Gia_ManForEachGate( p, i ) + nItems += 2 + Gia_ObjGateSize( p, i ); + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write non-constant classes + iPrev = 0; + Gia_ManForEachGate( p, i ) + { +//printf( "\nSize = %d ", Gia_ObjGateSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjGateSize(p, i) ); + Gia_GateForEachFanin( p, i, iFan, k ) + { +//printf( "Fan = %d ", iFan ); + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); + iPrev = iFan; + } + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i ); + iPrev = i; +//printf( "Node = %d ", i ); + } +//printf( "\n" ); + Gia_WriteInt( pBuffer, iPos ); + *pMapSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + Synopsis [Writes the AIG in the binary AIGER format.] Description [] @@ -536,10 +820,29 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int ABC_FREE( pBuffer ); // write the comment - fprintf( pFile, "c\n" ); + fprintf( pFile, "c" ); + // write equivalences + if ( p->pReprs && p->pNexts ) + { + int nEquivSize; + unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize ); + fprintf( pFile, "e" ); + fwrite( pEquivs, 1, nEquivSize, pFile ); + ABC_FREE( pEquivs ); + } + // write mapping + if ( p->pMapping ) + { + int nMapSize; + unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize ); + fprintf( pFile, "m" ); + fwrite( pMaps, 1, nMapSize, pFile ); + ABC_FREE( pMaps ); + } + // write placement if ( p->pName ) - fprintf( pFile, ".model %s\n", p->pName ); - fprintf( pFile, "This file was produced by the AIG package on %s\n", Gia_TimeStamp() ); + fprintf( pFile, "n%s%c", p->pName, '\0' ); + fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); fclose( pFile ); if ( p != pInit ) diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index d58429cd..735aca72 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -41,6 +41,7 @@ struct Cof_Obj_t_ unsigned fMark1 : 1; // second user-controlled mark unsigned nFanins : 4; // the number of fanins unsigned nFanouts : 24; // total number of fanouts + unsigned nFanoutsM; // total number of MUX ctrl fanouts unsigned Value; // application specific data int Id; // ID of the node int iNext; // next one in the linked list @@ -124,6 +125,7 @@ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia ) Cof_Man_t * p; Cof_Obj_t * pObjLog, * pFanLog; Gia_Obj_t * pObj; + int * pMuxRefs; int i, iHandle = 0; p = ABC_CALLOC( Cof_Man_t, 1 ); p->pGia = pGia; @@ -173,11 +175,14 @@ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia ) p->nObjs++; } assert( iHandle == p->nObjData ); + pMuxRefs = Gia_ManCreateMuxRefs( pGia ); Gia_ManForEachObj( pGia, pObj, i ) { pObjLog = Cof_ManObj( p, Gia_ObjHandle(pObj) ); assert( pObjLog->nFanouts == pObjLog->Value ); + pObjLog->nFanoutsM = pMuxRefs[i]; } + ABC_FREE( pMuxRefs ); return p; } @@ -509,8 +514,7 @@ int Cof_ManCountRemoved( Cof_Man_t * p, Cof_Obj_t * pRoot, int fConst1 ) void Cof_ManPrintHighFanoutOne( Cof_Man_t * p, Cof_Obj_t * pObj ) { printf( "%7d : ", pObj->Id ); - printf( "fi =%2d ", Cof_ObjFaninNum(pObj) ); - printf( "fo =%5d ", Cof_ObjFanoutNum(pObj) ); + printf( "i/o/c =%2d %5d %5d ", Cof_ObjFaninNum(pObj), Cof_ObjFanoutNum(pObj), 2*pObj->nFanoutsM ); printf( "l =%4d ", Cof_ObjLevel(p, pObj) ); printf( "s =%5d ", Cof_ManSuppSize(p, &pObj, 1) ); printf( "TFI =%7d ", Cof_ManTfiSize(p, &pObj, 1) ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index d5c0862f..4821dba9 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -196,11 +196,11 @@ int Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( ~pObj->Value ) return pObj->Value; - if ( p->pReprs && ~p->pReprs[Gia_ObjId(p, pObj)] ) + if ( p->pReprsOld && ~p->pReprsOld[Gia_ObjId(p, pObj)] ) { - Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprs[Gia_ObjId(p, pObj)] ); - pObj->Value = Gia_ManDupDfs_rec( pNew, p, pRepr ); - return pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprsOld[Gia_ObjId(p, pObj)] ); + pRepr->Value = Gia_ManDupDfs_rec( pNew, p, pRepr ); + return pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); } if ( Gia_ObjIsCi(pObj) ) return pObj->Value = Gia_ManAppendCi(pNew); @@ -380,7 +380,7 @@ Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) +Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; @@ -391,12 +391,12 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) Gia_ManSetRefs( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) - if ( pObj->Value > 0 || Gia_ObjIsRo(p, pObj) ) + if ( !fTrimCis || pObj->Value > 0 || Gia_ObjIsRo(p, pObj) ) pObj->Value = Gia_ManAppendCi(pNew); Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, i ) - if ( !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) ) + if ( !fTrimCos || !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); return pNew; @@ -413,11 +413,16 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar ) +Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pPivot; int i, iCofVar = -1; + if ( nLimFan > 0 ) + { + printf( "This feature is not implemented.\n" ); + return NULL; + } if ( !(iVar > 0 && iVar < Gia_ManObjNum(p)) ) { printf( "Gia_ManDupCofactored(): Variable %d is out of range (%d; %d).\n", iVar, 0, Gia_ManObjNum(p) ); @@ -502,7 +507,7 @@ void Gia_ManPrintRepr( Gia_Man_t * p ) Gia_Obj_t * pObj; int i; Gia_ManForEachObj( p, pObj, i ) - if ( ~p->pReprs[i] ) + if ( ~p->pReprsOld[i] ) printf( "%d->%d ", i, p->pReprs[i] ); printf( "\n" ); } @@ -569,7 +574,7 @@ Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ) Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; - assert( p->pReprs != NULL ); + assert( p->pReprsOld != NULL ); Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); @@ -719,6 +724,195 @@ Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ) } +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Creates miter of two designs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManMiter( Gia_Man_t * p0, Gia_Man_t * p1, int fXorOuts, int fComb, int fVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, iLit; + if ( fComb ) + { + if ( Gia_ManCiNum(p0) != Gia_ManCiNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of CIs.\n" ); + return NULL; + } + if ( Gia_ManCoNum(p0) != Gia_ManCoNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of COs.\n" ); + return NULL; + } + } + else + { + if ( Gia_ManPiNum(p0) != Gia_ManPiNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of PIs.\n" ); + return NULL; + } + if ( Gia_ManPoNum(p0) != Gia_ManPoNum(p1) ) + { + printf( "Gia_ManMiter(): Designs have different number of POs.\n" ); + return NULL; + } + if ( Gia_ManRegNum(p0) == 0 || Gia_ManRegNum(p1) == 0 ) + { + printf( "Gia_ManMiter(): At least one of the designs has no registers.\n" ); + return NULL; + } + } + // start the manager + pNew = Gia_ManStart( Gia_ManObjNum(p0) + Gia_ManObjNum(p1) ); + pNew->pName = Aig_UtilStrsav( "miter" ); + // map combinational inputs + Gia_ManFillValue( p0 ); + Gia_ManFillValue( p1 ); + Gia_ManConst0(p0)->Value = 0; + Gia_ManConst0(p1)->Value = 0; + // map internal nodes and outputs + Gia_ManHashAlloc( pNew ); + if ( fComb ) + { + // create combinational inputs + Gia_ManForEachCi( p0, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachCi( p1, pObj, i ) + pObj->Value = Gia_ObjToLit( pNew, Gia_ManCi(pNew, i) ); + // create combinational outputs + Gia_ManForEachCo( p0, pObj, i ) + { + Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) ); + Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(Gia_ManCo(p1,i)) ); + if ( fXorOuts ) + { + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(Gia_ManCo(p1,i)) ); + Gia_ManAppendCo( pNew, iLit ); + } + else + { + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p1,i)) ); + } + } + } + else + { + // create primary inputs + Gia_ManForEachPi( p0, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachPi( p1, pObj, i ) + pObj->Value = Gia_ObjToLit( pNew, Gia_ManPi(pNew, i) ); + // create latch outputs + Gia_ManForEachRo( p0, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachRo( p1, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // create primary outputs + Gia_ManForEachPo( p0, pObj, i ) + { + Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) ); + Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(Gia_ManPo(p1,i)) ); + if ( fXorOuts ) + { + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(Gia_ManPo(p1,i)) ); + Gia_ManAppendCo( pNew, iLit ); + } + else + { + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManPo(p1,i)) ); + } + } + // create register inputs + Gia_ManForEachRi( p0, pObj, i ) + { + Gia_ManMiter_rec( pNew, p0, Gia_ObjFanin0(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManForEachRi( p1, pObj, i ) + { + Gia_ManMiter_rec( pNew, p1, Gia_ObjFanin0(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p0) + Gia_ManRegNum(p1) ); + } + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transforms the circuit into a regular miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pObj2; + int i, iLit; + assert( (Gia_ManPoNum(p) & 1) == 0 ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + { + pObj2 = Gia_ManPo( p, ++i ); + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(pObj2) ); + Gia_ManAppendCo( pNew, iLit ); + } + Gia_ManForEachRi( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index 0469d1a4..6c2f00df 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -25,12 +25,18 @@ The code is based on the paper by D. Harel and Y. Koren, "Graph drawing by high-dimensional embedding", J. Graph Algs & Apps, Vol 8(2), pp. 195-217 (2004). + http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf + + Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah. + "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// + typedef float Emb_Dat_t; typedef struct Emb_Obj_t_ Emb_Obj_t; @@ -90,10 +96,10 @@ static inline Emb_Obj_t * Emb_ManCo( Emb_Man_t * p, int i ) static inline int Emb_ObjIsTerm( Emb_Obj_t * pObj ) { return pObj->fCi || pObj->fCo; } static inline int Emb_ObjIsCi( Emb_Obj_t * pObj ) { return pObj->fCi; } static inline int Emb_ObjIsCo( Emb_Obj_t * pObj ) { return pObj->fCo; } -static inline int Emb_ObjIsPi( Emb_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; } -static inline int Emb_ObjIsPo( Emb_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; } +//static inline int Emb_ObjIsPi( Emb_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; } +//static inline int Emb_ObjIsPo( Emb_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; } static inline int Emb_ObjIsNode( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins > 0; } -static inline int Emb_ObjIsConst0( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins == 0; } +//static inline int Emb_ObjIsConst0( Emb_Obj_t * pObj ) { return!Emb_ObjIsTerm(pObj) && pObj->nFanins == 0; } static inline int Emb_ObjSize( Emb_Obj_t * pObj ) { return sizeof(Emb_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } static inline int Emb_ObjFaninNum( Emb_Obj_t * pObj ) { return pObj->nFanins; } @@ -109,8 +115,8 @@ static inline void Emb_ObjSetTravIdPrevious( Emb_Man_t * p, Emb_Obj_t * p static inline int Emb_ObjIsTravIdCurrent( Emb_Man_t * p, Emb_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds); } static inline int Emb_ObjIsTravIdPrevious( Emb_Man_t * p, Emb_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds - 1); } -static inline Emb_Dat_t * Emb_ManVec( Emb_Man_t * p, int v ) { return p->pVecs + v * p->nObjs; } -static inline float * Emb_ManSol( Emb_Man_t * p, int v ) { return p->pSols + v * p->nObjs; } +static inline Emb_Dat_t * Emb_ManVec( Emb_Man_t * p, int v ) { return p->pVecs + v * p->nObjs; } +static inline float * Emb_ManSol( Emb_Man_t * p, int v ) { return p->pSols + v * p->nObjs; } #define Emb_ManForEachObj( p, pObj, i ) \ for ( i = 0; (i < p->nObjData) && (pObj = Emb_ManObj(p,i)); i += Emb_ObjSize(pObj) ) @@ -171,13 +177,13 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) p->nRegs = Gia_ManRegNum(pGia); p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); - p->nObjData = (sizeof(Emb_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia) + Gia_ManRegNum(pGia)); + p->nObjData = (sizeof(Emb_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia) + Gia_ManRegNum(pGia) + Gia_ManCoNum(pGia)); p->pObjData = ABC_CALLOC( int, p->nObjData ); // create constant node Gia_ManConst0(pGia)->Value = hHandle; pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; - pObjLog->nFanins = 0; + pObjLog->nFanins = Gia_ManCoNum(pGia); //0; pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); // count objects hHandle += Emb_ObjSize( pObjLog ); @@ -227,7 +233,7 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; pObjLog->nFanins = 1; - pObjLog->nFanouts = Gia_ObjIsRi( pGia, pObj ); + pObjLog->nFanouts = 1 + Gia_ObjIsRi( pGia, pObj ); pObjLog->fCo = 1; // add fanins pFanLog = Emb_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); @@ -249,8 +255,8 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) if ( !~Gia_ObjValue(pObj) ) continue; pObjLog = Emb_ManObj( p, Gia_ObjValue(pObj) ); - assert( pObjLog->nFanins == pObjLog->iFanin ); - assert( pObjLog->nFanouts == pObjLog->iFanout ); + assert( pObjLog->nFanins == pObjLog->iFanin || Gia_ObjIsConst0(pObj) ); + assert( pObjLog->nFanouts == pObjLog->iFanout || Gia_ObjIsCo(pObj) ); pObjLog->iFanin = pObjLog->iFanout = 0; } ABC_FREE( pGia->pRefs ); @@ -496,13 +502,13 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia ) p->nRegs = Gia_ManRegNum(pGia); p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); - p->nObjData = (sizeof(Emb_Obj_t) / 4) * nObjs + 2 * (nFanios + Gia_ManRegNum(pGia)); + p->nObjData = (sizeof(Emb_Obj_t) / 4) * nObjs + 2 * (nFanios + Gia_ManRegNum(pGia) + Gia_ManCoNum(pGia)); p->pObjData = ABC_CALLOC( int, p->nObjData ); // create constant node Gia_ManConst0(pGia)->Value = hHandle; pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; - pObjLog->nFanins = 0; + pObjLog->nFanins = Gia_ManCoNum(pGia); //0; pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); // count objects hHandle += Emb_ObjSize( pObjLog ); @@ -563,7 +569,7 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia ) pObjLog = Emb_ManObj( p, hHandle ); pObjLog->hHandle = hHandle; pObjLog->nFanins = 1; - pObjLog->nFanouts = Gia_ObjIsRi( pGia, pObj ); + pObjLog->nFanouts = 1 + Gia_ObjIsRi( pGia, pObj ); pObjLog->fCo = 1; // add fanins pFanLog = Emb_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); @@ -587,8 +593,8 @@ Emb_Man_t * Emb_ManStart( Gia_Man_t * pGia ) if ( !~Gia_ObjValue(pObj) ) continue; pObjLog = Emb_ManObj( p, Gia_ObjValue(pObj) ); - assert( pObjLog->nFanins == pObjLog->iFanin ); - assert( pObjLog->nFanouts == pObjLog->iFanout ); + assert( pObjLog->nFanins == pObjLog->iFanin || Gia_ObjIsConst0(pObj) ); + assert( pObjLog->nFanouts == pObjLog->iFanout || Gia_ObjIsCo(pObj) ); pObjLog->iFanin = pObjLog->iFanout = 0; } ABC_FREE( pGia->pRefs ); @@ -904,7 +910,7 @@ ABC_PRT( "Time", clock() - clk ); /**Function************************************************************* - Synopsis [Computes the distances from the given set of objects.] + Synopsis [Perform BFS from the set of nodes.] Description [Returns one of the most distant objects.] @@ -913,20 +919,11 @@ ABC_PRT( "Time", clock() - clk ); SeeAlso [] ***********************************************************************/ -Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * pDist ) +Emb_Obj_t * Emb_ManPerformBfs( Emb_Man_t * p, Vec_Int_t * vThis, Vec_Int_t * vNext, Emb_Dat_t * pDist ) { - Vec_Int_t * vThis, * vNext, * vTemp; + Vec_Int_t * vTemp; Emb_Obj_t * pThis, * pNext, * pResult; int i, k; - p->nReached = p->nDistMax = 0; - vThis = Vec_IntAlloc( 1000 ); - vNext = Vec_IntAlloc( 1000 ); - Emb_ManIncrementTravId( p ); - Emb_ManForEachObjVec( vStart, p, pThis, i ) - { - Emb_ObjSetTravIdCurrent( p, pThis ); - Vec_IntPush( vThis, pThis->hHandle ); - } assert( Vec_IntSize(vThis) > 0 ); for ( p->nDistMax = 0; Vec_IntSize(vThis) > 0; p->nDistMax++ ) { @@ -955,6 +952,74 @@ Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * assert( Vec_IntSize(vNext) > 0 ); pResult = Emb_ManObj( p, Vec_IntEntry(vNext, 0) ); assert( pDist == NULL || pDist[pResult->Value] == p->nDistMax - 1 ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Computes the distances from the given set of objects.] + + Description [Returns one of the most distant objects.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Emb_ManConnectedComponents( Emb_Man_t * p ) +{ + Gia_Obj_t * pObj; + Vec_Int_t * vThis, * vNext, * vResult; + Emb_Obj_t * pThis; + int i; + vResult = Vec_IntAlloc( 1000 ); + vThis = Vec_IntAlloc( 1000 ); + vNext = Vec_IntAlloc( 1000 ); + p->nReached = 0; + Emb_ManIncrementTravId( p ); + Gia_ManForEachCo( p->pGia, pObj, i ) + { + pThis = Emb_ManObj( p, Gia_ObjValue(pObj) ); + if ( Emb_ObjIsTravIdCurrent(p, pThis) ) + continue; + Emb_ObjSetTravIdCurrent( p, pThis ); + Vec_IntPush( vResult, pThis->hHandle ); + // perform BFS from this node + Vec_IntClear( vThis ); + Vec_IntPush( vThis, pThis->hHandle ); + Emb_ManPerformBfs( p, vThis, vNext, NULL ); + } + Vec_IntFree( vThis ); + Vec_IntFree( vNext ); + return vResult; +} + +/**Function************************************************************* + + Synopsis [Computes the distances from the given set of objects.] + + Description [Returns one of the most distant objects.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Emb_Obj_t * Emb_ManFindDistances( Emb_Man_t * p, Vec_Int_t * vStart, Emb_Dat_t * pDist ) +{ + Vec_Int_t * vThis, * vNext; + Emb_Obj_t * pThis, * pResult; + int i; + p->nReached = p->nDistMax = 0; + vThis = Vec_IntAlloc( 1000 ); + vNext = Vec_IntAlloc( 1000 ); + Emb_ManIncrementTravId( p ); + Emb_ManForEachObjVec( vStart, p, pThis, i ) + { + Emb_ObjSetTravIdCurrent( p, pThis ); + Vec_IntPush( vThis, pThis->hHandle ); + } + pResult = Emb_ManPerformBfs( p, vThis, vNext, pDist ); Vec_IntFree( vThis ); Vec_IntFree( vNext ); return pResult; @@ -1029,13 +1094,28 @@ void Emb_DumpGraphIntoFile( Emb_Man_t * p ) void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims ) { Emb_Obj_t * pRandom, * pPivot; - Vec_Int_t * vStart; + Vec_Int_t * vStart, * vComps; int d, nReached; - int i, Counter; + int i;//, Counter; + // connect unconnected components + vComps = Emb_ManConnectedComponents( p ); +// printf( "Components = %d. Considered %d objects (out of %d).\n", Vec_IntSize(vComps), p->nReached, Emb_ManObjNum(p) ); + if ( Vec_IntSize(vComps) > 1 ) + { + Emb_Obj_t * pFanin, * pObj = Emb_ManObj( p, 0 ); + Emb_ManForEachObjVec( vComps, p, pFanin, i ) + { + assert( Emb_ObjIsCo(pFanin) ); + pFanin->Fanios[pFanin->nFanins + pFanin->nFanouts-1] = + pObj->Fanios[i] = pObj->hHandle - pFanin->hHandle; + } + } + Vec_IntFree( vComps ); + // allocate memory for vectors assert( p->pVecs == NULL ); - p->pVecs = ABC_ALLOC( Emb_Dat_t, p->nObjs * nDims ); - for ( i = 0; i < p->nObjs * nDims; i++ ) - p->pVecs[i] = ABC_INFINITY; + p->pVecs = ABC_CALLOC( Emb_Dat_t, p->nObjs * nDims ); +// for ( i = 0; i < p->nObjs * nDims; i++ ) +// p->pVecs[i] = ABC_INFINITY; vStart = Vec_IntAlloc( nDims ); // get the pivot vertex pRandom = Emb_ManRandomVertex( p ); @@ -1046,7 +1126,7 @@ void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims ) nReached = p->nReached; if ( nReached < Emb_ManObjNum(p) ) { - printf( "Considering a connected component with %d objects (out of %d).\n", p->nReached, Emb_ManObjNum(p) ); +// printf( "Considering a connected component with %d objects (out of %d).\n", p->nReached, Emb_ManObjNum(p) ); } // start dimensions with this vertex Vec_IntClear( vStart ); @@ -1061,11 +1141,11 @@ void Emb_ManComputeDimensions( Emb_Man_t * p, int nDims ) } Vec_IntFree( vStart ); // make sure the number of reached objects is correct - Counter = 0; - for ( i = 0; i < p->nObjs; i++ ) - if ( p->pVecs[i] < ABC_INFINITY ) - Counter++; - assert( Counter == nReached ); +// Counter = 0; +// for ( i = 0; i < p->nObjs; i++ ) +// if ( p->pVecs[i] < ABC_INFINITY ) +// Counter++; +// assert( Counter == nReached ); } /**Function************************************************************* @@ -1338,7 +1418,6 @@ void Emb_ManComputeSolutions( Emb_Man_t * p, int nDims, int nSols ) ***********************************************************************/ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) { - extern int * Gia_SortFloats( float * pArray, int nSize ); float * pY0, * pY1, Max0, Max1, Min0, Min1, Str0, Str1; int * pPerm0, * pPerm1; int k; @@ -1373,10 +1452,10 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) pY1[k] = (pY1[k] != 0.0) ? ((pY1[k] - Min1) * Str1) : 0.0; // derive the order of these numbers - pPerm0 = Gia_SortFloats( pY0, p->nObjs ); - pPerm1 = Gia_SortFloats( pY1, p->nObjs ); + pPerm0 = Gia_SortFloats( pY0, NULL, p->nObjs ); + pPerm1 = Gia_SortFloats( pY1, NULL, p->nObjs ); - // average solutions and project them into 32K by 32K square + // average solutions and project them into square [0;0xffff] x [0;0xffff] p->pPlacement = ABC_ALLOC( unsigned short, 2 * p->nObjs ); for ( k = 0; k < p->nObjs; k++ ) { @@ -1387,6 +1466,127 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) ABC_FREE( pPerm1 ); } + +/**Function************************************************************* + + Synopsis [Computes wire-length.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Emb_ManComputeHPWL( Emb_Man_t * p ) +{ + double Result = 0.0; + Emb_Obj_t * pThis, * pNext; + int i, k, iMinX, iMaxX, iMinY, iMaxY; + if ( p->pPlacement == NULL ) + return 0.0; + Emb_ManForEachObj( p, pThis, i ) + { + iMinX = iMaxX = p->pPlacement[2*pThis->Value+0]; + iMinY = iMaxY = p->pPlacement[2*pThis->Value+1]; + Emb_ObjForEachFanout( pThis, pNext, k ) + { + iMinX = ABC_MIN( iMinX, p->pPlacement[2*pNext->Value+0] ); + iMaxX = ABC_MAX( iMaxX, p->pPlacement[2*pNext->Value+0] ); + iMinY = ABC_MIN( iMinY, p->pPlacement[2*pNext->Value+1] ); + iMaxY = ABC_MAX( iMaxY, p->pPlacement[2*pNext->Value+1] ); + } + Result += (iMaxX - iMinX) + (iMaxY - iMinY); + } + return Result; +} + + +/**Function************************************************************* + + Synopsis [Performs iterative refinement of the given placement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Emb_ManPlacementRefine( Emb_Man_t * p, int nIters, int fVerbose ) +{ + Emb_Obj_t * pThis, * pNext; + double CostThis, CostPrev; + float * pEdgeX, * pEdgeY; + float * pVertX, * pVertY; + float VertX, VertY; + int * pPermX, * pPermY; + int i, k, Iter, iMinX, iMaxX, iMinY, iMaxY; + int clk = clock(); + if ( p->pPlacement == NULL ) + return; + pEdgeX = ABC_ALLOC( float, p->nObjs ); + pEdgeY = ABC_ALLOC( float, p->nObjs ); + pVertX = ABC_ALLOC( float, p->nObjs ); + pVertY = ABC_ALLOC( float, p->nObjs ); + // refine placement + CostPrev = 0.0; + for ( Iter = 0; Iter < nIters; Iter++ ) + { + // compute centers of hyperedges + CostThis = 0.0; + Emb_ManForEachObj( p, pThis, i ) + { + iMinX = iMaxX = p->pPlacement[2*pThis->Value+0]; + iMinY = iMaxY = p->pPlacement[2*pThis->Value+1]; + Emb_ObjForEachFanout( pThis, pNext, k ) + { + iMinX = ABC_MIN( iMinX, p->pPlacement[2*pNext->Value+0] ); + iMaxX = ABC_MAX( iMaxX, p->pPlacement[2*pNext->Value+0] ); + iMinY = ABC_MIN( iMinY, p->pPlacement[2*pNext->Value+1] ); + iMaxY = ABC_MAX( iMaxY, p->pPlacement[2*pNext->Value+1] ); + } + pEdgeX[pThis->Value] = 0.5 * (iMaxX + iMinX); + pEdgeY[pThis->Value] = 0.5 * (iMaxY + iMinY); + CostThis += (iMaxX - iMinX) + (iMaxY - iMinY); + } + // compute new centers of objects + Emb_ManForEachObj( p, pThis, i ) + { + VertX = pEdgeX[pThis->Value]; + VertY = pEdgeY[pThis->Value]; + Emb_ObjForEachFanin( pThis, pNext, k ) + { + VertX += pEdgeX[pNext->Value]; + VertY += pEdgeY[pNext->Value]; + } + pVertX[pThis->Value] = VertX / (Emb_ObjFaninNum(pThis) + 1); + pVertY[pThis->Value] = VertY / (Emb_ObjFaninNum(pThis) + 1); + } + // sort these numbers + pPermX = Gia_SortFloats( pVertX, NULL, p->nObjs ); + pPermY = Gia_SortFloats( pVertY, NULL, p->nObjs ); + for ( k = 0; k < p->nObjs; k++ ) + { + p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); + p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); + } + ABC_FREE( pPermX ); + ABC_FREE( pPermY ); + // evaluate cost + if ( fVerbose ) + { + printf( "%2d : HPWL = %e ", Iter+1, CostThis ); + ABC_PRT( "Time", clock() - clk ); + } + } + ABC_FREE( pEdgeX ); + ABC_FREE( pEdgeY ); + ABC_FREE( pVertX ); + ABC_FREE( pVertY ); +} + + /**Function************************************************************* Synopsis [Derives solutions from original vectors and eigenvectors.] @@ -1413,6 +1613,68 @@ void Emb_ManPrintSolutions( Emb_Man_t * p, int nSols ) /**Function************************************************************* + Synopsis [Prepares image for dumping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Emb_ManDumpGnuplotPrepare( Emb_Man_t * p ) +{ +// int nRows = 496; +// int nCols = 710; + int nRows = 500; + int nCols = 700; + Vec_Int_t * vLines; + Emb_Obj_t * pThis; + char * pBuffer, ** ppRows; + int i, k, placeX, placeY; + int fStart; + // alloc memory + pBuffer = ABC_CALLOC( char, nRows * (nCols+1) ); + ppRows = ABC_ALLOC( char *, nRows ); + for ( i = 0; i < nRows; i++ ) + ppRows[i] = pBuffer + i*(nCols+1); + // put data into them + Emb_ManForEachObj( p, pThis, i ) + { + placeX = p->pPlacement[2*pThis->Value+0] * nCols / (1<<16); + placeY = p->pPlacement[2*pThis->Value+1] * nRows / (1<<16); + assert( placeX < nCols && placeY < nRows ); + ppRows[placeY][placeX] = 1; + } + // select lines + vLines = Vec_IntAlloc( 1000 ); + for ( i = 0; i < nRows; i++ ) + { + fStart = 0; + for ( k = 0; k <= nCols; k++ ) + { + if ( ppRows[i][k] && !fStart ) + { + Vec_IntPush( vLines, k ); + Vec_IntPush( vLines, i ); + fStart = 1; + } + if ( !ppRows[i][k] && fStart ) + { + Vec_IntPush( vLines, k-1 ); + Vec_IntPush( vLines, i ); + fStart = 0; + } + } + assert( fStart == 0 ); + } + ABC_FREE( pBuffer ); + ABC_FREE( ppRows ); + return vLines; +} + +/**Function************************************************************* + Synopsis [Derives solutions from original vectors and eigenvectors.] Description [] @@ -1422,71 +1684,89 @@ void Emb_ManPrintSolutions( Emb_Man_t * p, int nSols ) SeeAlso [] ***********************************************************************/ -void Emb_ManDumpGnuplot( Emb_Man_t * p, int nSols, char * pName ) +void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowImage ) { - int fDumpImage = 1; + extern void Gia_ManGnuplotShow( char * pPlotFileName ); // char * pDirectory = "place\\"; char * pDirectory = ""; extern char * Ioa_TimeStamp(); FILE * pFile; char Buffer[1000]; Emb_Obj_t * pThis, * pNext; - float * pSol0, * pSol1; int i, k; - if ( nSols < 2 ) - return; if ( p->pPlacement == NULL ) { printf( "Emb_ManDumpGnuplot(): Placement is not available.\n" ); return; } - pSol0 = Emb_ManSol( p, 0 ); - pSol1 = Emb_ManSol( p, 1 ); sprintf( Buffer, "%s%s", pDirectory, Aig_FileNameGenericAppend(pName, ".plt") ); pFile = fopen( Buffer, "w" ); fprintf( pFile, "# This Gnuplot file was produced by ABC on %s\n", Ioa_TimeStamp() ); fprintf( pFile, "\n" ); - if ( fDumpImage ) - { fprintf( pFile, "set nokey\n" ); + fprintf( pFile, "\n" ); + if ( !fShowImage ) + { // fprintf( pFile, "set terminal postscript\n" ); -// fprintf( pFile, "set output \'%s\'\n", Aig_FileNameGenericAppend(pName, ".ps") ); fprintf( pFile, "set terminal gif font \'arial\' 10 size 800,600 xffffff x000000 x000000 x000000\n" ); fprintf( pFile, "set output \'%s\'\n", Aig_FileNameGenericAppend(pName, ".gif") ); fprintf( pFile, "\n" ); } - fprintf( pFile, "set title \"%s : PI = %d PO = %d FF = %d Node = %d Obj = %d\\n", - pName, Emb_ManPiNum(p), Emb_ManPoNum(p), Emb_ManRegNum(p), Emb_ManNodeNum(p), Emb_ManObjNum(p) ); + fprintf( pFile, "set title \"%s : PI = %d PO = %d FF = %d Node = %d Obj = %d HPWL = %.2e\\n", + pName, Emb_ManPiNum(p), Emb_ManPoNum(p), Emb_ManRegNum(p), Emb_ManNodeNum(p), Emb_ManObjNum(p), Emb_ManComputeHPWL(p) ); fprintf( pFile, "(image generated by ABC and Gnuplot on %s)\"", Ioa_TimeStamp() ); fprintf( pFile, "font \"Times, 12\"\n" ); fprintf( pFile, "\n" ); fprintf( pFile, "plot [:] '-' w l\n" ); fprintf( pFile, "\n" ); - Emb_ManForEachObj( p, pThis, i ) + if ( fDumpLarge ) { - if ( !Emb_ObjIsTravIdCurrent(p, pThis) ) - continue; - Emb_ObjForEachFanout( pThis, pNext, k ) + int begX, begY, endX, endY; + Vec_Int_t * vLines = Emb_ManDumpGnuplotPrepare( p ); + Vec_IntForEachEntry( vLines, begX, i ) { - assert( Emb_ObjIsTravIdCurrent(p, pNext) ); -// fprintf( pFile, "%d %d\n", (int)pSol0[pThis->Value], (int)pSol1[pThis->Value] ); -// fprintf( pFile, "%d %d\n", (int)pSol0[pNext->Value], (int)pSol1[pNext->Value] ); -// fprintf( pFile, "%5.2f %5.2f\n", pSol0[pThis->Value], pSol1[pThis->Value] ); -// fprintf( pFile, "%5.2f %5.2f\n", pSol0[pNext->Value], pSol1[pNext->Value] ); - fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pThis->Value+0], p->pPlacement[2*pThis->Value+1] ); - fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pNext->Value+0], p->pPlacement[2*pNext->Value+1] ); + begY = Vec_IntEntry( vLines, i+1 ); + endX = Vec_IntEntry( vLines, i+2 ); + endY = Vec_IntEntry( vLines, i+3 ); + i += 3; + fprintf( pFile, "%5d %5d\n", begX, begY ); + fprintf( pFile, "%5d %5d\n", endX, endY ); fprintf( pFile, "\n" ); } + Vec_IntFree( vLines ); + } + else + { + Emb_ManForEachObj( p, pThis, i ) + { + if ( !Emb_ObjIsTravIdCurrent(p, pThis) ) + continue; + Emb_ObjForEachFanout( pThis, pNext, k ) + { + assert( Emb_ObjIsTravIdCurrent(p, pNext) ); + fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pThis->Value+0], p->pPlacement[2*pThis->Value+1] ); + fprintf( pFile, "%5d %5d\n", p->pPlacement[2*pNext->Value+0], p->pPlacement[2*pNext->Value+1] ); + fprintf( pFile, "\n" ); + } + } } fprintf( pFile, "EOF\n" ); fprintf( pFile, "\n" ); - if ( !fDumpImage ) + if ( fShowImage ) { - fprintf( pFile, "pause -1 \"Hit return to continue\"\n" ); + fprintf( pFile, "pause -1 \"Close window\"\n" ); // Hit return to continue fprintf( pFile, "reset\n" ); fprintf( pFile, "\n" ); } + else + { + fprintf( pFile, "# pause -1 \"Close window\"\n" ); // Hit return to continue + fprintf( pFile, "# reset\n" ); + fprintf( pFile, "\n" ); + } fclose( pFile ); + if ( fShowImage ) + Gia_ManGnuplotShow( Buffer ); } /**Function************************************************************* @@ -1500,7 +1780,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, int nSols, char * pName ) SeeAlso [] ***********************************************************************/ -void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, int fDump, int fVerbose ) +void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ) { Emb_Man_t * p; int clk, clkSetup; @@ -1508,18 +1788,18 @@ void Gia_ManSolveProblem( Gia_Man_t * pGia, int nDims, int nSols, int fCluster, // transform AIG into internal data-structure clk = clock(); - if ( fCluster ) + if ( pPars->fCluster ) { p = Emb_ManStart( pGia ); - if ( fVerbose ) + if ( pPars->fVerbose ) { - printf( "After clustering: " ); + printf( "Clustered: " ); Emb_ManPrintStats( p ); } } else p = Emb_ManStartSimple( pGia ); - p->fVerbose = fVerbose; + p->fVerbose = pPars->fVerbose; // Emb_ManPrintFanio( p ); // prepare data-structure @@ -1529,26 +1809,40 @@ clk = clock(); clkSetup = clock() - clk; clk = clock(); - Emb_ManComputeDimensions( p, nDims ); -if ( fVerbose ) + Emb_ManComputeDimensions( p, pPars->nDims ); +if ( pPars->fVerbose ) ABC_PRT( "Setup ", clkSetup ); -if ( fVerbose ) +if ( pPars->fVerbose ) ABC_PRT( "Dimensions", clock() - clk ); clk = clock(); - Emb_ManComputeCovariance( p, nDims ); -if ( fVerbose ) + Emb_ManComputeCovariance( p, pPars->nDims ); +if ( pPars->fVerbose ) ABC_PRT( "Matrix ", clock() - clk ); clk = clock(); - Emb_ManComputeEigenvectors( p, nDims, nSols ); - Emb_ManComputeSolutions( p, nDims, nSols ); - Emb_ManDerivePlacement( p, nSols ); -if ( fVerbose ) + Emb_ManComputeEigenvectors( p, pPars->nDims, pPars->nSols ); + Emb_ManComputeSolutions( p, pPars->nDims, pPars->nSols ); + Emb_ManDerivePlacement( p, pPars->nSols ); +if ( pPars->fVerbose ) ABC_PRT( "Eigenvecs ", clock() - clk ); - if ( fDump ) - Emb_ManDumpGnuplot( p, nSols, pGia->pName ); + if ( pPars->fRefine ) + { +clk = clock(); + Emb_ManPlacementRefine( p, pPars->nIters, pPars->fVerbose ); +if ( pPars->fVerbose ) +ABC_PRT( "Refinement", clock() - clk ); + } + + if ( (pPars->fDump || pPars->fDumpLarge) && pPars->nSols == 2 ) + { +clk = clock(); + Emb_ManDumpGnuplot( p, pGia->pName, pPars->fDumpLarge, pPars->fShowImage ); +if ( pPars->fVerbose ) +ABC_PRT( "Image dump", clock() - clk ); + } + Emb_ManStop( p ); } diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c new file mode 100644 index 00000000..d05dc5a9 --- /dev/null +++ b/src/aig/gia/giaEnable.c @@ -0,0 +1,210 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Structural detection of enables, sets and resets.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_CollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ) + { + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + // go through the branches + Gia_CollectSuper_rec( p, Gia_ObjChild0(pObj), vSuper ); + Gia_CollectSuper_rec( p, Gia_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_CollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + Vec_IntClear( vSuper ); +// Gia_CollectSuper_rec( p, pObj, vSuper ); + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin1(pObj)) ); + } + else + Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) ); + +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintSignals( Gia_Man_t * p, int * pFreq, char * pStr ) +{ + Vec_Int_t * vObjs; + int i, Counter = 0, nTotal = 0; + vObjs = Vec_IntAlloc( 100 ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( pFreq[i] > 1 ) + { + nTotal += pFreq[i]; + Counter++; + } + printf( "%s (total = %d driven = %d)\n", pStr, Counter, nTotal ); + Counter = 0; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( pFreq[i] > 1 ) + { + printf( "%3d : Obj = %6d Refs = %6d Freq = %6d\n", + ++Counter, i, Gia_ObjRefs(p, Gia_ManObj(p,i)), pFreq[i] ); + Vec_IntPush( vObjs, i ); + } + Vec_IntFree( vObjs ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset ) +{ + Vec_Int_t * vSuper; + Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp; + int i, k, Ent, * pSets, * pResets, * pEnables; + int nHaveSetReset = 0, nHaveEnable = 0; + assert( Gia_ManRegNum(p) > 0 ); + pSets = ABC_CALLOC( int, Gia_ManObjNum(p) ); + pResets = ABC_CALLOC( int, Gia_ManObjNum(p) ); + pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) ); + vSuper = Vec_IntAlloc( 100 ); + Gia_ManForEachRi( p, pFlop, i ) + { + pNode = Gia_ObjFanin0(pFlop); + if ( !Gia_ObjIsAnd(pNode) ) + continue; + // detect sets/resets + Gia_CollectSuper( p, pNode, vSuper ); + if ( Gia_ObjFaninC0(pFlop) ) + Vec_IntForEachEntry( vSuper, Ent, k ) + pSets[Ent]++; + else + Vec_IntForEachEntry( vSuper, Ent, k ) + pResets[Ent]++; + // detect enables + if ( !Gia_ObjIsMuxType(pNode) ) + continue; + pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 ); + pTemp = Gia_ObjRiToRo( p, pFlop ); + if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp ) + continue; + if ( !Gia_ObjFaninC0(pFlop) ) + { + pObj0 = Gia_Not(pObj0); + pObj1 = Gia_Not(pObj1); + } + if ( Gia_IsComplement(pObjC) ) + { + pObjC = Gia_Not(pObjC); + pTemp = pObj0; + pObj0 = pObj1; + pObj1 = pTemp; + } + // detect controls +// Gia_CollectSuper( p, pObjC, vSuper ); +// Vec_IntForEachEntry( vSuper, Ent, k ) +// pEnables[Ent]++; + pEnables[Gia_ObjId(p, pObjC)]++; + nHaveEnable++; + } + Gia_ManForEachRi( p, pFlop, i ) + { + pNode = Gia_ObjFanin0(pFlop); + if ( !Gia_ObjIsAnd(pNode) ) + continue; + // detect sets/resets + Gia_CollectSuper( p, pNode, vSuper ); + Vec_IntForEachEntry( vSuper, Ent, k ) + if ( pSets[Ent] > 1 || pResets[Ent] > 1 ) + { + nHaveSetReset++; + break; + } + } + Vec_IntFree( vSuper ); + Gia_ManCreateRefs( p ); + printf( "Flops with set/reset = %6d. Flops with enable = %6d.\n", nHaveSetReset, nHaveEnable ); + if ( fSetReset ) + { + Gia_ManPrintSignals( p, pSets, "Set signals" ); + Gia_ManPrintSignals( p, pResets, "Reset signals" ); + } + Gia_ManPrintSignals( p, pEnables, "Enable signals" ); + ABC_FREE( p->pRefs ); + ABC_FREE( pSets ); + ABC_FREE( pResets ); + ABC_FREE( pEnables ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c new file mode 100644 index 00000000..9e190da3 --- /dev/null +++ b/src/aig/gia/giaEquiv.c @@ -0,0 +1,618 @@ +/**CFile**************************************************************** + + FileName [giaEquiv.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Manipulation of equivalence classes.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaEquiv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Given representatives, derives pointers to the next objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManDeriveNexts( Gia_Man_t * p ) +{ + unsigned * pNexts, * pTails; + int i; + assert( p->pReprs ); + pNexts = ABC_CALLOC( unsigned, Gia_ManObjNum(p) ); + pTails = ABC_ALLOC( unsigned, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + pTails[i] = i; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID ) + continue; + pNexts[ pTails[p->pReprs[i].iRepr] ] = i; + pTails[p->pReprs[i].iRepr] = i; + } + ABC_FREE( pTails ); + return (int *)pNexts; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivCountOne( Gia_Man_t * p, int i ) +{ + int Ent, nLits = 1; + Gia_ClassForEachObj1( p, i, Ent ) + { + assert( Gia_ObjRepr(p, Ent) == i ); + nLits++; + } + return nLits; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter ) +{ + int Ent; + printf( "Class %4d : Num = %2d {", Counter, Gia_ManEquivCountOne(p, i) ); + Gia_ClassForEachObj( p, i, Ent ) + { + printf(" %d", Ent ); + if ( p->pReprs[Ent].fColorA || p->pReprs[Ent].fColorB ) + printf(" <%d%d>", p->pReprs[Ent].fColorA, p->pReprs[Ent].fColorB ); + } + printf( " }\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivCountLitsAll( Gia_Man_t * p ) +{ + int i, nLits = 0; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + nLits += (Gia_ObjRepr(p, i) != GIA_VOID); + return nLits; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivCheckLits( Gia_Man_t * p, int nLits ) +{ + int nLitsReal = Gia_ManEquivCountLitsAll( p ); + if ( nLitsReal != nLits ) + printf( "Detected a mismatch in counting equivalence classes (%d).\n", nLitsReal - nLits ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) +{ + int i, Counter = 0, Counter1 = 0, CounterX = 0, Proved = 0, nLits; + for ( i = 1; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjIsHead(p, i) ) + Counter++; + else if ( Gia_ObjIsConst(p, i) ) + Counter1++; + else if ( Gia_ObjIsNone(p, i) ) + CounterX++; + if ( Gia_ObjProved(p, i) ) + Proved++; + } + CounterX -= Gia_ManCoNum(p); + nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; + printf( "cls =%7d cst =%8d lit =%8d unused =%8d proof =%6d mem =%5.2f Mb\n", + Counter, Counter1, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem ); + assert( Gia_ManEquivCheckLits( p, nLits ) ); + if ( fVerbose ) + { + Counter = 0; + Gia_ManForEachClass( p, i ) + Gia_ManEquivPrintOne( p, i, ++Counter ); + } +} + +/**Function************************************************************* + + Synopsis [Returns representative node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) + return NULL; + return Gia_ManObj( p, Gia_ObjRepr(p, Gia_ObjId(p,pObj)) ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + if ( (pRepr = Gia_ManEquivRepr(p, pObj)) ) + { + Gia_ManEquivReduce_rec( pNew, p, pRepr ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRepr; + int i; + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + { + pObj->Value = Gia_ManAppendCi(pNew); + if ( (pRepr = Gia_ManEquivRepr(p, pObj)) ) + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + } + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj0, * pObj1; + int i; + assert( (Gia_ManPoNum(p) & 1) == 0 ); + Gia_ManForEachPo( p, pObj0, i ) + { + pObj1 = Gia_ManPo( p, ++i ); + if ( Gia_ObjChild0(pObj0) != Gia_ObjChild0(pObj1) ) + continue; + pObj0->iDiff0 = Gia_ObjId(p, pObj0); + pObj0->fCompl0 = 0; + pObj1->iDiff0 = Gia_ObjId(p, pObj1); + pObj1->fCompl0 = 0; + } +} + +/**Function************************************************************* + + Synopsis [Removes pointers to the unmarked nodes..] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivUpdatePointers( Gia_Man_t * p, Gia_Man_t * pNew ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + if ( !~pObj->Value ) + continue; + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + if ( pObjNew->fMark0 ) + pObj->Value = ~0; + } +} + +/**Function************************************************************* + + Synopsis [Removes pointers to the unmarked nodes..] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivDeriveReprs( Gia_Man_t * p, Gia_Man_t * pNew, Gia_Man_t * pFinal ) +{ + Vec_Int_t * vClass; + Gia_Obj_t * pObj, * pObjNew; + int i, k, iNode, iRepr, iPrev; + // start representatives + pFinal->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pFinal) ); + for ( i = 0; i < Gia_ManObjNum(pFinal); i++ ) + Gia_ObjSetRepr( pFinal, i, GIA_VOID ); + // iterate over constant candidates + Gia_ManForEachConst( p, i ) + { + pObj = Gia_ManObj( p, i ); + if ( !~pObj->Value ) + continue; + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_Lit2Var(pObjNew->Value) == 0 ) + continue; + Gia_ObjSetRepr( pFinal, Gia_Lit2Var(pObjNew->Value), 0 ); + } + // iterate over class candidates + vClass = Vec_IntAlloc( 100 ); + Gia_ManForEachClass( p, i ) + { + Vec_IntClear( vClass ); + Gia_ClassForEachObj( p, i, k ) + { + pObj = Gia_ManObj( p, k ); + if ( !~pObj->Value ) + continue; + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + Vec_IntPushUnique( vClass, Gia_Lit2Var(pObjNew->Value) ); + } + if ( Vec_IntSize( vClass ) < 2 ) + continue; + Vec_IntSort( vClass, 0 ); + iRepr = iPrev = Vec_IntEntry( vClass, 0 ); + Vec_IntForEachEntryStart( vClass, iNode, k, 1 ) + { + Gia_ObjSetRepr( pFinal, iNode, iRepr ); + assert( iPrev < iNode ); + iPrev = iNode; + } + } + Vec_IntFree( vClass ); + pFinal->pNexts = Gia_ManDeriveNexts( pFinal ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG while remapping equivalence classes.] + + Description [Drops the pairs of outputs if they are proved equivalent.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ) +{ + Gia_Man_t * pNew, * pFinal; + pNew = Gia_ManEquivReduce( p ); + if ( fMiterPairs ) + Gia_ManEquivFixOutputPairs( pNew ); + if ( fSeq ) + Gia_ManSeqMarkUsed( pNew ); + else + Gia_ManCombMarkUsed( pNew ); + Gia_ManEquivUpdatePointers( p, pNew ); + pFinal = Gia_ManDupMarked( pNew ); + Gia_ManEquivDeriveReprs( p, pNew, pFinal ); + Gia_ManStop( pNew ); + return pFinal; +} + +/**Function************************************************************* + + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivSetColor_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fOdds ) +{ + if ( Gia_ObjVisitColor( p, Gia_ObjId(p,pObj), fOdds ) ) + return 0; + if ( Gia_ObjIsRo(p, pObj) ) + return 1 + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj)), fOdds ); + assert( Gia_ObjIsAnd(pObj) ); + return 1 + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), fOdds ) + + Gia_ManEquivSetColor_rec( p, Gia_ObjFanin1(pObj), fOdds ); +} + +/**Function************************************************************* + + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ) +{ + Gia_Obj_t * pObj; + int i, nNodes[2] = {0,0}, nDiffs[2]; + assert( (Gia_ManPoNum(p) & 1) == 0 ); + Gia_ObjSetColors( p, 0 ); + Gia_ManForEachPi( p, pObj, i ) + Gia_ObjSetColors( p, Gia_ObjId(p,pObj) ); + Gia_ManForEachPo( p, pObj, i ) + nNodes[i&1] += Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), i&1 ); +// Gia_ManForEachObj( p, pObj, i ) +// if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ) +// assert( Gia_ObjColors(p, i) ); + nDiffs[0] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[0]); + nDiffs[1] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[1]); + if ( fVerbose ) + { + printf( "CI+AND = %7d A = %7d B = %7d Ad = %7d Bd = %7d AB = %7d.\n", + Gia_ManCiNum(p) + Gia_ManAndNum(p), + Gia_ManPiNum(p) + nNodes[0], Gia_ManPiNum(p) + nNodes[1], + nDiffs[0], nDiffs[1], + Gia_ManCiNum(p) + Gia_ManAndNum(p) - nDiffs[0] - nDiffs[1] ); + } + return (nDiffs[0] + nDiffs[1]) / 2; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits ) +{ + Gia_Obj_t * pRepr; + int iLitNew; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + return; + iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + if ( pObj->Value != (unsigned)iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) + Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) ); + pObj->Value = iLitNew; +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + Vec_Int_t * vXorLits; + int i, iLitNew; + if ( !p->pReprs ) + return NULL; + vXorLits = Vec_IntAlloc( 1000 ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + if ( pObj->Value != (unsigned)iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) + Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) ); + pObj->Value = iLitNew; + } + Gia_ManForEachCo( p, pObj, i ) + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits ); + Vec_IntForEachEntry( vXorLits, iLitNew, i ) + Gia_ManAppendCo( pNew, iLitNew ); + if ( Vec_IntSize(vXorLits) == 0 ) + { + printf( "Speculatively reduced model has no primary outputs.\n" ); + Gia_ManAppendCo( pNew, 0 ); + } + Gia_ManForEachRi( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntFree( vXorLits ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transforms equiv classes by removing the AB nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ) +{ + extern void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass ); + Vec_Int_t * vClass, * vClassNew; + int iRepr, iNode, Ent, k; + int nRemovedLits = 0, nRemovedClas = 0; + int nTotalLits = 0, nTotalClas = 0; + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts ); + vClass = Vec_IntAlloc( 100 ); + vClassNew = Vec_IntAlloc( 100 ); + Gia_ManForEachObj( p, pObj, i ) + if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ) + assert( Gia_ObjColors(p, i) ); + Gia_ManForEachClassReverse( p, iRepr ) + { + nTotalClas++; + Vec_IntClear( vClass ); + Vec_IntClear( vClassNew ); + Gia_ClassForEachObj( p, iRepr, iNode ) + { + nTotalLits++; + Vec_IntPush( vClass, iNode ); + assert( Gia_ObjColors(p, iNode) ); + if ( Gia_ObjColors(p, iNode) != 3 ) + Vec_IntPush( vClassNew, iNode ); + else + nRemovedLits++; + } + Vec_IntForEachEntry( vClass, Ent, k ) + { + p->pReprs[Ent].fFailed = p->pReprs[Ent].fProved = 0; + p->pReprs[Ent].iRepr = GIA_VOID; + p->pNexts[Ent] = 0; + } + if ( Vec_IntSize(vClassNew) < 2 ) + { + nRemovedClas++; + continue; + } + Cec_ManSimClassCreate( p, vClassNew ); + } + Vec_IntFree( vClass ); + Vec_IntFree( vClassNew ); + if ( fVerbose ) + printf( "Removed classes = %6d (out of %6d). Removed literals = %6d (out of %6d).\n", + nRemovedClas, nTotalClas, nRemovedLits, nTotalLits ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c index c2d2d33f..cf4c4aa5 100644 --- a/src/aig/gia/giaForce.c +++ b/src/aig/gia/giaForce.c @@ -23,47 +23,100 @@ /* The code is based on the paper by F. A. Aloul, I. L. Markov, and K. A. Sakallah. "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct For_Obj_t_ For_Obj_t; -struct For_Obj_t_ +typedef struct Frc_Obj_t_ Frc_Obj_t; +struct Frc_Obj_t_ { - int iObj; - float lNode; + unsigned fCi : 1; // terminal node CI + unsigned fCo : 1; // terminal node CO + unsigned fMark0 : 1; // first user-controlled mark + unsigned fMark1 : 1; // second user-controlled mark + unsigned nFanins : 28; // the number of fanins + unsigned nFanouts; // the number of fanouts + unsigned iFanout; // the current number of fanouts + int hHandle; // the handle of the node + int pPlace; // the placement of each node + union { + float fEdgeCenter; // center-of-gravity of the edge + unsigned iFanin; + }; + int Fanios[0]; // the array of fanins/fanouts }; -typedef struct For_Man_t_ For_Man_t; -struct For_Man_t_ +typedef struct Frc_Man_t_ Frc_Man_t; +struct Frc_Man_t_ { Gia_Man_t * pGia; // the original AIG manager + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) int nObjs; // the number of objects - int iObj; // the last added object - int * pPlace; // coordinates of objects - int * piNext; // array of next pointers - int * piRoot; // array of root pointers - float * plEdge; // edge coordinates - For_Obj_t * pNodes; // the array of nodes + int nRegs; // the number of registers + int * pObjData; // the array containing data for objects + int nObjData; // the size of array to store the logic network + int fVerbose; // verbose output flag + int nCutCur; // current cut + int nCutMax; // max cut seen }; -static inline int Gia_ObjPlace( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjId(p->pGia, pObj)]; } -static inline int Gia_ObjPlaceFanin0( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjFaninId0p(p->pGia, pObj)]; } -static inline int Gia_ObjPlaceFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { return p->pPlace[Gia_ObjFaninId1p(p->pGia, pObj)]; } - -static inline int Gia_ObjEdge( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjId(p->pGia, pObj)]; } -static inline int Gia_ObjEdgeFanin0( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)]; } -static inline int Gia_ObjEdgeFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { return p->plEdge[Gia_ObjFaninId1p(p->pGia, pObj)]; } +static inline int Frc_ManRegNum( Frc_Man_t * p ) { return p->nRegs; } +static inline int Frc_ManCiNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCis); } +static inline int Frc_ManCoNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCos); } +static inline int Frc_ManPiNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCis) - p->nRegs; } +static inline int Frc_ManPoNum( Frc_Man_t * p ) { return Vec_IntSize(p->vCos) - p->nRegs; } +static inline int Frc_ManObjNum( Frc_Man_t * p ) { return p->nObjs; } +static inline int Frc_ManNodeNum( Frc_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos); } + +static inline Frc_Obj_t * Frc_ManObj( Frc_Man_t * p, int hHandle ) { return (Frc_Obj_t *)(p->pObjData + hHandle); } +static inline Frc_Obj_t * Frc_ManCi( Frc_Man_t * p, int i ) { return Frc_ManObj( p, Vec_IntEntry(p->vCis,i) ); } +static inline Frc_Obj_t * Frc_ManCo( Frc_Man_t * p, int i ) { return Frc_ManObj( p, Vec_IntEntry(p->vCos,i) ); } + +static inline int Frc_ObjIsTerm( Frc_Obj_t * pObj ) { return pObj->fCi || pObj->fCo; } +static inline int Frc_ObjIsCi( Frc_Obj_t * pObj ) { return pObj->fCi; } +static inline int Frc_ObjIsCo( Frc_Obj_t * pObj ) { return pObj->fCo; } +static inline int Frc_ObjIsPi( Frc_Obj_t * pObj ) { return pObj->fCi && pObj->nFanins == 0; } +static inline int Frc_ObjIsPo( Frc_Obj_t * pObj ) { return pObj->fCo && pObj->nFanouts == 0; } +static inline int Frc_ObjIsNode( Frc_Obj_t * pObj ) { return!Frc_ObjIsTerm(pObj) && pObj->nFanins > 0; } +static inline int Frc_ObjIsConst0( Frc_Obj_t * pObj ) { return!Frc_ObjIsTerm(pObj) && pObj->nFanins == 0; } + +static inline int Frc_ObjSize( Frc_Obj_t * pObj ) { return sizeof(Frc_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } +static inline int Frc_ObjFaninNum( Frc_Obj_t * pObj ) { return pObj->nFanins; } +static inline int Frc_ObjFanoutNum( Frc_Obj_t * pObj ) { return pObj->nFanouts; } +static inline Frc_Obj_t * Frc_ObjFanin( Frc_Obj_t * pObj, int i ) { return (Frc_Obj_t *)(((int *)pObj) - pObj->Fanios[i]); } +static inline Frc_Obj_t * Frc_ObjFanout( Frc_Obj_t * pObj, int i ) { return (Frc_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); } + +#define Frc_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Frc_ManObj(p,i)); i += Frc_ObjSize(pObj) ) +#define Frc_ManForEachObjVec( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Frc_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) + +#define Frc_ManForEachNode( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Frc_ManObj(p,i)); i += Frc_ObjSize(pObj) ) if ( Frc_ObjIsTerm(pObj) ) {} else +#define Frc_ManForEachCi( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCis)) && (pObj = Frc_ManObj(p,Vec_IntEntry(p->vCis,i))); i++ ) +#define Frc_ManForEachCo( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCos)) && (pObj = Frc_ManObj(p,Vec_IntEntry(p->vCos,i))); i++ ) + +#define Frc_ObjForEachFanin( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Frc_ObjFanin(pObj,i)); i++ ) +#define Frc_ObjForEachFaninReverse( pObj, pNext, i ) \ + for ( i = (int)pObj->nFanins - 1; (i >= 0) && (pNext = Frc_ObjFanin(pObj,i)); i-- ) +#define Frc_ObjForEachFanout( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Frc_ObjFanout(pObj,i)); i++ ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// + /**Function************************************************************* - Synopsis [] + Synopsis [Creates fanin/fanout pair.] Description [] @@ -72,23 +125,128 @@ static inline int Gia_ObjEdgeFanin1( For_Man_t * p, Gia_Obj_t * pObj ) { retu SeeAlso [] ***********************************************************************/ -For_Man_t * For_ManStart( Gia_Man_t * pGia ) +void Frc_ObjAddFanin( Frc_Obj_t * pObj, Frc_Obj_t * pFanin ) +{ + assert( pObj->iFanin < pObj->nFanins ); + assert( pFanin->iFanout < pFanin->nFanouts ); + pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] = + pObj->Fanios[pObj->iFanin++] = pObj->hHandle - pFanin->hHandle; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Frc_Man_t * Frc_ManStartSimple( Gia_Man_t * pGia ) { - For_Man_t * p; - p = ABC_CALLOC( For_Man_t, 1 ); - p->pGia = pGia; - p->nObjs = Gia_ManObjNum(pGia); - p->pPlace = ABC_ALLOC( int, p->nObjs ); - p->piNext = ABC_ALLOC( int, p->nObjs ); - p->piRoot = ABC_ALLOC( int, p->nObjs ); - p->plEdge = ABC_ALLOC( float, p->nObjs ); - p->pNodes = ABC_ALLOC( For_Obj_t, p->nObjs ); + Frc_Man_t * p; + Frc_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj;//, * pObjRi, * pObjRo; + int i, nNodes, hHandle = 0; + // prepare the AIG + Gia_ManCreateRefs( pGia ); + // create logic network + p = ABC_CALLOC( Frc_Man_t, 1 ); + p->pGia = pGia; + p->nRegs = Gia_ManRegNum(pGia); + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Frc_Obj_t) / 4) * Gia_ManObjNum(pGia) + 2 * (2 * Gia_ManAndNum(pGia) + Gia_ManCoNum(pGia)); + p->pObjData = ABC_CALLOC( int, p->nObjData ); + // create constant node + Gia_ManConst0(pGia)->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes = 1; + p->nObjs++; + // create the PIs + Gia_ManForEachCi( pGia, pObj, i ) + { + // create PI object + pObj->Value = hHandle; + Vec_IntPush( p->vCis, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->fCi = 0; + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; + } + // create internal nodes + Gia_ManForEachAnd( pGia, pObj, i ) + { + assert( Gia_ObjRefs( pGia, pObj ) > 0 ); + // create node object + pObj->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 2; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + // add fanins + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin1(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes++; + p->nObjs++; + } + // create the POs + Gia_ManForEachCo( pGia, pObj, i ) + { + // create PO object + pObj->Value = hHandle; + Vec_IntPush( p->vCos, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 1; + pObjLog->nFanouts = 0; + pObjLog->fCo = 1; + // add fanins + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; + } + // connect registers +// Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, i ) +// Frc_ObjAddFanin( Frc_ManObj(p,Gia_ObjValue(pObjRo)), Frc_ManObj(p,Gia_ObjValue(pObjRi)) ); + assert( nNodes == Frc_ManNodeNum(p) ); + assert( hHandle == p->nObjData ); + if ( hHandle != p->nObjData ) + printf( "Frc_ManStartSimple(): Fatal error in internal representation.\n" ); + // make sure the fanin/fanout counters are correct + Gia_ManForEachObj( pGia, pObj, i ) + { + if ( !~Gia_ObjValue(pObj) ) + continue; + pObjLog = Frc_ManObj( p, Gia_ObjValue(pObj) ); + assert( pObjLog->nFanins == pObjLog->iFanin ); + assert( pObjLog->nFanouts == pObjLog->iFanout ); + pObjLog->iFanin = pObjLog->iFanout = 0; + } + ABC_FREE( pGia->pRefs ); return p; } /**Function************************************************************* - Synopsis [] + Synopsis [Collect the fanin IDs.] Description [] @@ -97,19 +255,50 @@ For_Man_t * For_ManStart( Gia_Man_t * pGia ) SeeAlso [] ***********************************************************************/ -void For_ManStop( For_Man_t * p ) +void Frc_ManCollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper, Vec_Int_t * vVisit ) { - ABC_FREE( p->pPlace ); - ABC_FREE( p->piNext ); - ABC_FREE( p->piRoot ); - ABC_FREE( p->plEdge ); - ABC_FREE( p->pNodes ); - ABC_FREE( p ); + if ( pObj->fMark1 ) + return; + pObj->fMark1 = 1; + Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); + if ( pObj->fMark0 ) + { + Vec_IntPush( vSuper, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Frc_ManCollectSuper_rec( p, Gia_ObjFanin0(pObj), vSuper, vVisit ); + Frc_ManCollectSuper_rec( p, Gia_ObjFanin1(pObj), vSuper, vVisit ); + } /**Function************************************************************* - Synopsis [Derives random ordering of nodes.] + Synopsis [Collect the fanin IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper, Vec_Int_t * vVisit ) +{ + int Entry, i; + Vec_IntClear( vSuper ); + Vec_IntClear( vVisit ); + assert( pObj->fMark0 == 1 ); + pObj->fMark0 = 0; + Frc_ManCollectSuper_rec( p, pObj, vSuper, vVisit ); + pObj->fMark0 = 1; + Vec_IntForEachEntry( vVisit, Entry, i ) + Gia_ManObj(p, Entry)->fMark1 = 0; +} + +/**Function************************************************************* + + Synopsis [Assigns references while removing the MUX/XOR ones.] Description [] @@ -118,24 +307,44 @@ void For_ManStop( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManSetInitPlaceRandom( For_Man_t * p ) +void Frc_ManCreateRefsSpecial( Gia_Man_t * p ) { - int i, Temp, iNext; - Aig_ManRandom( 1 ); - for ( i = 0; i < p->nObjs; i++ ) - p->pPlace[i] = i; - for ( i = 0; i < p->nObjs; i++ ) + Gia_Obj_t * pObj, * pFan0, * pFan1; + Gia_Obj_t * pObjC, * pObjD0, * pObjD1; + int i; + assert( p->pRefs == NULL ); + Gia_ManCleanMark0( p ); + Gia_ManCreateRefs( p ); + Gia_ManForEachAnd( p, pObj, i ) { - iNext = Aig_ManRandom( 0 ) % p->nObjs; - Temp = p->pPlace[i]; - p->pPlace[i] = p->pPlace[iNext]; - p->pPlace[iNext] = Temp; + assert( pObj->fMark0 == 0 ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + // skip nodes whose fanins are PIs or are already marked + if ( Gia_ObjIsCi(pFan0) || pFan0->fMark0 || + Gia_ObjIsCi(pFan1) || pFan1->fMark0 ) + continue; + // skip nodes that are not MUX type + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + // the node is MUX type, mark it and its fanins + pObj->fMark0 = 1; + pFan0->fMark0 = 1; + pFan1->fMark0 = 1; + // deref the control + pObjC = Gia_ObjRecognizeMux( pObj, &pObjD1, &pObjD0 ); + Gia_ObjRefDec( p, Gia_Regular(pObjC) ); + if ( Gia_Regular(pObjD0) == Gia_Regular(pObjD1) ) + Gia_ObjRefDec( p, Gia_Regular(pObjD0) ); } + Gia_ManForEachAnd( p, pObj, i ) + assert( Gia_ObjRefs(p, pObj) > 0 ); + Gia_ManCleanMark0( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Assigns references while removing the MUX/XOR ones.] Description [] @@ -144,39 +353,196 @@ void For_ManSetInitPlaceRandom( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManSetInitPlaceDfs_rec( For_Man_t * p, Gia_Obj_t * pObj, int fRev ) +void Frc_ManTransformRefs( Gia_Man_t * p, int * pnObjs, int * pnFanios ) { - if ( pObj->fMark0 ) - return; - pObj->fMark0 = 1; - if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) + Vec_Int_t * vSuper, * vVisit; + Gia_Obj_t * pObj, * pFanin; + int i, k, Counter; + assert( p->pRefs != NULL ); + + // mark nodes to be used in the logic network + Gia_ManCleanMark0( p ); + Gia_ManConst0(p)->fMark0 = 1; + // mark the inputs + Gia_ManForEachCi( p, pObj, i ) + pObj->fMark0 = 1; + // mark those nodes that have ref count more than 1 + Gia_ManForEachAnd( p, pObj, i ) + pObj->fMark0 = (Gia_ObjRefs(p, pObj) > 1); + // mark the output drivers + Gia_ManForEachCoDriver( p, pObj, i ) + pObj->fMark0 = 1; + + // count the number of nodes + Counter = 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += pObj->fMark0; + *pnObjs = Counter + Gia_ManCoNum(p); + + // reset the references + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + // reference from internal nodes + Counter = 0; + vSuper = Vec_IntAlloc( 100 ); + vVisit = Vec_IntAlloc( 100 ); + Gia_ManCleanMark1( p ); + Gia_ManForEachAnd( p, pObj, i ) { - p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++; - return; + if ( pObj->fMark0 == 0 ) + continue; + Frc_ManCollectSuper( p, pObj, vSuper, vVisit ); + Gia_ManForEachObjVec( vSuper, p, pFanin, k ) + { + assert( pFanin->fMark0 ); + Gia_ObjRefInc( p, pFanin ); + } + Counter += Vec_IntSize( vSuper ); } - if ( Gia_ObjIsCo(pObj) ) + Gia_ManCheckMark1( p ); + Vec_IntFree( vSuper ); + Vec_IntFree( vVisit ); + // reference from outputs + Gia_ManForEachCoDriver( p, pObj, i ) { - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev ); - p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++; - return; + assert( pObj->fMark0 ); + Gia_ObjRefInc( p, pObj ); } - assert( Gia_ObjIsAnd(pObj) ); - if ( fRev ) + *pnFanios = Counter + Gia_ManCoNum(p); +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Frc_Man_t * Frc_ManStart( Gia_Man_t * pGia ) +{ + Frc_Man_t * p; + Frc_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj, * pFanin;//, * pObjRi, * pObjRo; + Vec_Int_t * vSuper, * vVisit; + int nObjs, nFanios, nNodes = 0; + int i, k, hHandle = 0; + // prepare the AIG +// Gia_ManCreateRefs( pGia ); + Frc_ManCreateRefsSpecial( pGia ); + Frc_ManTransformRefs( pGia, &nObjs, &nFanios ); + Gia_ManFillValue( pGia ); + // create logic network + p = ABC_CALLOC( Frc_Man_t, 1 ); + p->pGia = pGia; + p->nRegs = Gia_ManRegNum(pGia); + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Frc_Obj_t) / 4) * nObjs + 2 * nFanios; + p->pObjData = ABC_CALLOC( int, p->nObjData ); + // create constant node + Gia_ManConst0(pGia)->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes++; + p->nObjs++; + // create the PIs + Gia_ManForEachCi( pGia, pObj, i ) { - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin1(pObj), fRev ); - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev ); + // create PI object + pObj->Value = hHandle; + Vec_IntPush( p->vCis, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->fCi = 1; + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; } - else + // create internal nodes + vSuper = Vec_IntAlloc( 100 ); + vVisit = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( pGia, pObj, i ) { - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin0(pObj), fRev ); - For_ManSetInitPlaceDfs_rec( p, Gia_ObjFanin1(pObj), fRev ); + if ( pObj->fMark0 == 0 ) + { + assert( Gia_ObjRefs( pGia, pObj ) == 0 ); + continue; + } + assert( Gia_ObjRefs( pGia, pObj ) > 0 ); + Frc_ManCollectSuper( pGia, pObj, vSuper, vVisit ); + // create node object + pObj->Value = hHandle; + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = Vec_IntSize( vSuper ); + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + // add fanins + Gia_ManForEachObjVec( vSuper, pGia, pFanin, k ) + { + pFanLog = Frc_ManObj( p, Gia_ObjValue(pFanin) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + } + // count objects + hHandle += Frc_ObjSize( pObjLog ); + nNodes++; + p->nObjs++; + } + Vec_IntFree( vSuper ); + Vec_IntFree( vVisit ); + // create the POs + Gia_ManForEachCo( pGia, pObj, i ) + { + // create PO object + pObj->Value = hHandle; + Vec_IntPush( p->vCos, hHandle ); + pObjLog = Frc_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 1; + pObjLog->nFanouts = 0; + pObjLog->fCo = 1; + // add fanins + pFanLog = Frc_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Frc_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Frc_ObjSize( pObjLog ); + p->nObjs++; } - p->pPlace[ Gia_ObjId(p->pGia, pObj) ] = p->iObj++; + // connect registers +// Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, i ) +// Frc_ObjAddFanin( Frc_ManObj(p,Gia_ObjValue(pObjRo)), Frc_ManObj(p,Gia_ObjValue(pObjRi)) ); + Gia_ManCleanMark0( pGia ); + assert( nNodes == Frc_ManNodeNum(p) ); + assert( nObjs == p->nObjs ); + assert( hHandle == p->nObjData ); + if ( hHandle != p->nObjData ) + printf( "Frc_ManStart(): Fatal error in internal representation.\n" ); + // make sure the fanin/fanout counters are correct + Gia_ManForEachObj( pGia, pObj, i ) + { + if ( !~Gia_ObjValue(pObj) ) + continue; + pObjLog = Frc_ManObj( p, Gia_ObjValue(pObj) ); + assert( pObjLog->nFanins == pObjLog->iFanin ); + assert( pObjLog->nFanouts == pObjLog->iFanout ); + pObjLog->iFanin = pObjLog->iFanout = 0; + } + ABC_FREE( pGia->pRefs ); + return p; } /**Function************************************************************* - Synopsis [Derives DFS ordering of nodes.] + Synopsis [Creates logic network isomorphic to the given AIG.] Description [] @@ -185,25 +551,25 @@ void For_ManSetInitPlaceDfs_rec( For_Man_t * p, Gia_Obj_t * pObj, int fRev ) SeeAlso [] ***********************************************************************/ -void For_ManSetInitPlaceDfs( For_Man_t * p, int fRev ) +void Frc_ManPrintStats( Frc_Man_t * p ) { - Gia_Obj_t * pObj; - int i; - p->iObj = 0; - Gia_ManCleanMark0( p->pGia ); - For_ManSetInitPlaceDfs_rec( p, Gia_ManConst0(p->pGia), fRev ); - Gia_ManForEachCo( p->pGia, pObj, i ) - For_ManSetInitPlaceDfs_rec( p, pObj, fRev ); - Gia_ManForEachCi( p->pGia, pObj, i ) - if ( pObj->fMark0 == 0 ) - For_ManSetInitPlaceDfs_rec( p, pObj, fRev ); - assert( p->iObj == p->nObjs ); - Gia_ManCleanMark0( p->pGia ); +// if ( p->pName ) +// printf( "%8s : ", p->pName ); + printf( "i/o =%7d/%7d ", Frc_ManPiNum(p), Frc_ManPoNum(p) ); + if ( Frc_ManRegNum(p) ) + printf( "ff =%7d ", Frc_ManRegNum(p) ); + printf( "node =%8d ", Frc_ManNodeNum(p) ); + printf( "obj =%8d ", Frc_ManObjNum(p) ); +// printf( "lev =%5d ", Frc_ManLevelNum(p) ); +// printf( "cut =%5d ", Frc_ManCrossCut(p) ); + printf( "mem =%5.2f Mb", 4.0*p->nObjData/(1<<20) ); +// printf( "obj =%5d ", Frc_ManObjNum(p) ); + printf( "\n" ); } /**Function************************************************************* - Synopsis [Computes span for the given placement.] + Synopsis [Creates logic network isomorphic to the given AIG.] Description [] @@ -212,29 +578,72 @@ void For_ManSetInitPlaceDfs( For_Man_t * p, int fRev ) SeeAlso [] ***********************************************************************/ -double For_ManGetEdgeSpan( For_Man_t * p ) +void Frc_ManStop( Frc_Man_t * p ) { - double Result = 0.0; - Gia_Obj_t * pObj; - int i, Diff; - Gia_ManForEachAnd( p->pGia, pObj, i ) + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + ABC_FREE( p->pObjData ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Computes cross cut size for the given order of POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Frc_ManCrossCut_rec( Frc_Man_t * p, Frc_Obj_t * pObj ) +{ + assert( pObj->iFanout > 0 ); + if ( pObj->iFanout-- == pObj->nFanouts ) { - Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin0(p, pObj); - Result += (double)ABC_ABS(Diff); - Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin1(p, pObj); - Result += (double)ABC_ABS(Diff); + Frc_Obj_t * pFanin; + int i; + p->nCutCur++; + p->nCutMax = ABC_MAX( p->nCutMax, p->nCutCur ); + if ( !Frc_ObjIsCi(pObj) ) + Frc_ObjForEachFanin( pObj, pFanin, i ) + p->nCutCur -= Frc_ManCrossCut_rec( p, pFanin ); } - Gia_ManForEachCo( p->pGia, pObj, i ) + return pObj->iFanout == 0; +} + +/**Function************************************************************* + + Synopsis [Computes cross cut size for the given order of POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Frc_ManCrossCut2_rec( Frc_Man_t * p, Frc_Obj_t * pObj ) +{ + assert( pObj->iFanout > 0 ); + if ( pObj->iFanout-- == pObj->nFanouts ) { - Diff = Gia_ObjPlace(p, pObj) - Gia_ObjPlaceFanin0(p, pObj); - Result += (double)ABC_ABS(Diff); + Frc_Obj_t * pFanin; + int i; + p->nCutCur++; + p->nCutMax = ABC_MAX( p->nCutMax, p->nCutCur ); + if ( !Frc_ObjIsCi(pObj) ) + Frc_ObjForEachFaninReverse( pObj, pFanin, i ) + p->nCutCur -= Frc_ManCrossCut2_rec( p, pFanin ); } - return Result; + return pObj->iFanout == 0; } /**Function************************************************************* - Synopsis [Computes max cut of the given placement.] + Synopsis [Computes cross cut size for the given order of POs.] Description [] @@ -243,68 +652,138 @@ double For_ManGetEdgeSpan( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -int For_ManGetMaxCut( For_Man_t * p ) +int Frc_ManCrossCut( Frc_Man_t * p, Vec_Int_t * vOrder, int fReverse ) { - Gia_Obj_t * pObj; - int i, iObj, iFan, * pTemp; - int nCutCut, nCutMax; - pTemp = ABC_CALLOC( int, p->nObjs ); - Gia_ManForEachAnd( p->pGia, pObj, i ) + Frc_Obj_t * pObj; + int i; + assert( Vec_IntSize(vOrder) == Frc_ManCoNum(p) ); + p->nCutCur = 0; + p->nCutMax = 0; + Frc_ManForEachObj( p, pObj, i ) + pObj->iFanout = pObj->nFanouts; + Frc_ManForEachObjVec( vOrder, p, pObj, i ) { - iObj = Gia_ObjPlace(p, pObj); - iFan = Gia_ObjPlaceFanin0(p, pObj); - if ( iObj < iFan ) - { - pTemp[iObj]++; - pTemp[iFan]--; - } - else - { - pTemp[iObj]--; - pTemp[iFan]++; - } - iObj = Gia_ObjPlace(p, pObj); - iFan = Gia_ObjPlaceFanin1(p, pObj); - if ( iObj < iFan ) - { - pTemp[iObj]++; - pTemp[iFan]--; - } + assert( Frc_ObjIsCo(pObj) ); + if ( fReverse ) + p->nCutCur -= Frc_ManCrossCut2_rec( p, Frc_ObjFanin(pObj,0) ); else - { - pTemp[iObj]--; - pTemp[iFan]++; - } + p->nCutCur -= Frc_ManCrossCut_rec( p, Frc_ObjFanin(pObj,0) ); } - Gia_ManForEachCo( p->pGia, pObj, i ) + assert( p->nCutCur == 0 ); +// Frc_ManForEachObj( p, pObj, i ) +// assert( pObj->iFanout == 0 ); + return p->nCutMax; +} + +/**Function************************************************************* + + Synopsis [Collects CO handles.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Frc_ManCollectCos( Frc_Man_t * p ) +{ + Vec_Int_t * vCoOrder; + Frc_Obj_t * pObj; + int i; + vCoOrder = Vec_IntAlloc( Frc_ManCoNum(p) ); + Frc_ManForEachCo( p, pObj, i ) + Vec_IntPush( vCoOrder, pObj->hHandle ); + return vCoOrder; +} + +/**Function************************************************************* + + Synopsis [Computes cross cut size for the given order of POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManCrossCutTest( Frc_Man_t * p, Vec_Int_t * vOrderInit ) +{ + Vec_Int_t * vOrder; + int clk = clock(); + vOrder = vOrderInit? vOrderInit : Frc_ManCollectCos( p ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 0 ) ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 1 ) ); + Vec_IntReverseOrder( vOrder ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 0 ) ); + printf( "CrossCut = %6d\n", Frc_ManCrossCut( p, vOrder, 1 ) ); + Vec_IntReverseOrder( vOrder ); + if ( vOrder != vOrderInit ) + Vec_IntFree( vOrder ); +// ABC_PRT( "Time", clock() - clk ); +} + + + +/**Function************************************************************* + + Synopsis [Generates random placement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManPlaceRandom( Frc_Man_t * p ) +{ + Frc_Obj_t * pThis; + int * pPlacement; + int i, h, Temp, iNext, Counter; + pPlacement = ABC_ALLOC( int, p->nObjs ); + for ( i = 0; i < p->nObjs; i++ ) + pPlacement[i] = i; + for ( i = 0; i < p->nObjs; i++ ) { - iObj = Gia_ObjPlace(p, pObj); - iFan = Gia_ObjPlaceFanin0(p, pObj); - if ( iObj < iFan ) - { - pTemp[iObj]++; - pTemp[iFan]--; - } - else - { - pTemp[iObj]--; - pTemp[iFan]++; - } + iNext = Aig_ManRandom( 0 ) % p->nObjs; + Temp = pPlacement[i]; + pPlacement[i] = pPlacement[iNext]; + pPlacement[iNext] = Temp; } - nCutCut = nCutMax = 0; - for ( i = 0; i < p->nObjs; i++ ) + Counter = 0; + Frc_ManForEachObj( p, pThis, h ) + pThis->pPlace = pPlacement[Counter++]; + ABC_FREE( pPlacement ); +} + +/**Function************************************************************* + + Synopsis [Shuffles array of random integers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManArrayShuffle( Vec_Int_t * vArray ) +{ + int i, iNext, Temp; + for ( i = 0; i < vArray->nSize; i++ ) { - nCutCut += pTemp[i]; - nCutMax = ABC_MAX( nCutCut, nCutMax ); + iNext = Aig_ManRandom( 0 ) % vArray->nSize; + Temp = vArray->pArray[i]; + vArray->pArray[i] = vArray->pArray[iNext]; + vArray->pArray[iNext] = Temp; } - ABC_FREE( pTemp ); - assert( nCutCut == 0 ); - return nCutMax; } /**Function************************************************************* - Synopsis [Computes hyper-edge centers.] + Synopsis [Computes cross cut size for the given order of POs.] Description [] @@ -313,31 +792,23 @@ int For_ManGetMaxCut( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManEdgeCenters( For_Man_t * p ) +void Frc_ManPlaceDfs_rec( Frc_Man_t * p, Frc_Obj_t * pObj, int * piPlace ) { - Gia_Obj_t * pObj; - int i; - memset( p->plEdge, 0, sizeof(float) * p->nObjs ); - Gia_ManForEachObj( p->pGia, pObj, i ) + assert( pObj->iFanout > 0 ); + if ( pObj->iFanout-- == pObj->nFanouts ) { - p->plEdge[i] = Gia_ObjPlace(p, pObj); - if ( Gia_ObjIsAnd(pObj) ) - { - p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj); - p->plEdge[Gia_ObjFaninId1p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj); - } - else if ( Gia_ObjIsCo(pObj) ) - { - p->plEdge[Gia_ObjFaninId0p(p->pGia, pObj)] += Gia_ObjPlace(p, pObj); - } + Frc_Obj_t * pFanin; + int i; + if ( !Frc_ObjIsCi(pObj) ) + Frc_ObjForEachFanin( pObj, pFanin, i ) + Frc_ManPlaceDfs_rec( p, pFanin, piPlace ); + pObj->pPlace = (*piPlace)++; } - Gia_ManForEachObj( p->pGia, pObj, i ) - p->plEdge[i] /= 1.0 + Gia_ObjRefs( p->pGia, pObj ); } /**Function************************************************************* - Synopsis [Computes object centers.] + Synopsis [Generates DFS placement.] Description [] @@ -346,30 +817,156 @@ void For_ManEdgeCenters( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManObjCenters( For_Man_t * p ) +void Frc_ManPlaceDfs( Frc_Man_t * p, Vec_Int_t * vCoOrder ) { - Gia_Obj_t * pObj; - int i; - Gia_ManForEachObj( p->pGia, pObj, i ) + Frc_Obj_t * pObj; + int i, nPlaces = 0; + Frc_ManForEachObj( p, pObj, i ) { - p->pNodes[i].lNode = Gia_ObjEdge(p, pObj); - if ( Gia_ObjIsAnd(pObj) ) + pObj->iFanout = pObj->nFanouts; + if ( pObj->nFanouts == 0 && !Frc_ObjIsCo(pObj) ) + pObj->pPlace = nPlaces++; + } + Frc_ManForEachObjVec( vCoOrder, p, pObj, i ) + { + assert( Frc_ObjIsCo(pObj) ); + Frc_ManPlaceDfs_rec( p, Frc_ObjFanin(pObj,0), &nPlaces ); + pObj->pPlace = nPlaces++; + } + assert( nPlaces == p->nObjs ); +} + +/**Function************************************************************* + + Synopsis [Generates DFS placement by trying both orders.] + + Description [Returns the cross cut size of the best order. ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Frc_ManPlaceDfsBoth( Frc_Man_t * p, Vec_Int_t * vCoOrder, int * piCutSize2 ) +{ + int nCutStart1, nCutStart2; + nCutStart1 = Frc_ManCrossCut( p, vCoOrder, 0 ); + Vec_IntReverseOrder( vCoOrder ); + nCutStart2 = Frc_ManCrossCut( p, vCoOrder, 0 ); + if ( nCutStart1 <= nCutStart2 ) + { + Vec_IntReverseOrder( vCoOrder ); // undo + Frc_ManPlaceDfs( p, vCoOrder ); + *piCutSize2 = nCutStart2; + return nCutStart1; + } + else + { + Frc_ManPlaceDfs( p, vCoOrder ); + Vec_IntReverseOrder( vCoOrder ); // undo + *piCutSize2 = nCutStart1; + return nCutStart2; + } +} + +/**Function************************************************************* + + Synopsis [Performs iterative refinement of the given placement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Frc_ManPlacementRefine( Frc_Man_t * p, int nIters, int fVerbose ) +{ + int fRandomize = 0; + Vec_Int_t * vCoOrder; + Frc_Obj_t * pThis, * pNext; + double CostThis, CostPrev; + float * pVertX, VertX; + int * pPermX, * pHandles; + int k, h, Iter, iMinX, iMaxX, Counter, nCutStart, nCutCur, nCutCur2, nCutPrev; + int clk = clock(), clk2, clk2Total = 0; + // create starting one-dimensional placement + vCoOrder = Frc_ManCollectCos( p ); + if ( fRandomize ) + Frc_ManArrayShuffle( vCoOrder ); + nCutStart = Frc_ManPlaceDfsBoth( p, vCoOrder, &nCutCur2 ); + // refine placement + CostPrev = 0.0; + nCutPrev = nCutStart; + pHandles = ABC_ALLOC( int, p->nObjs ); + pVertX = ABC_ALLOC( float, p->nObjs ); + for ( Iter = 0; Iter < nIters; Iter++ ) + { + // compute centers of hyperedges + CostThis = 0.0; + Frc_ManForEachObj( p, pThis, h ) + { + iMinX = iMaxX = pThis->pPlace; + Frc_ObjForEachFanout( pThis, pNext, k ) + { + iMinX = ABC_MIN( iMinX, pNext->pPlace ); + iMaxX = ABC_MAX( iMaxX, pNext->pPlace ); + } + pThis->fEdgeCenter = 0.5 * (iMaxX + iMinX); + CostThis += (iMaxX - iMinX); + } + // compute new centers of objects + Counter = 0; + Frc_ManForEachObj( p, pThis, h ) { - p->pNodes[i].lNode += Gia_ObjEdgeFanin0(p, pObj); - p->pNodes[i].lNode += Gia_ObjEdgeFanin1(p, pObj); - p->pNodes[i].lNode /= 3.0; + VertX = pThis->fEdgeCenter; + Frc_ObjForEachFanin( pThis, pNext, k ) + VertX += pNext->fEdgeCenter; + pVertX[Counter] = VertX / (Frc_ObjFaninNum(pThis) + 1); + pHandles[Counter++] = h; } - else if ( Gia_ObjIsCo(pObj) ) + assert( Counter == Frc_ManObjNum(p) ); + // sort these numbers + clk2 = clock(); + pPermX = Gia_SortFloats( pVertX, pHandles, p->nObjs ); + clk2Total += clock() - clk2; + assert( pPermX == pHandles ); + Vec_IntClear( vCoOrder ); + for ( k = 0; k < p->nObjs; k++ ) { - p->pNodes[i].lNode += Gia_ObjEdgeFanin0(p, pObj); - p->pNodes[i].lNode /= 2.0; + pThis = Frc_ManObj( p, pPermX[k] ); + pThis->pPlace = k; + if ( Frc_ObjIsCo(pThis) ) + Vec_IntPush( vCoOrder, pThis->hHandle ); } +/* + printf( "Ordering of PIs:\n" ); + Frc_ManForEachCi( p, pThis, k ) + printf( "PI number = %7d. Object handle = %7d, Coordinate = %7d.\n", + k, pThis->hHandle, pThis->pPlace ); +*/ + nCutCur = Frc_ManPlaceDfsBoth( p, vCoOrder, &nCutCur2 ); + // evaluate cost + if ( fVerbose ) + { + printf( "%2d : Span = %e ", Iter+1, CostThis ); + printf( "Cut = %6d (%5.2f %%) CutR = %6d ", nCutCur, 100.0*(nCutStart-nCutCur)/nCutStart, nCutCur2 ); + ABC_PRTn( "Total", clock() - clk ); + ABC_PRT( "Sort", clk2Total ); +// Frc_ManCrossCutTest( p, vCoOrder ); + } +// if ( 1.0 * nCutPrev / nCutCur < 1.001 ) +// break; + nCutPrev = nCutCur; } + ABC_FREE( pHandles ); + ABC_FREE( pVertX ); + Vec_IntFree( vCoOrder ); } /**Function************************************************************* - Synopsis [Sorts objects by their new centers.] + Synopsis [Returns 1 if all fanouts are COsw.] Description [] @@ -378,65 +975,56 @@ void For_ManObjCenters( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -int For_ObjCompare( For_Obj_t ** pp0, For_Obj_t ** pp1 ) +int Frc_ObjFanoutsAreCos( Frc_Obj_t * pThis ) { - if ( (*pp0)->lNode < (*pp1)->lNode ) - return -1; - if ( (*pp0)->lNode > (*pp1)->lNode ) - return 1; - return 0; + Frc_Obj_t * pNext; + int i; + Frc_ObjForEachFanout( pThis, pNext, i ) + if ( !Frc_ObjIsCo(pNext) ) + return 0; + return 1; } /**Function************************************************************* - Synopsis [Sorts objects by their new centers.] + Synopsis [Computes the distances from the given set of objects.] - Description [] + Description [Returns one of the most distant objects.] SideEffects [] SeeAlso [] - + ***********************************************************************/ -void For_ManSortObjects( For_Man_t * p ) +void Frc_DumpGraphIntoFile( Frc_Man_t * p ) { - For_Obj_t * pNode, * pPrev; - Vec_Ptr_t * vArray; - int i, k, iPlace; - // link the nodes into lists by cost - memset( p->piRoot, 0xff, sizeof(int) * p->nObjs ); - for ( i = 0; i < p->nObjs; i++ ) + FILE * pFile; + Frc_Obj_t * pThis, * pNext; + int i, k, Counter = 0; + // assign numbers to CIs and internal nodes + Frc_ManForEachObj( p, pThis, i ) { - p->pNodes[i].iObj = i; - iPlace = (int)p->pNodes[i].lNode; - assert( iPlace >= 0 && iPlace < p->nObjs ); - p->piNext[i] = p->piRoot[iPlace]; - p->piRoot[iPlace] = i; + if ( i && ((Frc_ObjIsCi(pThis) && !Frc_ObjFanoutsAreCos(pThis)) || Frc_ObjIsNode(pThis)) ) + pThis->iFanin = Counter++; + else + pThis->iFanin = ~0; } - // reconstruct the order - p->iObj = 0; - pPrev = NULL; - vArray = Vec_PtrAlloc( 100 ); - for ( i = 0; i < p->nObjs; i++ ) + // assign numbers to all other nodes + pFile = fopen( "x\\large\\aig\\dg1.g", "w" ); + Frc_ManForEachObj( p, pThis, i ) { - Vec_PtrClear( vArray ); - for ( k = p->piRoot[i]; ~((unsigned)k); k = p->piNext[k] ) - Vec_PtrPush( vArray, p->pNodes + k ); - Vec_PtrSort( vArray, (int (*)())For_ObjCompare ); - Vec_PtrForEachEntry( vArray, pNode, k ) + Frc_ObjForEachFanout( pThis, pNext, k ) { - p->pPlace[ pNode->iObj ] = p->iObj++; - assert( !pPrev || pPrev->lNode <= pNode->lNode ); - pPrev = pNode; + if ( ~pThis->iFanin && ~pNext->iFanin ) + fprintf( pFile, "%d %d\n", pThis->iFanin, pNext->iFanin ); } } - Vec_PtrFree( vArray ); - assert( p->iObj == p->nObjs ); + fclose( pFile ); } /**Function************************************************************* - Synopsis [] + Synopsis [Experiment with the FORCE algorithm.] Description [] @@ -445,33 +1033,25 @@ void For_ManSortObjects( For_Man_t * p ) SeeAlso [] ***********************************************************************/ -void For_ManPlaceByForce( For_Man_t * p ) +void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose ) { - int clk, Iter, fUseCut = 1; - double iCostThis, iCostPrev; - iCostThis = fUseCut? For_ManGetMaxCut(p) : For_ManGetEdgeSpan(p); - printf( "Init = %12.0f. \n", iCostThis ); - Iter = 0; - do { - Iter++; - iCostPrev = iCostThis; -clk = clock(); - For_ManEdgeCenters( p ); -//ABC_PRT( "Time", clock() - clk ); -clk = clock(); - For_ManObjCenters( p ); -//ABC_PRT( "Time", clock() - clk ); -clk = clock(); - For_ManSortObjects( p ); -//ABC_PRT( "Time", clock() - clk ); - iCostThis = fUseCut? For_ManGetMaxCut(p) : For_ManGetEdgeSpan(p); - printf( "%4d = %12.0f. \n", Iter, iCostThis ); - } while ( iCostPrev > iCostThis ); + Frc_Man_t * p; + Aig_ManRandom( 1 ); + if ( fClustered ) + p = Frc_ManStart( pGia ); + else + p = Frc_ManStartSimple( pGia ); +// Frc_DumpGraphIntoFile( p ); + if ( fVerbose ) + Frc_ManPrintStats( p ); +// Frc_ManCrossCutTest( p, NULL ); + Frc_ManPlacementRefine( p, nIters, fVerbose ); + Frc_ManStop( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Experiment with the FORCE algorithm.] Description [] @@ -480,51 +1060,40 @@ clk = clock(); SeeAlso [] ***********************************************************************/ -void For_ManExperiment( Gia_Man_t * pGia ) +void For_ManFileExperiment() { - For_Man_t * p; + FILE * pFile; + int * pBuffer; + int i, Size, Exp = 25; int clk = clock(); - p = For_ManStart( pGia ); - Gia_ManCreateRefs( pGia ); - - // use DSF order -clk = clock(); - For_ManSetInitPlaceDfs( p, 0 ); - printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) ); - printf( "Max span = %8d ", For_ManGetMaxCut(p) ); -ABC_PRT( "Time", clock() - clk ); - -clk = clock(); - For_ManPlaceByForce( p ); -ABC_PRT( "Time", clock() - clk ); - // use modified DFS order -clk = clock(); - For_ManSetInitPlaceDfs( p, 1 ); - printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) ); - printf( "Max span = %8d ", For_ManGetMaxCut(p) ); -ABC_PRT( "Time", clock() - clk ); + Size = (1 << Exp); + printf( "2^%d machine words (%d bytes).\n", Exp, sizeof(int) * Size ); -clk = clock(); - For_ManPlaceByForce( p ); -ABC_PRT( "Time", clock() - clk ); + pBuffer = ABC_ALLOC( int, Size ); + for ( i = 0; i < Size; i++ ) + pBuffer[i] = i; +ABC_PRT( "Fillup", clock() - clk ); - // use random order clk = clock(); - For_ManSetInitPlaceRandom( p ); - printf( "Tot span = %12.0f ", For_ManGetEdgeSpan(p) ); - printf( "Max span = %8d ", For_ManGetMaxCut(p) ); -ABC_PRT( "Time", clock() - clk ); + pFile = fopen( "test.txt", "rb" ); + fread( pBuffer, 1, sizeof(int) * Size, pFile ); + fclose( pFile ); +ABC_PRT( "Read ", clock() - clk ); clk = clock(); - For_ManPlaceByForce( p ); -ABC_PRT( "Time", clock() - clk ); - - For_ManStop( p ); + pFile = fopen( "test.txt", "wb" ); + fwrite( pBuffer, 1, sizeof(int) * Size, pFile ); + fclose( pFile ); +ABC_PRT( "Write ", clock() - clk ); +/* +2^25 machine words (134217728 bytes). +Fillup = 0.06 sec +Read = 0.08 sec +Write = 1.81 sec +*/ } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - +////////////////////////////////////////////////////////////////////////
\ No newline at end of file diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index e6e45cb5..95bffee8 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -68,8 +68,13 @@ void Gia_ManStop( Gia_Man_t * p ) { Vec_IntFree( p->vCis ); Vec_IntFree( p->vCos ); + ABC_FREE( p->pCexComb ); + ABC_FREE( p->pIso ); + ABC_FREE( p->pMapping ); ABC_FREE( p->pFanData ); + ABC_FREE( p->pReprsOld ); ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); ABC_FREE( p->pName ); ABC_FREE( p->pRefs ); ABC_FREE( p->pLevels ); @@ -98,12 +103,16 @@ void Gia_ManPrintStats( Gia_Man_t * p ) printf( "ff =%7d ", Gia_ManRegNum(p) ); printf( "and =%8d ", Gia_ManAndNum(p) ); printf( "lev =%5d ", Gia_ManLevelNum(p) ); -// printf( "cut =%5d ", Gia_ManCrossCut(p) ); + printf( "cut =%5d ", Gia_ManCrossCut(p) ); printf( "mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); // printf( "obj =%5d ", Gia_ManObjNum(p) ); printf( "\n" ); // Gia_ManSatExperiment( p ); + if ( p->pReprs && p->pNexts ) + Gia_ManEquivPrintClasses( p, 0, 0.0 ); + if ( p->pMapping ) + Gia_ManPrintMappingStats( p ); } /**Function************************************************************* diff --git a/src/aig/gia/giaMap.c b/src/aig/gia/giaMap.c new file mode 100644 index 00000000..72bdb001 --- /dev/null +++ b/src/aig/gia/giaMap.c @@ -0,0 +1,305 @@ +/**CFile**************************************************************** + + FileName [giaMap.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Manipulation of mapping associated with the AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "if.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetIfParsDefault( If_Par_t * pPars ) +{ +// extern void * Abc_FrameReadLibLut(); + // set defaults + memset( pPars, 0, sizeof(If_Par_t) ); + // user-controlable paramters +// pPars->nLutSize = -1; + pPars->nLutSize = 6; + pPars->nCutsMax = 8; + pPars->nFlowIters = 1; + pPars->nAreaIters = 2; + pPars->DelayTarget = -1; + pPars->Epsilon = (float)0.005; + pPars->fPreprocess = 1; + pPars->fArea = 0; + pPars->fFancy = 0; + pPars->fExpRed = 1; //// + pPars->fLatchPaths = 0; + pPars->fEdge = 1; + pPars->fPower = 0; + pPars->fCutMin = 0; + pPars->fSeqMap = 0; + pPars->fVerbose = 0; + // internal parameters + pPars->fTruth = 0; + pPars->nLatches = 0; + pPars->fLiftLeaves = 0; +// pPars->pLutLib = Abc_FrameReadLibLut(); + pPars->pLutLib = NULL; + pPars->pTimesArr = NULL; + pPars->pTimesArr = NULL; + pPars->pFuncCost = NULL; +} + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) +{ +// extern Vec_Int_t * SGia_ManComputeSwitchProbs( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ); +// Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL; +// float * pSwitching, * pSwitching2; + If_Man_t * pIfMan; + If_Obj_t * pIfObj; + Gia_Obj_t * pNode; + int i, clk = clock(); + Gia_ManLevelNum( p ); +/* + // set the number of registers (switch activity will be combinational) + Gia_ManSetRegNum( p, 0 ); + if ( pPars->fPower ) + { + vSwitching = SGia_ManComputeSwitchProbs( p, 48, 16, 0 ); + if ( pPars->fVerbose ) + { + ABC_PRT( "Computing switching activity", clock() - clk ); + } + pSwitching = (float *)vSwitching->pArray; + vSwitching2 = Vec_IntStart( Gia_ManObjNumMax(p) ); + pSwitching2 = (float *)vSwitching2->pArray; + } +*/ + // start the mapping manager and set its parameters + pIfMan = If_ManStart( pPars ); +// pIfMan->vSwitching = vSwitching2; + // load the AIG into the mapper + Gia_ManForEachObj( p, pNode, i ) + { + if ( Gia_ObjIsAnd(pNode) ) + pIfObj = If_ManCreateAnd( pIfMan, + If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), + If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); + else if ( Gia_ObjIsCi(pNode) ) + { + pIfObj = If_ManCreateCi( pIfMan ); + If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) ); +// printf( "pi=%d ", pIfObj->Level ); + if ( pIfMan->nLevelMax < (int)pIfObj->Level ) + pIfMan->nLevelMax = (int)pIfObj->Level; + } + else if ( Gia_ObjIsCo(pNode) ) + { + pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); +// printf( "po=%d ", pIfObj->Level ); + } + else if ( Gia_ObjIsConst0(pNode) ) + pIfObj = If_Not(If_ManConst1( pIfMan )); + else // add the node to the mapper + assert( 0 ); + // save the result + assert( Vec_PtrEntry(vAigToIf, i) == NULL ); + Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); +// if ( vSwitching2 ) +// pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; +/* // set up the choice node + if ( Gia_ObjIsChoice( p, pNode ) ) + { + pIfMan->nChoices++; + for ( pPrev = pNode, pFanin = Gia_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Gia_ObjEquiv(p, pFanin) ) + If_ObjSetChoice( pPrev->pData, pFanin->pData ); + If_ManCreateChoice( pIfMan, pNode->pData ); + } +// assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) ); +*/ + } +// if ( vSwitching ) +// Vec_IntFree( vSwitching ); + return pIfMan; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) +{ + int * pMapping, iOffset; + Vec_Ptr_t * vIfToAig; + Gia_Obj_t * pObj, * pObjRepr; + If_Obj_t * pIfObj; + If_Cut_t * pCutBest; + int i, k, j, nLeaves, * ppLeaves; + int nItems = 0; + assert( Gia_ManCiNum(p) == If_ManCiNum(pIfMan) ); + assert( Gia_ManCoNum(p) == If_ManCoNum(pIfMan) ); + assert( Gia_ManAndNum(p) == If_ManAndNum(pIfMan) ); + // create mapping of IF to AIG + vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) ); + Gia_ManForEachObj( p, pObj, i ) + { + pIfObj = Vec_PtrEntry( vAigToIf, i ); + Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj ); + if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) + continue; + nItems += 2 + If_CutLeaveNum( If_ObjCutBest(pIfObj) ); + } + // construct the network + pMapping = ABC_CALLOC( int, Gia_ManObjNum(p) + nItems ); + iOffset = Gia_ManObjNum(p); + Gia_ManForEachObj( p, pObj, i ) + { + pIfObj = Vec_PtrEntry( vAigToIf, i ); + if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) + continue; + pCutBest = If_ObjCutBest( pIfObj ); + nLeaves = If_CutLeaveNum( pCutBest ); + ppLeaves = If_CutLeaves( pCutBest ); + // create node + k = iOffset; + pMapping[k++] = nLeaves; + for ( j = 0; j < nLeaves; j++ ) + { + pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[j] ); + pMapping[k++] = Gia_ObjId( p, pObjRepr ); + } + pMapping[k++] = i; + pMapping[i] = iOffset; + iOffset = k; + } + assert( iOffset <= Gia_ManObjNum(p) + nItems ); + Vec_PtrFree( vIfToAig ); +// pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Interface with the FPGA mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars ) +{ + If_Man_t * pIfMan; + Vec_Ptr_t * vAigToIf; + // set the arrival times + pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) ); + memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) ); + // translate into the mapper + vAigToIf = Vec_PtrStart( Gia_ManObjNum(p) ); + pIfMan = Gia_ManToIf( p, pPars, vAigToIf ); + if ( pIfMan == NULL ) + return 0; +// pIfMan->pManTim = Tim_ManDup( pManTime, 0 ); + if ( !If_ManPerformMapping( pIfMan ) ) + { + If_ManStop( pIfMan ); + return 0; + } + // transform the result of mapping into the new network + ABC_FREE( p->pMapping ); + p->pMapping = Gia_ManFromIf( pIfMan, p, vAigToIf ); +// if ( pPars->fBidec && pPars->nLutSize <= 8 ) +// Gia_ManBidecResyn( pNtk, 0 ); + If_ManStop( pIfMan ); + Vec_PtrFree( vAigToIf ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintMappingStats( Gia_Man_t * p ) +{ + int * pLevels; + int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0; + if ( !p->pMapping ) + return; + pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachGate( p, i ) + { + nLuts++; + nFanins += Gia_ObjGateSize(p, i); + nLutSize = ABC_MAX( nLutSize, Gia_ObjGateSize(p, i) ); + Gia_GateForEachFanin( p, i, iFan, k ) + pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] ); + pLevels[i]++; + LevelMax = ABC_MAX( LevelMax, pLevels[i] ); + } + ABC_FREE( pLevels ); + printf( "mapping : " ); + printf( "%d=lut =%7d ", nLutSize, nLuts ); + printf( "edge =%8d ", nFanins ); + printf( "lev =%5d ", LevelMax ); + printf( "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); + printf( "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c index 3f72b0b9..9058af7d 100644 --- a/src/aig/gia/giaScl.c +++ b/src/aig/gia/giaScl.c @@ -30,7 +30,7 @@ /**Function************************************************************* - Synopsis [Returns the number of unmarked nodes.] + Synopsis [Marks unreachable internal nodes and returned their number.] Description [] @@ -45,13 +45,13 @@ int Gia_ManCombMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) return 0; pObj->fMark0 = 0; assert( Gia_ObjIsAnd(pObj) ); - return Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) + - Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ) + 1; + return 1 + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ); } /**Function************************************************************* - Synopsis [Returns the number of unused nodes.] + Synopsis [Marks unreachable internal nodes and returned their number.] Description [] @@ -90,7 +90,7 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ) /**Function************************************************************* - Synopsis [Marks CIs/COs reachable from POs.] + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] Description [] @@ -99,29 +99,26 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) +int Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) { if ( !pObj->fMark0 ) - return; + return 0; pObj->fMark0 = 0; if ( Gia_ObjIsCo(pObj) ) - { - Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); - return; - } + return Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); if ( Gia_ObjIsRo(p, pObj) ) { Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ObjRoToRi(p, pObj)) ); - return; + return 0; } assert( Gia_ObjIsAnd(pObj) ); - Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); - Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots ); + return 1 + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ) + + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots ); } /**Function************************************************************* - Synopsis [Performs sequential cleanup.] + Synopsis [Marks CIs/COs/ANDs unreachable from POs.] Description [] @@ -130,19 +127,38 @@ void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ) +int Gia_ManSeqMarkUsed( Gia_Man_t * p ) { Vec_Int_t * vRoots; Gia_Obj_t * pObj; - int i; + int i, nNodes = 0; Gia_ManSetMark0( p ); Gia_ManConst0(p)->fMark0 = 0; Gia_ManForEachPi( p, pObj, i ) pObj->fMark0 = 0; + Gia_ManForEachPo( p, pObj, i ) + pObj->fMark0 = 0; vRoots = Gia_ManCollectPoIds( p ); Gia_ManForEachObjVec( vRoots, p, pObj, i ) - Gia_ManSeqMarkUsed_rec( p, pObj, vRoots ); + nNodes += Gia_ManSeqMarkUsed_rec( p, pObj, vRoots ); Vec_IntFree( vRoots ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs sequential cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ) +{ + Gia_ManSeqMarkUsed( p ); return Gia_ManDupMarked( p ); } diff --git a/src/aig/gia/giaSort.c b/src/aig/gia/giaSort.c index aec98fd8..8574297d 100644 --- a/src/aig/gia/giaSort.c +++ b/src/aig/gia/giaSort.c @@ -245,12 +245,15 @@ void minisat_sort3(float* array, int* perm, int size) SeeAlso [] ***********************************************************************/ -int * Gia_SortFloats( float * pArray, int nSize ) +int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ) { - int i, * pPerm; - pPerm = ABC_ALLOC( int, nSize ); - for ( i = 0; i < nSize; i++ ) - pPerm[i] = i; + int i; + if ( pPerm == NULL ) + { + pPerm = ABC_ALLOC( int, nSize ); + for ( i = 0; i < nSize; i++ ) + pPerm[i] = i; + } minisat_sort3( pArray, pPerm, nSize ); // for ( i = 1; i < nSize; i++ ) // assert( pArray[i-1] <= pArray[i] ); diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 64f191f1..cc1a3861 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -300,6 +300,34 @@ void Gia_ManCreateRefs( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Assigns references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManCreateMuxRefs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pCtrl, * pFan0, * pFan1; + int i, * pMuxRefs; + pMuxRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + continue; + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_ObjRecognizeMux( pObj, &pFan0, &pFan1 ); + pMuxRefs[ Gia_ObjId(p, Gia_Regular(pCtrl)) ]++; + } + return pMuxRefs; +} + +/**Function************************************************************* + Synopsis [Computes the maximum frontier size.] Description [] @@ -549,6 +577,45 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob return NULL; } + +/**Function************************************************************* + + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDoubleOuts ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = Aig_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Aig_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + if ( fDoubleOuts ) + RetValue = Gia_ManPo(pAig, 2*p->iPo)->fMark0 ^ Gia_ManPo(pAig, 2*p->iPo+1)->fMark0; + else + RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; + Gia_ManCleanMark0(pAig); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 7a68b554..4410b497 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -5,6 +5,8 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaDfs.c \ src/aig/gia/giaDup.c \ src/aig/gia/giaEmbed.c \ + src/aig/gia/giaEnable.c \ + src/aig/gia/giaEquiv.c \ src/aig/gia/giaFanout.c \ src/aig/gia/giaForce.c \ src/aig/gia/giaFrames.c \ @@ -12,6 +14,7 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaGlitch.c \ src/aig/gia/giaHash.c \ src/aig/gia/giaMan.c \ + src/aig/gia/giaMap.c \ src/aig/gia/giaScl.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSort.c \ diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c index 11c866f4..b81414a5 100644 --- a/src/aig/ioa/ioaReadAig.c +++ b/src/aig/ioa/ioaReadAig.c @@ -341,6 +341,18 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck ) Aig_ManShortNames( pNew ); } */ + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + pCur++; + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Aig_UtilStrsav( pCur ); + } + } // skipping the comments ABC_FREE( pContents ); diff --git a/src/aig/ioa/ioaWriteAig.c b/src/aig/ioa/ioaWriteAig.c index 3d37c0a7..42aa42db 100644 --- a/src/aig/ioa/ioaWriteAig.c +++ b/src/aig/ioa/ioaWriteAig.c @@ -375,10 +375,10 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int } */ // write the comment - fprintf( pFile, "c\n" ); + fprintf( pFile, "c" ); if ( pMan->pName ) - fprintf( pFile, ".model %s\n", pMan->pName ); - fprintf( pFile, "This file was produced by the AIG package on %s\n", Ioa_TimeStamp() ); + fprintf( pFile, "n%s%c", pMan->pName, '\0' ); + fprintf( pFile, "\nThis file was produced by the IOA package in ABC on %s\n", Ioa_TimeStamp() ); fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); fclose( pFile ); } diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 174a3e97..71bdadf6 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -568,13 +568,17 @@ int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** printf( "The output number %d of the miter is constant 1.\n", i ); Counter++; continue; - } + } if ( !Aig_ObjIsNode(pFanin) || !Aig_ObjRecognizeExor( pFanin, &pObj0, &pObj1 ) ) { +/* printf( "The miter cannot be demitered.\n" ); Vec_PtrFree( vSet0 ); Vec_PtrFree( vSet1 ); return 0; +*/ + printf( "The output number %d cannot be demitered.\n", i ); + continue; } if ( Aig_ObjFaninC0(pObj) ) pObj0 = Aig_Not(pObj0); diff --git a/src/aig/ssw/sswCore.c b/src/aig/ssw/sswCore.c index 16430ace..9d09d4e7 100644 --- a/src/aig/ssw/sswCore.c +++ b/src/aig/ssw/sswCore.c @@ -179,7 +179,8 @@ clk = clock(); printf( "Cex =%5d. ", p->nSatCallsSat-nSatCallsSat ); printf( "R =%4d. ", p->nRecycles-nRecycles ); } - printf( "F =%5d. ", p->nSatFailsReal-nSatFailsReal ); + printf( "F =%5d. %s ", p->nSatFailsReal-nSatFailsReal, + (Saig_ManPoNum(p->pAig)==1 && Ssw_ObjIsConst1Cand(p->pAig,Aig_ObjFanin0(Aig_ManPo(p->pAig,0))))? "+" : "-" ); ABC_PRT( "T", clock() - clk ); } // if ( p->pPars->fDynamic && p->nSatCallsSat-nSatCallsSat < 100 ) diff --git a/src/base/abc/abcBlifMv.zip b/src/base/abc/abcBlifMv.zip Binary files differdeleted file mode 100644 index 4a4d080a..00000000 --- a/src/base/abc/abcBlifMv.zip +++ /dev/null diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index fb8dcaae..6c75cf3f 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -92,6 +92,12 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) { printf( "Abc_ObjAddFanin(): Error! Creating net \"%s\" with two fanins.\n", Abc_ObjName(pObj) ); } +/* + if ( Abc_ObjIsCo(pFanin) ) + { + printf( "Abc_ObjAddFanin(): Error! Creating fanout of a CO.\n", Abc_ObjName(pFanin) ); + } +*/ } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index e7187a9f..1164c3da 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -82,6 +82,7 @@ static int Abc_CommandFastExtract ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandEliminate ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDisjoint ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandLutpack ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandLutmin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandImfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTrace ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -151,14 +152,13 @@ static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandISat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandNFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSimSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMatch ( Abc_Frame_t * pAbc, int argc, char ** argv ); //static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv ); +//static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandQbf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -217,7 +217,6 @@ static int Abc_CommandExtWin ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandInsWin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandCec2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -258,6 +257,7 @@ static int Abc_CommandAbc8Bidec ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandAbc8Strash ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Lutpack ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc8Lutmin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Balance ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Speedup ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Merge ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -279,6 +279,7 @@ static int Abc_CommandAbc9Read ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandAbc9Write ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Ps ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9PFan ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9PSig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Status ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Show ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Hash ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -287,13 +288,18 @@ static int Abc_CommandAbc9Cof ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandAbc9Trim ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Dfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sim ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Equiv ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Times ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Frames ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Miter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Scl ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Fraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Srm ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Cec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Force ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Embed ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9If ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbcTestNew ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -391,6 +397,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "eliminate", Abc_CommandEliminate, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "dsd", Abc_CommandDisjoint, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "lutpack", Abc_CommandLutpack, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "lutmin", Abc_CommandLutmin, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "imfs", Abc_CommandImfs, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "mfs", Abc_CommandMfs, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "trace", Abc_CommandTrace, 0 ); @@ -460,10 +467,9 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "New AIG", "isat", Abc_CommandISat, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "ifraig", Abc_CommandIFraig, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "dfraig", Abc_CommandDFraig, 1 ); - Cmd_CommandAdd( pAbc, "New AIG", "nfraig", Abc_CommandNFraig, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "csweep", Abc_CommandCSweep, 1 ); // Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 ); - Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 ); +// Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "qbf", Abc_CommandQbf, 0 ); Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 ); @@ -520,7 +526,6 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Sequential", "inswin", Abc_CommandInsWin, 1 ); Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 ); - Cmd_CommandAdd( pAbc, "Verification", "cec2", Abc_CommandCec2, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dcec", Abc_CommandDCec, 0 ); Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsec", Abc_CommandDSec, 0 ); @@ -582,6 +587,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "AIG", "&w", Abc_CommandAbc9Write, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&ps", Abc_CommandAbc9Ps, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&pfan", Abc_CommandAbc9PFan, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&psig", Abc_CommandAbc9PSig, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&status", Abc_CommandAbc9Status, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&show", Abc_CommandAbc9Show, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&hash", Abc_CommandAbc9Hash, 0 ); @@ -590,13 +596,18 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "AIG", "&trim", Abc_CommandAbc9Trim, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&dfs", Abc_CommandAbc9Dfs, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&sim", Abc_CommandAbc9Sim, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&equiv", Abc_CommandAbc9Equiv, 0 ); Cmd_CommandAdd( pAbc, "AIG", "×", Abc_CommandAbc9Times, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&frames", Abc_CommandAbc9Frames, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&miter", Abc_CommandAbc9Miter, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&scl", Abc_CommandAbc9Scl, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&sat", Abc_CommandAbc9Sat, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&fraig", Abc_CommandAbc9Fraig, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&srm", Abc_CommandAbc9Srm, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&cec", Abc_CommandAbc9Cec, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&force", Abc_CommandAbc9Force, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&embed", Abc_CommandAbc9Embed, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&if", Abc_CommandAbc9If, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&test", Abc_CommandAbc9Test, 0 ); Cmd_CommandAdd( pAbc, "Various", "testnew", Abc_CommandAbcTestNew, 0 ); @@ -634,6 +645,10 @@ void Abc_Init( Abc_Frame_t * pAbc ) extern void Gia_SortTest(); // Gia_SortTest(); } + { + void For_ManFileExperiment(); +// For_ManFileExperiment(); + } } @@ -3694,6 +3709,85 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandLutmin( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + int nLutSize; + int fVerbose; + extern Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose ); + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + nLutSize = 6; + fVerbose = 1; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + fprintf( pErr, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + nLutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutSize > 1 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + // modify the current network + pNtkRes = Abc_NtkLutmin( pNtk, nLutSize, fVerbose ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "The command has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: lutmin [-K <num>] [-vh]\n" ); + fprintf( pErr, "\t perform FPGA mapping while minimizing the LUT count\n" ); + fprintf( pErr, "\t as described in the paper T. Sasao and A. Mishchenko:\n" ); + fprintf( pErr, "\t \"On the number of LUTs to implement logic functions\".\n" ); + fprintf( pErr, "\t-K <num> : the LUT size to use for the mapping (2 <= num) [default = %d]\n", nLutSize ); + fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandImfs( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -5369,12 +5463,6 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } - if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) ) - { - fprintf( pErr, "The miter's PO is not an EXOR.\n" ); - return 1; - } - // get the new network if ( fSeq ) { @@ -5391,6 +5479,11 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "The network is not a single-output miter.\n" ); return 1; } + if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) ) + { + fprintf( pErr, "The miter's PO is not an EXOR.\n" ); + return 1; + } if ( !Abc_NtkDemiter( pNtk ) ) { fprintf( pErr, "Demitering has failed.\n" ); @@ -8163,6 +8256,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NtkDarTest( Abc_Ntk_t * pNtk ); extern Abc_Ntk_t * Abc_NtkDarTestNtk( Abc_Ntk_t * pNtk ); extern void Amap_LibertyTest( char * pFileName ); + extern void Bbl_ManTest( Abc_Ntk_t * pNtk ); + extern void Bbl_ManSimpleDemo(); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -8379,6 +8474,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) // Abc_NtkDarTest( pNtk ); + Bbl_ManTest( pNtk ); +// Bbl_ManSimpleDemo(); return 0; usage: fprintf( pErr, "usage: test [-h] <file_name>\n" ); @@ -10076,152 +10173,6 @@ usage: SeeAlso [] ***********************************************************************/ -int Abc_CommandNFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Cec_ParCsw_t Pars, * p = &Pars; - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - extern Abc_Ntk_t * Abc_NtkDarSatSweep( Abc_Ntk_t * pNtk, Cec_ParCsw_t * pPars ); - - pNtk = Abc_FrameReadNtk(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - Cec_ManCswSetDefaultParams( p ); - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "WRCNZLrfvh" ) ) != EOF ) - { - switch ( c ) - { - case 'W': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-W\" should be followed by an integer.\n" ); - goto usage; - } - p->nWords = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( p->nWords < 0 ) - goto usage; - break; - case 'R': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" ); - goto usage; - } - p->nRounds = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( p->nRounds < 0 ) - goto usage; - break; - case 'C': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - p->nBTLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( p->nBTLimit < 0 ) - goto usage; - break; - case 'N': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); - goto usage; - } - p->nSatVarMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( p->nSatVarMax < 0 ) - goto usage; - break; - case 'Z': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-Z\" should be followed by an integer.\n" ); - goto usage; - } - p->nCallsRecycle = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( p->nCallsRecycle < 0 ) - goto usage; - break; - case 'L': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" ); - goto usage; - } - p->nLevelMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( p->nLevelMax < 0 ) - goto usage; - break; - case 'r': - p->fRewriting ^= 1; - break; - case 'f': - p->fFirstStop ^= 1; - break; - case 'v': - p->fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "This command works only for strashed networks.\n" ); - return 1; - } - pNtkRes = Abc_NtkDarSatSweep( pNtk, p ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Command has failed.\n" ); - return 0; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; -usage: - fprintf( pErr, "usage: nfraig [-WRCNZL num] [-rfvh]\n" ); - fprintf( pErr, "\t performs fraiging using a new method\n" ); - fprintf( pErr, "\t-W num : lthe number of simulation words [default = %d]\n", p->nWords ); - fprintf( pErr, "\t-R num : the number of simulation rounds [default = %d]\n", p->nRounds ); - fprintf( pErr, "\t-C num : limit on conflicts at a node [default = %d]\n", p->nBTLimit ); - fprintf( pErr, "\t-N num : the min number of SAT vars before recycling [default = %d]\n", p->nSatVarMax ); - fprintf( pErr, "\t-Z num : the min number of SAT calls before recycling [default = %d]\n", p->nCallsRecycle ); - fprintf( pErr, "\t-L num : the maximum level of the nodes to be swept [default = %d]\n", p->nLevelMax ); - fprintf( pErr, "\t-r : toggle the use of AIG rewriting [default = %s]\n", p->fRewriting? "yes": "no" ); - fprintf( pErr, "\t-f : stop after one output is disproved [default = %s]\n", p->fFirstStop? "yes": "no" ); - fprintf( pErr, "\t-v : enable verbose printout [default = %s]\n", p->fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Abc_CommandCSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -12792,6 +12743,13 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Empty network.\n" ); return 1; } +/* + if ( pPars->fSeqMap ) + { + fprintf( pErr, "Sequential mapping is currently disabled.\n" ); + return 1; + } +*/ if ( pPars->fSeqMap && pPars->nLatches == 0 ) { @@ -12825,12 +12783,6 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } - if ( pPars->fSeqMap ) - { - fprintf( pErr, "Sequential mapping is currently disabled.\n" ); - return 1; - } - // enable truth table computation if choices are selected if ( (c = Abc_NtkGetChoiceNum( pNtk )) ) { @@ -15828,6 +15780,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) int nConfLimit; int nInsLimit; int fPartition; + int fIgnoreNames; extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit ); extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ); @@ -15846,8 +15799,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) nConfLimit = 10000; nInsLimit = 0; fPartition = 0; + fIgnoreNames = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "TCIPpsvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "TCIPpsnvh" ) ) != EOF ) { switch ( c ) { @@ -15901,6 +15855,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSat ^= 1; break; + case 'n': + fIgnoreNames ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -15913,6 +15870,12 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) nArgcNew = argc - globalUtilOptind; if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) return 1; + + if ( fIgnoreNames ) + { + Abc_NtkShortNames( pNtk1 ); + Abc_NtkShortNames( pNtk2 ); + } // perform equivalence checking if ( fPartition ) @@ -15933,7 +15896,7 @@ usage: strcpy( Buffer, "unused" ); else sprintf( Buffer, "%d", nPartSize ); - fprintf( pErr, "usage: cec [-T num] [-C num] [-I num] [-P num] [-psvh] <file1> <file2>\n" ); + fprintf( pErr, "usage: cec [-T num] [-C num] [-I num] [-P num] [-psnvh] <file1> <file2>\n" ); fprintf( pErr, "\t performs combinational equivalence checking\n" ); fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds ); fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); @@ -15941,6 +15904,7 @@ usage: fprintf( pErr, "\t-P num : partition size for multi-output networks [default = %s]\n", Buffer ); fprintf( pErr, "\t-p : toggle automatic partitioning [default = %s]\n", fPartition? "yes": "no" ); fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" ); + fprintf( pErr, "\t-n : toggle using names to match CIs/COs [default = %s]\n", fIgnoreNames? "yes": "no" ); fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); @@ -16115,149 +16079,6 @@ usage: SeeAlso [] ***********************************************************************/ -int Abc_CommandCec2( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Cec_ParCec_t Pars, * pPars = &Pars; - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtk1, * pNtk2; - int fDelete1, fDelete2; - char ** pArgvNew; - int nArgcNew; - int fMiter; - int c; - - extern int Abc_NtkDarCec2( Abc_Ntk_t * pNtk0, Abc_Ntk_t * pNtk1, Cec_ParCec_t * pPars ); - - pNtk = Abc_FrameReadNtk(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fMiter = 0; - Cec_ManCecSetDefaultParams( pPars ); - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "BMImfrsvh" ) ) != EOF ) - { - switch ( c ) - { - case 'B': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-B\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nBTLimitBeg = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nBTLimitBeg < 0 ) - goto usage; - break; - case 'M': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nBTlimitMulti = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nBTlimitMulti < 0 ) - goto usage; - break; - case 'I': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nIters = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nIters < 0 ) - goto usage; - break; - case 'm': - fMiter ^= 1; - break; - case 'f': - pPars->fFirstStop ^= 1; - break; - case 'r': - pPars->fRewriting ^= 1; - break; - case 's': - pPars->fSatSweeping ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - default: - goto usage; - } - } - - pArgvNew = argv + globalUtilOptind; - nArgcNew = argc - globalUtilOptind; - if ( fMiter ) - { - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( Abc_NtkIsStrash(pNtk) ) - { - pNtk1 = pNtk; - fDelete1 = 0; - } - else - { - pNtk1 = Abc_NtkStrash( pNtk, 0, 1, 0 ); - fDelete1 = 1; - } - pNtk2 = NULL; - fDelete2 = 0; - } - else - { - if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) - return 1; - } - - // perform equivalence checking - Abc_NtkDarCec2( pNtk1, pNtk2, pPars ); - - if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); - return 0; - -usage: - fprintf( pErr, "usage: cec2 [-BMI num] [-frsvh] <file1> <file2>\n" ); - fprintf( pErr, "\t performs combinational equivalence checking\n" ); - fprintf( pErr, "\t-B num : staring limit on the number of conflicts [default = %d]\n", pPars->nBTLimitBeg ); - fprintf( pErr, "\t-M num : multiple of the above limit [default = %d]\n", pPars->nBTlimitMulti ); - fprintf( pErr, "\t-I num : the number of iterations [default = %d]\n", pPars->nIters ); - fprintf( pErr, "\t-m : toggle working on two networks or a miter [default = %s]\n", fMiter? "miter": "two networks" ); - fprintf( pErr, "\t-f : toggle stopping after first mismatch [default = %s]\n", pPars->fFirstStop? "yes": "no" ); - fprintf( pErr, "\t-r : toggle AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" ); - fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", pPars->fSatSweeping? "SAT only": "FRAIG + SAT" ); - fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); - fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); - fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); - fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -22157,6 +21978,56 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9PSig( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + int c; + int fSetReset = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "rh" ) ) != EOF ) + { + switch ( c ) + { + case 'r': + fSetReset ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9PSigs(): There is no AIG.\n" ); + return 1; + } + if ( Gia_ManRegNum(pAbc->pAig) == 0 ) + { + printf( "Abc_CommandAbc9PSigs(): Works only for sequential circuits.\n" ); + return 1; + } + Gia_ManDetectSeqSignals( pAbc->pAig, fSetReset ); + return 0; + +usage: + fprintf( stdout, "usage: &psig [-rh]\n" ); + fprintf( stdout, "\t prints enable/set/reset statistics\n" ); + fprintf( stdout, "\t-r : toggle printing set/reset signals [default = %s]\n", fSetReset? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Status( Abc_Frame_t * pAbc, int argc, char ** argv ) { int c; @@ -22336,9 +22207,9 @@ usage: int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; - int c, iVar = 0; + int c, iVar = 0, nLimFan = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "VLh" ) ) != EOF ) { switch ( c ) { @@ -22353,6 +22224,17 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iVar < 0 ) goto usage; break; + case 'L': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + nLimFan = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLimFan < 0 ) + goto usage; + break; case 'h': goto usage; default: @@ -22364,7 +22246,7 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Abc_CommandAbc9Cof(): There is no AIG.\n" ); return 1; } - pAbc->pAig = Gia_ManDupCofactored( pTemp = pAbc->pAig, iVar ); + pAbc->pAig = Gia_ManDupCofactored( pTemp = pAbc->pAig, iVar, nLimFan ); if ( pAbc->pAig == NULL ) { pAbc->pAig = pTemp; @@ -22375,9 +22257,10 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( stdout, "usage: &cof [-V num] [-h]\n" ); + fprintf( stdout, "usage: &cof [-VL num] [-h]\n" ); fprintf( stdout, "\t performs cofactoring w.r.t. a variable\n" ); fprintf( stdout, "\t-V num : the zero-based ID of the variable to cofactor [default = %d]\n", iVar ); + fprintf( stdout, "\t-L num : cofactor w.r.t. variables whose fanout is higher [default = %d]\n", nLimFan ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; } @@ -22397,11 +22280,19 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; int c; + int fTrimCis = 1; + int fTrimCos = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ioh" ) ) != EOF ) { switch ( c ) { + case 'i': + fTrimCis ^= 1; + break; + case 'o': + fTrimCos ^= 1; + break; case 'h': goto usage; default: @@ -22413,13 +22304,15 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Abc_CommandAbc9Trim(): There is no AIG.\n" ); return 1; } - pAbc->pAig = Gia_ManDupTrimmed( pTemp = pAbc->pAig ); + pAbc->pAig = Gia_ManDupTrimmed( pTemp = pAbc->pAig, fTrimCis, fTrimCos ); Gia_ManStop( pTemp ); return 0; usage: - fprintf( stdout, "usage: &trim [-h]\n" ); + fprintf( stdout, "usage: &trim [-ioh]\n" ); fprintf( stdout, "\t removes PIs without fanout and PO driven by constants\n" ); + fprintf( stdout, "\t-i : toggle removing PIs [default = %s]\n", fTrimCis? "yes": "no" ); + fprintf( stdout, "\t-o : toggle removing POs [default = %s]\n", fTrimCos? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; } @@ -22563,6 +22456,104 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9Equiv( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParSim_t Pars, * pPars = &Pars; + int c; + Cec_ManSimSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "WRTsmfdvh" ) ) != EOF ) + { + switch ( c ) + { + case 'W': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-W\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nWords = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nWords < 0 ) + goto usage; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRounds = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRounds < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->TimeLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->TimeLimit < 0 ) + goto usage; + break; + case 's': + pPars->fSeqSimulate ^= 1; + break; + case 'm': + pPars->fCheckMiter ^= 1; + break; + case 'f': + pPars->fFirstStop ^= 1; + break; + case 'd': + pPars->fDoubleOuts ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9Equiv(): There is no AIG.\n" ); + return 1; + } + Cec_ManSimulation( pAbc->pAig, pPars ); + return 0; + +usage: + fprintf( stdout, "usage: &equiv [-WRT <num>] [-smfdvh]\n" ); + fprintf( stdout, "\t computes candidate equivalence classes\n" ); + fprintf( stdout, "\t-W num : the number of words to simulate [default = %d]\n", pPars->nWords ); + fprintf( stdout, "\t-R num : the number of rounds to simulate [default = %d]\n", pPars->nRounds ); + fprintf( stdout, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); + fprintf( stdout, "\t-s : toggle seq vs. comb simulation [default = %s]\n", pPars->fSeqSimulate? "yes": "no" ); + fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" ); + fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-d : toggle using two POs intead of XOR [default = %s]\n", pPars->fDoubleOuts? "yes": "no" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Times( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; @@ -22685,6 +22676,119 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pFile; + Gia_Man_t * pAux; + Gia_Man_t * pSecond; + char * FileName, * pTemp; + char ** pArgvNew; + int nArgcNew; + int c; + int fXorOuts = 1; + int fComb = 1; + int fTrans = 0; + int fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "xctvh" ) ) != EOF ) + { + switch ( c ) + { + case 'x': + fXorOuts ^= 1; + break; + case 'c': + fComb ^= 1; + break; + case 't': + fTrans ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( fTrans ) + { + if ( (Gia_ManPoNum(pAbc->pAig) & 1) == 1 ) + { + printf( "Abc_CommandAbc9Miter(): The number of outputs should be even.\n" ); + return 0; + } + pAbc->pAig = Gia_ManTransformMiter( pAux = pAbc->pAig ); + Gia_ManStop( pAux ); + printf( "Abc_CommandAbc9Miter(): Miter is transformed by merging POs pair-wise.\n" ); + return 0; + } + + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 1 ) + { + printf( "File name is not given on the command line.\n" ); + return 1; + } + + // get the input file name + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); + fprintf( pAbc->Err, "\n" ); + return 1; + } + fclose( pFile ); + pSecond = Gia_ReadAiger( FileName, 0 ); + if ( pSecond == NULL ) + { + printf( "Reading AIGER has failed.\n" ); + return 0; + } + // compute the miter + pAbc->pAig = Gia_ManMiter( pAux = pAbc->pAig, pSecond, fXorOuts, fComb, fVerbose ); + Gia_ManStop( pSecond ); + if ( pAbc->pAig == NULL ) + { + printf( "Miter construction has failed.\n" ); + pAbc->pAig = pAux; + } + else + Gia_ManStop( pAux ); + return 0; + +usage: + fprintf( stdout, "usage: &miter [-xctvh] <file>\n" ); + fprintf( stdout, "\t creates miter of two designs (current AIG vs. <file>)\n" ); + fprintf( stdout, "\t-x : toggle creating XOR of output pairs [default = %s]\n", fXorOuts? "yes": "no" ); + fprintf( stdout, "\t-c : toggle creating combinational miter [default = %s]\n", fComb? "yes": "no" ); + fprintf( stdout, "\t-t : toggle XORing pair-wise POs of the miter [default = %s]\n", fTrans? "yes": "no" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + fprintf( stdout, "\t<file> : AIGER file with the design to miter\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Scl( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; @@ -22747,7 +22851,7 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Cec_ManSatSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CSNfvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CSNmfvh" ) ) != EOF ) { switch ( c ) { @@ -22784,6 +22888,9 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nCallsRecycle < 0 ) goto usage; break; + case 'm': + pPars->fCheckMiter ^= 1; + break; case 'f': pPars->fFirstStop ^= 1; break; @@ -22804,12 +22911,13 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( stdout, "usage: &sat [-CSN <num>] [-fvh]\n" ); + fprintf( stdout, "usage: &sat [-CSN <num>] [-mfvh]\n" ); fprintf( stdout, "\t performs SAT solving for the combinational outputs\n" ); fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); fprintf( stdout, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax ); - fprintf( stdout, "\t-N num : the max number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle ); - fprintf( stdout, "\t-f : toggle stopping when an output is satisfiable [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle ); + fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" ); + fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; @@ -22828,12 +22936,12 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Cec_ParCsw_t ParsCsw, * pPars = &ParsCsw; + Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp; int c; - Cec_ManCswSetDefaultParams( pPars ); + Cec_ManFraSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "WRILDCSNrmwvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "WRILDCrmfdwvh" ) ) != EOF ) { switch ( c ) { @@ -22903,34 +23011,18 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBTLimit < 0 ) goto usage; break; - case 'S': - if ( globalUtilOptind >= argc ) - { - fprintf( stdout, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nSatVarMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nSatVarMax < 0 ) - goto usage; - break; - case 'N': - if ( globalUtilOptind >= argc ) - { - fprintf( stdout, "Command line switch \"-N\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nCallsRecycle = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nCallsRecycle < 0 ) - goto usage; - break; case 'r': pPars->fRewriting ^= 1; break; case 'm': + pPars->fCheckMiter ^= 1; + break; + case 'f': pPars->fFirstStop ^= 1; break; + case 'd': + pPars->fDoubleOuts ^= 1; + break; case 'w': pPars->fVeryVerbose ^= 1; break; @@ -22946,12 +23038,16 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Abc_CommandAbc9Fraig(): There is no AIG.\n" ); return 1; } - pAbc->pAig = Cec_ManSatSweeping( pTemp = pAbc->pAig, pPars ); - Gia_ManStop( pTemp ); + pTemp = Cec_ManSatSweeping( pAbc->pAig, pPars ); + if ( pTemp ) + { + Gia_ManStop( pAbc->pAig ); + pAbc->pAig = pTemp; + } return 0; usage: - fprintf( stdout, "usage: &fraig [-WRILDCSN <num>] [-rmwvh]\n" ); + fprintf( stdout, "usage: &fraig [-WRILDC <num>] [-rmfdwvh]\n" ); fprintf( stdout, "\t performs combinational SAT sweeping\n" ); fprintf( stdout, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords ); fprintf( stdout, "\t-R num : the number of simulation rounds [default = %d]\n", pPars->nRounds ); @@ -22959,10 +23055,10 @@ usage: fprintf( stdout, "\t-L num : the max number of levels of nodes to consider [default = %d]\n", pPars->nLevelMax ); fprintf( stdout, "\t-D num : the max number of steps of speculative reduction [default = %d]\n", pPars->nDepthMax ); fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); - fprintf( stdout, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax ); - fprintf( stdout, "\t-N num : the max number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle ); fprintf( stdout, "\t-r : toggle the use of AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" ); - fprintf( stdout, "\t-m : toggle stopping when an output is satisfiable [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" ); + fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-d : toggle using double output miters [default = %s]\n", pPars->fDoubleOuts? "yes": "no" ); fprintf( stdout, "\t-w : toggle printing even more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); @@ -22980,14 +23076,196 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9Srm(): There is no AIG.\n" ); + return 1; + } + pAbc->pAig = Gia_ManSpecReduce( pTemp = pAbc->pAig ); + Gia_ManStop( pTemp ); + return 0; + +usage: + fprintf( stdout, "usage: &srm [-vh]\n" ); + fprintf( stdout, "\t testing various procedures\n" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + FILE * pFile; + Gia_Man_t * pSecond, * pMiter; + char * FileName, * pTemp; + char ** pArgvNew; + int c, nArgcNew, fMiter = 0; + Cec_ManCecSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBTLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBTLimit < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->TimeLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->TimeLimit < 0 ) + goto usage; + break; + case 'm': + fMiter ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( fMiter ) + { + printf( "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Cec_ManVerify( pAbc->pAig, pPars ); + return 0; + } + + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 1 ) + { + printf( "File name is not given on the command line.\n" ); + return 1; + } + + // get the input file name + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); + fprintf( pAbc->Err, "\n" ); + return 1; + } + fclose( pFile ); + pSecond = Gia_ReadAiger( FileName, 0 ); + if ( pSecond == NULL ) + { + printf( "Reading AIGER has failed.\n" ); + return 0; + } + // compute the miter + pMiter = Gia_ManMiter( pAbc->pAig, pSecond, 0, 1, pPars->fVerbose ); + if ( pMiter ) + { + Cec_ManVerify( pMiter, pPars ); + Gia_ManStop( pMiter ); + } + Gia_ManStop( pSecond ); + return 0; + +usage: + fprintf( stdout, "usage: &cec [-CT num] [-mvh]\n" ); + fprintf( stdout, "\t new combinational equivalence checker\n" ); + fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); + fprintf( stdout, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); + fprintf( stdout, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits"); + fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Force( Abc_Frame_t * pAbc, int argc, char ** argv ) { + int nIters = 20; + int fClustered = 1; + int fVerbose = 1; int c; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Icvh" ) ) != EOF ) { switch ( c ) { + case 'I': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nIters = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nIters < 0 ) + goto usage; + break; + case 'c': + fClustered ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; case 'h': goto usage; default: @@ -22996,17 +23274,20 @@ int Abc_CommandAbc9Force( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pAig == NULL ) { - printf( "Abc_CommandAbc9Test(): There is no AIG.\n" ); + printf( "Abc_CommandAbc9Force(): There is no AIG.\n" ); return 1; } - For_ManExperiment( pAbc->pAig ); + For_ManExperiment( pAbc->pAig, nIters, fClustered, fVerbose ); return 0; usage: - fprintf( stdout, "usage: &force [-h]\n" ); - fprintf( stdout, "\t one-dimensional placement algorithm FORCE introduced by\n" ); - fprintf( stdout, "\t F. A. Aloul, I. L. Markov, and K. A. Sakallah (GLSVLSI’03).\n" ); - fprintf( stdout, "\t-h : print the command usage\n"); + fprintf( stdout, "usage: &force [-I <num>] [-cvh]\n" ); + fprintf( stdout, "\t one-dimensional placement algorithm FORCE introduced by\n" ); + fprintf( stdout, "\t F. A. Aloul, I. L. Markov, and K. A. Sakallah (GLSVLSI’03).\n" ); + fprintf( stdout, "\t-I num : the number of refinement iterations [default = %d]\n", nIters ); + fprintf( stdout, "\t-c : toggle clustered representation [default = %s]\n", fClustered? "yes":"no"); + fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes":"no"); + fprintf( stdout, "\t-h : print the command usage\n"); return 1; } @@ -23023,13 +23304,19 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Embed( Abc_Frame_t * pAbc, int argc, char ** argv ) { - int nDims = 30; - int fCluster = 0; - int fDump = 0; - int fVerbose = 0; + Emb_Par_t Pars, * pPars = &Pars; int c; + pPars->nDims = 30; + pPars->nIters = 10; + pPars->nSols = 2; + pPars->fRefine = 0; + pPars->fCluster = 0; + pPars->fDump = 0; + pPars->fDumpLarge = 0; + pPars->fShowImage = 0; + pPars->fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Ddcvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "DIrcdlsvh" ) ) != EOF ) { switch ( c ) { @@ -23039,19 +23326,39 @@ int Abc_CommandAbc9Embed( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( stdout, "Command line switch \"-D\" should be followed by an integer.\n" ); goto usage; } - nDims = atoi(argv[globalUtilOptind]); + pPars->nDims = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nDims < 0 ) + if ( pPars->nDims < 0 ) goto usage; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIters = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIters < 0 ) + goto usage; + break; + case 'r': + pPars->fRefine ^= 1; + break; case 'c': - fCluster ^= 1; + pPars->fCluster ^= 1; break; case 'd': - fDump ^= 1; + pPars->fDump ^= 1; + break; + case 'l': + pPars->fDumpLarge ^= 1; + break; + case 's': + pPars->fShowImage ^= 1; break; case 'v': - fVerbose ^= 1; + pPars->fVerbose ^= 1; break; case 'h': goto usage; @@ -23061,24 +23368,247 @@ int Abc_CommandAbc9Embed( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pAig == NULL ) { - printf( "Abc_CommandAbc9Test(): There is no AIG.\n" ); + printf( "Abc_CommandAbc9Embed(): There is no AIG.\n" ); return 1; } - Gia_ManSolveProblem( pAbc->pAig, nDims, 2, fCluster, fDump, fVerbose ); + Gia_ManSolveProblem( pAbc->pAig, pPars ); return 0; usage: - fprintf( stdout, "usage: &embed [-D num] [-dcvh]\n" ); + fprintf( stdout, "usage: &embed [-DI <num>] [-rdlscvh]\n" ); fprintf( stdout, "\t fast placement based on high-dimensional embedding from\n" ); fprintf( stdout, "\t D. Harel and Y. Koren, \"Graph drawing by high-dimensional\n" ); fprintf( stdout, "\t embedding\", J. Graph Algs & Apps, 2004, Vol 8(2), pp. 195-217\n" ); - fprintf( stdout, "\t-D num : the number of dimensions for embedding [default = %d]\n", nDims ); - fprintf( stdout, "\t-d : toggle dumping placement into a Gnuplot file [default = %s]\n", fDump? "yes":"no"); - fprintf( stdout, "\t-c : toggle clustered representation [default = %s]\n", fCluster? "yes":"no"); - fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes":"no"); + fprintf( stdout, "\t-D num : the number of dimensions for embedding [default = %d]\n", pPars->nDims ); + fprintf( stdout, "\t-I num : the number of refinement iterations [default = %d]\n", pPars->nIters ); + fprintf( stdout, "\t-r : toggle the use of refinement [default = %s]\n", pPars->fRefine? "yes":"no"); + fprintf( stdout, "\t-c : toggle clustered representation [default = %s]\n", pPars->fCluster? "yes":"no"); + fprintf( stdout, "\t-d : toggle dumping placement into a Gnuplot file [default = %s]\n", pPars->fDump? "yes":"no"); + fprintf( stdout, "\t-l : toggle dumping Gnuplot for large placement [default = %s]\n", pPars->fDumpLarge? "yes":"no"); + fprintf( stdout, "\t-s : toggle showing image if Gnuplot is installed [default = %s]\n", pPars->fShowImage? "yes":"no"); + fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); fprintf( stdout, "\t-h : print the command usage\n"); return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + char Buffer[200]; + char LutSize[200]; + If_Par_t Pars, * pPars = &Pars; + int c; + extern void Gia_ManSetIfParsDefault( If_Par_t * pPars ); + extern int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars ); + if ( pAbc->pAbc8Lib == NULL ) + { + printf( "LUT library is not given. Using default 6-LUT library.\n" ); + pAbc->pAbc8Lib = If_SetSimpleLutLib( 6 ); + } + // set defaults + Gia_ManSetIfParsDefault( pPars ); + pPars->pLutLib = pAbc->pAbc8Lib; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFADEqaflepmrstbvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-K\" should be followed by a positive integer.\n" ); + goto usage; + } + pPars->nLutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLutSize < 0 ) + goto usage; + // if the LUT size is specified, disable library + pPars->pLutLib = NULL; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-C\" should be followed by a positive integer.\n" ); + goto usage; + } + pPars->nCutsMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutsMax < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-F\" should be followed by a positive integer.\n" ); + goto usage; + } + pPars->nFlowIters = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFlowIters < 0 ) + goto usage; + break; + case 'A': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-A\" should be followed by a positive integer.\n" ); + goto usage; + } + pPars->nAreaIters = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nAreaIters < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-D\" should be followed by a floating point number.\n" ); + goto usage; + } + pPars->DelayTarget = (float)atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->DelayTarget <= 0.0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-E\" should be followed by a floating point number.\n" ); + goto usage; + } + pPars->Epsilon = (float)atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->Epsilon < 0.0 || pPars->Epsilon > 1.0 ) + goto usage; + break; + case 'q': + pPars->fPreprocess ^= 1; + break; + case 'a': + pPars->fArea ^= 1; + break; + case 'r': + pPars->fExpRed ^= 1; + break; + case 'f': + pPars->fFancy ^= 1; + break; + case 'l': + pPars->fLatchPaths ^= 1; + break; + case 'e': + pPars->fEdge ^= 1; + break; + case 'p': + pPars->fPower ^= 1; + break; + case 'm': + pPars->fCutMin ^= 1; + break; + case 's': + pPars->fSeqMap ^= 1; + break; + case 't': + pPars->fLiftLeaves ^= 1; + break; + case 'b': + pPars->fBidec ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9If(): There is no AIG to map.\n" ); + return 1; + } + + if ( pPars->nLutSize < 3 || pPars->nLutSize > IF_MAX_LUTSIZE ) + { + fprintf( stdout, "Incorrect LUT size (%d).\n", pPars->nLutSize ); + return 1; + } + + if ( pPars->nCutsMax < 1 || pPars->nCutsMax >= (1<<12) ) + { + fprintf( stdout, "Incorrect number of cuts.\n" ); + return 1; + } +/* + // enable truth table computation if choices are selected + if ( (c = Aig_ManChoiceNum( pAbc->pAbc8Aig )) ) + { + printf( "Performing LUT mapping with %d choices.\n", c ); + pPars->fExpRed = 0; + } +*/ + // enable truth table computation if cut minimization is selected + if ( pPars->fCutMin ) + { + pPars->fTruth = 1; + pPars->fExpRed = 0; + } + + // complain if truth tables are requested but the cut size is too large + if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE ) + { + fprintf( stdout, "Truth tables cannot be computed for LUT larger than %d inputs.\n", IF_MAX_FUNC_LUTSIZE ); + return 1; + } + + if ( !Gia_MappingIf( pAbc->pAig, pPars ) ) + { + printf( "Abc_CommandAbc9If(): Mapping of the AIG has failed.\n" ); + return 1; + } + return 0; + +usage: + if ( pPars->DelayTarget == -1 ) + sprintf( Buffer, "best possible" ); + else + sprintf( Buffer, "%.2f", pPars->DelayTarget ); + if ( pPars->nLutSize == -1 ) + sprintf( LutSize, "library" ); + else + sprintf( LutSize, "%d", pPars->nLutSize ); + fprintf( stdout, "usage: &if [-KCFA num] [-DE float] [-qarlepmbvh]\n" ); + fprintf( stdout, "\t performs FPGA technology mapping of the network\n" ); + fprintf( stdout, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize ); + fprintf( stdout, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax ); + fprintf( stdout, "\t-F num : the number of area flow recovery iterations (num >= 0) [default = %d]\n", pPars->nFlowIters ); + fprintf( stdout, "\t-A num : the number of exact area recovery iterations (num >= 0) [default = %d]\n", pPars->nAreaIters ); + fprintf( stdout, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer ); + fprintf( stdout, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->Epsilon ); + fprintf( stdout, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" ); + fprintf( stdout, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" ); +// fprintf( stdout, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" ); + fprintf( stdout, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "yes": "no" ); + fprintf( stdout, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" ); + fprintf( stdout, "\t-e : uses edge-based cut selection heuristics [default = %s]\n", pPars->fEdge? "yes": "no" ); + fprintf( stdout, "\t-p : uses power-aware cut selection heuristics [default = %s]\n", pPars->fPower? "yes": "no" ); + fprintf( stdout, "\t-m : enables cut minimization by removing vacuous variables [default = %s]\n", pPars->fCutMin? "yes": "no" ); +// fprintf( stdout, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeqMap? "yes": "no" ); +// fprintf( stdout, "\t-t : toggles the use of true sequential cuts [default = %s]\n", pPars->fLiftLeaves? "yes": "no" ); + fprintf( stdout, "\t-b : toggles deriving local AIGs using bi-decomposition [default = %s]\n", pPars->fBidec? "yes": "no" ); + fprintf( stdout, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : prints the command usage\n"); + return 1; +} /**Function************************************************************* @@ -23093,14 +23623,18 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) { - int c; + Gia_Man_t * pTemp = NULL; + int c, fVerbose = 0; extern void Gia_SatSolveTest( Gia_Man_t * p ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) { switch ( c ) { + case 'v': + fVerbose ^= 1; + break; case 'h': goto usage; default: @@ -23116,19 +23650,18 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Gia_ManReduceConst( pAbc->pAig, 1 ); // Sat_ManTest( pAbc->pAig, Gia_ManCo(pAbc->pAig, 0), 0 ); // Gia_ManTestDistance( pAbc->pAig ); -// For_ManExperiment( pAbc->pAig ); - Gia_ManSolveProblem( pAbc->pAig, 30, 2, 1, 0, 1 ); // Gia_SatSolveTest( pAbc->pAig ); +// For_ManExperiment( pAbc->pAig, 20, 1, 1 ); return 0; usage: - fprintf( stdout, "usage: &test [-h]\n" ); + fprintf( stdout, "usage: &test [-vh]\n" ); fprintf( stdout, "\t testing various procedures\n" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; } - /**Function************************************************************* Synopsis [] diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index dbd461c4..ca33667f 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -702,35 +702,6 @@ Abc_Ntk_t * Abc_NtkDarFraig( Abc_Ntk_t * pNtk, int nConfLimit, int fDoSparse, in SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkDarSatSweep( Abc_Ntk_t * pNtk, Cec_ParCsw_t * pPars ) -{ -/* - extern Aig_Man_t * Cec_ManSatSweep( Aig_Man_t * pAig, Cec_ParCsw_t * pPars ); - Abc_Ntk_t * pNtkAig; - Aig_Man_t * pMan, * pTemp; - pMan = Abc_NtkToDar( pNtk, 0, 0 ); - if ( pMan == NULL ) - return NULL; - pMan = Cec_ManSatSweep( pTemp = pMan, pPars ); - Aig_ManStop( pTemp ); - pNtkAig = Abc_NtkFromDar( pNtk, pMan ); - Aig_ManStop( pMan ); - return pNtkAig; - */ - return NULL; -} - -/**Function************************************************************* - - Synopsis [Gives the current ABC network to AIG manager for processing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ Abc_Ntk_t * Abc_NtkDarFraigPart( Abc_Ntk_t * pNtk, int nPartSize, int nConfLimit, int nLevelMax, int fVerbose ) { Abc_Ntk_t * pNtkAig; @@ -1184,7 +1155,17 @@ int Abc_NtkDarCec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int fPa Aig_Man_t * pMan, * pMan1, * pMan2; Abc_Ntk_t * pMiter; int RetValue, clkTotal = clock(); - +/* + { + extern void Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose ); + Aig_Man_t * pAig0 = Abc_NtkToDar( pNtk1, 0, 0 ); + Aig_Man_t * pAig1 = Abc_NtkToDar( pNtk2, 0, 0 ); + Cec_ManVerifyTwoAigs( pAig0, pAig1, 1 ); + Aig_ManStop( pAig0 ); + Aig_ManStop( pAig1 ); + return 1; + } +*/ // cannot partition if it is already a miter if ( pNtk2 == NULL && fPartition == 1 ) { @@ -1285,82 +1266,6 @@ ABC_PRT( "Time", clock() - clkTotal ); SeeAlso [] ***********************************************************************/ -int Abc_NtkDarCec2( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Cec_ParCec_t * pPars ) -{ - Aig_Man_t * pMan1, * pMan2 = NULL; - int RetValue, clkTotal = clock(); - if ( pNtk2 ) - { - if ( Abc_NtkPiNum(pNtk1) != Abc_NtkPiNum(pNtk2) ) - { - printf( "Networks have different number of PIs.\n" ); - return -1; - } - if ( Abc_NtkPoNum(pNtk1) != Abc_NtkPoNum(pNtk2) ) - { - printf( "Networks have different number of POs.\n" ); - return -1; - } - } - if ( pNtk1 ) - { - pMan1 = Abc_NtkToDar( pNtk1, 0, 0 ); - if ( pMan1 == NULL ) - { - printf( "Converting into AIG has failed.\n" ); - return -1; - } - } - if ( pNtk2 ) - { - pMan2 = Abc_NtkToDar( pNtk2, 0, 0 ); - if ( pMan2 == NULL ) - { - Aig_ManStop( pMan1 ); - printf( "Converting into AIG has failed.\n" ); - return -1; - } - } - // perform verification -// RetValue = Cec_Solve( pMan1, pMan2, pPars ); - RetValue = -1; - // transfer model if given - pNtk1->pModel = pMan1->pData, pMan1->pData = NULL; - Aig_ManStop( pMan1 ); - if ( pMan2 ) - Aig_ManStop( pMan2 ); - - // report the miter - if ( RetValue == 1 ) - { - printf( "Networks are equivalent. " ); -ABC_PRT( "Time", clock() - clkTotal ); - } - else if ( RetValue == 0 ) - { - printf( "Networks are NOT EQUIVALENT. " ); -ABC_PRT( "Time", clock() - clkTotal ); - } - else - { - printf( "Networks are UNDECIDED. " ); -ABC_PRT( "Time", clock() - clkTotal ); - } - fflush( stdout ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Gives the current ABC network to AIG manager for processing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, Fra_Ssw_t * pPars ) { Fraig_Params_t Params; @@ -1797,8 +1702,8 @@ int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk ) Aig_ManStop( pPart1 ); Aig_ManStop( pMan ); return 1; -} - +} + /**Function************************************************************* Synopsis [Gives the current ABC network to AIG manager for processing.] @@ -1826,6 +1731,7 @@ int Abc_NtkDarProve( Abc_Ntk_t * pNtk, Fra_Sec_t * pSecPar ) Abc_NtkMakeComb( pNtkComb, 1 ); // solve it using combinational equivalence checking Prove_ParamsSetDefault( pParams ); + pParams->fVerbose = 1; RetValue = Abc_NtkIvyProve( &pNtkComb, pParams ); // transfer model if given // pNtk->pModel = pNtkComb->pModel; pNtkComb->pModel = NULL; diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 7f3d2071..796a51a4 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -161,7 +161,8 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * int i, nNodesDsd; // save the CI nodes in the DSD nodes - Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)(ABC_PTRINT_T)Abc_NtkCreateNodeConst1(pNtkNew) ); + Abc_AigConst1(pNtk)->pCopy = pNodeNew = Abc_NtkCreateNodeConst1(pNtkNew); + Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)(ABC_PTRINT_T)pNodeNew ); Abc_NtkForEachCi( pNtk, pNode, i ) { pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c new file mode 100644 index 00000000..6906e2c4 --- /dev/null +++ b/src/base/abci/abcLutmin.c @@ -0,0 +1,209 @@ +/**CFile**************************************************************** + + FileName [abcLutmin.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Minimization of the number of LUTs.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcLutmin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Converts the node to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreateNodeLut( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc, Abc_Obj_t * pNode, int nLutSize ) +{ + DdNode * bFuncNew; + Abc_Obj_t * pNodeNew; + int i, nStart = ABC_MIN( 0, Abc_ObjFaninNum(pNode) - nLutSize ); + // create a new node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + // add the fanins in the order, in which they appear in the reordered manager + for ( i = nStart; i < Abc_ObjFaninNum(pNode); i++ ) + Abc_ObjAddFanin( pNodeNew, Abc_ObjFanin(pNode, i)->pCopy ); + // transfer the function + bFuncNew = Extra_bddMove( dd, bFunc, nStart ); Cudd_Ref( bFuncNew ); + assert( Cudd_SupportSize(dd, bFuncNew) <= nLutSize ); + pNodeNew->pData = Extra_TransferLevelByLevel( dd, pNtkNew->pManFunc, bFuncNew ); Cudd_Ref( pNodeNew->pData ); + Cudd_RecursiveDeref( dd, bFuncNew ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Converts the node to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeBddToMuxesLut_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node, Abc_Obj_t * pNode, int nLutSize ) +{ + Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC; + assert( !Cudd_IsComplement(bFunc) ); + if ( bFunc == b1 ) + return Abc_NtkCreateNodeConst1(pNtkNew); + if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) ) + return pNodeNew; + if ( dd->perm[bFunc->index] >= Abc_ObjFaninNum(pNode) - nLutSize ) + { + pNodeNew = Abc_NtkCreateNodeLut( pNtkNew, dd, bFunc, pNode, nLutSize ); + st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew ); + return pNodeNew; + } + // solve for the children nodes + pNodeNew0 = Abc_NodeBddToMuxesLut_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node, pNode, nLutSize ); + if ( Cudd_IsComplement(cuddE(bFunc)) ) + pNodeNew0 = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew0 ); + pNodeNew1 = Abc_NodeBddToMuxesLut_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node, pNode, nLutSize ); + if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) ) + assert( 0 ); + // create the MUX node + pNodeNew = Abc_NtkCreateNodeMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 ); + st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Converts the node to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeBddToMuxesLut( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, int nLutSize ) +{ + DdManager * dd = pNodeOld->pNtk->pManFunc; + DdNode * bFunc = pNodeOld->pData; + Abc_Obj_t * pFaninOld, * pNodeNew; + st_table * tBdd2Node; + int i; + // create the table mapping BDD nodes into the ABC nodes + tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash ); + // add the constant and the elementary vars + Abc_ObjForEachFanin( pNodeOld, pFaninOld, i ) + st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy ); + // create the new nodes recursively + pNodeNew = Abc_NodeBddToMuxesLut_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node, pNodeOld, nLutSize ); + st_free_table( tBdd2Node ); + if ( Cudd_IsComplement(bFunc) ) + pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkLutminConstruct( Abc_Ntk_t * pNtkClp, Abc_Ntk_t * pNtkDec, int nLutSize ) +{ + Abc_Obj_t * pObj, * pDriver; + int i; + Abc_NtkForEachCo( pNtkClp, pObj, i ) + { + pDriver = Abc_ObjFanin0( pObj ); + if ( !Abc_ObjIsNode(pDriver) ) + continue; + if ( Abc_ObjFaninNum(pDriver) == 0 ) + pDriver->pCopy = Abc_NtkDupObj( pNtkDec, pDriver, 0 ); + else + pDriver->pCopy = Abc_NodeBddToMuxesLut( pNtkDec, pDriver, nLutSize ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose ) +{ + extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose ); + Abc_Ntk_t * pNtkDec, * pNtkClp, * pTemp; + // collapse the network and reorder BDDs + if ( Abc_NtkIsStrash(pNtk) ) + pTemp = Abc_NtkDup( pNtk ); + else + pTemp = Abc_NtkStrash( pNtk, 0, 1, 0 ); + pNtkClp = Abc_NtkCollapse( pTemp, 10000, 0, 1, 0 ); + Abc_NtkDelete( pTemp ); + if ( pNtkClp == NULL ) + return NULL; + if ( !Abc_NtkIsBddLogic(pNtkClp) ) + Abc_NtkToBdd( pNtkClp ); + Abc_NtkBddReorder( pNtkClp, fVerbose ); + // decompose one output at a time + pNtkDec = Abc_NtkStartFrom( pNtkClp, ABC_NTK_LOGIC, ABC_FUNC_BDD ); + // make sure the new manager has enough inputs + Cudd_bddIthVar( pNtkDec->pManFunc, nLutSize ); + // put the results into the new network (save new CO drivers in old CO drivers) + Abc_NtkLutminConstruct( pNtkClp, pNtkDec, nLutSize ); + // finalize the new network + Abc_NtkFinalize( pNtkClp, pNtkDec ); + Abc_NtkDelete( pNtkClp ); + // make the network minimum base + Abc_NtkMinimumBase( pNtkDec ); + // fix the problem with complemented and duplicated CO edges + Abc_NtkLogicMakeSimpleCos( pNtkDec, 0 ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkDec ) ) + { + printf( "Abc_NtkLutmin: The network check has failed.\n" ); + return 0; + } + return pNtkDec; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/module.make b/src/base/abci/module.make index e520dcce..9214bb52 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -24,6 +24,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcIf.c \ src/base/abci/abcIvy.c \ src/base/abci/abcLut.c \ + src/base/abci/abcLutmin.c \ src/base/abci/abcMap.c \ src/base/abci/abcMerge.c \ src/base/abci/abcMini.c \ diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index 21853e9a..398415ae 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1737,6 +1737,73 @@ usage: } +/**Function************************************************************* + + Synopsis [Computes dimentions of the graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManGnuplotShow( char * pPlotFileName ) +{ + FILE * pFile; + void * pAbc; + char * pProgNameGnuplotWin = "wgnuplot.exe"; + char * pProgNameGnuplotUnix = "gnuplot"; + char * pProgNameGnuplot; + + // read in the Capo plotting output + if ( (pFile = fopen( pPlotFileName, "r" )) == NULL ) + { + fprintf( stdout, "Cannot open the plot file \"%s\".\n\n", pPlotFileName ); + return; + } + fclose( pFile ); + + pAbc = Abc_FrameGetGlobalFrame(); + + // get the names from the plotting software + if ( Cmd_FlagReadByName(pAbc, "gnuplotwin") ) + pProgNameGnuplotWin = Cmd_FlagReadByName(pAbc, "gnuplotwin"); + if ( Cmd_FlagReadByName(pAbc, "gnuplotunix") ) + pProgNameGnuplotUnix = Cmd_FlagReadByName(pAbc, "gnuplotunix"); + + // check if Gnuplot is available + if ( (pFile = fopen( pProgNameGnuplotWin, "r" )) ) + pProgNameGnuplot = pProgNameGnuplotWin; + else if ( (pFile = fopen( pProgNameGnuplotUnix, "r" )) ) + pProgNameGnuplot = pProgNameGnuplotUnix; + else if ( pFile == NULL ) + { + fprintf( stdout, "Cannot find \"%s\" or \"%s\" in the current directory.\n", pProgNameGnuplotWin, pProgNameGnuplotUnix ); + return; + } + fclose( pFile ); + + // spawn the viewer +#ifdef WIN32 + if ( _spawnl( _P_NOWAIT, pProgNameGnuplot, pProgNameGnuplot, pPlotFileName, NULL ) == -1 ) + { + fprintf( stdout, "Cannot find \"%s\".\n", pProgNameGnuplot ); + return; + } +#else + { + char Command[1000]; + sprintf( Command, "%s %s ", pProgNameGnuplot, pPlotFileName ); + if ( system( Command ) == -1 ) + { + fprintf( stdout, "Cannot execute \"%s\".\n", Command ); + return; + } + } +#endif +} + /**Function******************************************************************** Synopsis [Calls Capo internally.] diff --git a/src/base/io/io.c b/src/base/io/io.c index ee5df414..e8af161e 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -28,6 +28,7 @@ static int IoCommandRead ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadAiger ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadBaf ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandReadBblif ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadBlif ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadBlifMv ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadBench ( Abc_Frame_t * pAbc, int argc, char **argv ); @@ -45,6 +46,7 @@ static int IoCommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteHie ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteAiger ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteBaf ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandWriteBblif ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteBlif ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteBlifMv ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteBench ( Abc_Frame_t * pAbc, int argc, char **argv ); @@ -83,6 +85,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "read", IoCommandRead, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_aiger", IoCommandReadAiger, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_baf", IoCommandReadBaf, 1 ); + Cmd_CommandAdd( pAbc, "I/O", "read_bblif", IoCommandReadBblif, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_blif", IoCommandReadBlif, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_blif_mv", IoCommandReadBlifMv, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_bench", IoCommandReadBench, 1 ); @@ -100,6 +103,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "write_hie", IoCommandWriteHie, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_aiger", IoCommandWriteAiger, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_baf", IoCommandWriteBaf, 0 ); + Cmd_CommandAdd( pAbc, "I/O", "write_bblif", IoCommandWriteBblif, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_blif", IoCommandWriteBlif, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_blif_mv", IoCommandWriteBlifMv, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_bench", IoCommandWriteBench, 0 ); @@ -316,6 +320,60 @@ usage: SeeAlso [] ***********************************************************************/ +int IoCommandReadBblif( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Abc_Ntk_t * pNtk; + char * pFileName; + int fCheck; + int c; + + fCheck = 1; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) + { + switch ( c ) + { + case 'c': + fCheck ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + goto usage; + // get the input file name + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader + pNtk = Io_Read( pFileName, IO_FILE_BBLIF, fCheck ); + if ( pNtk == NULL ) + return 1; + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: read_bblif [-ch] <file>\n" ); + fprintf( pAbc->Err, "\t read the network in a binary BLIF format\n" ); + fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" ); + fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); + fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk; @@ -1329,6 +1387,54 @@ usage: SeeAlso [] ***********************************************************************/ +int IoCommandWriteBblif( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + char * pFileName; + int c; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pNtkCur == NULL ) + { + fprintf( pAbc->Out, "Empty network.\n" ); + return 0; + } + if ( argc != globalUtilOptind + 1 ) + goto usage; + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BBLIF ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: write_bblif [-h] <file>\n" ); + fprintf( pAbc->Err, "\t write the network into a binary BLIF file\n" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .bblif)\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv ) { char * pFileName; diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index c11168df..bade17df 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -44,6 +44,7 @@ typedef enum { IO_FILE_NONE = 0, IO_FILE_AIGER, IO_FILE_BAF, + IO_FILE_BBLIF, IO_FILE_BLIF, IO_FILE_BLIFMV, IO_FILE_BENCH, @@ -73,6 +74,8 @@ typedef enum { extern Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ); /*=== abcReadBaf.c ============================================================*/ extern Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck ); +/*=== abcReadBblif.c ============================================================*/ +extern Abc_Ntk_t * Io_ReadBblif( char * pFileName, int fCheck ); /*=== abcReadBlif.c ===========================================================*/ extern Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck ); /*=== abcReadBlifMv.c =========================================================*/ @@ -91,6 +94,8 @@ extern Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck ); extern void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int fCompact ); /*=== abcWriteBaf.c ===========================================================*/ extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName ); +/*=== abcWriteBblif.c ===========================================================*/ +extern void Io_WriteBblif( Abc_Ntk_t * pNtk, char * pFileName ); /*=== abcWriteBlif.c ==========================================================*/ extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches ); extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches ); diff --git a/src/base/io/ioReadAiger.c b/src/base/io/ioReadAiger.c index 2c37e210..c26e4cd5 100644 --- a/src/base/io/ioReadAiger.c +++ b/src/base/io/ioReadAiger.c @@ -463,19 +463,19 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ) } // read the name of the model if given - if ( *pCur == 'c' && pCur < pContents + nFileSize ) + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) { - if ( !strncmp( pCur + 2, ".model", 6 ) ) + pCur++; + if ( *pCur == 'n' ) { - char * pTemp; - for ( pTemp = pCur + 9; *pTemp && *pTemp != '\n'; pTemp++ ); - *pTemp = 0; + pCur++; + // read model name ABC_FREE( pNtkNew->pName ); - pNtkNew->pName = Extra_UtilStrsav( pCur + 9 ); + pNtkNew->pName = Extra_UtilStrsav( pCur ); } } - // skipping the comments ABC_FREE( pContents ); Vec_PtrFree( vNodes ); diff --git a/src/base/io/ioReadBblif.c b/src/base/io/ioReadBblif.c new file mode 100644 index 00000000..84ef1e29 --- /dev/null +++ b/src/base/io/ioReadBblif.c @@ -0,0 +1,342 @@ +/**CFile**************************************************************** + + FileName [ioReadBblif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Procedures to read AIG in the binary format.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ioReadBblif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ioAbc.h" +#include "dec.h" +#include "bblif.h" + +// For description of Binary BLIF format, refer to "abc/src/aig/bbl/bblif.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Fnction************************************************************* + + Synopsis [Constructs ABC network from the manager.] + + Description [The ABC network is started, as well as the array vCopy, + which will map the new ID of each object in the BBLIF manager into + the ponter ot the corresponding object in the ABC. For each internal + node, determined by Bbl_ObjIsLut(), the SOP representation is created + by retrieving the SOP representation of the BBLIF object. Finally, + the objects are connected using fanin/fanout creation, and the dummy + names are assigned because ABC requires each CI/CO to have a name.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Bbl_ManToAbc( Bbl_Man_t * p ) +{ + Abc_Ntk_t * pNtk; + Abc_Obj_t * pObjNew; + Bbl_Obj_t * pObj, * pFanin; + Vec_Ptr_t * vCopy; + // start the network + pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); + pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) ); + // create objects + vCopy = Vec_PtrStart( 1000 ); + Bbl_ManForEachObj( p, pObj ) + { + if ( Bbl_ObjIsInput(pObj) ) + pObjNew = Abc_NtkCreatePi( pNtk ); + else if ( Bbl_ObjIsOutput(pObj) ) + pObjNew = Abc_NtkCreatePo( pNtk ); + else if ( Bbl_ObjIsLut(pObj) ) + pObjNew = Abc_NtkCreateNode( pNtk ); + else assert( 0 ); + if ( Bbl_ObjIsLut(pObj) ) + pObjNew->pData = Abc_SopRegister( pNtk->pManFunc, Bbl_ObjSop(p, pObj) ); + Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew ); + } + // connect objects + Bbl_ManForEachObj( p, pObj ) + Bbl_ObjForEachFanin( pObj, pFanin ) + Abc_ObjAddFanin( Vec_PtrEntry(vCopy, Bbl_ObjId(pObj)), Vec_PtrEntry(vCopy, Bbl_ObjId(pFanin)) ); + // finalize + Vec_PtrFree( vCopy ); + Abc_NtkAddDummyPiNames( pNtk ); + Abc_NtkAddDummyPoNames( pNtk ); + if ( !Abc_NtkCheck( pNtk ) ) + printf( "Bbl_ManToAbc(): Network check has failed.\n" ); + return pNtk; +} + +/**Fnction************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManDfs_rec( Bbl_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + extern void Bbl_ObjMark( Bbl_Obj_t * p ); + extern int Bbl_ObjIsMarked( Bbl_Obj_t * p ); + Bbl_Obj_t * pFanin; + if ( Bbl_ObjIsMarked(pObj) || Bbl_ObjIsInput(pObj) ) + return; + Bbl_ObjForEachFanin( pObj, pFanin ) + Bbl_ManDfs_rec( pFanin, vNodes ); + assert( !Bbl_ObjIsMarked(pObj) ); // checks if acyclic + Bbl_ObjMark( pObj ); + Vec_PtrPush( vNodes, pObj ); +} + +/**Fnction************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Bbl_ManDfs( Bbl_Man_t * p ) +{ + Vec_Ptr_t * vNodes; + Bbl_Obj_t * pObj; + vNodes = Vec_PtrAlloc( 1000 ); + Bbl_ManForEachObj( p, pObj ) + if ( Bbl_ObjIsLut(pObj) ) + Bbl_ManDfs_rec( pObj, vNodes ); + return vNodes; +} + +/**Fnction************************************************************* + + Synopsis [Constructs AIG in ABC from the manager.] + + Description [The ABC network is started, as well as the array vCopy, + which will map the new ID of each object in the BBLIF manager into + the ponter ot the corresponding AIG object in the ABC. For each internal + node in a topological oder the AIG representation is created + by factoring the SOP representation of the BBLIF object. Finally, + the CO objects are created, and the dummy names are assigned because + ABC requires each CI/CO to have a name.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Bbl_ManToAig( Bbl_Man_t * p ) +{ + extern int Bbl_ManFncSize( Bbl_Man_t * p ); + extern int Bbl_ObjFncHandle( Bbl_Obj_t * p ); + extern Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs ); + int fVerbose = 0; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pObjNew; + Bbl_Obj_t * pObj, * pFanin; + Vec_Ptr_t * vCopy, * vNodes, * vFaninAigs; + Dec_Graph_t ** pFForms; + int i, clk; +clk = clock(); + // map SOP handles into factored forms + pFForms = ABC_CALLOC( Dec_Graph_t *, Bbl_ManFncSize(p) ); + Bbl_ManForEachObj( p, pObj ) + if ( pFForms[Bbl_ObjFncHandle(pObj)] == NULL ) + pFForms[Bbl_ObjFncHandle(pObj)] = Dec_Factor( Bbl_ObjSop(p, pObj) ); +if ( fVerbose ) +ABC_PRT( "Fct", clock() - clk ); + // start the network + pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); + pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) ); + vCopy = Vec_PtrStart( 1000 ); + // create CIs + Bbl_ManForEachObj( p, pObj ) + { + if ( !Bbl_ObjIsInput(pObj) ) + continue; + Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), Abc_NtkCreatePi(pNtk) ); + } +clk = clock(); + // create internal nodes + vNodes = Bbl_ManDfs( p ); + vFaninAigs = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + // collect fanin AIGs + Vec_PtrClear( vFaninAigs ); + Bbl_ObjForEachFanin( pObj, pFanin ) + Vec_PtrPush( vFaninAigs, Vec_PtrEntry( vCopy, Bbl_ObjId(pFanin) ) ); + // create the new node + pObjNew = Dec_GraphToAig( pNtk, pFForms[Bbl_ObjFncHandle(pObj)], vFaninAigs ); + Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew ); + } + Vec_PtrFree( vFaninAigs ); + Vec_PtrFree( vNodes ); +if ( fVerbose ) +ABC_PRT( "AIG", clock() - clk ); + // create COs + Bbl_ManForEachObj( p, pObj ) + { + if ( !Bbl_ObjIsOutput(pObj) ) + continue; + pObjNew = Vec_PtrEntry( vCopy, Bbl_ObjId(Bbl_ObjFaninFirst(pObj)) ); + Abc_ObjAddFanin( Abc_NtkCreatePo(pNtk), pObjNew ); + } + Abc_AigCleanup( pNtk->pManFunc ); + // clear factored forms + for ( i = Bbl_ManFncSize(p) - 1; i >= 0; i-- ) + if ( pFForms[i] ) + Dec_GraphFree( pFForms[i] ); + ABC_FREE( pFForms ); + // finalize +clk = clock(); + Vec_PtrFree( vCopy ); + Abc_NtkAddDummyPiNames( pNtk ); + Abc_NtkAddDummyPoNames( pNtk ); +if ( fVerbose ) +ABC_PRT( "Nam", clock() - clk ); +// if ( !Abc_NtkCheck( pNtk ) ) +// printf( "Bbl_ManToAig(): Network check has failed.\n" ); + return pNtk; +} + +/**Fnction************************************************************* + + Synopsis [Verifies equivalence for two combinational networks.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManVerify( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) +{ + extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ); + Abc_Ntk_t * pAig1, * pAig2; + pAig1 = Abc_NtkStrash( pNtk1, 0, 1, 0 ); + pAig2 = Abc_NtkStrash( pNtk2, 0, 1, 0 ); + Abc_NtkShortNames( pAig1 ); + Abc_NtkShortNames( pAig2 ); + Abc_NtkCecFraig( pAig1, pAig2, 0, 0 ); + Abc_NtkDelete( pAig1 ); + Abc_NtkDelete( pAig2 ); +} + +/**Fnction************************************************************* + + Synopsis [Performs testing of the new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbl_ManTest( Abc_Ntk_t * pNtk ) +{ + extern Bbl_Man_t * Bbl_ManFromAbc( Abc_Ntk_t * pNtk ); + + Abc_Ntk_t * pNtkNew; + Bbl_Man_t * p, * pNew; + char * pFileName = "test.bblif"; + int clk, clk1, clk2, clk3, clk4, clk5; +clk = clock(); + p = Bbl_ManFromAbc( pNtk ); + Bbl_ManPrintStats( p ); +clk1 = clock() - clk; +//Bbl_ManDumpBlif( p, "test_bbl.blif" ); + + // write into file and back +clk = clock(); + Bbl_ManDumpBinaryBlif( p, pFileName ); +clk2 = clock() - clk; + + // read from file +clk = clock(); + pNew = Bbl_ManReadBinaryBlif( pFileName ); + Bbl_ManStop( p ); p = pNew; +clk3 = clock() - clk; + + // generate ABC network +clk = clock(); + pNtkNew = Bbl_ManToAig( p ); +// pNtkNew = Bbl_ManToAbc( p ); + Bbl_ManStop( p ); +clk4 = clock() - clk; + + // equivalence check +clk = clock(); +// Bbl_ManVerify( pNtk, pNtkNew ); + Abc_NtkDelete( pNtkNew ); +clk5 = clock() - clk; + +printf( "Runtime stats:\n" ); +ABC_PRT( "ABC to Man", clk1 ); +ABC_PRT( "Writing ", clk2 ); +ABC_PRT( "Reading ", clk3 ); +ABC_PRT( "Man to ABC", clk4 ); +ABC_PRT( "Verify ", clk5 ); +} + +/**Function************************************************************* + + Synopsis [Reads the AIG in the binary format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Io_ReadBblif( char * pFileName, int fCheck ) +{ + Bbl_Man_t * p; + Abc_Ntk_t * pNtkNew; + // read the file + p = Bbl_ManReadBinaryBlif( pFileName ); + pNtkNew = Bbl_ManToAig( p ); + Bbl_ManStop( p ); + // check the result + if ( fCheck && !Abc_NtkCheckRead( pNtkNew ) ) + { + printf( "Io_ReadBaf: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index c67c183d..c00c3008 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -51,6 +51,8 @@ Io_FileType_t Io_ReadFileType( char * pFileName ) return IO_FILE_AIGER; if ( !strcmp( pExt, "baf" ) ) return IO_FILE_BAF; + if ( !strcmp( pExt, "bblif" ) ) + return IO_FILE_BBLIF; if ( !strcmp( pExt, "blif" ) ) return IO_FILE_BLIF; if ( !strcmp( pExt, "bench" ) ) @@ -108,12 +110,14 @@ Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck } fclose( pFile ); // read the AIG - if ( FileType == IO_FILE_AIGER || FileType == IO_FILE_BAF ) + if ( FileType == IO_FILE_AIGER || FileType == IO_FILE_BAF || FileType == IO_FILE_BBLIF ) { if ( FileType == IO_FILE_AIGER ) pNtk = Io_ReadAiger( pFileName, fCheck ); - else // if ( FileType == IO_FILE_BAF ) + else if ( FileType == IO_FILE_BAF ) pNtk = Io_ReadBaf( pFileName, fCheck ); + else // if ( FileType == IO_FILE_BBLIF ) + pNtk = Io_ReadBblif( pFileName, fCheck ); if ( pNtk == NULL ) { fprintf( stdout, "Reading AIG from file has failed.\n" ); @@ -258,7 +262,7 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType ) } if ( FileType == IO_FILE_AIGER ) Io_WriteAiger( pNtk, pFileName, 1, 0 ); - else // if ( FileType == IO_FILE_BAF ) + else //if ( FileType == IO_FILE_BAF ) Io_WriteBaf( pNtk, pFileName ); return; } @@ -278,6 +282,18 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType ) Io_WriteGml( pNtk, pFileName ); return; } + if ( FileType == IO_FILE_BBLIF ) + { + if ( !Abc_NtkIsLogic(pNtk) ) + { + fprintf( stdout, "Writing Binary BLIF is only possible for logic networks.\n" ); + return; + } + if ( !Abc_NtkHasSop(pNtk) ) + Abc_NtkToSop( pNtk, 0 ); + Io_WriteBblif( pNtk, pFileName ); + return; + } /* if ( FileType == IO_FILE_BLIFMV ) { diff --git a/src/base/io/ioWriteAiger.c b/src/base/io/ioWriteAiger.c index f1793a59..8957743c 100644 --- a/src/base/io/ioWriteAiger.c +++ b/src/base/io/ioWriteAiger.c @@ -726,10 +726,10 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int f } // write the comment - fprintfBz2Aig( &b, "c\n" ); + fprintfBz2Aig( &b, "c" ); if ( pNtk->pName && strlen(pNtk->pName) > 0 ) - fprintfBz2Aig( &b, ".model %s\n", pNtk->pName ); - fprintfBz2Aig( &b, "This file was produced by ABC on %s\n", Extra_TimeStamp() ); + fprintfBz2Aig( &b, "n%s%c", pNtk->pName, '\0' ); + fprintfBz2Aig( &b, "\nThis file was written by ABC on %s\n", Extra_TimeStamp() ); fprintfBz2Aig( &b, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); // close the file diff --git a/src/base/io/ioWriteBblif.c b/src/base/io/ioWriteBblif.c new file mode 100644 index 00000000..e5bd6503 --- /dev/null +++ b/src/base/io/ioWriteBblif.c @@ -0,0 +1,111 @@ +/**CFile**************************************************************** + + FileName [ioWriteBblif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Procedures to write AIG in the binary format.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ioWriteBblif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ioAbc.h" +#include "bblif.h" + +// For description of Binary BLIF format, refer to "abc/src/aig/bbl/bblif.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Fnction************************************************************* + + Synopsis [Construct manager from the ABC network.] + + Description [In the ABC network each object has a unique integer ID. + This ID is used when we construct objects of the BBLIF manager + corresponding to each object of the ABC network. The objects can be + added to the manager in any order (although below they are added in the + topological order), but by the time fanin/fanout connections are created, + corresponding objects are already constructed. In the end the checking + procedure is called.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bbl_Man_t * Bbl_ManFromAbc( Abc_Ntk_t * pNtk ) +{ + Bbl_Man_t * p; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj, * pFanin; + int i, k; + assert( Abc_NtkIsSopLogic(pNtk) ); + // start the data manager + p = Bbl_ManStart( Abc_NtkName(pNtk) ); + // collect internal nodes to be added + vNodes = Abc_NtkDfs( pNtk, 0 ); + // create combinational inputs + Abc_NtkForEachCi( pNtk, pObj, i ) + Bbl_ManCreateObject( p, BBL_OBJ_CI, Abc_ObjId(pObj), 0, NULL ); + // create internal nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + Bbl_ManCreateObject( p, BBL_OBJ_NODE, Abc_ObjId(pObj), Abc_ObjFaninNum(pObj), pObj->pData ); + // create combinational outputs + Abc_NtkForEachCo( pNtk, pObj, i ) + Bbl_ManCreateObject( p, BBL_OBJ_CO, Abc_ObjId(pObj), 1, NULL ); + // create fanin/fanout connections for internal nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Bbl_ManAddFanin( p, Abc_ObjId(pObj), Abc_ObjId(pFanin) ); + // create fanin/fanout connections for combinational outputs + Abc_NtkForEachCo( pNtk, pObj, i ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Bbl_ManAddFanin( p, Abc_ObjId(pObj), Abc_ObjId(pFanin) ); + Vec_PtrFree( vNodes ); + // sanity check + Bbl_ManCheck( p ); + return p; +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteBblif( Abc_Ntk_t * pNtk, char * pFileName ) +{ + Bbl_Man_t * p; + p = Bbl_ManFromAbc( pNtk ); +//Bbl_ManPrintStats( p ); +//Bbl_ManDumpBlif( p, "test_bbl.blif" ); + Bbl_ManDumpBinaryBlif( p, pFileName ); + Bbl_ManStop( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/io/module.make b/src/base/io/module.make index 6f4e2539..993bd7d2 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -1,6 +1,7 @@ SRC += src/base/io/io.c \ src/base/io/ioReadAiger.c \ src/base/io/ioReadBaf.c \ + src/base/io/ioReadBblif.c \ src/base/io/ioReadBench.c \ src/base/io/ioReadBlif.c \ src/base/io/ioReadBlifAig.c \ @@ -13,6 +14,7 @@ SRC += src/base/io/io.c \ src/base/io/ioUtil.c \ src/base/io/ioWriteAiger.c \ src/base/io/ioWriteBaf.c \ + src/base/io/ioWriteBblif.c \ src/base/io/ioWriteBench.c \ src/base/io/ioWriteBlif.c \ src/base/io/ioWriteBlifMv.c \ diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c index f83747cf..aa213010 100644 --- a/src/base/ver/verCore.c +++ b/src/base/ver/verCore.c @@ -623,7 +623,7 @@ void Ver_ParseRemoveSuffixTable( Ver_Man_t * pMan ) ***********************************************************************/ int Ver_ParseSignalPrefix( Ver_Man_t * pMan, char ** ppWord, int * pnMsb, int * pnLsb ) { - char * pWord = *ppWord; + char * pWord = *ppWord, * pTemp; int nMsb, nLsb; assert( pWord[0] == '[' ); // get the beginning @@ -654,6 +654,17 @@ int Ver_ParseSignalPrefix( Ver_Man_t * pMan, char ** ppWord, int * pnMsb, int * } assert( *pWord == ']' ); pWord++; + + // fix the case when \<name> follows after [] without space + if ( *pWord == '\\' ) + { + pWord++; + pTemp = pWord; + while ( *pTemp && *pTemp != ' ' ) + pTemp++; + if ( *pTemp == ' ' ) + *pTemp = 0; + } } assert( nMsb >= 0 && nLsb >= 0 ); // return diff --git a/src/base/ver/verParse.c b/src/base/ver/verParse.c index 9462fc8b..c38399f2 100644 --- a/src/base/ver/verParse.c +++ b/src/base/ver/verParse.c @@ -101,6 +101,15 @@ char * Ver_ParseGetName( Ver_Man_t * pMan ) pMan->fNameLast = 1; Ver_StreamPopChar( p ); pWord = Ver_StreamGetWord( p, " \r\n" ); + Ver_StreamSkipChars( p, " \r\n" ); + if ( Ver_StreamScanChar(p) == '[' ) + { + char This, * pEnd = pWord + strlen( pWord ); + while ( (This = Ver_StreamPopChar(p)) != ']' ) + *pEnd++ = This; + *pEnd++ = This; + *pEnd = 0; + } } else pWord = Ver_StreamGetWord( p, " \t\n\r(),;" ); diff --git a/src/map/amap/amapLiberty.c b/src/map/amap/amapLiberty.c index 7f46ffdf..4177e27e 100644 --- a/src/map/amap/amapLiberty.c +++ b/src/map/amap/amapLiberty.c @@ -346,6 +346,7 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName ) { FILE * pFile; Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput; + char * pForm; int Counter; if ( pFileName == NULL ) pFile = stdout; @@ -408,6 +409,12 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName ) } pOutput = Amap_LibertyCellOutput( p, pCell ); pFunc = Amap_LibertyPinFunction( p, pOutput ); + pForm = Amap_LibertyGetStringFormula( p, pFunc->Head ); + if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") ) + { + printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm ); + continue; + } fprintf( pFile, "GATE " ); fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) ); @@ -542,13 +549,17 @@ static inline int Amap_LibertyCharIsSpace( char c ) SeeAlso [] ***********************************************************************/ -static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd ) +static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd, int fStopAtNewLine ) { char * pPos = *ppPos; for ( ; pPos < pEnd; pPos++ ) { if ( *pPos == '\n' ) + { p->nLines++; + if ( fStopAtNewLine ) + break; + } if ( !Amap_LibertyCharIsSpace(*pPos) ) break; } @@ -582,9 +593,9 @@ static inline int Amap_LibertySkipEntry( char ** ppPos, char * pEnd ) else { for ( ; pPos < pEnd; pPos++ ) - if ( *pPos == ' ' || - *pPos == ':' || *pPos == ';' || - *pPos == '(' || *pPos == ')' || + if ( *pPos == ' ' || *pPos == '\r' || *pPos == '\n' || + *pPos == ':' || *pPos == ';' || + *pPos == '(' || *pPos == ')' || *pPos == '{' || *pPos == '}' ) break; } @@ -708,28 +719,28 @@ int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd ) Amap_Item_t * pItem; Amap_Pair_t Key, Head, Body; char * pNext, * pStop; - if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) ) return -2; Key.Beg = *ppPos - p->pContents; if ( Amap_LibertySkipEntry( ppPos, pEnd ) ) goto exit; Key.End = *ppPos - p->pContents; - if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) ) goto exit; pNext = *ppPos; if ( *pNext == ':' ) { *ppPos = pNext + 1; - if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) ) goto exit; Head.Beg = *ppPos - p->pContents; if ( Amap_LibertySkipEntry( ppPos, pEnd ) ) goto exit; Head.End = *ppPos - p->pContents; - if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 1 ) ) goto exit; pNext = *ppPos; - if ( *pNext != ';' ) + if ( *pNext != ';' && *pNext != '\n' ) goto exit; *ppPos = pNext + 1; // end of equation @@ -747,7 +758,7 @@ int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd ) Head.Beg = pNext - p->pContents + 1; Head.End = pStop - p->pContents; *ppPos = pStop + 1; - if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) ) { // end of list pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_LIST ); @@ -883,7 +894,7 @@ int Amap_LibertyParse( char * pFileName, char * pFileGenlib, int fVerbose ) { if ( fVerbose ) printf( "Parsing finished successfully.\n" ); -// Amap_LibertyPrintLiberty( p, "temp.lib" ); +// Amap_LibertyPrintLiberty( p, "temp_.lib" ); Amap_LibertyPrintGenlib( p, "temp.genlib" ); RetValue = 1; } diff --git a/src/map/amap/amapParse.c b/src/map/amap/amapParse.c index 48dabca2..bfa8e6a5 100644 --- a/src/map/amap/amapParse.c +++ b/src/map/amap/amapParse.c @@ -35,6 +35,7 @@ #define AMAP_EQN_SYM_AND '*' // logic AND #define AMAP_EQN_SYM_XOR '^' // logic XOR #define AMAP_EQN_SYM_OR '+' // logic OR +#define AMAP_EQN_SYM_OR2 '|' // logic OR // the list of opcodes (also specifying operation precedence) #define AMAP_EQN_OPER_NEG 10 // negation @@ -180,6 +181,7 @@ Hop_Obj_t * Amap_ParseFormula( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVa break; case AMAP_EQN_SYM_AND: case AMAP_EQN_SYM_OR: + case AMAP_EQN_SYM_OR2: case AMAP_EQN_SYM_XOR: if ( Flag != AMAP_EQN_FLAG_VAR ) { @@ -189,7 +191,7 @@ Hop_Obj_t * Amap_ParseFormula( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVa } if ( *pTemp == AMAP_EQN_SYM_AND ) Vec_IntPush( pStackOp, AMAP_EQN_OPER_AND ); - else if ( *pTemp == AMAP_EQN_SYM_OR ) + else if ( *pTemp == AMAP_EQN_SYM_OR || *pTemp == AMAP_EQN_SYM_OR2 ) Vec_IntPush( pStackOp, AMAP_EQN_OPER_OR ); else //if ( *pTemp == AMAP_EQN_SYM_XOR ) Vec_IntPush( pStackOp, AMAP_EQN_OPER_XOR ); @@ -246,9 +248,9 @@ Hop_Obj_t * Amap_ParseFormula( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVa // scan the next name for ( i = 0; pTemp[i] && pTemp[i] != ' ' && pTemp[i] != '\t' && pTemp[i] != '\r' && pTemp[i] != '\n' && - pTemp[i] != AMAP_EQN_SYM_AND && pTemp[i] != AMAP_EQN_SYM_OR && - pTemp[i] != AMAP_EQN_SYM_XOR && pTemp[i] != AMAP_EQN_SYM_NEGAFT && - pTemp[i] != AMAP_EQN_SYM_CLOSE; i++ ) + pTemp[i] != AMAP_EQN_SYM_AND && pTemp[i] != AMAP_EQN_SYM_OR && pTemp[i] != AMAP_EQN_SYM_OR2 && + pTemp[i] != AMAP_EQN_SYM_XOR && pTemp[i] != AMAP_EQN_SYM_NEGAFT && pTemp[i] != AMAP_EQN_SYM_CLOSE; + i++ ) { if ( pTemp[i] == AMAP_EQN_SYM_NEG || pTemp[i] == AMAP_EQN_SYM_OPEN ) { diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c index 0f0ca002..e3fd47f1 100644 --- a/src/map/if/ifCore.c +++ b/src/map/if/ifCore.c @@ -55,13 +55,10 @@ int If_ManPerformMapping( If_Man_t * p ) // try sequential mapping if ( p->pPars->fSeqMap ) { - int RetValue = 1; - printf( "Currently sequential mapping is not performed.\n" ); -// RetValue = If_ManPerformMappingSeq( p ); - return RetValue; -// return 1; +// if ( p->pPars->fVerbose ) + printf( "Performing sequential mapping without retiming.\n" ); + return If_ManPerformMappingSeq( p ); } - return If_ManPerformMappingComb( p ); } diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c index 2879081c..fd1078a6 100644 --- a/src/map/if/ifMap.c +++ b/src/map/if/ifMap.c @@ -169,7 +169,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep If_ObjForEachCut( pObj, pCut, i ) p->pPars->pFuncUser( p, pObj, pCut ); - // ABC_FREE the cuts + // free the cuts If_ManDerefNodeCutSet( p, pObj ); } @@ -253,7 +253,7 @@ void If_ObjPerformMappingChoice( If_Man_t * p, If_Obj_t * pObj, int Mode, int fP if ( Mode && pObj->nRefs > 0 ) If_CutAreaRef( p, If_ObjCutBest(pObj) ); - // ABC_FREE the cuts + // free the cuts If_ManDerefChoiceCutSet( p, pObj ); } diff --git a/src/map/if/ifSeq.c b/src/map/if/ifSeq.c index 8d1de8c1..e4e27e71 100644 --- a/src/map/if/ifSeq.c +++ b/src/map/if/ifSeq.c @@ -124,6 +124,16 @@ int If_ManPerformMappingRoundSeq( If_Man_t * p, int nIter ) int fVeryVerbose = 0; int fChange = 0; + if ( nIter == 1 ) + { + // if some latches depend on PIs, update their values + Vec_PtrForEachEntry( p->vLatchOrder, pObj, i ) + { + If_ObjSetLValue( pObj, If_ObjLValue(If_ObjFanin0(pObj)) - p->Period ); + If_ObjSetArrTime( pObj, If_ObjLValue(pObj) ); + } + } + // map the internal nodes p->nCutsMerged = 0; If_ManForEachNode( p, pObj, i ) @@ -158,13 +168,14 @@ int If_ManPerformMappingRoundSeq( If_Man_t * p, int nIter ) } // compute area and delay + If_ManMarkMapping( p ); if ( fVeryVerbose ) { p->RequiredGlo = If_ManDelayMax( p, 1 ); - p->AreaGlo = If_ManScanMapping(p); +// p->AreaGlo = If_ManScanMapping(p); printf( "S%d: Fi = %6.2f. Del = %6.2f. Area = %8.2f. Cuts = %8d. ", nIter, (float)p->Period, p->RequiredGlo, p->AreaGlo, p->nCutsMerged ); - PRT( "T", clock() - clk ); + ABC_PRT( "T", clock() - clk ); } return fChange; } @@ -185,26 +196,26 @@ int If_ManBinarySearchPeriod( If_Man_t * p ) If_Obj_t * pObj; int i, c, fConverged; int fResetRefs = 0; - p->nAttempts++; // reset initial LValues (PIs to 0; others to -inf) If_ManForEachObj( p, pObj, i ) { - if ( If_ObjIsPi(pObj) || If_ObjIsConst1(pObj) ) - { - If_ObjSetLValue( pObj, (float)0.0 ); - If_ObjSetArrTime( pObj, (float)0.0 ); - } - else - { - If_ObjSetLValue( pObj, (float)-IF_INFINITY ); - If_ObjSetArrTime( pObj, (float)-IF_INFINITY ); - } + If_ObjSetLValue( pObj, (float)-IF_INFINITY ); + If_ObjSetArrTime( pObj, (float)-IF_INFINITY ); // undo any previous mapping, except for CIs if ( If_ObjIsAnd(pObj) ) If_ObjCutBest(pObj)->nLeaves = 0; } + pObj = If_ManConst1( p ); + If_ObjSetLValue( pObj, (float)0.0 ); + If_ObjSetArrTime( pObj, (float)0.0 ); + If_ManForEachPi( p, pObj, i ) + { + pObj = If_ManCi( p, i ); + If_ObjSetLValue( pObj, (float)0.0 ); + If_ObjSetArrTime( pObj, (float)0.0 ); + } // update all values iteratively fConverged = 0; @@ -223,9 +234,10 @@ int If_ManBinarySearchPeriod( If_Man_t * p ) } // report the results + If_ManMarkMapping( p ); if ( p->pPars->fVerbose ) { - p->AreaGlo = If_ManScanMapping(p); +// p->AreaGlo = If_ManScanMapping(p); printf( "Attempt = %2d. Iters = %3d. Area = %10.2f. Fi = %6.2f. ", p->nAttempts, c, p->AreaGlo, (float)p->Period ); if ( fConverged ) printf( " Feasible" ); @@ -279,15 +291,6 @@ void If_ManPerformMappingSeqPost( If_Man_t * p ) If_Obj_t * pObjLi, * pObjLo, * pObj; int i; - // link the latch outputs (CIs) directly to the drivers of latch inputs (COs) - for ( i = 0; i < p->pPars->nLatches; i++ ) - { - pObjLi = If_ManLi( p, i ); - pObjLo = If_ManLo( p, i ); -// printf( "%3d : %2d -> %2d \n", i, -// (int)If_ObjLValue(If_ObjFanin0(pObjLo)), (int)If_ObjLValue(pObjLo) ); - } - // set arrival times assert( p->pPars->pTimesArr != NULL ); If_ManForEachLatchOutput( p, pObjLo, i ) @@ -295,7 +298,7 @@ void If_ManPerformMappingSeqPost( If_Man_t * p ) // set the required times assert( p->pPars->pTimesReq == NULL ); - p->pPars->pTimesReq = ALLOC( float, If_ManCoNum(p) ); + p->pPars->pTimesReq = ABC_ALLOC( float, If_ManCoNum(p) ); If_ManForEachPo( p, pObj, i ) { p->pPars->pTimesReq[i] = p->RequiredGlo2; @@ -338,7 +341,7 @@ int If_ManPerformMappingSeq( If_Man_t * p ) // perform combinational mapping to get the upper bound on the clock period If_ManPerformMappingRound( p, 1, 0, 0, NULL ); - p->RequiredGlo = If_ManDelayMax( p, 0 ); + p->RequiredGlo = If_ManDelayMax( p, 0 ); p->RequiredGlo2 = p->RequiredGlo; // set direct linking of latches with their inputs @@ -373,24 +376,12 @@ int If_ManPerformMappingSeq( If_Man_t * p ) return 0; } } - if ( p->pPars->fVerbose ) +// if ( p->pPars->fVerbose ) { -/* - { - FILE * pTable; - pTable = fopen( "iscas/stats_new.txt", "a+" ); -// fprintf( pTable, "%s ", pNtk->pName ); - fprintf( pTable, "%d ", p->Period ); - // fprintf( pTable, "%.2f ", (float)(s_MappingMem)/(float)(1<<20) ); -// fprintf( pTable, "%.2f", (float)(s_MappingTime)/(float)(CLOCKS_PER_SEC) ); -// fprintf( pTable, "\n" ); - fclose( pTable ); - } -*/ printf( "The best clock period is %3d. ", p->Period ); - PRT( "Sequential time", clock() - clkTotal ); + ABC_PRT( "Time", clock() - clkTotal ); } - p->RequiredGlo = (float)PeriodBest; + p->RequiredGlo = (float)(PeriodBest); // postprocess it using combinational mapping If_ManPerformMappingSeqPost( p ); diff --git a/src/map/if/module.make b/src/map/if/module.make index 7489d3b4..53ed7c03 100644 --- a/src/map/if/module.make +++ b/src/map/if/module.make @@ -4,6 +4,7 @@ SRC += src/map/if/ifCore.c \ src/map/if/ifMan.c \ src/map/if/ifMap.c \ src/map/if/ifReduce.c \ + src/map/if/ifSeq.c \ src/map/if/ifTime.c \ src/map/if/ifTruth.c \ src/map/if/ifUtil.c diff --git a/src/map/mio/mio81214.zip b/src/map/mio/mio81214.zip Binary files differdeleted file mode 100644 index 12f766a9..00000000 --- a/src/map/mio/mio81214.zip +++ /dev/null diff --git a/src/misc/vec/vecFlt.h b/src/misc/vec/vecFlt.h index 93402cf2..8f0ea42d 100644 --- a/src/misc/vec/vecFlt.h +++ b/src/misc/vec/vecFlt.h @@ -383,6 +383,8 @@ static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Entry ) int i; if ( p->nSize >= nSize ) return; + if ( nSize < 2 * p->nSize ) + nSize = 2 * p->nSize; Vec_FltGrow( p, nSize ); for ( i = p->nSize; i < nSize; i++ ) p->pArray[i] = Entry; diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index 0f7a41ab..c3c92f09 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -409,10 +409,9 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill ) int i; if ( p->nSize >= nSize ) return; - if ( 2 * p->nSize > nSize ) - Vec_IntGrow( p, 2 * nSize ); - else - Vec_IntGrow( p, nSize ); + if ( nSize < 2 * p->nSize ) + nSize = 2 * p->nSize; + Vec_IntGrow( p, nSize ); for ( i = p->nSize; i < nSize; i++ ) p->pArray[i] = Fill; p->nSize = nSize; @@ -743,6 +742,28 @@ static inline int Vec_IntFindMin( Vec_Int_t * p ) /**Function************************************************************* + Synopsis [Reverses the order of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntReverseOrder( Vec_Int_t * p ) +{ + int i, Temp; + for ( i = 0; i < p->nSize/2; i++ ) + { + Temp = p->pArray[i]; + p->pArray[i] = p->pArray[p->nSize-1-i]; + p->pArray[p->nSize-1-i] = Temp; + } +} + +/**Function************************************************************* + Synopsis [Comparison procedure for two integers.] Description [] diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 4d09acb7..6fc5109b 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -388,10 +388,9 @@ static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry ) if ( p->nSize >= nSize ) return; assert( p->nSize < nSize ); - if ( 2 * p->nSize > nSize ) - Vec_PtrGrow( p, 2 * nSize ); - else - Vec_PtrGrow( p, nSize ); + if ( nSize < 2 * p->nSize ) + nSize = 2 * p->nSize; + Vec_PtrGrow( p, nSize ); for ( i = p->nSize; i < nSize; i++ ) p->pArray[i] = Entry; p->nSize = nSize; @@ -616,6 +615,29 @@ static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems ) /**Function************************************************************* + Synopsis [Reverses the order of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_PtrReverseOrder( Vec_Ptr_t * p ) +{ + void * Temp; + int i; + for ( i = 0; i < p->nSize/2; i++ ) + { + Temp = p->pArray[i]; + p->pArray[i] = p->pArray[p->nSize-1-i]; + p->pArray[p->nSize-1-i] = Temp; + } +} + +/**Function************************************************************* + Synopsis [Sorting the entries by their integer value.] Description [] diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h index dc0b2bad..c77a3a17 100644 --- a/src/misc/vec/vecStr.h +++ b/src/misc/vec/vecStr.h @@ -361,10 +361,9 @@ static inline void Vec_StrFillExtra( Vec_Str_t * p, int nSize, char Fill ) int i; if ( p->nSize >= nSize ) return; - if ( 2 * p->nSize > nSize ) - Vec_StrGrow( p, 2 * nSize ); - else - Vec_StrGrow( p, nSize ); + if ( nSize < 2 * p->nSize ) + nSize = 2 * p->nSize; + Vec_StrGrow( p, nSize ); for ( i = p->nSize; i < nSize; i++ ) p->pArray[i] = Fill; p->nSize = nSize; diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c index 2886668e..158dc70a 100644 --- a/src/opt/dec/decAbc.c +++ b/src/opt/dec/decAbc.c @@ -66,6 +66,53 @@ Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ) Synopsis [Transforms the decomposition graph into the AIG.] + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Dec_SopToAig( Abc_Ntk_t * pNtk, char * pSop, Vec_Ptr_t * vFaninAigs ) +{ + Abc_Obj_t * pFunc; + Dec_Graph_t * pFForm; + Dec_Node_t * pNode; + int i; + pFForm = Dec_Factor( pSop ); + Dec_GraphForEachLeaf( pFForm, pNode, i ) + pNode->pFunc = Vec_PtrEntry( vFaninAigs, i ); + pFunc = Dec_GraphToNetwork( pNtk, pFForm ); + Dec_GraphFree( pFForm ); + return pFunc; +} + +/**Function************************************************************* + + Synopsis [Transforms the decomposition graph into the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs ) +{ + Abc_Obj_t * pFunc; + Dec_Node_t * pNode; + int i; + Dec_GraphForEachLeaf( pFForm, pNode, i ) + pNode->pFunc = Vec_PtrEntry( vFaninAigs, i ); + pFunc = Dec_GraphToNetwork( pNtk, pFForm ); + return pFunc; +} + +/**Function************************************************************* + + Synopsis [Transforms the decomposition graph into the AIG.] + Description [AIG nodes for the fanins should be assigned to pNode->pFunc of the leaves of the graph before calling this procedure.] diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index d2ebf552..df04cd1f 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -851,6 +851,7 @@ static lbool sat_solver_search(sat_solver* s, ABC_INT64_T nof_conflicts, ABC_INT // use activity factors in every even restart if ( (s->nRestarts & 1) && veci_size(&s->act_vars) > 0 ) +// if ( veci_size(&s->act_vars) > 0 ) for ( i = 0; i < s->act_vars.size; i++ ) act_var_bump_factor(s, s->act_vars.ptr[i]); |