| /**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 |
| |