| /**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 "misc/util/abc_global.h" | |
| #include "bblif.h" | |
| ABC_NAMESPACE_IMPL_START | |
| //////////////////////////////////////////////////////////////////////// | |
| /// 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->nCap ) | |
| Vec_IntGrow( p, nSize ); | |
| else if ( nSize > p->nCap ) | |
| Vec_IntGrow( p, 2 * p->nCap ); | |
| 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; | |
| int RetValue; | |
| nFileSize = Bbl_ManFileSize( pFileName ); | |
| pFile = fopen( pFileName, "rb" ); | |
| pContents = BBLIF_ALLOC( char, nFileSize ); | |
| RetValue = 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 /// | |
| //////////////////////////////////////////////////////////////////////// | |
| ABC_NAMESPACE_IMPL_END | |