diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2015-07-21 17:51:28 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2015-07-21 17:51:28 -0700 |
commit | 91b62b3bb8ee38938d4119d4cbd2360a652974bd (patch) | |
tree | 0d4207652a871a2e8118ef98cf4b70b3a7f6a19d /src/base/bac | |
parent | 477ecc172f3d9088bf6ecd21044b9d1c758d7b64 (diff) | |
download | abc-91b62b3bb8ee38938d4119d4cbd2360a652974bd.tar.gz abc-91b62b3bb8ee38938d4119d4cbd2360a652974bd.tar.bz2 abc-91b62b3bb8ee38938d4119d4cbd2360a652974bd.zip |
Renaming Cba into Bac.
Diffstat (limited to 'src/base/bac')
-rw-r--r-- | src/base/bac/bac.c | 52 | ||||
-rw-r--r-- | src/base/bac/bac.h | 1017 | ||||
-rw-r--r-- | src/base/bac/bacBac.c | 298 | ||||
-rw-r--r-- | src/base/bac/bacBlast.c | 587 | ||||
-rw-r--r-- | src/base/bac/bacCom.c | 728 | ||||
-rw-r--r-- | src/base/bac/bacLib.c | 52 | ||||
-rw-r--r-- | src/base/bac/bacNtk.c | 604 | ||||
-rw-r--r-- | src/base/bac/bacOper.c | 365 | ||||
-rw-r--r-- | src/base/bac/bacPrs.h | 363 | ||||
-rw-r--r-- | src/base/bac/bacPrsBuild.c | 356 | ||||
-rw-r--r-- | src/base/bac/bacPrsTrans.c | 211 | ||||
-rw-r--r-- | src/base/bac/bacPrtAbc.c | 486 | ||||
-rw-r--r-- | src/base/bac/bacPtr.c | 470 | ||||
-rw-r--r-- | src/base/bac/bacReadBlif.c | 453 | ||||
-rw-r--r-- | src/base/bac/bacReadSmt.c | 42 | ||||
-rw-r--r-- | src/base/bac/bacReadVec.c | 875 | ||||
-rw-r--r-- | src/base/bac/bacWriteBlif.c | 236 | ||||
-rw-r--r-- | src/base/bac/bacWriteSmt.c | 52 | ||||
-rw-r--r-- | src/base/bac/bacWriteVer.c | 703 | ||||
-rw-r--r-- | src/base/bac/module.make | 15 |
20 files changed, 7965 insertions, 0 deletions
diff --git a/src/base/bac/bac.c b/src/base/bac/bac.c new file mode 100644 index 00000000..fdbee7b7 --- /dev/null +++ b/src/base/bac/bac.c @@ -0,0 +1,52 @@ +/**CFile**************************************************************** + + FileName [bac.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Parses several flavors of word-level Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bac.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bac.h b/src/base/bac/bac.h new file mode 100644 index 00000000..27792363 --- /dev/null +++ b/src/base/bac/bac.h @@ -0,0 +1,1017 @@ +/**CFile**************************************************************** + + FileName [bac.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bac.h,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__base__bac__bac_h +#define ABC__base__bac__bac_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig/gia/gia.h" +#include "misc/extra/extra.h" +#include "misc/util/utilNam.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// network objects +typedef enum { + BAC_OBJ_NONE = 0, // 0: unused + BAC_OBJ_PI, // 1: input + BAC_OBJ_PO, // 2: output + BAC_OBJ_BI, // 3: box input + BAC_OBJ_BO, // 4: box output + BAC_OBJ_BOX, // 5: box + + BAC_BOX_CF, + BAC_BOX_CT, + BAC_BOX_CX, + BAC_BOX_CZ, + BAC_BOX_BUF, + BAC_BOX_INV, + BAC_BOX_AND, + BAC_BOX_NAND, + BAC_BOX_OR, + BAC_BOX_NOR, + BAC_BOX_XOR, + BAC_BOX_XNOR, + BAC_BOX_SHARP, + BAC_BOX_SHARPL, + BAC_BOX_MUX, + BAC_BOX_MAJ, + + BAC_BOX_RAND, + BAC_BOX_RNAND, + BAC_BOX_ROR, + BAC_BOX_RNOR, + BAC_BOX_RXOR, + BAC_BOX_RXNOR, + + BAC_BOX_LAND, + BAC_BOX_LNAND, + BAC_BOX_LOR, + BAC_BOX_LNOR, + BAC_BOX_LXOR, + BAC_BOX_LXNOR, + + BAC_BOX_NMUX, + BAC_BOX_SEL, + BAC_BOX_PSEL, + BAC_BOX_ENC, + BAC_BOX_PENC, + BAC_BOX_DEC, + BAC_BOX_EDEC, + + BAC_BOX_ADD, + BAC_BOX_SUB, + BAC_BOX_MUL, + BAC_BOX_DIV, + BAC_BOX_MOD, + BAC_BOX_REM, + BAC_BOX_POW, + BAC_BOX_MIN, + BAC_BOX_ABS, + + BAC_BOX_LTHAN, + BAC_BOX_LETHAN, + BAC_BOX_METHAN, + BAC_BOX_MTHAN, + BAC_BOX_EQU, + BAC_BOX_NEQU, + + BAC_BOX_SHIL, + BAC_BOX_SHIR, + BAC_BOX_ROTL, + BAC_BOX_ROTR, + + BAC_BOX_GATE, + BAC_BOX_LUT, + BAC_BOX_ASSIGN, + + BAC_BOX_TRI, + BAC_BOX_RAM, + BAC_BOX_RAMR, + BAC_BOX_RAMW, + BAC_BOX_RAMWC, + BAC_BOX_RAMBOX, + + BAC_BOX_LATCH, + BAC_BOX_LATCHRS, + BAC_BOX_DFF, + BAC_BOX_DFFRS, + + BAC_BOX_UNKNOWN // 67 +} Bac_ObjType_t; + + +// name types +typedef enum { + BAC_NAME_BIN = 0, // 0: binary variable + BAC_NAME_WORD, // 1: first bit of word-level variable + BAC_NAME_INFO, // 2: first bit of special variable + BAC_NAME_INDEX, // 3: index of word-level variable +} Bac_NameType_t; + + +typedef struct Bac_Ntk_t_ Bac_Ntk_t; +typedef struct Bac_Man_t_ Bac_Man_t; + +// network +struct Bac_Ntk_t_ +{ + Bac_Man_t * pDesign; // design + int NameId; // name ID + int iCopy; // copy module + int iBoxNtk; // instance network ID + int iBoxObj; // instance object ID + int Count; // object counter + int Mark; // visit mark + // interface + Vec_Int_t vInputs; // inputs + Vec_Int_t vOutputs; // outputs + Vec_Int_t vInfo; // input/output/wire info + // object attributes + Vec_Str_t vType; // types + Vec_Int_t vFanin; // fanin + Vec_Int_t vIndex; // index + Vec_Int_t vName; // original NameId or InstId + Vec_Int_t vFanout; // fanout + Vec_Int_t vCopy; // copy + // other + Vec_Int_t vArray; + Vec_Int_t vArray2; +}; + +// design +struct Bac_Man_t_ +{ + // design names + char * pName; // design name + char * pSpec; // spec file name + Abc_Nam_t * pStrs; // string manager + Abc_Nam_t * pMods; // module name manager + // internal data + int iRoot; // root network + int nNtks; // number of current networks + Bac_Ntk_t * pNtks; // networks + // user data + Vec_Str_t * vOut; + Vec_Str_t * vOut2; + Vec_Int_t vBuf2RootNtk; + Vec_Int_t vBuf2RootObj; + Vec_Int_t vBuf2LeafNtk; + Vec_Int_t vBuf2LeafObj; + void * pMioLib; + void ** ppGraphs; + int ElemGates[4]; + char * pPrimNames[BAC_BOX_UNKNOWN]; + char * pPrimSymbs[BAC_BOX_UNKNOWN]; +}; + +static inline char * Bac_ManName( Bac_Man_t * p ) { return p->pName; } +static inline char * Bac_ManSpec( Bac_Man_t * p ) { return p->pSpec; } +static inline int Bac_ManNtkNum( Bac_Man_t * p ) { return p->nNtks; } +static inline int Bac_ManPrimNum( Bac_Man_t * p ) { return Abc_NamObjNumMax(p->pMods) - Bac_ManNtkNum(p); } +static inline int Bac_ManNtkIsOk( Bac_Man_t * p, int i ) { return i > 0 && i <= Bac_ManNtkNum(p); } +static inline Bac_Ntk_t * Bac_ManNtk( Bac_Man_t * p, int i ) { return Bac_ManNtkIsOk(p, i) ? p->pNtks + i : NULL; } +static inline int Bac_ManNtkFindId( Bac_Man_t * p, char * pName ) { return Abc_NamStrFind(p->pMods, pName); } +static inline Bac_Ntk_t * Bac_ManNtkFind( Bac_Man_t * p, char * pName ) { return Bac_ManNtk( p, Bac_ManNtkFindId(p, pName) ); } +static inline Bac_Ntk_t * Bac_ManRoot( Bac_Man_t * p ) { return Bac_ManNtk(p, p->iRoot); } +static inline char * Bac_ManStr( Bac_Man_t * p, int i ) { return Abc_NamStr(p->pStrs, i); } +static inline int Bac_ManStrId( Bac_Man_t * p, char * pStr ) { return Abc_NamStrFind(p->pStrs, pStr); } +static inline char * Bac_ManPrimName( Bac_Man_t * p, Bac_ObjType_t Type ) { return p->pPrimNames[Type]; } +static inline char * Bac_ManPrimSymb( Bac_Man_t * p, Bac_ObjType_t Type ) { return p->pPrimSymbs[Type]; } + +static inline int Bac_NtkId( Bac_Ntk_t * p ) { int i = p - p->pDesign->pNtks; assert(Bac_ManNtkIsOk(p->pDesign, i)); return i; } +static inline Bac_Man_t * Bac_NtkMan( Bac_Ntk_t * p ) { return p->pDesign; } +static inline int Bac_NtkNameId( Bac_Ntk_t * p ) { return p->NameId; } +static inline char * Bac_NtkName( Bac_Ntk_t * p ) { return Bac_ManStr(p->pDesign, Bac_NtkNameId(p)); } +static inline int Bac_NtkCopy( Bac_Ntk_t * p ) { return p->iCopy; } +static inline Bac_Ntk_t * Bac_NtkCopyNtk(Bac_Man_t * pNew, Bac_Ntk_t * p) { return Bac_ManNtk(pNew, Bac_NtkCopy(p)); } +static inline void Bac_NtkSetCopy( Bac_Ntk_t * p, int i ) { assert(p->iCopy == -1); p->iCopy = i; } + +static inline int Bac_NtkObjNum( Bac_Ntk_t * p ) { return Vec_StrSize(&p->vType); } +static inline int Bac_NtkObjNumAlloc( Bac_Ntk_t * p ) { return Vec_StrCap(&p->vType); } +static inline int Bac_NtkPiNum( Bac_Ntk_t * p ) { return Vec_IntSize(&p->vInputs); } +static inline int Bac_NtkPoNum( Bac_Ntk_t * p ) { return Vec_IntSize(&p->vOutputs); } +static inline int Bac_NtkPioNum( Bac_Ntk_t * p ) { return Bac_NtkPiNum(p) + Bac_NtkPoNum(p); } +static inline int Bac_NtkPiNumAlloc( Bac_Ntk_t * p ) { return Vec_IntCap(&p->vInputs); } +static inline int Bac_NtkPoNumAlloc( Bac_Ntk_t * p ) { return Vec_IntCap(&p->vOutputs); } +static inline int Bac_NtkBiNum( Bac_Ntk_t * p ) { return Vec_StrCountEntryLit(&p->vType, (char)BAC_OBJ_BI); } +static inline int Bac_NtkBoNum( Bac_Ntk_t * p ) { return Vec_StrCountEntryLit(&p->vType, (char)BAC_OBJ_BO); } +static inline int Bac_NtkCiNum( Bac_Ntk_t * p ) { return Bac_NtkPiNum(p) + Bac_NtkBoNum(p); } +static inline int Bac_NtkCoNum( Bac_Ntk_t * p ) { return Bac_NtkPoNum(p) + Bac_NtkBiNum(p); } +static inline int Bac_NtkBoxNum( Bac_Ntk_t * p ) { return Bac_NtkObjNum(p) - Vec_StrCountSmallerLit(&p->vType, (char)BAC_OBJ_BOX); } +static inline int Bac_NtkPrimNum( Bac_Ntk_t * p ) { return Vec_StrCountLargerLit(&p->vType, (char)BAC_OBJ_BOX); } +static inline int Bac_NtkUserNum( Bac_Ntk_t * p ) { return Vec_StrCountEntryLit(&p->vType, (char)BAC_OBJ_BOX); } + +static inline int Bac_NtkPi( Bac_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vInputs, i); } +static inline int Bac_NtkPo( Bac_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vOutputs, i); } +static inline char * Bac_NtkStr( Bac_Ntk_t * p, int i ) { return Bac_ManStr(p->pDesign, i); } +static inline Bac_Ntk_t * Bac_NtkHostNtk( Bac_Ntk_t * p ) { return p->iBoxNtk > 0 ? Bac_ManNtk(p->pDesign, p->iBoxNtk) : NULL; } +static inline int Bac_NtkHostObj( Bac_Ntk_t * p ) { return p->iBoxObj; } +static inline void Bac_NtkSetHost( Bac_Ntk_t * p, int n, int i ) { assert(p->iBoxNtk == -1); p->iBoxNtk = n; p->iBoxObj = i; } + +static inline int Bac_InfoRange( int Beg, int End ) { return End > Beg ? End - Beg + 1 : Beg - End + 1; } +static inline int Bac_NtkInfoNum( Bac_Ntk_t * p ) { return Vec_IntSize(&p->vInfo)/3; } +static inline int Bac_NtkInfoNumAlloc( Bac_Ntk_t * p ) { return Vec_IntCap(&p->vInfo)/3; } +static inline int Bac_NtkInfoType( Bac_Ntk_t * p, int i ) { return Abc_Lit2Att2(Vec_IntEntry(&p->vInfo, 3*i)); } +static inline int Bac_NtkInfoName( Bac_Ntk_t * p, int i ) { return Abc_Lit2Var2(Vec_IntEntry(&p->vInfo, 3*i)); } +static inline int Bac_NtkInfoBeg( Bac_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vInfo, 3*i+1); } +static inline int Bac_NtkInfoEnd( Bac_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vInfo, 3*i+2); } +static inline int Bac_NtkInfoRange( Bac_Ntk_t * p, int i ) { int* a = Vec_IntEntryP(&p->vInfo, 3*i); return a[1]>=0 ? Bac_InfoRange( a[1], a[2] ) : 1; } +static inline int Bac_NtkInfoIndex( Bac_Ntk_t * p, int i, int j ) { int* a = Vec_IntEntryP(&p->vInfo, 3*i); assert(a[1]>=0); return a[1]<a[2] ? a[1]+j : a[1]-j;} +static inline void Bac_NtkAddInfo( Bac_Ntk_t * p,int i,int b,int e){ Vec_IntPush(&p->vInfo, i); Vec_IntPushTwo(&p->vInfo, b, e); } +static inline void Bac_NtkSetInfoName( Bac_Ntk_t * p, int i, int n){ Vec_IntWriteEntry( &p->vInfo, 3*i, n ); } + +static inline void Bac_NtkStartNames( Bac_Ntk_t * p ) { assert(Bac_NtkObjNumAlloc(p)); Vec_IntFill(&p->vName, Bac_NtkObjNumAlloc(p), 0); } +static inline void Bac_NtkStartFanouts( Bac_Ntk_t * p ) { assert(Bac_NtkObjNumAlloc(p)); Vec_IntFill(&p->vFanout, Bac_NtkObjNumAlloc(p), 0); } +static inline void Bac_NtkStartCopies( Bac_Ntk_t * p ) { assert(Bac_NtkObjNumAlloc(p)); Vec_IntFill(&p->vCopy, Bac_NtkObjNumAlloc(p), -1); } +static inline void Bac_NtkFreeNames( Bac_Ntk_t * p ) { Vec_IntErase(&p->vName); } +static inline void Bac_NtkFreeFanouts( Bac_Ntk_t * p ) { Vec_IntErase(&p->vFanout); } +static inline void Bac_NtkFreeCopies( Bac_Ntk_t * p ) { Vec_IntErase(&p->vCopy); } +static inline int Bac_NtkHasNames( Bac_Ntk_t * p ) { return p->vName.pArray != NULL; } +static inline int Bac_NtkHasFanouts( Bac_Ntk_t * p ) { return p->vFanout.pArray != NULL; } +static inline int Bac_NtkHasCopies( Bac_Ntk_t * p ) { return p->vCopy.pArray != NULL; } + +static inline int Bac_TypeIsBox( Bac_ObjType_t Type ) { return Type >= BAC_OBJ_BOX && Type < BAC_BOX_UNKNOWN; } +static inline Bac_NameType_t Bac_NameType( int n ) { assert( n ); return (Bac_NameType_t)Abc_Lit2Att2( n ); } +static inline int Bac_CharIsDigit( char c ) { return c >= '0' && c <= '9'; } + +static inline Bac_ObjType_t Bac_ObjType( Bac_Ntk_t * p, int i ) { return (Bac_ObjType_t)Abc_Lit2Var((int)(unsigned char)Vec_StrEntry(&p->vType, i)); } +static inline int Bac_ObjIsPi( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_OBJ_PI; } +static inline int Bac_ObjIsPo( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_OBJ_PO; } +static inline int Bac_ObjIsPio( Bac_Ntk_t * p, int i ) { return Bac_ObjIsPi(p, i) || Bac_ObjIsPo(p, i); } +static inline int Bac_ObjIsBi( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_OBJ_BI; } +static inline int Bac_ObjIsBo( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_OBJ_BO; } +static inline int Bac_ObjIsBio( Bac_Ntk_t * p, int i ) { return Bac_ObjIsBi(p, i) || Bac_ObjIsBo(p, i); } +static inline int Bac_ObjIsBox( Bac_Ntk_t * p, int i ) { return Bac_TypeIsBox(Bac_ObjType(p, i)); } +static inline int Bac_ObjIsBoxUser( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_OBJ_BOX; } +static inline int Bac_ObjIsBoxPrim( Bac_Ntk_t * p, int i ) { return Bac_ObjIsBox(p, i) && !Bac_ObjIsBoxUser(p, i); } +static inline int Bac_ObjIsGate( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_BOX_GATE; } +static inline int Bac_ObjIsCi( Bac_Ntk_t * p, int i ) { return Bac_ObjIsPi(p, i) || Bac_ObjIsBo(p, i); } +static inline int Bac_ObjIsCo( Bac_Ntk_t * p, int i ) { return Bac_ObjIsPo(p, i) || Bac_ObjIsBi(p, i); } +static inline int Bac_ObjIsCio( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) < BAC_OBJ_BOX; } +static inline int Bac_ObjIsConst( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) >= BAC_BOX_CF && Bac_ObjType(p, i) <= BAC_BOX_CZ; } +static inline int Bac_ObjIsConstBin( Bac_Ntk_t * p, int i ) { return Bac_ObjType(p, i) == BAC_BOX_CF || Bac_ObjType(p, i) == BAC_BOX_CT; } + +static inline int Bac_ObjBit( Bac_Ntk_t * p, int i ) { assert(!Bac_ObjIsBox(p, i)); return Abc_LitIsCompl((int)Vec_StrEntry(&p->vType, i)); } +static inline void Bac_ObjSetBit( Bac_Ntk_t * p, int i ) { char *q = Vec_StrArray(&p->vType); assert(!Bac_ObjIsBox(p, i)); q[i] = (char)Abc_LitNot((int)q[i]); } +static inline int Bac_ObjFanin( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsCo(p, i)); return Vec_IntEntry(&p->vFanin, i); } +static inline int Bac_ObjIndex( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsCio(p, i)); return Vec_IntEntry(&p->vIndex, i); } +static inline int Bac_ObjNameInt( Bac_Ntk_t * p, int i ) { assert(!Bac_ObjIsCo(p, i)); return Vec_IntEntry(&p->vName, i); } +static inline int Bac_ObjName( Bac_Ntk_t * p, int i ) { return Bac_ObjIsCo(p, i) ? Bac_ObjNameInt(p, Bac_ObjFanin(p,i)) : Bac_ObjNameInt(p, i); } +static inline Bac_NameType_t Bac_ObjNameType( Bac_Ntk_t * p, int i ) { return Bac_NameType( Bac_ObjName(p, i) ); } +static inline int Bac_ObjNameId( Bac_Ntk_t * p, int i ) { return Abc_Lit2Var2( Bac_ObjName(p, i) ); } +static inline char * Bac_ObjNameStr( Bac_Ntk_t * p, int i ) { assert(Bac_ObjNameType(p, i) <= BAC_NAME_WORD); return Bac_NtkStr(p, Bac_ObjNameId(p, i)); } +static inline int Bac_ObjCopy( Bac_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vCopy, i); } +static inline int Bac_ObjFanout( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsCi(p, i)); return Vec_IntEntry(&p->vFanout, i); } +static inline int Bac_ObjNextFanout( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsCo(p, i)); return Vec_IntEntry(&p->vFanout, i); } +static inline void Bac_ObjSetFanout( Bac_Ntk_t * p, int i, int x ) { assert(Bac_ObjIsCi(p, i)); Vec_IntSetEntry(&p->vFanout, i, x); } +static inline void Bac_ObjSetNextFanout( Bac_Ntk_t * p,int i,int x){ assert(Bac_ObjIsCo(p, i)); Vec_IntSetEntry(&p->vFanout, i, x); } +static inline void Bac_ObjCleanFanin( Bac_Ntk_t * p, int i ) { assert(Bac_ObjFanin(p, i) >= 0 && Bac_ObjIsCo(p, i)); Vec_IntSetEntry( &p->vFanin, i, -1); } +static inline void Bac_ObjSetFanin( Bac_Ntk_t * p, int i, int x ) { assert(Bac_ObjFanin(p, i) == -1 && Bac_ObjIsCo(p, i)); Vec_IntSetEntry( &p->vFanin, i, x); } +static inline void Bac_ObjSetIndex( Bac_Ntk_t * p, int i, int x ) { assert(Bac_ObjIndex(p, i) == -1); Vec_IntSetEntry( &p->vIndex, i, x ); } +static inline void Bac_ObjSetName( Bac_Ntk_t * p, int i, int x ) { assert(Bac_ObjName(p, i) == 0 && !Bac_ObjIsCo(p, i)); Vec_IntSetEntry( &p->vName, i, x ); } +static inline void Bac_ObjSetCopy( Bac_Ntk_t * p, int i, int x ) { assert(Bac_ObjCopy(p, i) == -1); Vec_IntSetEntry( &p->vCopy, i, x ); } +static inline int Bac_ObjGetConst( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsCi(p, i)); return Bac_ObjIsBo(p, i) && Bac_ObjIsConst(p, i-1) ? Bac_ObjType(p, i-1) : 0; } + +static inline int Bac_BoxBiNum( Bac_Ntk_t * p, int i ) { int s = i-1; assert(Bac_ObjIsBox(p, i)); while (--i >= 0 && Bac_ObjIsBi(p, i)) {} return s - i; } +static inline int Bac_BoxBoNum( Bac_Ntk_t * p, int i ) { int s = i+1; assert(Bac_ObjIsBox(p, i)); while (++i < Bac_NtkObjNum(p) && Bac_ObjIsBo(p, i)) {} return i - s; } +static inline int Bac_BoxSize( Bac_Ntk_t * p, int i ) { return 1 + Bac_BoxBiNum(p, i) + Bac_BoxBoNum(p, i); } +static inline int Bac_BoxBi( Bac_Ntk_t * p, int b, int i ) { assert(Bac_ObjIsBox(p, b)); return b - 1 - i; } +static inline int Bac_BoxBo( Bac_Ntk_t * p, int b, int i ) { assert(Bac_ObjIsBox(p, b)); return b + 1 + i; } +//static inline int Bac_BoxBiBox( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsBi(p, i)); return i + 1 + Bac_ObjIndex(p, i); } +static inline int Bac_BoxBoBox( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsBo(p, i)); return i - 1 - Bac_ObjIndex(p, i); } +static inline int Bac_BoxFanin( Bac_Ntk_t * p, int b, int i ) { return Bac_ObjFanin(p, Bac_BoxBi(p, b, i)); } +static inline int Bac_BoxFaninBox( Bac_Ntk_t * p, int b, int i ) { return Bac_BoxBoBox(p, Bac_BoxFanin(p, b, i)); } +static inline int Bac_BoxBiRange( Bac_Ntk_t * p, int i ) { int s = i; assert(Bac_ObjIsBi(p, i) && !Bac_ObjBit(p, i)); while (--i >= 0 && Bac_ObjIsBi(p, i) && Bac_ObjBit(p, i)) {} return s - i; } +static inline int Bac_BoxBoRange( Bac_Ntk_t * p, int i ) { int s = i; assert(Bac_ObjIsBo(p, i) && !Bac_ObjBit(p, i)); while (++i < Bac_NtkObjNum(p) && Bac_ObjIsBo(p, i) && Bac_ObjBit(p, i)) {} return i - s; } +static inline int Bac_ObjPiRange( Bac_Ntk_t * p, int i ) { int s = i; assert(Bac_ObjIsPi(p, i) && !Bac_ObjBit(p, i)); while (++i < Bac_NtkObjNum(p) && Bac_ObjIsPi(p, i) && Bac_ObjBit(p, i)) {} return i - s; } + +static inline int Bac_BoxNtkId( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsBox(p, i)); return Vec_IntEntry(&p->vFanin, i); } +static inline void Bac_BoxSetNtkId( Bac_Ntk_t * p, int i, int x ) { assert(Bac_ObjIsBox(p, i)&&Bac_ManNtkIsOk(p->pDesign, x));Vec_IntSetEntry(&p->vFanin, i, x);} +//static inline int Bac_BoxBiNtkId( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsBi(p, i)); return Bac_BoxNtkId(p, Bac_BoxBiBox(p, i)); } +static inline int Bac_BoxBoNtkId( Bac_Ntk_t * p, int i ) { assert(Bac_ObjIsBo(p, i)); return Bac_BoxNtkId(p, Bac_BoxBoBox(p, i)); } +static inline Bac_Ntk_t * Bac_BoxNtk( Bac_Ntk_t * p, int i ) { return Bac_ManNtk( p->pDesign, Bac_BoxNtkId(p, i) ); } +//static inline Bac_Ntk_t * Bac_BoxBiNtk( Bac_Ntk_t * p, int i ) { return Bac_ManNtk( p->pDesign, Bac_BoxBiNtkId(p, i) ); } +static inline Bac_Ntk_t * Bac_BoxBoNtk( Bac_Ntk_t * p, int i ) { return Bac_ManNtk( p->pDesign, Bac_BoxBoNtkId(p, i) ); } +static inline char * Bac_BoxNtkName( Bac_Ntk_t * p, int i ) { return Abc_NamStr( p->pDesign->pMods, Bac_BoxNtkId(p, i) ); } + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +#define Bac_ManForEachNtk( p, pNtk, i ) \ + for ( i = 1; (i <= Bac_ManNtkNum(p)) && (((pNtk) = Bac_ManNtk(p, i)), 1); i++ ) + +#define Bac_NtkForEachPi( p, iObj, i ) \ + for ( i = 0; (i < Bac_NtkPiNum(p)) && (((iObj) = Bac_NtkPi(p, i)), 1); i++ ) +#define Bac_NtkForEachPo( p, iObj, i ) \ + for ( i = 0; (i < Bac_NtkPoNum(p)) && (((iObj) = Bac_NtkPo(p, i)), 1); i++ ) +#define Bac_NtkForEachPoDriver( p, iObj, i ) \ + for ( i = 0; (i < Bac_NtkPoNum(p)) && (((iObj) = Bac_ObjFanin(p, Bac_NtkPo(p, i))), 1); i++ ) + +#define Bac_NtkForEachPiMain( p, iObj, i ) \ + for ( i = 0; (i < Bac_NtkPiNum(p)) && (((iObj) = Bac_NtkPi(p, i)), 1); i++ ) if ( Bac_ObjBit(p, iObj) ) {} else +#define Bac_NtkForEachPoMain( p, iObj, i ) \ + for ( i = 0; (i < Bac_NtkPoNum(p)) && (((iObj) = Bac_NtkPo(p, i)), 1); i++ ) if ( Bac_ObjBit(p, iObj) ) {} else + +#define Bac_NtkForEachObj( p, i ) if ( !Bac_ObjType(p, i) ) {} else \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) +#define Bac_NtkForEachObjType( p, Type, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)) && (((Type) = Bac_ObjType(p, i)), 1); i++ ) if ( !Type ) {} else + +#define Bac_NtkForEachBox( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsBox(p, i) ) {} else +#define Bac_NtkForEachBoxUser( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsBoxUser(p, i) ) {} else +#define Bac_NtkForEachBoxPrim( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsBoxPrim(p, i) ) {} else + +#define Bac_NtkForEachCi( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsCi(p, i) ) {} else +#define Bac_NtkForEachCo( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsCo(p, i) ) {} else +#define Bac_NtkForEachCio( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsCio(p, i) ){} else + +#define Bac_NtkForEachBi( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsBi(p, i) ){} else +#define Bac_NtkForEachBo( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsBo(p, i) ){} else +#define Bac_NtkForEachBio( p, i ) \ + for ( i = 0; (i < Bac_NtkObjNum(p)); i++ ) if ( !Bac_ObjIsBio(p, i) ){} else + +#define Bac_BoxForEachBi( p, iBox, iTerm, i ) \ + for ( iTerm = iBox - 1, i = 0; iTerm >= 0 && Bac_ObjIsBi(p, iTerm); iTerm--, i++ ) +#define Bac_BoxForEachBo( p, iBox, iTerm, i ) \ + for ( iTerm = iBox + 1, i = 0; iTerm < Bac_NtkObjNum(p) && Bac_ObjIsBo(p, iTerm); iTerm++, i++ ) +#define Bac_BoxForEachBiReverse( p, iBox, iTerm, i ) \ + for ( i = Bac_BoxBiNum(p, iBox), iTerm = iBox - i--; Bac_ObjIsBi(p, iTerm); iTerm++, i-- ) + +#define Bac_BoxForEachBiMain( p, iBox, iTerm, i ) \ + for ( iTerm = iBox - 1, i = 0; iTerm >= 0 && Bac_ObjIsBi(p, iTerm); iTerm--, i++ ) if ( Bac_ObjBit(p, iTerm) ) {} else +#define Bac_BoxForEachBoMain( p, iBox, iTerm, i ) \ + for ( iTerm = iBox + 1, i = 0; iTerm < Bac_NtkObjNum(p) && Bac_ObjIsBo(p, iTerm); iTerm++, i++ ) if ( Bac_ObjBit(p, iTerm) ) {} else + +#define Bac_BoxForEachFanin( p, iBox, iFanin, i ) \ + for ( i = 0; iBox - 1 - i >= 0 && Bac_ObjIsBi(p, iBox - 1 - i) && (((iFanin) = Bac_BoxFanin(p, iBox, i)), 1); i++ ) +#define Bac_BoxForEachFaninBox( p, iBox, iFanin, i ) \ + for ( i = 0; iBox - 1 - i >= 0 && Bac_ObjIsBi(p, iBox - 1 - i) && (((iFanin) = Bac_BoxFaninBox(p, iBox, i)), 1); i++ ) + +#define Bac_ObjForEachFanout( p, iCi, iCo ) \ + for ( iCo = Bac_ObjFanout(p, iCi); iCo; iCo = Bac_ObjNextFanout(p, iCo) ) +#define Bac_BoxForEachFanoutBox( p, iBox, iCo, iFanBox ) \ + for ( assert(Bac_BoxBoNum(p, iBox) == 1), iCo = Bac_ObjFanout(p, Bac_BoxBo(p, iBox, 0)); iCo && ((iFanBox = Bac_BoxBiBox(p, iCo)), 1); iCo = Bac_ObjNextFanout(p, iCo) ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Object APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Bac_ObjAlloc( Bac_Ntk_t * p, Bac_ObjType_t Type, int Fanin ) +{ + int iObj = Bac_NtkObjNum(p); + assert( iObj == Vec_IntSize(&p->vFanin) ); + if ( Type == BAC_OBJ_PI ) + Vec_IntPush( &p->vInputs, iObj ); + else if ( Type == BAC_OBJ_PO ) + Vec_IntPush( &p->vOutputs, iObj ); + Vec_StrPush( &p->vType, (char)Abc_Var2Lit(Type, 0) ); + Vec_IntPush( &p->vFanin, Fanin ); + return iObj; +} +static inline int Bac_ObjDup( Bac_Ntk_t * pNew, Bac_Ntk_t * p, int i ) +{ + int iObj = Bac_ObjAlloc( pNew, Bac_ObjType(p, i), Bac_ObjIsBox(p, i) ? Bac_BoxNtkId(p, i) : -1 ); + if ( Bac_NtkHasNames(p) && Bac_NtkHasNames(pNew) && !Bac_ObjIsCo(p, i) ) + Bac_ObjSetName( pNew, iObj, Bac_ObjName(p, i) ); + Bac_ObjSetCopy( p, i, iObj ); + return iObj; +} +static inline int Bac_BoxAlloc( Bac_Ntk_t * p, Bac_ObjType_t Type, int nIns, int nOuts, int iNtk ) +{ + int i, iObj; + for ( i = nIns - 1; i >= 0; i-- ) + Bac_ObjAlloc( p, BAC_OBJ_BI, -1 ); + iObj = Bac_ObjAlloc( p, Type, iNtk ); + for ( i = 0; i < nOuts; i++ ) + Bac_ObjAlloc( p, BAC_OBJ_BO, -1 ); + return iObj; +} +static inline int Bac_BoxDup( Bac_Ntk_t * pNew, Bac_Ntk_t * p, int iBox ) +{ + int i, iTerm, iBoxNew; + Bac_BoxForEachBiReverse( p, iBox, iTerm, i ) + Bac_ObjDup( pNew, p, iTerm ); + iBoxNew = Bac_ObjDup( pNew, p, iBox ); + if ( Bac_NtkHasNames(p) && Bac_NtkHasNames(pNew) && Bac_ObjName(p, iBox) ) + Bac_ObjSetName( pNew, iBoxNew, Bac_ObjName(p, iBox) ); + if ( Bac_BoxNtk(p, iBox) ) + Bac_BoxSetNtkId( pNew, iBoxNew, Bac_NtkCopy(Bac_BoxNtk(p, iBox)) ); + Bac_BoxForEachBo( p, iBox, iTerm, i ) + Bac_ObjDup( pNew, p, iTerm ); + return iBoxNew; +} +static inline void Bac_BoxDelete( Bac_Ntk_t * p, int iBox ) +{ + int iStart = iBox - Bac_BoxBiNum(p, iBox); + int i, iStop = iBox + Bac_BoxBoNum(p, iBox); + for ( i = iStart; i <= iStop; i++ ) + { + Vec_StrWriteEntry( &p->vType, i, (char)0 ); + Vec_IntWriteEntry( &p->vFanin, i, -1 ); + if ( Bac_NtkHasNames(p) ) + Vec_IntWriteEntry( &p->vName, i, 0 ); + if ( Bac_NtkHasFanouts(p) ) + Vec_IntWriteEntry( &p->vFanout, i, 0 ); + } +} +static inline void Bac_BoxReplace( Bac_Ntk_t * p, int iBox, int * pArray, int nSize ) +{ + extern void Bac_NtkUpdateFanout( Bac_Ntk_t * p, int iOld, int iNew ); + int i, Limit = Bac_BoxBoNum(p, iBox); + assert( Limit == nSize ); + for ( i = 0; i < Limit; i++ ) + Bac_NtkUpdateFanout( p, Bac_BoxBo(p, iBox, i), pArray[i] ); +} + + +static inline Vec_Int_t * Bac_BoxCollectRanges( Bac_Ntk_t * p, int iBox ) +{ + static Vec_Int_t Bits, * vBits = &Bits; + static int pArray[10]; int i, iTerm; + assert( !Bac_ObjIsBoxUser(p, iBox) ); + // initialize array + vBits->pArray = pArray; + vBits->nSize = 0; + vBits->nCap = 10; + // iterate through inputs + Bac_BoxForEachBiMain( p, iBox, iTerm, i ) + Vec_IntPush( vBits, Bac_BoxBiRange(p, iTerm) ); + // iterate through outputs + Bac_BoxForEachBoMain( p, iBox, iTerm, i ) + Vec_IntPush( vBits, Bac_BoxBoRange(p, iTerm) ); + assert( Vec_IntSize(vBits) < 10 ); + //Vec_IntPrint( vBits ); + return vBits; +} + +/**Function************************************************************* + + Synopsis [Prints vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_StrPrint( Vec_Str_t * p, int fInt ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( fInt ) + printf( "%d ", (int)p->pArray[i] ); + else + printf( "%c ", p->pArray[i] ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Network APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Bac_NtkAlloc( Bac_Ntk_t * pNew, int NameId, int nIns, int nOuts, int nObjs ) +{ + int NtkId, fFound; + assert( pNew->pDesign != NULL ); + assert( Bac_NtkPiNum(pNew) == 0 ); + assert( Bac_NtkPoNum(pNew) == 0 ); + pNew->NameId = NameId; + pNew->iCopy = -1; + pNew->iBoxNtk = -1; + pNew->iBoxObj = -1; + Vec_IntGrow( &pNew->vInputs, nIns ); + Vec_IntGrow( &pNew->vOutputs, nOuts ); + Vec_StrGrow( &pNew->vType, nObjs ); + Vec_IntGrow( &pNew->vFanin, nObjs ); + // check if the network is unique + NtkId = Abc_NamStrFindOrAdd( pNew->pDesign->pMods, Bac_NtkStr(pNew, NameId), &fFound ); + if ( fFound ) + printf( "Network with name %s already exists.\n", Bac_NtkStr(pNew, NameId) ); + else + assert( NtkId == Bac_NtkId(pNew) ); +} +static inline void Bac_NtkDup( Bac_Ntk_t * pNew, Bac_Ntk_t * p ) +{ + int i, iObj; + assert( pNew != p ); + Bac_NtkAlloc( pNew, Bac_NtkNameId(p), Bac_NtkPiNum(p), Bac_NtkPoNum(p), Bac_NtkObjNum(p) ); + if ( Vec_IntSize(&p->vInfo) ) + Vec_IntAppend( &pNew->vInfo, &p->vInfo ); + Bac_NtkStartCopies( p ); + if ( Bac_NtkHasNames(p) ) + Bac_NtkStartNames( pNew ); + Bac_NtkForEachPi( p, iObj, i ) + Bac_ObjDup( pNew, p, iObj ); + Bac_NtkForEachBox( p, iObj ) + Bac_BoxDup( pNew, p, iObj ); + Bac_NtkForEachPo( p, iObj, i ) + Bac_ObjDup( pNew, p, iObj ); + Bac_NtkForEachCo( p, iObj ) + Bac_ObjSetFanin( pNew, Bac_ObjCopy(p, iObj), Bac_ObjCopy(p, Bac_ObjFanin(p, iObj)) ); + //Bac_NtkFreeCopies( p ); // needed for name transfer and host ntk + assert( Bac_NtkObjNum(pNew) == Bac_NtkObjNumAlloc(pNew) ); +} +static inline void Bac_NtkDupUserBoxes( Bac_Ntk_t * pNew, Bac_Ntk_t * p ) +{ + int i, iObj; + assert( pNew != p ); + Bac_NtkAlloc( pNew, Bac_NtkNameId(p), Bac_NtkPiNum(p), Bac_NtkPoNum(p), Bac_NtkObjNum(p) + 3*Bac_NtkCoNum(p) ); + if ( Vec_IntSize(&p->vInfo) ) + Vec_IntAppend( &pNew->vInfo, &p->vInfo ); + Bac_NtkStartCopies( p ); + Bac_NtkForEachPi( p, iObj, i ) + Bac_ObjDup( pNew, p, iObj ); + Bac_NtkForEachPo( p, iObj, i ) + Bac_ObjDup( pNew, p, iObj ); + Bac_NtkForEachBoxUser( p, iObj ) + Bac_BoxDup( pNew, p, iObj ); + // connect feed-throughs + Bac_NtkForEachCo( p, iObj ) + if ( Bac_ObjCopy(p, iObj) >= 0 && Bac_ObjCopy(p, Bac_ObjFanin(p, iObj)) >= 0 ) + Bac_ObjSetFanin( pNew, Bac_ObjCopy(p, iObj), Bac_ObjCopy(p, Bac_ObjFanin(p, iObj)) ); +} +static inline void Bac_NtkMoveNames( Bac_Ntk_t * pNew, Bac_Ntk_t * p ) +{ + int i, iBox, iObj; + assert( Bac_NtkHasNames(p) ); + assert( !Bac_NtkHasNames(pNew) ); + Bac_NtkStartNames( pNew ); + Bac_NtkForEachPi( p, iObj, i ) + Bac_ObjSetName( pNew, Bac_ObjCopy(p, iObj), Bac_ObjName(p, iObj) ); + Bac_NtkForEachBoxUser( p, iBox ) + { + Bac_ObjSetName( pNew, Bac_ObjCopy(p, iBox), Bac_ObjName(p, iBox) ); + Bac_BoxForEachBo( p, iBox, iObj, i ) + Bac_ObjSetName( pNew, Bac_ObjCopy(p, iObj), Bac_ObjName(p, iObj) ); + } + Bac_NtkForEachBoxUser( p, iBox ) + Bac_BoxForEachBi( p, iBox, iObj, i ) + if ( !Bac_ObjName(pNew, Bac_ObjFanin(pNew, Bac_ObjCopy(p, iObj))) ) + Bac_ObjSetName( pNew, Bac_ObjFanin(pNew, Bac_ObjCopy(p, iObj)), Bac_ObjName(p, iObj) ); + Bac_NtkForEachPo( p, iObj, i ) + if ( !Bac_ObjName(pNew, Bac_ObjFanin(pNew, Bac_ObjCopy(p, iObj))) ) + Bac_ObjSetName( pNew, Bac_ObjFanin(pNew, Bac_ObjCopy(p, iObj)), Bac_ObjName(p, iObj) ); +} + +static inline void Bac_NtkFree( Bac_Ntk_t * p ) +{ + Vec_IntErase( &p->vInputs ); + Vec_IntErase( &p->vOutputs ); + Vec_IntErase( &p->vInfo ); + Vec_StrErase( &p->vType ); + Vec_IntErase( &p->vFanin ); + Vec_IntErase( &p->vIndex ); + Vec_IntErase( &p->vName ); + Vec_IntErase( &p->vFanout ); + Vec_IntErase( &p->vCopy ); + Vec_IntErase( &p->vArray ); + Vec_IntErase( &p->vArray2 ); +} +static inline int Bac_NtkMemory( Bac_Ntk_t * p ) +{ + int nMem = sizeof(Bac_Ntk_t); + nMem += (int)Vec_IntMemory(&p->vInputs); + nMem += (int)Vec_IntMemory(&p->vOutputs); + nMem += (int)Vec_IntMemory(&p->vInfo); + nMem += (int)Vec_StrMemory(&p->vType); + nMem += (int)Vec_IntMemory(&p->vFanin); + nMem += (int)Vec_IntMemory(&p->vIndex); + nMem += (int)Vec_IntMemory(&p->vName); + nMem += (int)Vec_IntMemory(&p->vFanout); + nMem += (int)Vec_IntMemory(&p->vCopy); + return nMem; +} +static inline void Bac_NtkPrintStats( Bac_Ntk_t * p ) +{ + printf( "pi =%5d ", Bac_NtkPiNum(p) ); + printf( "pi =%5d ", Bac_NtkPoNum(p) ); + printf( "box =%6d ", Bac_NtkBoxNum(p) ); + printf( "clp =%7d ", p->Count ); + printf( "obj =%7d ", Bac_NtkObjNum(p) ); + printf( "%s ", Bac_NtkName(p) ); + if ( Bac_NtkHostNtk(p) > 0 ) + printf( "-> %s", Bac_NtkName(Bac_NtkHostNtk(p)) ); + printf( "\n" ); +} +static inline void Bac_NtkDeriveIndex( Bac_Ntk_t * p ) +{ + int i, iObj, iTerm; + Vec_IntFill( &p->vIndex, Bac_NtkObjNum(p), -1 ); + Bac_NtkForEachPi( p, iObj, i ) + Bac_ObjSetIndex( p, iObj, i ); + Bac_NtkForEachPo( p, iObj, i ) + Bac_ObjSetIndex( p, iObj, i ); + Bac_NtkForEachBox( p, iObj ) + { + Bac_BoxForEachBi( p, iObj, iTerm, i ) + Bac_ObjSetIndex( p, iTerm, i ); + Bac_BoxForEachBo( p, iObj, iTerm, i ) + Bac_ObjSetIndex( p, iTerm, i ); + } +} +static inline void Bac_NtkPrint( Bac_Ntk_t * p ) +{ + int i, Type, Value, Beg, End; + printf( "Interface (%d):\n", Bac_NtkInfoNum(p) ); + Vec_IntForEachEntryTriple( &p->vInfo, Value, Beg, End, i ) + { + printf( "%6d : ", i ); + printf( "Type =%3d ", Bac_NtkInfoType(p, i/3) ); + if ( Beg >= 0 ) + printf( "[%d:%d] ", End, Beg ); + else + printf( " " ); + printf( "Name =%3d ", Bac_NtkInfoName(p, i/3) ); + if ( Bac_NtkInfoName(p, i/3) ) + printf( "%s", Bac_NtkStr( p, Bac_NtkInfoName(p, i/3) ) ); + printf( "\n" ); + } + printf( "Objects (%d):\n", Bac_NtkObjNum(p) ); + Bac_NtkForEachObjType( p, Type, i ) + { + printf( "%6d : ", i ); + printf( "Type =%3d ", Type ); + if ( Bac_ObjIsCo(p, i) ) + printf( "Fanin =%6d ", Bac_ObjFanin(p, i) ); + else if ( Bac_NtkHasNames(p) && Bac_ObjName(p, i) ) + { + printf( "Name =%6d(%d) ", Bac_ObjNameId(p, i), Bac_ObjNameType(p, i) ); + if ( Bac_ObjNameType(p, i) <= BAC_NAME_WORD ) + printf( "%s", Bac_ObjNameStr(p, i) ); + } + printf( "\n" ); + } +} + + +/**Function************************************************************* + + Synopsis [Manager APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Bac_Man_t * Bac_ManAlloc( char * pFileName, int nNtks ) +{ + extern void Bac_ManSetupTypes( char ** pNames, char ** pSymbs ); + Bac_Ntk_t * pNtk; int i; + Bac_Man_t * pNew = ABC_CALLOC( Bac_Man_t, 1 ); + pNew->pName = Extra_FileDesignName( pFileName ); + pNew->pSpec = Abc_UtilStrsav( pFileName ); + pNew->pStrs = Abc_NamStart( 1000, 24 ); + pNew->pMods = Abc_NamStart( 1000, 24 ); + pNew->iRoot = 1; + pNew->nNtks = nNtks; + pNew->pNtks = ABC_CALLOC( Bac_Ntk_t, pNew->nNtks + 1 ); + Bac_ManForEachNtk( pNew, pNtk, i ) + pNtk->pDesign = pNew; + Bac_ManSetupTypes( pNew->pPrimNames, pNew->pPrimSymbs ); + return pNew; +} +static inline Bac_Man_t * Bac_ManStart( Bac_Man_t * p, int nNtks ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_Man_t * pNew = ABC_CALLOC( Bac_Man_t, 1 ); + pNew->pName = Abc_UtilStrsav( Bac_ManName(p) ); + pNew->pSpec = Abc_UtilStrsav( Bac_ManSpec(p) ); + pNew->pStrs = Abc_NamRef( p->pStrs ); + pNew->pMods = Abc_NamStart( 1000, 24 ); + pNew->iRoot = 1; + pNew->nNtks = nNtks; + pNew->pNtks = ABC_CALLOC( Bac_Ntk_t, nNtks + 1 ); + Bac_ManForEachNtk( pNew, pNtk, i ) + pNtk->pDesign = pNew; + return pNew; +} +static inline Bac_Man_t * Bac_ManDup( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk, * pHost; int i; + Bac_Man_t * pNew = Bac_ManStart( p, Bac_ManNtkNum(p) ); + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkSetCopy( pNtk, i ); + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkDup( Bac_NtkCopyNtk(pNew, pNtk), pNtk ); + Bac_ManForEachNtk( p, pNtk, i ) + if ( (pHost = Bac_NtkHostNtk(pNtk)) ) + Bac_NtkSetHost( Bac_NtkCopyNtk(pNew, pNtk), Bac_NtkCopy(pHost), Bac_ObjCopy(pHost, Bac_NtkHostObj(pNtk)) ); + return pNew; +} +static inline Bac_Man_t * Bac_ManDupUserBoxes( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk, * pHost; int i; + Bac_Man_t * pNew = Bac_ManStart( p, Bac_ManNtkNum(p) ); + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkSetCopy( pNtk, i ); + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkDupUserBoxes( Bac_NtkCopyNtk(pNew, pNtk), pNtk ); + Bac_ManForEachNtk( p, pNtk, i ) + if ( (pHost = Bac_NtkHostNtk(pNtk)) ) + Bac_NtkSetHost( Bac_NtkCopyNtk(pNew, pNtk), Bac_NtkCopy(pHost), Bac_ObjCopy(pHost, Bac_NtkHostObj(pNtk)) ); + return pNew; +} +static inline void Bac_ManMoveNames( Bac_Man_t * pNew, Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkMoveNames( Bac_NtkCopyNtk(pNew, pNtk), pNtk ); +} + + +static inline void Bac_ManFree( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkFree( pNtk ); + Vec_IntErase( &p->vBuf2LeafNtk ); + Vec_IntErase( &p->vBuf2LeafObj ); + Vec_IntErase( &p->vBuf2RootNtk ); + Vec_IntErase( &p->vBuf2RootObj ); + Abc_NamDeref( p->pStrs ); + Abc_NamDeref( p->pMods ); + ABC_FREE( p->pName ); + ABC_FREE( p->pSpec ); + ABC_FREE( p->pNtks ); + ABC_FREE( p ); +} +static inline int Bac_ManMemory( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i; + int nMem = sizeof(Bac_Man_t); + if ( p->pName ) + nMem += (int)strlen(p->pName); + if ( p->pSpec ) + nMem += (int)strlen(p->pSpec); + nMem += Abc_NamMemUsed(p->pStrs); + nMem += Abc_NamMemUsed(p->pMods); + Bac_ManForEachNtk( p, pNtk, i ) + nMem += Bac_NtkMemory( pNtk ); + return nMem; +} +static inline int Bac_ManObjNum( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i, Count = 0; + Bac_ManForEachNtk( p, pNtk, i ) + Count += Bac_NtkObjNum(pNtk); + return Count; +} +static inline int Bac_ManNodeNum( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i, Count = 0; + Bac_ManForEachNtk( p, pNtk, i ) + Count += Bac_NtkBoxNum( pNtk ); + return Count; +} +static inline int Bac_ManBoxNum_rec( Bac_Ntk_t * p ) +{ + int iObj, Counter = 0; + if ( p->Count >= 0 ) + return p->Count; + Bac_NtkForEachBox( p, iObj ) + Counter += Bac_ObjIsBoxUser(p, iObj) ? Bac_ManBoxNum_rec( Bac_BoxNtk(p, iObj) ) : 1; + return (p->Count = Counter); +} +static inline int Bac_ManBoxNum( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( p, pNtk, i ) + pNtk->Count = -1; + return Bac_ManBoxNum_rec( Bac_ManRoot(p) ); +} +static inline void Bac_ManPrintStats( Bac_Man_t * p, int nModules, int fVerbose ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_Ntk_t * pRoot = Bac_ManRoot( p ); + printf( "%-12s : ", Bac_ManName(p) ); + printf( "pi =%5d ", Bac_NtkPiNum(pRoot) ); + printf( "po =%5d ", Bac_NtkPoNum(pRoot) ); + printf( "pri =%4d ", Bac_ManPrimNum(p) ); + printf( "mod =%6d ", Bac_ManNtkNum(p) ); + printf( "box =%7d ", Bac_ManNodeNum(p) ); + printf( "obj =%7d ", Bac_ManObjNum(p) ); + printf( "mem =%6.3f MB", 1.0*Bac_ManMemory(p)/(1<<20) ); + printf( "\n" ); + Bac_ManBoxNum( p ); + Bac_ManForEachNtk( p, pNtk, i ) + { + if ( i == nModules+1 ) + break; + printf( "Module %5d : ", i ); + Bac_NtkPrintStats( pNtk ); + } +} + + + +/**Function************************************************************* + + Synopsis [Other APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Bac_ObjType_t Ptr_SopToType( char * pSop ) +{ + if ( !strcmp(pSop, " 0\n") ) return BAC_BOX_CF; + if ( !strcmp(pSop, " 1\n") ) return BAC_BOX_CT; + if ( !strcmp(pSop, "1 1\n") ) return BAC_BOX_BUF; + if ( !strcmp(pSop, "0 1\n") ) return BAC_BOX_INV; + if ( !strcmp(pSop, "11 1\n") ) return BAC_BOX_AND; + if ( !strcmp(pSop, "00 1\n") ) return BAC_BOX_NOR; + if ( !strcmp(pSop, "00 0\n") ) return BAC_BOX_OR; + if ( !strcmp(pSop, "-1 1\n1- 1\n") ) return BAC_BOX_OR; + if ( !strcmp(pSop, "1- 1\n-1 1\n") ) return BAC_BOX_OR; + if ( !strcmp(pSop, "01 1\n10 1\n") ) return BAC_BOX_XOR; + if ( !strcmp(pSop, "10 1\n01 1\n") ) return BAC_BOX_XOR; + if ( !strcmp(pSop, "11 1\n00 1\n") ) return BAC_BOX_XNOR; + if ( !strcmp(pSop, "00 1\n11 1\n") ) return BAC_BOX_XNOR; + if ( !strcmp(pSop, "10 1\n") ) return BAC_BOX_SHARP; + if ( !strcmp(pSop, "01 1\n") ) return BAC_BOX_SHARPL; + assert( 0 ); + return BAC_OBJ_NONE; +} +static inline char * Ptr_SopToTypeName( char * pSop ) +{ + if ( !strcmp(pSop, " 0\n") ) return "BAC_BOX_C0"; + if ( !strcmp(pSop, " 1\n") ) return "BAC_BOX_C1"; + if ( !strcmp(pSop, "1 1\n") ) return "BAC_BOX_BUF"; + if ( !strcmp(pSop, "0 1\n") ) return "BAC_BOX_INV"; + if ( !strcmp(pSop, "11 1\n") ) return "BAC_BOX_AND"; + if ( !strcmp(pSop, "00 1\n") ) return "BAC_BOX_NOR"; + if ( !strcmp(pSop, "00 0\n") ) return "BAC_BOX_OR"; + if ( !strcmp(pSop, "-1 1\n1- 1\n") ) return "BAC_BOX_OR"; + if ( !strcmp(pSop, "1- 1\n-1 1\n") ) return "BAC_BOX_OR"; + if ( !strcmp(pSop, "01 1\n10 1\n") ) return "BAC_BOX_XOR"; + if ( !strcmp(pSop, "10 1\n01 1\n") ) return "BAC_BOX_XOR"; + if ( !strcmp(pSop, "11 1\n00 1\n") ) return "BAC_BOX_XNOR"; + if ( !strcmp(pSop, "00 1\n11 1\n") ) return "BAC_BOX_XNOR"; + if ( !strcmp(pSop, "10 1\n") ) return "BAC_BOX_SHARP"; + if ( !strcmp(pSop, "01 1\n") ) return "BAC_BOX_SHARPL"; + assert( 0 ); + return NULL; +} +static inline char * Ptr_TypeToName( Bac_ObjType_t Type ) +{ + if ( Type == BAC_BOX_CF ) return "const0"; + if ( Type == BAC_BOX_CT ) return "const1"; + if ( Type == BAC_BOX_CX ) return "constX"; + if ( Type == BAC_BOX_CZ ) return "constZ"; + if ( Type == BAC_BOX_BUF ) return "buf"; + if ( Type == BAC_BOX_INV ) return "not"; + if ( Type == BAC_BOX_AND ) return "and"; + if ( Type == BAC_BOX_NAND ) return "nand"; + if ( Type == BAC_BOX_OR ) return "or"; + if ( Type == BAC_BOX_NOR ) return "nor"; + if ( Type == BAC_BOX_XOR ) return "xor"; + if ( Type == BAC_BOX_XNOR ) return "xnor"; + if ( Type == BAC_BOX_MUX ) return "mux"; + if ( Type == BAC_BOX_MAJ ) return "maj"; + if ( Type == BAC_BOX_SHARP ) return "sharp"; + if ( Type == BAC_BOX_SHARPL) return "sharpl"; + assert( 0 ); + return "???"; +} +static inline char * Ptr_TypeToSop( Bac_ObjType_t Type ) +{ + if ( Type == BAC_BOX_CF ) return " 0\n"; + if ( Type == BAC_BOX_CT ) return " 1\n"; + if ( Type == BAC_BOX_CX ) return " 0\n"; + if ( Type == BAC_BOX_CZ ) return " 0\n"; + if ( Type == BAC_BOX_BUF ) return "1 1\n"; + if ( Type == BAC_BOX_INV ) return "0 1\n"; + if ( Type == BAC_BOX_AND ) return "11 1\n"; + if ( Type == BAC_BOX_NAND ) return "11 0\n"; + if ( Type == BAC_BOX_OR ) return "00 0\n"; + if ( Type == BAC_BOX_NOR ) return "00 1\n"; + if ( Type == BAC_BOX_XOR ) return "01 1\n10 1\n"; + if ( Type == BAC_BOX_XNOR ) return "00 1\n11 1\n"; + if ( Type == BAC_BOX_SHARP ) return "10 1\n"; + if ( Type == BAC_BOX_SHARPL) return "01 1\n"; + if ( Type == BAC_BOX_MUX ) return "11- 1\n0-1 1\n"; + if ( Type == BAC_BOX_MAJ ) return "11- 1\n1-1 1\n-11 1\n"; + assert( 0 ); + return "???"; +} + +/*=== bacCom.c ===============================================================*/ +extern void Abc_FrameImportPtr( Vec_Ptr_t * vPtr ); +extern Vec_Ptr_t * Abc_FrameExportPtr(); + +/*=== bacBlast.c =============================================================*/ +extern int Bac_NtkBuildLibrary( Bac_Man_t * p ); +extern Gia_Man_t * Bac_ManExtract( Bac_Man_t * p, int fBuffers, int fVerbose ); +extern Bac_Man_t * Bac_ManInsertGia( Bac_Man_t * p, Gia_Man_t * pGia ); +extern void * Bac_ManInsertAbc( Bac_Man_t * p, void * pAbc ); +/*=== bacCba.c ===============================================================*/ +extern Bac_Man_t * Bac_ManReadBac( char * pFileName ); +extern void Bac_ManWriteBac( char * pFileName, Bac_Man_t * p ); +/*=== bacNtk.c ===============================================================*/ +extern char * Bac_NtkGenerateName( Bac_Ntk_t * p, Bac_ObjType_t Type, Vec_Int_t * vBits ); +extern Bac_ObjType_t Bac_NameToType( char * pName ); +extern Vec_Int_t * Bac_NameToRanges( char * pName ); +extern void Bac_NtkUpdateFanout( Bac_Ntk_t * p, int iOld, int iNew ); +extern void Bac_ManDeriveFanout( Bac_Man_t * p ); +//extern void Bac_ManAssignInternNames( Bac_Man_t * p ); +extern void Bac_ManAssignInternWordNames( Bac_Man_t * p ); +extern Bac_Man_t * Bac_ManCollapse( Bac_Man_t * p ); +extern void Bac_ManSetupTypes( char ** pNames, char ** pSymbs ); +/*=== bacPtr.c ===============================================================*/ +extern void Bac_PtrFree( Vec_Ptr_t * vDes ); +extern int Bac_PtrMemory( Vec_Ptr_t * vDes ); +extern void Bac_PtrDumpBlif( char * pFileName, Vec_Ptr_t * vDes ); +extern void Bac_PtrDumpVerilog( char * pFileName, Vec_Ptr_t * vDes ); +extern Vec_Ptr_t * Bac_PtrTransformTest( Vec_Ptr_t * vDes ); +/*=== bacPtrAbc.c ============================================================*/ +extern Bac_Man_t * Bac_PtrTransformToCba( Vec_Ptr_t * vDes ); +extern Vec_Ptr_t * Bac_PtrDeriveFromCba( Bac_Man_t * p ); +/*=== bacPrsBuild.c ==========================================================*/ +extern Bac_Man_t * Psr_ManBuildCba( char * pFileName, Vec_Ptr_t * vDes ); +/*=== bacReadBlif.c ==========================================================*/ +extern Vec_Ptr_t * Psr_ManReadBlif( char * pFileName ); +/*=== bacReadSmt.c ===========================================================*/ +extern Vec_Ptr_t * Psr_ManReadSmt( char * pFileName ); +/*=== bacReadVer.c ===========================================================*/ +extern Vec_Ptr_t * Psr_ManReadVerilog( char * pFileName ); +/*=== bacWriteBlif.c =========================================================*/ +extern void Psr_ManWriteBlif( char * pFileName, Vec_Ptr_t * p ); +extern void Bac_ManWriteBlif( char * pFileName, Bac_Man_t * p ); +/*=== bacWriteVer.c ==========================================================*/ +extern void Psr_ManWriteVerilog( char * pFileName, Vec_Ptr_t * p ); +extern void Bac_ManWriteVerilog( char * pFileName, Bac_Man_t * p, int fUseAssign ); + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/bac/bacBac.c b/src/base/bac/bacBac.c new file mode 100644 index 00000000..4f2971a5 --- /dev/null +++ b/src/base/bac/bacBac.c @@ -0,0 +1,298 @@ +/**CFile**************************************************************** + + FileName [bacBac.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Verilog parser.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacBac.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Read CBA.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int BacManReadBacLine( Vec_Str_t * vOut, int * pPos, char * pBuffer, char * pLimit ) +{ + char c; + while ( (c = Vec_StrEntry(vOut, (*pPos)++)) != '\n' && pBuffer < pLimit ) + *pBuffer++ = c; + *pBuffer = 0; + return pBuffer < pLimit; +} +int BacManReadBacNameAndNums( char * pBuffer, int * Num1, int * Num2, int * Num3, int * Num4 ) +{ + *Num1 = *Num2 = *Num3 = *Num4 = -1; + // read name + while ( *pBuffer && *pBuffer != ' ' ) + pBuffer++; + if ( !*pBuffer ) + return 0; + assert( *pBuffer == ' ' ); + *pBuffer = 0; + // read Num1 + *Num1 = atoi(++pBuffer); + while ( *pBuffer && *pBuffer != ' ' ) + pBuffer++; + if ( !*pBuffer ) + return 0; + // read Num2 + assert( *pBuffer == ' ' ); + *Num2 = atoi(++pBuffer); + while ( *pBuffer && *pBuffer != ' ' ) + pBuffer++; + if ( !*pBuffer ) + return 1; + // read Num3 + assert( *pBuffer == ' ' ); + *Num3 = atoi(++pBuffer); + while ( *pBuffer && *pBuffer != ' ' ) + pBuffer++; + if ( !*pBuffer ) + return 1; + // read Num4 + assert( *pBuffer == ' ' ); + *Num4 = atoi(++pBuffer); + return 1; +} +void Bac_ManReadBacVecStr( Vec_Str_t * vOut, int * pPos, Vec_Str_t * p, int nSize ) +{ + memcpy( Vec_StrArray(p), Vec_StrArray(vOut) + *pPos, nSize ); + *pPos += nSize; + p->nSize = nSize; + assert( Vec_StrSize(p) == Vec_StrCap(p) ); +} +void Bac_ManReadBacVecInt( Vec_Str_t * vOut, int * pPos, Vec_Int_t * p, int nSize ) +{ + memcpy( Vec_IntArray(p), Vec_StrArray(vOut) + *pPos, nSize ); + *pPos += nSize; + p->nSize = nSize / 4; + assert( Vec_IntSize(p) == Vec_IntCap(p) ); +} +void Bac_ManReadBacNtk( Vec_Str_t * vOut, int * pPos, Bac_Ntk_t * pNtk ) +{ + int i, Type; + //char * pName; int iObj, NameId; + Bac_ManReadBacVecStr( vOut, pPos, &pNtk->vType, Bac_NtkObjNumAlloc(pNtk) ); + Bac_ManReadBacVecInt( vOut, pPos, &pNtk->vFanin, 4 * Bac_NtkObjNumAlloc(pNtk) ); + Bac_ManReadBacVecInt( vOut, pPos, &pNtk->vInfo, 12 * Bac_NtkInfoNumAlloc(pNtk) ); + Bac_NtkForEachObjType( pNtk, Type, i ) + { + if ( Type == BAC_OBJ_PI ) + Vec_IntPush( &pNtk->vInputs, i ); + if ( Type == BAC_OBJ_PO ) + Vec_IntPush( &pNtk->vOutputs, i ); + } + assert( Bac_NtkPiNum(pNtk) == Bac_NtkPiNumAlloc(pNtk) ); + assert( Bac_NtkPoNum(pNtk) == Bac_NtkPoNumAlloc(pNtk) ); + assert( Bac_NtkObjNum(pNtk) == Bac_NtkObjNumAlloc(pNtk) ); + assert( Bac_NtkInfoNum(pNtk) == Bac_NtkInfoNumAlloc(pNtk) ); +/* + // read input/output/box names + Bac_NtkForEachPiMain( pNtk, iObj, i ) + { + pName = Vec_StrEntryP( vOut, Pos ); + NameId = Abc_NamStrFindOrAdd( p->pStrs, pName, NULL ); + Pos += strlen(pName) + 1; + } + Bac_NtkForEachPoMain( pNtk, iObj, i ) + { + pName = Vec_StrEntryP( vOut, Pos ); + NameId = Abc_NamStrFindOrAdd( p->pStrs, pName, NULL ); + Pos += strlen(pName) + 1; + } + Bac_NtkForEachBox( pNtk, iObj ) + { + pName = Vec_StrEntryP( vOut, Pos ); + NameId = Abc_NamStrFindOrAdd( p->pStrs, pName, NULL ); + Pos += strlen(pName) + 1; + } +*/ +} +Bac_Man_t * Bac_ManReadBacInt( Vec_Str_t * vOut ) +{ + Bac_Man_t * p; + Bac_Ntk_t * pNtk; + char Buffer[1000] = "#"; + int i, NameId, Pos = 0, nNtks, Num1, Num2, Num3, Num4; + while ( Buffer[0] == '#' ) + if ( !BacManReadBacLine(vOut, &Pos, Buffer, Buffer+1000) ) + return NULL; + if ( !BacManReadBacNameAndNums(Buffer, &nNtks, &Num2, &Num3, &Num4) ) + return NULL; + // start manager + assert( nNtks > 0 ); + p = Bac_ManAlloc( Buffer, nNtks ); + // start networks + Bac_ManForEachNtk( p, pNtk, i ) + { + if ( !BacManReadBacLine(vOut, &Pos, Buffer, Buffer+1000) ) + { + Bac_ManFree( p ); + return NULL; + } + if ( !BacManReadBacNameAndNums(Buffer, &Num1, &Num2, &Num3, &Num4) ) + { + Bac_ManFree( p ); + return NULL; + } + assert( Num1 >= 0 && Num2 >= 0 && Num3 >= 0 ); + NameId = Abc_NamStrFindOrAdd( p->pStrs, Buffer, NULL ); + Bac_NtkAlloc( pNtk, NameId, Num1, Num2, Num3 ); + Vec_IntFill( &pNtk->vInfo, 3 * Num4, -1 ); + } + // read networks + Bac_ManForEachNtk( p, pNtk, i ) + Bac_ManReadBacNtk( vOut, &Pos, pNtk ); + assert( Bac_ManNtkNum(p) == nNtks ); + assert( Pos == Vec_StrSize(vOut) ); + return p; +} +Bac_Man_t * Bac_ManReadBac( char * pFileName ) +{ + Bac_Man_t * p; + FILE * pFile; + Vec_Str_t * vOut; + int nFileSize; + pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + rewind( pFile ); + // load the contents + vOut = Vec_StrAlloc( nFileSize ); + vOut->nSize = vOut->nCap; + assert( nFileSize == Vec_StrSize(vOut) ); + nFileSize = fread( Vec_StrArray(vOut), 1, Vec_StrSize(vOut), pFile ); + assert( nFileSize == Vec_StrSize(vOut) ); + fclose( pFile ); + // read the networks + p = Bac_ManReadBacInt( vOut ); + if ( p != NULL ) + { + ABC_FREE( p->pSpec ); + p->pSpec = Abc_UtilStrsav( pFileName ); + } + Vec_StrFree( vOut ); + return p; +} + +/**Function************************************************************* + + Synopsis [Write CBA.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_ManWriteBacNtk( Vec_Str_t * vOut, Bac_Ntk_t * pNtk ) +{ + //char * pName; int iObj, NameId; + Vec_StrPushBuffer( vOut, (char *)Vec_StrArray(&pNtk->vType), Bac_NtkObjNum(pNtk) ); + Vec_StrPushBuffer( vOut, (char *)Vec_IntArray(&pNtk->vFanin), 4 * Bac_NtkObjNum(pNtk) ); + Vec_StrPushBuffer( vOut, (char *)Vec_IntArray(&pNtk->vInfo), 12 * Bac_NtkInfoNum(pNtk) ); +/* + // write input/output/box names + Bac_NtkForEachPiMain( pNtk, iObj, i ) + { + pName = Bac_ObjNameStr( pNtk, iObj ); + Vec_StrPrintStr( vOut, pName ); + Vec_StrPush( vOut, '\0' ); + } + Bac_NtkForEachPoMain( pNtk, iObj, i ) + { + pName = Bac_ObjNameStr( pNtk, iObj ); + Vec_StrPrintStr( vOut, pName ); + Vec_StrPush( vOut, '\0' ); + } + Bac_NtkForEachBox( pNtk, iObj ) + { + pName = Bac_ObjNameStr( pNtk, iObj ); + Vec_StrPrintStr( vOut, pName ); + Vec_StrPush( vOut, '\0' ); + } +*/ +} +void Bac_ManWriteBacInt( Vec_Str_t * vOut, Bac_Man_t * p ) +{ + char Buffer[1000]; + Bac_Ntk_t * pNtk; int i; + sprintf( Buffer, "# Design \"%s\" written by ABC on %s\n", Bac_ManName(p), Extra_TimeStamp() ); + Vec_StrPrintStr( vOut, Buffer ); + // write short info + sprintf( Buffer, "%s %d \n", Bac_ManName(p), Bac_ManNtkNum(p) ); + Vec_StrPrintStr( vOut, Buffer ); + Bac_ManForEachNtk( p, pNtk, i ) + { + sprintf( Buffer, "%s %d %d %d %d \n", Bac_NtkName(pNtk), + Bac_NtkPiNum(pNtk), Bac_NtkPoNum(pNtk), Bac_NtkObjNum(pNtk), Bac_NtkInfoNum(pNtk) ); + Vec_StrPrintStr( vOut, Buffer ); + } + Bac_ManForEachNtk( p, pNtk, i ) + Bac_ManWriteBacNtk( vOut, pNtk ); +} +void Bac_ManWriteBac( char * pFileName, Bac_Man_t * p ) +{ + Vec_Str_t * vOut; + assert( p->pMioLib == NULL ); + vOut = Vec_StrAlloc( 10000 ); + Bac_ManWriteBacInt( vOut, p ); + if ( Vec_StrSize(vOut) > 0 ) + { + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + else + { + fwrite( Vec_StrArray(vOut), 1, Vec_StrSize(vOut), pFile ); + fclose( pFile ); + } + } + Vec_StrFree( vOut ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacBlast.c b/src/base/bac/bacBlast.c new file mode 100644 index 00000000..f1843648 --- /dev/null +++ b/src/base/bac/bacBlast.c @@ -0,0 +1,587 @@ +/**CFile**************************************************************** + + FileName [bacBlast.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Bit-blasting of the netlist.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacBlast.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "base/abc/abc.h" +#include "map/mio/mio.h" +#include "bool/dec/dec.h" +#include "base/main/mainInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_ManPrepareGates( Bac_Man_t * p ) +{ + Dec_Graph_t ** ppGraphs; int i; + if ( p->pMioLib == NULL ) + return; + ppGraphs = ABC_CALLOC( Dec_Graph_t *, Abc_NamObjNumMax(p->pMods) ); + for ( i = 1; i < Abc_NamObjNumMax(p->pMods); i++ ) + { + char * pGateName = Abc_NamStr( p->pMods, i ); + Mio_Gate_t * pGate = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pMioLib, pGateName, NULL ); + if ( pGate != NULL ) + ppGraphs[i] = Dec_Factor( Mio_GateReadSop(pGate) ); + } + assert( p->ppGraphs == NULL ); + p->ppGraphs = (void **)ppGraphs; +} +void Bac_ManUndoGates( Bac_Man_t * p ) +{ + int i; + if ( p->pMioLib == NULL ) + return; + for ( i = 1; i < Abc_NamObjNumMax(p->pMods); i++ ) + if ( p->ppGraphs[i] ) + Dec_GraphFree( (Dec_Graph_t *)p->ppGraphs[i] ); + ABC_FREE( p->ppGraphs ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_ManAddBarbuf( Gia_Man_t * pNew, int iRes, Bac_Man_t * p, int iLNtk, int iLObj, int iRNtk, int iRObj, Vec_Int_t * vMap ) +{ + int iBufLit, iIdLit; + if ( iRes == 0 || iRes == 1 ) + return iRes; + assert( iRes > 0 ); + if ( vMap && Abc_Lit2Var(iRes) < Vec_IntSize(vMap) && (iIdLit = Vec_IntEntry(vMap, Abc_Lit2Var(iRes))) >= 0 && + Vec_IntEntry(&p->vBuf2LeafNtk, Abc_Lit2Var(iIdLit)) == iLNtk && Vec_IntEntry(&p->vBuf2RootNtk, Abc_Lit2Var(iIdLit)) == iRNtk ) + return Abc_LitNotCond( Vec_IntEntry(pNew->vBarBufs, Abc_Lit2Var(iIdLit)), Abc_LitIsCompl(iRes) ^ Abc_LitIsCompl(iIdLit) ); + assert( Bac_ManNtkIsOk(p, iLNtk) && Bac_ManNtkIsOk(p, iRNtk) ); + Vec_IntPush( &p->vBuf2LeafNtk, iLNtk ); + Vec_IntPush( &p->vBuf2LeafObj, iLObj ); + Vec_IntPush( &p->vBuf2RootNtk, iRNtk ); + Vec_IntPush( &p->vBuf2RootObj, iRObj ); + iBufLit = Gia_ManAppendBuf( pNew, iRes ); + if ( vMap ) + { + Vec_IntSetEntryFull( vMap, Abc_Lit2Var(iRes), Abc_Var2Lit(Vec_IntSize(pNew->vBarBufs), Abc_LitIsCompl(iRes)) ); + Vec_IntPush( pNew->vBarBufs, iBufLit ); + } + return iBufLit; +} +int Bac_ManExtract_rec( Gia_Man_t * pNew, Bac_Ntk_t * p, int i, int fBuffers, Vec_Int_t * vMap ) +{ + int iRes = Bac_ObjCopy( p, i ); + if ( iRes >= 0 ) + return iRes; + if ( Bac_ObjIsCo(p, i) ) + iRes = Bac_ManExtract_rec( pNew, p, Bac_ObjFanin(p, i), fBuffers, vMap ); + else if ( Bac_ObjIsPi(p, i) ) + { + Bac_Ntk_t * pHost = Bac_NtkHostNtk( p ); + int iObj = Bac_BoxBi( pHost, Bac_NtkHostObj(p), Bac_ObjIndex(p, i) ); + iRes = Bac_ManExtract_rec( pNew, pHost, iObj, fBuffers, vMap ); + if ( fBuffers ) + iRes = Bac_ManAddBarbuf( pNew, iRes, p->pDesign, Bac_NtkId(p), i, Bac_NtkId(pHost), iObj, vMap ); + } + else if ( Bac_ObjIsBo(p, i) ) + { + int iBox = Bac_BoxBoBox(p, i); + if ( Bac_ObjIsBoxUser(p, iBox) ) // user box + { + Bac_Ntk_t * pBox = Bac_BoxBoNtk( p, i ); + int iObj = Bac_NtkPo( pBox, Bac_ObjIndex(p, i) ); + iRes = Bac_ManExtract_rec( pNew, pBox, iObj, fBuffers, vMap ); + if ( fBuffers ) + iRes = Bac_ManAddBarbuf( pNew, iRes, p->pDesign, Bac_NtkId(p), i, Bac_NtkId(pBox), iObj, vMap ); + } + else // primitive + { + int iFanin, nLits, pLits[16]; + assert( Bac_ObjIsBoxPrim(p, iBox) ); + Bac_BoxForEachFanin( p, iBox, iFanin, nLits ) + pLits[nLits] = Bac_ManExtract_rec( pNew, p, iFanin, fBuffers, vMap ); + assert( nLits <= 16 ); + if ( p->pDesign->ppGraphs ) // mapped gate + { + extern int Gia_ManFactorGraph( Gia_Man_t * p, Dec_Graph_t * pFForm, Vec_Int_t * vLeaves ); + Dec_Graph_t * pGraph = (Dec_Graph_t *)p->pDesign->ppGraphs[Bac_BoxNtkId(p, iBox)]; + Vec_Int_t Leaves = { nLits, nLits, pLits }; + assert( pGraph != NULL ); + return Gia_ManFactorGraph( pNew, pGraph, &Leaves ); + } + else + { + Bac_ObjType_t Type = Bac_ObjType(p, iBox); + if ( nLits == 0 ) + { + if ( Type == BAC_BOX_CF ) + iRes = 0; + else if ( Type == BAC_BOX_CT ) + iRes = 1; + else assert( 0 ); + } + else if ( nLits == 1 ) + { + if ( Type == BAC_BOX_BUF ) + iRes = pLits[0]; + else if ( Type == BAC_BOX_INV ) + iRes = Abc_LitNot( pLits[0] ); + else assert( 0 ); + } + else if ( nLits == 2 ) + { + if ( Type == BAC_BOX_AND ) + iRes = Gia_ManHashAnd( pNew, pLits[0], pLits[1] ); + else if ( Type == BAC_BOX_NAND ) + iRes = Abc_LitNot( Gia_ManHashAnd( pNew, pLits[0], pLits[1] ) ); + else if ( Type == BAC_BOX_OR ) + iRes = Gia_ManHashOr( pNew, pLits[0], pLits[1] ); + else if ( Type == BAC_BOX_NOR ) + iRes = Abc_LitNot( Gia_ManHashOr( pNew, pLits[0], pLits[1] ) ); + else if ( Type == BAC_BOX_XOR ) + iRes = Gia_ManHashXor( pNew, pLits[0], pLits[1] ); + else if ( Type == BAC_BOX_XNOR ) + iRes = Abc_LitNot( Gia_ManHashXor( pNew, pLits[0], pLits[1] ) ); + else if ( Type == BAC_BOX_SHARP ) + iRes = Gia_ManHashAnd( pNew, pLits[0], Abc_LitNot(pLits[1]) ); + else if ( Type == BAC_BOX_SHARPL ) + iRes = Gia_ManHashAnd( pNew, Abc_LitNot(pLits[0]), pLits[1] ); + else assert( 0 ); + } + else if ( nLits == 3 ) + { + if ( Type == BAC_BOX_MUX ) + iRes = Gia_ManHashMux( pNew, pLits[0], pLits[1], pLits[2] ); + else if ( Type == BAC_BOX_MAJ ) + iRes = Gia_ManHashMaj( pNew, pLits[0], pLits[1], pLits[2] ); + else if ( Type == BAC_BOX_ADD ) + { + int iRes0 = Gia_ManHashAnd( pNew, pLits[1], pLits[2] ); + int iRes1 = Gia_ManHashOr( pNew, pLits[1], pLits[2] ); + assert( Bac_BoxBoNum(p, iBox) == 2 ); + if ( Bac_BoxBo(p, iBox, 0) == i ) // sum + iRes = Gia_ManHashXor( pNew, pLits[0], Gia_ManHashAnd(pNew, Abc_LitNot(iRes0), iRes1) ); + else if ( Bac_BoxBo(p, iBox, 1) == i ) // cout + iRes = Gia_ManHashOr( pNew, iRes0, Gia_ManHashAnd(pNew, pLits[0], iRes1) ); + else assert( 0 ); + } + else assert( 0 ); + } + else assert( 0 ); + } + } + } + else assert( 0 ); + Bac_ObjSetCopy( p, i, iRes ); + return iRes; +} +Gia_Man_t * Bac_ManExtract( Bac_Man_t * p, int fBuffers, int fVerbose ) +{ + Bac_Ntk_t * pNtk, * pRoot = Bac_ManRoot(p); + Gia_Man_t * pNew, * pTemp; + Vec_Int_t * vMap = NULL; + int i, iObj; + + Vec_IntClear( &p->vBuf2LeafNtk ); + Vec_IntClear( &p->vBuf2LeafObj ); + Vec_IntClear( &p->vBuf2RootNtk ); + Vec_IntClear( &p->vBuf2RootObj ); + + Bac_ManForEachNtk( p, pNtk, i ) + { + Bac_NtkDeriveIndex( pNtk ); + Bac_NtkStartCopies( pNtk ); + } + + // start the manager + pNew = Gia_ManStart( Bac_ManNodeNum(p) ); + pNew->pName = Abc_UtilStrsav(p->pName); + pNew->pSpec = Abc_UtilStrsav(p->pSpec); + + // primary inputs + Bac_NtkForEachPi( pRoot, iObj, i ) + Bac_ObjSetCopy( pRoot, iObj, Gia_ManAppendCi(pNew) ); + + // internal nodes + Gia_ManHashAlloc( pNew ); + pNew->vBarBufs = Vec_IntAlloc( 10000 ); + vMap = Vec_IntStartFull( 10000 ); + Bac_ManPrepareGates( p ); + Bac_NtkForEachPo( pRoot, iObj, i ) + Bac_ManExtract_rec( pNew, pRoot, iObj, fBuffers, vMap ); + Bac_ManUndoGates( p ); + Vec_IntFreeP( &vMap ); + Gia_ManHashStop( pNew ); + + // primary outputs + Bac_NtkForEachPo( pRoot, iObj, i ) + Gia_ManAppendCo( pNew, Bac_ObjCopy(pRoot, iObj) ); + assert( Vec_IntSize(&p->vBuf2LeafNtk) == pNew->nBufs ); + + // cleanup + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + //Gia_ManPrintStats( pNew, NULL ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Mark each GIA node with the network it belongs to.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_ManMarkNodesGia( Bac_Man_t * p, Gia_Man_t * pGia ) +{ + Gia_Obj_t * pObj; int i, Count = 0; + assert( Vec_IntSize(&p->vBuf2LeafNtk) == Gia_ManBufNum(pGia) ); + Gia_ManConst0(pGia)->Value = 1; + Gia_ManForEachPi( pGia, pObj, i ) + pObj->Value = 1; + Gia_ManForEachAnd( pGia, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Vec_IntEntry( &p->vBuf2LeafNtk, Count++ ); + else + { + pObj->Value = Gia_ObjFanin0(pObj)->Value; + assert( pObj->Value == Gia_ObjFanin1(pObj)->Value ); + } + } + assert( Count == Gia_ManBufNum(pGia) ); + Gia_ManForEachPo( pGia, pObj, i ) + { + assert( Gia_ObjFanin0(pObj)->Value == 1 ); + pObj->Value = 1; + } +} +void Bac_ManRemapBarbufs( Bac_Man_t * pNew, Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int Entry, i; + //assert( Vec_IntSize(&p->vBuf2RootNtk) ); + assert( !Vec_IntSize(&pNew->vBuf2RootNtk) ); + Vec_IntAppend( &pNew->vBuf2RootNtk, &p->vBuf2RootNtk ); + Vec_IntAppend( &pNew->vBuf2RootObj, &p->vBuf2RootObj ); + Vec_IntAppend( &pNew->vBuf2LeafNtk, &p->vBuf2LeafNtk ); + Vec_IntAppend( &pNew->vBuf2LeafObj, &p->vBuf2LeafObj ); + Vec_IntForEachEntry( &p->vBuf2LeafObj, Entry, i ) + { + pNtk = Bac_ManNtk( p, Vec_IntEntry(&p->vBuf2LeafNtk, i) ); + Vec_IntWriteEntry( &pNew->vBuf2LeafObj, i, Bac_ObjCopy(pNtk, Entry) ); + } + Vec_IntForEachEntry( &p->vBuf2RootObj, Entry, i ) + { + pNtk = Bac_ManNtk( p, Vec_IntEntry(&p->vBuf2RootNtk, i) ); + Vec_IntWriteEntry( &pNew->vBuf2RootObj, i, Bac_ObjCopy(pNtk, Entry) ); + } +} +void Bac_NtkCreateAndConnectBuffer( Gia_Man_t * pGia, Gia_Obj_t * pObj, Bac_Ntk_t * p, int iTerm ) +{ + int iObj; + if ( pGia && Gia_ObjFaninId0p(pGia, pObj) > 0 ) + { + iObj = Bac_ObjAlloc( p, BAC_OBJ_BI, Gia_ObjFanin0(pObj)->Value ); + Bac_ObjAlloc( p, Gia_ObjFaninC0(pObj) ? BAC_BOX_INV : BAC_BOX_BUF, -1 ); + } + else + { + Bac_ObjAlloc( p, pGia && Gia_ObjFaninC0(pObj) ? BAC_BOX_CT : BAC_BOX_CF, -1 ); + } + iObj = Bac_ObjAlloc( p, BAC_OBJ_BO, -1 ); + Bac_ObjSetFanin( p, iTerm, iObj ); +} +void Bac_NtkInsertGia( Bac_Man_t * p, Gia_Man_t * pGia ) +{ + Bac_Ntk_t * pNtk, * pRoot = Bac_ManRoot( p ); + int i, j, k, iBox, iTerm, Count = 0; + Gia_Obj_t * pObj; + + Gia_ManConst0(pGia)->Value = ~0; + Gia_ManForEachPi( pGia, pObj, i ) + pObj->Value = Bac_NtkPi( pRoot, i ); + Gia_ManForEachAnd( pGia, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + { + pNtk = Bac_ManNtk( p, Vec_IntEntry(&p->vBuf2RootNtk, Count) ); + iTerm = Vec_IntEntry( &p->vBuf2RootObj, Count ); + assert( Bac_ObjIsCo(pNtk, iTerm) ); + if ( Bac_ObjFanin(pNtk, iTerm) == -1 ) // not a feedthrough + Bac_NtkCreateAndConnectBuffer( pGia, pObj, pNtk, iTerm ); + // prepare leaf + pObj->Value = Vec_IntEntry( &p->vBuf2LeafObj, Count++ ); + } + else + { + int iLit0 = Gia_ObjFanin0(pObj)->Value; + int iLit1 = Gia_ObjFanin1(pObj)->Value; + Bac_ObjType_t Type; + pNtk = Bac_ManNtk( p, pObj->Value ); + if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + Type = BAC_BOX_NOR; + else if ( Gia_ObjFaninC1(pObj) ) + Type = BAC_BOX_SHARP; + else if ( Gia_ObjFaninC0(pObj) ) + { + Type = BAC_BOX_SHARP; + ABC_SWAP( int, iLit0, iLit1 ); + } + else + Type = BAC_BOX_AND; + // create box + iTerm = Bac_ObjAlloc( pNtk, BAC_OBJ_BI, iLit1 ); + iTerm = Bac_ObjAlloc( pNtk, BAC_OBJ_BI, iLit0 ); + Bac_ObjAlloc( pNtk, Type, -1 ); + pObj->Value = Bac_ObjAlloc( pNtk, BAC_OBJ_BO, -1 ); + } + } + assert( Count == Gia_ManBufNum(pGia) ); + + // create constant 0 drivers for COs without barbufs + Bac_ManForEachNtk( p, pNtk, i ) + { + Bac_NtkForEachBox( pNtk, iBox ) + Bac_BoxForEachBi( pNtk, iBox, iTerm, j ) + if ( Bac_ObjFanin(pNtk, iTerm) == -1 ) + Bac_NtkCreateAndConnectBuffer( NULL, NULL, pNtk, iTerm ); + Bac_NtkForEachPo( pNtk, iTerm, k ) + if ( pNtk != pRoot && Bac_ObjFanin(pNtk, iTerm) == -1 ) + Bac_NtkCreateAndConnectBuffer( NULL, NULL, pNtk, iTerm ); + } + // create node and connect POs + Gia_ManForEachPo( pGia, pObj, i ) + if ( Bac_ObjFanin(pRoot, Bac_NtkPo(pRoot, i)) == -1 ) // not a feedthrough + Bac_NtkCreateAndConnectBuffer( pGia, pObj, pRoot, Bac_NtkPo(pRoot, i) ); +} +Bac_Man_t * Bac_ManInsertGia( Bac_Man_t * p, Gia_Man_t * pGia ) +{ + Bac_Man_t * pNew = Bac_ManDupUserBoxes( p ); + Bac_ManMarkNodesGia( p, pGia ); + Bac_ManRemapBarbufs( pNew, p ); + Bac_NtkInsertGia( pNew, pGia ); + Bac_ManMoveNames( pNew, p ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bac_Man_t * Bac_ManBlastTest( Bac_Man_t * p ) +{ + Gia_Man_t * pGia = Bac_ManExtract( p, 1, 0 ); + Bac_Man_t * pNew = Bac_ManInsertGia( p, pGia ); + Gia_ManStop( pGia ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Mark each GIA node with the network it belongs to.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NodeIsSeriousGate( Abc_Obj_t * p ) +{ + return Abc_ObjIsNode(p) && Abc_ObjFaninNum(p) > 0 && !Abc_ObjIsBarBuf(p); +} +void Bac_ManMarkNodesAbc( Bac_Man_t * p, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj, * pFanin; int i, k, Count = 0; + assert( Vec_IntSize(&p->vBuf2LeafNtk) == pNtk->nBarBufs2 ); + Abc_NtkForEachPi( pNtk, pObj, i ) + pObj->iTemp = 1; + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_ObjIsBarBuf(pObj) ) + pObj->iTemp = Vec_IntEntry( &p->vBuf2LeafNtk, Count++ ); + else if ( Abc_NodeIsSeriousGate(pObj) ) + { + pObj->iTemp = Abc_ObjFanin0(pObj)->iTemp; + Abc_ObjForEachFanin( pObj, pFanin, k ) + assert( pObj->iTemp == pFanin->iTemp ); + } + } + Abc_NtkForEachPo( pNtk, pObj, i ) + { + if ( !Abc_NodeIsSeriousGate(Abc_ObjFanin0(pObj)) ) + continue; + assert( Abc_ObjFanin0(pObj)->iTemp == 1 ); + pObj->iTemp = Abc_ObjFanin0(pObj)->iTemp; + } + assert( Count == pNtk->nBarBufs2 ); +} +void Bac_NtkCreateOrConnectFanin( Abc_Obj_t * pFanin, Bac_Ntk_t * p, int iTerm ) +{ + int iObj; + if ( pFanin && Abc_NodeIsSeriousGate(pFanin) )//&& Bac_ObjName(p, pFanin->iTemp) == -1 ) // gate without name + { + iObj = pFanin->iTemp; + } + else if ( pFanin && (Abc_ObjIsPi(pFanin) || Abc_ObjIsBarBuf(pFanin) || Abc_NodeIsSeriousGate(pFanin)) ) // PI/BO or gate with name + { + iObj = Bac_ObjAlloc( p, BAC_OBJ_BI, pFanin->iTemp ); + Bac_ObjAlloc( p, BAC_BOX_GATE, p->pDesign->ElemGates[2] ); // buffer + iObj = Bac_ObjAlloc( p, BAC_OBJ_BO, -1 ); + } + else + { + assert( !pFanin || Abc_NodeIsConst0(pFanin) || Abc_NodeIsConst1(pFanin) ); + Bac_ObjAlloc( p, BAC_BOX_GATE, p->pDesign->ElemGates[(pFanin && Abc_NodeIsConst1(pFanin))] ); // const 0/1 + iObj = Bac_ObjAlloc( p, BAC_OBJ_BO, -1 ); + } + Bac_ObjSetFanin( p, iTerm, iObj ); +} +void Bac_NtkPrepareLibrary( Bac_Man_t * p, Mio_Library_t * pLib ) +{ + Mio_Gate_t * pGate; + Mio_Gate_t * pGate0 = Mio_LibraryReadConst0( pLib ); + Mio_Gate_t * pGate1 = Mio_LibraryReadConst1( pLib ); + Mio_Gate_t * pGate2 = Mio_LibraryReadBuf( pLib ); + if ( !pGate0 || !pGate1 || !pGate2 ) + { + printf( "The library does not have one of the elementary gates.\n" ); + return; + } + p->ElemGates[0] = Abc_NamStrFindOrAdd( p->pMods, Mio_GateReadName(pGate0), NULL ); + p->ElemGates[1] = Abc_NamStrFindOrAdd( p->pMods, Mio_GateReadName(pGate1), NULL ); + p->ElemGates[2] = Abc_NamStrFindOrAdd( p->pMods, Mio_GateReadName(pGate2), NULL ); + Mio_LibraryForEachGate( pLib, pGate ) + if ( pGate != pGate0 && pGate != pGate1 && pGate != pGate2 ) + Abc_NamStrFindOrAdd( p->pMods, Mio_GateReadName(pGate), NULL ); + assert( Abc_NamObjNumMax(p->pMods) > 1 ); +} +int Bac_NtkBuildLibrary( Bac_Man_t * p ) +{ + int RetValue = 1; + Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + if ( pLib == NULL ) + printf( "The standard cell library is not available.\n" ), RetValue = 0; + else + Bac_NtkPrepareLibrary( p, pLib ); + p->pMioLib = pLib; + return RetValue; +} +void Bac_NtkInsertNtk( Bac_Man_t * p, Abc_Ntk_t * pNtk ) +{ + Bac_Ntk_t * pCbaNtk, * pRoot = Bac_ManRoot( p ); + int i, j, k, iBox, iTerm, Count = 0; + Abc_Obj_t * pObj; + assert( Abc_NtkHasMapping(pNtk) ); + Bac_NtkPrepareLibrary( p, (Mio_Library_t *)pNtk->pManFunc ); + p->pMioLib = pNtk->pManFunc; + + Abc_NtkForEachPi( pNtk, pObj, i ) + pObj->iTemp = Bac_NtkPi( pRoot, i ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_ObjIsBarBuf(pObj) ) + { + pCbaNtk = Bac_ManNtk( p, Vec_IntEntry(&p->vBuf2RootNtk, Count) ); + iTerm = Vec_IntEntry( &p->vBuf2RootObj, Count ); + assert( Bac_ObjIsCo(pCbaNtk, iTerm) ); + if ( Bac_ObjFanin(pCbaNtk, iTerm) == -1 ) // not a feedthrough + Bac_NtkCreateOrConnectFanin( Abc_ObjFanin0(pObj), pCbaNtk, iTerm ); + // prepare leaf + pObj->iTemp = Vec_IntEntry( &p->vBuf2LeafObj, Count++ ); + } + else if ( Abc_NodeIsSeriousGate(pObj) ) + { + pCbaNtk = Bac_ManNtk( p, pObj->iTemp ); + for ( k = Abc_ObjFaninNum(pObj)-1; k >= 0; k-- ) + iTerm = Bac_ObjAlloc( pCbaNtk, BAC_OBJ_BI, Abc_ObjFanin(pObj, k)->iTemp ); + Bac_ObjAlloc( pCbaNtk, BAC_BOX_GATE, Abc_NamStrFind(p->pMods, Mio_GateReadName((Mio_Gate_t *)pObj->pData)) ); + pObj->iTemp = Bac_ObjAlloc( pCbaNtk, BAC_OBJ_BO, -1 ); + } + } + assert( Count == pNtk->nBarBufs2 ); + + // create constant 0 drivers for COs without barbufs + Bac_ManForEachNtk( p, pCbaNtk, i ) + { + Bac_NtkForEachBox( pCbaNtk, iBox ) + Bac_BoxForEachBi( pCbaNtk, iBox, iTerm, j ) + if ( Bac_ObjFanin(pCbaNtk, iTerm) == -1 ) + Bac_NtkCreateOrConnectFanin( NULL, pCbaNtk, iTerm ); + Bac_NtkForEachPo( pCbaNtk, iTerm, k ) + if ( pCbaNtk != pRoot && Bac_ObjFanin(pCbaNtk, iTerm) == -1 ) + Bac_NtkCreateOrConnectFanin( NULL, pCbaNtk, iTerm ); + } + // create node and connect POs + Abc_NtkForEachPo( pNtk, pObj, i ) + if ( Bac_ObjFanin(pRoot, Bac_NtkPo(pRoot, i)) == -1 ) // not a feedthrough + Bac_NtkCreateOrConnectFanin( Abc_ObjFanin0(pObj), pRoot, Bac_NtkPo(pRoot, i) ); +} +void * Bac_ManInsertAbc( Bac_Man_t * p, void * pAbc ) +{ + Abc_Ntk_t * pNtk = (Abc_Ntk_t *)pAbc; + Bac_Man_t * pNew = Bac_ManDupUserBoxes( p ); + Bac_ManMarkNodesAbc( p, pNtk ); + Bac_ManRemapBarbufs( pNew, p ); + Bac_NtkInsertNtk( pNew, pNtk ); + Bac_ManMoveNames( pNew, p ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacCom.c b/src/base/bac/bacCom.c new file mode 100644 index 00000000..5e414620 --- /dev/null +++ b/src/base/bac/bacCom.c @@ -0,0 +1,728 @@ +/**CFile**************************************************************** + + FileName [bacCom.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Command handlers.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacCom.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" +#include "proof/cec/cec.h" +#include "base/main/mainInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Bac_CommandRead ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandWrite ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandClp ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Bac_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static inline Bac_Man_t * Bac_AbcGetMan( Abc_Frame_t * pAbc ) { return (Bac_Man_t *)pAbc->pAbcCba; } +static inline void Bac_AbcFreeMan( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcCba ) Bac_ManFree(Bac_AbcGetMan(pAbc)); } +static inline void Bac_AbcUpdateMan( Abc_Frame_t * pAbc, Bac_Man_t * p ) { Bac_AbcFreeMan(pAbc); pAbc->pAbcCba = p; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function******************************************************************** + + Synopsis [Accessing current Bac_Ntk_t.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Abc_FrameImportPtr( Vec_Ptr_t * vPtr ) +{ + Bac_Man_t * p; + if ( Abc_FrameGetGlobalFrame() == NULL ) + { + printf( "ABC framework is not started.\n" ); + return; + } + p = Bac_PtrTransformToCba( vPtr ); + if ( p == NULL ) + printf( "Converting from Ptr failed.\n" ); + Bac_AbcUpdateMan( Abc_FrameGetGlobalFrame(), p ); +} +Vec_Ptr_t * Abc_FrameExportPtr() +{ + Vec_Ptr_t * vPtr; + Bac_Man_t * p; + if ( Abc_FrameGetGlobalFrame() == NULL ) + { + printf( "ABC framework is not started.\n" ); + return NULL; + } + p = Bac_AbcGetMan( Abc_FrameGetGlobalFrame() ); + if ( p == NULL ) + printf( "There is no CBA design present.\n" ); + vPtr = Bac_PtrDeriveFromCba( p ); + if ( vPtr == NULL ) + printf( "Converting to Ptr has failed.\n" ); + return vPtr; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Bac_Init( Abc_Frame_t * pAbc ) +{ + Cmd_CommandAdd( pAbc, "New word level", "@_read", Bac_CommandRead, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_write", Bac_CommandWrite, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_ps", Bac_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_put", Bac_CommandPut, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_get", Bac_CommandGet, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_clp", Bac_CommandClp, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_cec", Bac_CommandCec, 0 ); + Cmd_CommandAdd( pAbc, "New word level", "@_test", Bac_CommandTest, 0 ); +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Bac_End( Abc_Frame_t * pAbc ) +{ + Bac_AbcFreeMan( pAbc ); +} + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandRead( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pFile; + Bac_Man_t * p = NULL; + Vec_Ptr_t * vDes = NULL; + char * pFileName = NULL; + int c, fUseAbc = 0, fUsePtr = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "apvh" ) ) != EOF ) + { + switch ( c ) + { + case 'a': + fUseAbc ^= 1; + break; + case 'p': + fUsePtr ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + printf( "Bac_CommandRead(): Input file name should be given on the command line.\n" ); + return 0; + } + // get the file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) + { + Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); + if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".blif", ".smt", ".bac", NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + // perform reading + if ( fUseAbc || fUsePtr ) + { + extern Vec_Ptr_t * Ptr_AbcDeriveDes( Abc_Ntk_t * pNtk ); + Abc_Ntk_t * pAbcNtk = Io_ReadNetlist( pFileName, Io_ReadFileType(pFileName), 0 ); + Vec_Ptr_t * vDes = Ptr_AbcDeriveDes( pAbcNtk ); + p = Bac_PtrTransformToCba( vDes ); + Bac_PtrFree( vDes ); // points to names in pAbcNtk + if ( p ) + { + ABC_FREE( p->pSpec ); + p->pSpec = Abc_UtilStrsav( pAbcNtk->pSpec ); + } + Abc_NtkDelete( pAbcNtk ); + } + else if ( !strcmp( Extra_FileNameExtension(pFileName), "blif" ) ) + { + vDes = Psr_ManReadBlif( pFileName ); + if ( vDes && Vec_PtrSize(vDes) ) + p = Psr_ManBuildCba( pFileName, vDes ); + if ( vDes ) + Psr_ManVecFree( vDes ); + } + else if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + { + vDes = Psr_ManReadVerilog( pFileName ); + if ( vDes && Vec_PtrSize(vDes) ) + p = Psr_ManBuildCba( pFileName, vDes ); + if ( vDes ) + Psr_ManVecFree( vDes ); + } + else if ( !strcmp( Extra_FileNameExtension(pFileName), "smt" ) ) + { + vDes = NULL;//Psr_ManReadSmt( pFileName ); + if ( vDes && Vec_PtrSize(vDes) ) + p = Psr_ManBuildCba( pFileName, vDes ); + if ( vDes ) + Psr_ManVecFree( vDes ); + } + else if ( !strcmp( Extra_FileNameExtension(pFileName), "bac" ) ) + { + p = Bac_ManReadBac( pFileName ); + } + else + { + printf( "Unrecognized input file extension.\n" ); + return 0; + } + Bac_AbcUpdateMan( pAbc, p ); + return 0; +usage: + Abc_Print( -2, "usage: @_read [-apvh] <file_name>\n" ); + Abc_Print( -2, "\t reads hierarchical design in BLIF or Verilog\n" ); + Abc_Print( -2, "\t-a : toggle using old ABC parser [default = %s]\n", fUseAbc? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle using Ptr construction [default = %s]\n", fUsePtr? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandWrite( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Bac_Man_t * p = Bac_AbcGetMan(pAbc); + char * pFileName = NULL; + int fUseAssign = 1; + int fUsePtr = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "apvh" ) ) != EOF ) + { + switch ( c ) + { + case 'a': + fUseAssign ^= 1; + break; + case 'p': + fUsePtr ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandWrite(): There is no current design.\n" ); + return 0; + } + if ( argc == globalUtilOptind + 1 ) + pFileName = argv[globalUtilOptind]; + else if ( argc == globalUtilOptind && p ) + pFileName = Extra_FileNameGenericAppend( Bac_ManName(p), "_out.v" ); + else + { + printf( "Output file name should be given on the command line.\n" ); + return 0; + } + // perform writing + if ( !strcmp( Extra_FileNameExtension(pFileName), "blif" ) ) + Bac_ManWriteBlif( pFileName, p ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + { + if ( fUsePtr ) + { + Vec_Ptr_t * vPtr = Bac_PtrDeriveFromCba( p ); + if ( vPtr == NULL ) + printf( "Converting to Ptr has failed.\n" ); + else + { + Bac_PtrDumpVerilog( pFileName, vPtr ); + Bac_PtrFree( vPtr ); + } + } + else + Bac_ManWriteVerilog( pFileName, p, fUseAssign ); + } + else if ( !strcmp( Extra_FileNameExtension(pFileName), "bac" ) ) + Bac_ManWriteBac( pFileName, p ); + else + { + printf( "Unrecognized output file extension.\n" ); + return 0; + } + return 0; +usage: + Abc_Print( -2, "usage: @_write [-apvh]\n" ); + Abc_Print( -2, "\t writes the design into a file in BLIF or Verilog\n" ); + Abc_Print( -2, "\t-a : toggle using assign-statement for primitives [default = %s]\n", fUseAssign? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle using Ptr construction (mapped Verilog only) [default = %s]\n", fUsePtr? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Bac_Man_t * p = Bac_AbcGetMan(pAbc); + int c, nModules = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Mvh" ) ) != EOF ) + { + switch ( c ) + { + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + nModules = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nModules < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandPs(): There is no current design.\n" ); + return 0; + } + Bac_ManPrintStats( p, nModules, fVerbose ); + return 0; +usage: + Abc_Print( -2, "usage: @_ps [-M num] [-vh]\n" ); + Abc_Print( -2, "\t prints statistics\n" ); + Abc_Print( -2, "\t-M num : the number of first modules to report [default = %d]\n", nModules ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandPut( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Bac_Man_t * p = Bac_AbcGetMan(pAbc); + Gia_Man_t * pGia = NULL; + int c, fBarBufs = 1, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBarBufs ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandPut(): There is no current design.\n" ); + return 0; + } + pGia = Bac_ManExtract( p, fBarBufs, fVerbose ); + if ( pGia == NULL ) + { + Abc_Print( 1, "Bac_CommandPut(): Conversion to AIG has failed.\n" ); + return 0; + } + Abc_FrameUpdateGia( pAbc, pGia ); + return 0; +usage: + Abc_Print( -2, "usage: @_put [-bvh]\n" ); + Abc_Print( -2, "\t extracts AIG from the hierarchical design\n" ); + Abc_Print( -2, "\t-b : toggle using barrier buffers [default = %s]\n", fBarBufs? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandGet( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Bac_Man_t * pNew = NULL, * p = Bac_AbcGetMan(pAbc); + int c, fMapped = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "mvh" ) ) != EOF ) + { + switch ( c ) + { + case 'm': + fMapped ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandGet(): There is no current design.\n" ); + return 0; + } + if ( fMapped ) + { + if ( pAbc->pNtkCur == NULL ) + { + Abc_Print( 1, "Bac_CommandGet(): There is no current mapped design.\n" ); + return 0; + } + pNew = (Bac_Man_t *)Bac_ManInsertAbc( p, pAbc->pNtkCur ); + } + else + { + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Bac_CommandGet(): There is no current AIG.\n" ); + return 0; + } + pNew = Bac_ManInsertGia( p, pAbc->pGia ); + } + Bac_AbcUpdateMan( pAbc, pNew ); + return 0; +usage: + Abc_Print( -2, "usage: @_get [-mvh]\n" ); + Abc_Print( -2, "\t inserts AIG or mapped network into the hierarchical design\n" ); + Abc_Print( -2, "\t-m : toggle using mapped network from main-space [default = %s]\n", fMapped? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandClp( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Bac_Man_t * pNew = NULL, * p = Bac_AbcGetMan(pAbc); + 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 ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandGet(): There is no current design.\n" ); + return 0; + } + pNew = Bac_ManCollapse( p ); + Bac_AbcUpdateMan( pAbc, pNew ); + return 0; +usage: + Abc_Print( -2, "usage: @_clp [-vh]\n" ); + Abc_Print( -2, "\t collapses the current hierarchical design\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Bac_Man_t * p = Bac_AbcGetMan(pAbc); + Gia_Man_t * pFirst, * pSecond, * pMiter; + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + Vec_Ptr_t * vDes; + char * FileName, * pStr, ** pArgvNew; + int c, nArgcNew, fDumpMiter = 0; + FILE * pFile; + Cec_ManCecSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandCec(): There is no current design.\n" ); + return 0; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 1 ) + { + if ( p->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = p->pSpec; + } + else + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pStr = FileName; *pStr; pStr++ ) + if ( *pStr == '>' ) + *pStr = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".v", ".blif", NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + + // extract AIG from the current design + pFirst = Bac_ManExtract( p, 0, 0 ); + if ( pFirst == NULL ) + { + Abc_Print( -1, "Extracting AIG from the current design has failed.\n" ); + return 0; + } + // extract AIG from the second design + if ( !strcmp( Extra_FileNameExtension(FileName), "blif" ) ) + vDes = Psr_ManReadBlif( FileName ); + else if ( !strcmp( Extra_FileNameExtension(FileName), "v" ) ) + vDes = Psr_ManReadVerilog( FileName ); + else assert( 0 ); + p = Psr_ManBuildCba( FileName, vDes ); + Psr_ManVecFree( vDes ); + pSecond = Bac_ManExtract( p, 0, 0 ); + Bac_ManFree( p ); + if ( pSecond == NULL ) + { + Gia_ManStop( pFirst ); + Abc_Print( -1, "Extracting AIG from the original design has failed.\n" ); + return 0; + } + // compute the miter + pMiter = Gia_ManMiter( pFirst, pSecond, 0, 1, 0, 0, pPars->fVerbose ); + if ( pMiter ) + { + if ( fDumpMiter ) + { + Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "cec_miter.aig" ); + Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 ); + } + pAbc->Status = Cec_ManVerify( pMiter, pPars ); + //Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Gia_ManStop( pMiter ); + } + Gia_ManStop( pFirst ); + Gia_ManStop( pSecond ); + return 0; +usage: + Abc_Print( -2, "usage: @_cec [-vh]\n" ); + Abc_Print( -2, "\t combinational equivalence checking\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Bac_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Psr_ManReadBlifTest(); + extern void Psr_ManReadVerilogTest(); + extern void Psr_SmtReadSmtTest(); + //Bac_Man_t * p = Bac_AbcGetMan(pAbc); + 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 ( p == NULL ) + { + Abc_Print( 1, "Bac_CommandTest(): There is no current design.\n" ); + return 0; + } +*/ + //Bac_PtrTransformTestTest(); + //Psr_ManReadVerilogTest(); + //Psr_SmtReadSmtTest(); + return 0; +usage: + Abc_Print( -2, "usage: @_test [-vh]\n" ); + Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacLib.c b/src/base/bac/bacLib.c new file mode 100644 index 00000000..b2a16eb6 --- /dev/null +++ b/src/base/bac/bacLib.c @@ -0,0 +1,52 @@ +/**CFile**************************************************************** + + FileName [bacLib.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Library procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacLib.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacNtk.c b/src/base/bac/bacNtk.c new file mode 100644 index 00000000..4d2cd665 --- /dev/null +++ b/src/base/bac/bacNtk.c @@ -0,0 +1,604 @@ +/**CFile**************************************************************** + + FileName [bacNtk.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Netlist manipulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacNtk.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Bac_Pair_t_ Bac_Pair_t; +struct Bac_Pair_t_ +{ + Bac_ObjType_t Type; + char * pName; + char * pSymb; +}; +static const char * s_Pref = "ABC_"; +static Bac_Pair_t s_Types[BAC_BOX_UNKNOWN] = +{ + { BAC_OBJ_NONE, "NONE", NULL }, + { BAC_OBJ_PI, "PI", NULL }, + { BAC_OBJ_PO, "PO", NULL }, + { BAC_OBJ_BI, "BI", NULL }, + { BAC_OBJ_BO, "BO", NULL }, + { BAC_OBJ_BOX, "BOX", NULL }, + + { BAC_BOX_CF, "CF", "o" }, + { BAC_BOX_CT, "CT", "o" }, + { BAC_BOX_CX, "CX", "o" }, + { BAC_BOX_CZ, "CZ", "o" }, + { BAC_BOX_BUF, "BUF", "ao" }, + { BAC_BOX_INV, "INV", "ao" }, + { BAC_BOX_AND, "AND", "abo" }, + { BAC_BOX_NAND, "NAND", "abo" }, + { BAC_BOX_OR, "OR", "abo" }, + { BAC_BOX_NOR, "NOR", "abo" }, + { BAC_BOX_XOR, "XOR", "abo" }, + { BAC_BOX_XNOR, "XNOR", "abo" }, + { BAC_BOX_SHARP, "SHARP", "abo" }, + { BAC_BOX_SHARPL, "SHARPL", "abo" }, + { BAC_BOX_MUX, "MUX", "cabo" }, + { BAC_BOX_MAJ, "MAJ", "abco" }, + + { BAC_BOX_RAND, "RAND", "ao" }, + { BAC_BOX_RNAND, "RNAND", "ao" }, + { BAC_BOX_ROR, "ROR", "ao" }, + { BAC_BOX_RNOR, "RNOR", "ao" }, + { BAC_BOX_RXOR, "RXOR", "ao" }, + { BAC_BOX_RXNOR, "RXNOR", "ao" }, + + { BAC_BOX_LAND, "LAND", "abo" }, + { BAC_BOX_LNAND, "LNAND", "abo" }, + { BAC_BOX_LOR, "LOR", "abo" }, + { BAC_BOX_LNOR, "LNOR", "abo" }, + { BAC_BOX_LXOR, "LXOR", "abo" }, + { BAC_BOX_LXNOR, "LXNOR", "abo" }, + + { BAC_BOX_NMUX, "NMUX", "abo" }, + { BAC_BOX_SEL, "SEL", "abo" }, + { BAC_BOX_PSEL, "PSEL", "iabo" }, + { BAC_BOX_ENC, "ENC", "ao" }, + { BAC_BOX_PENC, "PENC", "ao" }, + { BAC_BOX_DEC, "DEC", "ao" }, + { BAC_BOX_EDEC, "EDEC", "abo" }, + + { BAC_BOX_ADD, "ADD", "iabso" }, + { BAC_BOX_SUB, "SUB", "abo" }, + { BAC_BOX_MUL, "MUL", "abo" }, + { BAC_BOX_DIV, "DIV", "abo" }, + { BAC_BOX_MOD, "MOD", "abo" }, + { BAC_BOX_REM, "REM", "abo" }, + { BAC_BOX_POW, "POW", "abo" }, + { BAC_BOX_MIN, "MIN", "ao" }, + { BAC_BOX_ABS, "ABS", "ao" }, + + { BAC_BOX_LTHAN, "LTHAN", "iabo" }, + { BAC_BOX_LETHAN, "LETHAN", "abo" }, + { BAC_BOX_METHAN, "METHAN", "abo" }, + { BAC_BOX_MTHAN, "MTHAN", "abo" }, + { BAC_BOX_EQU, "EQU", "abo" }, + { BAC_BOX_NEQU, "NEQU", "abo" }, + + { BAC_BOX_SHIL, "SHIL", "abo" }, + { BAC_BOX_SHIR, "SHIR", "abo" }, + { BAC_BOX_ROTL, "ROTL", "abo" }, + { BAC_BOX_ROTR, "ROTR", "abo" }, + + { BAC_BOX_GATE, "GATE", "io" }, + { BAC_BOX_LUT, "LUT", "io" }, + { BAC_BOX_ASSIGN, "ASSIGN", "abo" }, + + { BAC_BOX_TRI, "TRI", "abo" }, + { BAC_BOX_RAM, "RAM", "eadro" }, + { BAC_BOX_RAMR, "RAMR", "eamo" }, + { BAC_BOX_RAMW, "RAMW", "eado" }, + { BAC_BOX_RAMWC, "RAMWC", "ceado" }, + { BAC_BOX_RAMBOX, "RAMBOX", "io" }, + + { BAC_BOX_LATCH, "LATCH", "dvsgq" }, + { BAC_BOX_LATCHRS, "LATCHRS", "dsrgq" }, + { BAC_BOX_DFF, "DFF", "dvscq" }, + { BAC_BOX_DFFRS, "DFFRS", "dsrcq" } +}; +static inline int Bac_GetTypeId( Bac_ObjType_t Type ) +{ + int i; + for ( i = 1; i < BAC_BOX_UNKNOWN; i++ ) + if ( s_Types[i].Type == Type ) + return i; + return -1; +} +void Bac_ManSetupTypes( char ** pNames, char ** pSymbs ) +{ + Bac_ObjType_t Type; + for ( Type = 1; Type < BAC_BOX_UNKNOWN; Type++ ) + { + int Id = Bac_GetTypeId( Type ); + pNames[Type] = s_Types[Id].pName; + pSymbs[Type] = s_Types[Id].pSymb; + } +} + +char * Bac_NtkGenerateName( Bac_Ntk_t * p, Bac_ObjType_t Type, Vec_Int_t * vBits ) +{ + static char Buffer[100]; + char * pTemp; int i, Bits; + char * pName = Bac_ManPrimName( p->pDesign, Type ); + char * pSymb = Bac_ManPrimSymb( p->pDesign, Type ); + assert( Vec_IntSize(vBits) == (int)strlen(pSymb) ); + sprintf( Buffer, "%s%s_", s_Pref, pName ); + pTemp = Buffer + strlen(Buffer); + Vec_IntForEachEntry( vBits, Bits, i ) + { + sprintf( pTemp, "%c%d", pSymb[i], Bits ); + pTemp += strlen(pTemp); + } + //Vec_IntPrint( vBits ); + //printf( "%s\n", Buffer ); + return Buffer; +} + +Bac_ObjType_t Bac_NameToType( char * pName ) +{ + Bac_ObjType_t i; + if ( strncmp(pName, s_Pref, strlen(s_Pref)) ) + return 0; + pName += strlen(s_Pref); + for ( i = 1; i < BAC_BOX_UNKNOWN; i++ ) + if ( !strncmp(pName, s_Types[i].pName, strlen(s_Types[i].pName)) ) + return s_Types[i].Type; + return 0; +} +Vec_Int_t * Bac_NameToRanges( char * pName ) +{ + static Vec_Int_t Bits, * vBits = &Bits; + static int pArray[10]; + char * pTemp; + int Num = 0, Count = 0; + // initialize array + vBits->pArray = pArray; + vBits->nSize = 0; + vBits->nCap = 10; + // check the name + assert( !strncmp(pName, s_Pref, strlen(s_Pref)) ); + for ( pTemp = pName; *pTemp && !Bac_CharIsDigit(*pTemp); pTemp++ ); + assert( Bac_CharIsDigit(*pTemp) ); + for ( ; *pTemp; pTemp++ ) + { + if ( Bac_CharIsDigit(*pTemp) ) + Num = 10 * Num + *pTemp - '0'; + else + Vec_IntPush( vBits, Num ), Count += Num, Num = 0; + } + assert( Num > 0 ); + Vec_IntPush( vBits, Num ); Count += Num; + assert( Vec_IntSize(vBits) <= 10 ); + return vBits; +} + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Replaces fanin iOld by iNew in all fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_NtkUpdateFanout( Bac_Ntk_t * p, int iOld, int iNew ) +{ + int iCo; + assert( Bac_ObjIsCi(p, iOld) ); + assert( Bac_ObjIsCi(p, iNew) ); + Bac_ObjForEachFanout( p, iOld, iCo ) + { + assert( Bac_ObjFanin(p, iCo) == iOld ); + Bac_ObjCleanFanin( p, iCo ); + Bac_ObjSetFanin( p, iCo, iNew ); + } + Bac_ObjSetFanout( p, iNew, Bac_ObjFanout(p, iOld) ); + Bac_ObjSetFanout( p, iOld, 0 ); +} + +/**Function************************************************************* + + Synopsis [Derives fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_NtkDeriveFanout( Bac_Ntk_t * p ) +{ + int iCi, iCo; + assert( !Bac_NtkHasFanouts(p) ); + Bac_NtkStartFanouts( p ); + Bac_NtkForEachCo( p, iCo ) + { + assert( !Bac_ObjNextFanout(p, iCo) ); + iCi = Bac_ObjFanin(p, iCo); + if ( Bac_ObjFanout(p, iCi) ) + Bac_ObjSetNextFanout( p, Bac_ObjFanout(p, iCi), iCo ); + Bac_ObjSetFanout( p, iCi, iCo ); + } + Bac_NtkForEachCo( p, iCo ) + if ( !Bac_ObjNextFanout(p, iCo) ) + Bac_ObjSetFanout( p, Bac_ObjFanin(p, iCo), iCo ); +} +void Bac_ManDeriveFanout( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( p, pNtk, i ) + Bac_NtkDeriveFanout( pNtk ); +} + +/**Function************************************************************* + + Synopsis [Assigns word-level names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_ManAssignInternTwo( Bac_Ntk_t * p, int iNum, int nDigits, char * pPref, Vec_Int_t * vMap ) +{ + char Buffer[16]; int i, NameId = 0; + for ( i = 0; !NameId || Vec_IntEntry(vMap, NameId); i++ ) + { + if ( i == 0 ) + sprintf( Buffer, "%s%0*d", pPref, nDigits, iNum ); + else + sprintf( Buffer, "%s%0*d_%d", pPref, nDigits, iNum, i ); + NameId = Abc_NamStrFindOrAdd( p->pDesign->pStrs, Buffer, NULL ); + } + Vec_IntWriteEntry( vMap, NameId, 1 ); + return NameId; +} +int Bac_ManAssignCountNames( Bac_Ntk_t * p ) +{ + int i, iObj, iBox, Count = 0; + Bac_NtkForEachPiMain( p, iObj, i ) + if ( !Bac_ObjNameInt(p, iObj) ) + Count++; + Bac_NtkForEachBox( p, iBox ) + Bac_BoxForEachBoMain( p, iBox, iObj, i ) + if ( !Bac_ObjNameInt(p, iObj) ) + Count++; + return Count; +} +void Bac_ManAssignInternWordNamesNtk( Bac_Ntk_t * p, Vec_Int_t * vMap ) +{ + int k, iObj, iTerm, iName = -1, iBit = -1; + int nDigits, nPis = 0, nPos = 0, nNames = 1; + // start names + if ( !Bac_NtkHasNames(p) ) + Bac_NtkStartNames(p); + nDigits = Abc_Base10Log( Bac_ManAssignCountNames(p) ); + // populate map with the currently used names + Bac_NtkForEachCi( p, iObj ) + if ( Bac_ObjNameInt(p, iObj) ) + Vec_IntWriteEntry( vMap, Bac_ObjNameId(p, iObj), 1 ); + Bac_NtkForEachBox( p, iObj ) + if ( Bac_ObjNameInt(p, iObj) ) + Vec_IntWriteEntry( vMap, Bac_ObjNameId(p, iObj), 1 ); + // assign CI names + Bac_NtkForEachCi( p, iObj ) + { + if ( Bac_ObjNameInt(p, iObj) ) + { + iName = -1; + iBit = -1; + continue; + } + if ( Bac_ObjBit(p, iObj) ) + { + assert( iBit > 0 ); + Bac_ObjSetName( p, iObj, Abc_Var2Lit2(iBit++, BAC_NAME_INDEX) ); + } + else + { + //int Type = Bac_ObjType(p, iObj); + int Range = Bac_ObjIsPi(p, iObj) ? Bac_ObjPiRange(p, iObj) : Bac_BoxBoRange(p, iObj); + iName = Bac_ManAssignInternTwo( p, nNames++, nDigits, (char*)(Bac_ObjIsPi(p, iObj) ? "i":"n"), vMap ); + if ( Range == 1 ) + Bac_ObjSetName( p, iObj, Abc_Var2Lit2(iName, BAC_NAME_BIN) ); + else + Bac_ObjSetName( p, iObj, Abc_Var2Lit2(iName, BAC_NAME_WORD) ); + iBit = 1; + } + } + // transfer names to the interface + if ( Bac_NtkInfoNum(p) ) + { + for ( k = 0; k < Bac_NtkInfoNum(p); k++ ) + { + //char * pName = Bac_NtkName(p); + if ( Bac_NtkInfoType(p, k) == 1 ) // PI + { + iObj = Bac_NtkPi(p, nPis); + assert( !Bac_ObjBit(p, iObj) ); + assert( Bac_ObjNameType(p, iObj) <= BAC_NAME_WORD ); + Bac_NtkSetInfoName( p, k, Abc_Var2Lit2(Bac_ObjNameId(p, iObj), 1) ); + nPis += Bac_NtkInfoRange(p, k); + } + else if ( Bac_NtkInfoType(p, k) == 2 ) // PO + { + iObj = Bac_NtkPo(p, nPos); + assert( !Bac_ObjBit(p, iObj) ); + iObj = Bac_ObjFanin(p, iObj); + assert( Bac_ObjNameType(p, iObj) <= BAC_NAME_WORD ); + Bac_NtkSetInfoName( p, k, Abc_Var2Lit2(Bac_ObjNameId(p, iObj), 2) ); + nPos += Bac_NtkInfoRange(p, k); + } + else assert( 0 ); + } + assert( nPis == Bac_NtkPiNum(p) ); + assert( nPos == Bac_NtkPoNum(p) ); + } + // assign instance names + nDigits = Abc_Base10Log( Bac_NtkObjNum(p) ); + Bac_NtkForEachBox( p, iObj ) + if ( !Bac_ObjNameInt(p, iObj) ) + { + iName = Bac_ManAssignInternTwo( p, iObj, nDigits, "g", vMap ); + Bac_ObjSetName( p, iObj, Abc_Var2Lit2(iName, BAC_NAME_BIN) ); + } + // unmark all names + Bac_NtkForEachPi( p, iObj, k ) + if ( Bac_ObjNameType(p, iObj) <= BAC_NAME_WORD ) + Vec_IntWriteEntry( vMap, Bac_ObjNameId(p, iObj), 0 ); + Bac_NtkForEachBox( p, iObj ) + { + Vec_IntWriteEntry( vMap, Bac_ObjNameId(p, iObj), 0 ); + Bac_BoxForEachBo( p, iObj, iTerm, k ) + if ( Bac_ObjNameType(p, iTerm) <= BAC_NAME_WORD ) + Vec_IntWriteEntry( vMap, Bac_ObjNameId(p, iTerm), 0 ); + } +// printf( "Generated %d word-level names.\n", nNames-1 ); +} +void Bac_ManAssignInternWordNames( Bac_Man_t * p ) +{ + Vec_Int_t * vMap = Vec_IntStart( 2*Bac_ManObjNum(p) ); + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( p, pNtk, i ) + Bac_ManAssignInternWordNamesNtk( pNtk, vMap ); + assert( Vec_IntCountEntry(vMap, 0) == Vec_IntSize(vMap) ); + Vec_IntFree( vMap ); +} + + +/**Function************************************************************* + + Synopsis [Count number of objects after collapsing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_ManClpObjNum_rec( Bac_Ntk_t * p ) +{ + int i, Counter = 0; + if ( p->Count >= 0 ) + return p->Count; + Bac_NtkForEachBox( p, i ) + Counter += Bac_ObjIsBoxUser(p, i) ? Bac_ManClpObjNum_rec( Bac_BoxNtk(p, i) ) + 3*Bac_BoxBoNum(p, i) : Bac_BoxSize(p, i); + return (p->Count = Counter); +} +int Bac_ManClpObjNum( Bac_Man_t * p ) +{ + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( p, pNtk, i ) + pNtk->Count = -1; + return Bac_NtkPioNum( Bac_ManRoot(p) ) + Bac_ManClpObjNum_rec( Bac_ManRoot(p) ); +} + +/**Function************************************************************* + + Synopsis [Collects boxes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_NtkDfs_rec( Bac_Ntk_t * p, int iObj, Vec_Int_t * vBoxes ) +{ + int k, iFanin; + if ( Bac_ObjIsBo(p, iObj) == 1 ) + { + Bac_NtkDfs_rec( p, Bac_ObjFanin(p, iObj), vBoxes ); + return; + } + assert( Bac_ObjIsPi(p, iObj) || Bac_ObjIsBox(p, iObj) ); + if ( Bac_ObjCopy(p, iObj) > 0 ) // visited + return; + Bac_ObjSetCopy( p, iObj, 1 ); + Bac_BoxForEachFanin( p, iObj, iFanin, k ) + Bac_NtkDfs_rec( p, iFanin, vBoxes ); + Vec_IntPush( vBoxes, iObj ); +} +Vec_Int_t * Bac_NtkDfs( Bac_Ntk_t * p ) +{ + int i, iObj; + Vec_Int_t * vBoxes = Vec_IntAlloc( Bac_NtkBoxNum(p) ); + Bac_NtkStartCopies( p ); // -1 = not visited; 1 = finished + Bac_NtkForEachPi( p, iObj, i ) + Bac_ObjSetCopy( p, iObj, 1 ); + Bac_NtkForEachPo( p, iObj, i ) + Bac_NtkDfs_rec( p, Bac_ObjFanin(p, iObj), vBoxes ); + return vBoxes; +} + +/**Function************************************************************* + + Synopsis [Collects user boxes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_NtkDfsUserBoxes_rec( Bac_Ntk_t * p, int iObj, Vec_Int_t * vBoxes ) +{ + int k, iFanin; + assert( Bac_ObjIsBoxUser(p, iObj) ); + if ( Bac_ObjCopy(p, iObj) == 1 ) // visited + return 1; + if ( Bac_ObjCopy(p, iObj) == 0 ) // loop + return 0; + Bac_ObjSetCopy( p, iObj, 0 ); + Bac_BoxForEachFanin( p, iObj, iFanin, k ) + if ( Bac_ObjIsBo(p, iFanin) && Bac_ObjIsBoxUser(p, Bac_ObjFanin(p, iFanin)) ) + if ( !Bac_NtkDfsUserBoxes_rec( p, Bac_ObjFanin(p, iFanin), vBoxes ) ) + return 0; + Vec_IntPush( vBoxes, iObj ); + Bac_ObjSetCopy( p, iObj, 1 ); + return 1; +} +int Bac_NtkDfsUserBoxes( Bac_Ntk_t * p ) +{ + int iObj; + Bac_NtkStartCopies( p ); // -1 = not visited; 0 = on the path; 1 = finished + Vec_IntClear( &p->vArray ); + Bac_NtkForEachBoxUser( p, iObj ) + if ( !Bac_NtkDfsUserBoxes_rec( p, iObj, &p->vArray ) ) + { + printf( "Cyclic dependency of user boxes is detected.\n" ); + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_NtkCollapse_rec( Bac_Ntk_t * pNew, Bac_Ntk_t * p, Vec_Int_t * vSigs ) +{ + int i, iObj, iObjNew, iTerm; + Bac_NtkStartCopies( p ); + // set PI copies + assert( Vec_IntSize(vSigs) == Bac_NtkPiNum(p) ); + Bac_NtkForEachPi( p, iObj, i ) + Bac_ObjSetCopy( p, iObj, Vec_IntEntry(vSigs, i) ); + // duplicate internal objects and create buffers for hierarchy instances + Bac_NtkForEachBox( p, iObj ) + if ( Bac_ObjIsBoxPrim( p, iObj ) ) + Bac_BoxDup( pNew, p, iObj ); + else + { + Bac_BoxForEachBo( p, iObj, iTerm, i ) + { + iObjNew = Bac_ObjAlloc( pNew, BAC_OBJ_BI, -1 ); + iObjNew = Bac_ObjAlloc( pNew, BAC_BOX_BUF, -1 ); // buffer + iObjNew = Bac_ObjAlloc( pNew, BAC_OBJ_BO, -1 ); + Bac_ObjSetCopy( p, iTerm, iObjNew ); + } + } + // duplicate user modules and connect objects + Bac_NtkForEachBox( p, iObj ) + if ( Bac_ObjIsBoxPrim( p, iObj ) ) + { + Bac_BoxForEachBi( p, iObj, iTerm, i ) + Bac_ObjSetFanin( pNew, Bac_ObjCopy(p, iTerm), Bac_ObjCopy(p, Bac_ObjFanin(p, iTerm)) ); + } + else + { + Vec_IntClear( vSigs ); + Bac_BoxForEachBi( p, iObj, iTerm, i ) + Vec_IntPush( vSigs, Bac_ObjCopy(p, Bac_ObjFanin(p, iTerm)) ); + Bac_NtkCollapse_rec( pNew, Bac_BoxNtk(p, iObj), vSigs ); + assert( Vec_IntSize(vSigs) == Bac_BoxBoNum(p, iObj) ); + Bac_BoxForEachBo( p, iObj, iTerm, i ) + Bac_ObjSetFanin( pNew, Bac_ObjCopy(p, iTerm)-2, Vec_IntEntry(vSigs, i) ); + } + // collect POs + Vec_IntClear( vSigs ); + Bac_NtkForEachPo( p, iObj, i ) + Vec_IntPush( vSigs, Bac_ObjCopy(p, Bac_ObjFanin(p, iObj)) ); +} +Bac_Man_t * Bac_ManCollapse( Bac_Man_t * p ) +{ + int i, iObj; + Vec_Int_t * vSigs = Vec_IntAlloc( 1000 ); + Bac_Man_t * pNew = Bac_ManStart( p, 1 ); + Bac_Ntk_t * pRoot = Bac_ManRoot( p ); + Bac_Ntk_t * pRootNew = Bac_ManRoot( pNew ); + Bac_NtkAlloc( pRootNew, Bac_NtkNameId(pRoot), Bac_NtkPiNum(pRoot), Bac_NtkPoNum(pRoot), Bac_ManClpObjNum(p) ); + if ( Vec_IntSize(&pRoot->vInfo) ) + Vec_IntAppend( &pRootNew->vInfo, &pRoot->vInfo ); + Bac_NtkForEachPi( pRoot, iObj, i ) + Vec_IntPush( vSigs, Bac_ObjAlloc(pRootNew, BAC_OBJ_PI, -1) ); + Bac_NtkCollapse_rec( pRootNew, pRoot, vSigs ); + assert( Vec_IntSize(vSigs) == Bac_NtkPoNum(pRoot) ); + Bac_NtkForEachPo( pRoot, iObj, i ) + Bac_ObjAlloc( pRootNew, BAC_OBJ_PO, Vec_IntEntry(vSigs, i) ); + assert( Bac_NtkObjNum(pRootNew) == Bac_NtkObjNumAlloc(pRootNew) ); + Vec_IntFree( vSigs ); + // transfer PI/PO names + if ( Bac_NtkHasNames(pRoot) ) + { + Bac_NtkStartNames( pRootNew ); + Bac_NtkForEachPi( pRoot, iObj, i ) + Bac_ObjSetName( pRootNew, Bac_NtkPi(pRootNew, i), Bac_ObjName(pRoot, iObj) ); + Bac_NtkForEachPoDriver( pRoot, iObj, i ) + if ( !Bac_ObjIsPi(pRoot, iObj) ) + Bac_ObjSetName( pRootNew, Bac_ObjCopy(pRoot, iObj), Bac_ObjName(pRoot, iObj) ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacOper.c b/src/base/bac/bacOper.c new file mode 100644 index 00000000..0550eca6 --- /dev/null +++ b/src/base/bac/bacOper.c @@ -0,0 +1,365 @@ +/**CFile**************************************************************** + + FileName [bacOper.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Operator procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacOper.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_BoxCreate( Bac_Ntk_t * p, Bac_ObjType_t Type, Vec_Int_t * vFanins, int nInA, int nInB, int nOuts ) +{ + char pName[100]; int i, iObj, iFanin; + assert( BAC_OBJ_BOX < Type && Type < BAC_BOX_UNKNOWN ); + if ( BAC_BOX_CF <= Type && Type <= BAC_BOX_CZ ) + { + sprintf( pName, "ABCCTo%d", nOuts ); + assert( 0 == Vec_IntSize(vFanins) ); + iObj = Bac_BoxAlloc( p, Type, 0, nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( BAC_BOX_BUF <= Type && Type <= BAC_BOX_INV ) + { + char * pPref[2] = { "ABCBUF", "ABCINV" }; + assert( nInA == nOuts ); + assert( nInA == Vec_IntSize(vFanins) ); + sprintf( pName, "%sa%do%d", pPref[Type - BAC_BOX_BUF], nInA, nOuts ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( BAC_BOX_AND <= Type && Type <= BAC_BOX_XNOR ) + { + char * pPref[6] = { "ABCAND", "ABCNAND", "ABCOR", "ABCNOR", "ABCXOR", "ABCXNOR" }; + assert( nInA == nOuts && nInB == nOuts ); + assert( nInA + nInB == Vec_IntSize(vFanins) ); + sprintf( pName, "%sa%db%do%d", pPref[Type - BAC_BOX_AND], nInA, nInB, nOuts ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( Type == BAC_BOX_MUX ) + { + char * pPref[1] = { "ABCMUX" }; + assert( nInA == nOuts && nInB == nOuts ); + assert( 1 + nInA + nInB == Vec_IntSize(vFanins) ); + sprintf( pName, "%sc%da%db%do%d", pPref[Type - BAC_BOX_MUX], 1, nInA, nInB, nOuts ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( Type == BAC_BOX_MAJ ) + { + char * pPref[1] = { "ABCMAJ" }; + assert( nInA == 1 && nInB == 1 && nOuts == 1 ); + assert( 3 == Vec_IntSize(vFanins) ); + sprintf( pName, "%sa%db%dc%do%d", pPref[Type - BAC_BOX_MAJ], 1, 1, 1, 1 ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( BAC_BOX_RAND <= Type && Type <= BAC_BOX_RXNOR ) + { + char * pPref[6] = { "ABCRAND", "ABCRNAND", "ABCROR", "ABCRNOR", "ABCRXOR", "ABCRXNOR" }; + assert( nInA == nInB && 1 == nOuts ); + assert( nInA + nInB == Vec_IntSize(vFanins) ); + sprintf( pName, "%sa%db%do%d", pPref[Type - BAC_BOX_RAND], nInA, nInB, nOuts ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( Type == BAC_BOX_SEL ) + { + char * pPref[1] = { "ABCSEL" }; + assert( nInA * nOuts == nInB ); + assert( nInA + nInB == Vec_IntSize(vFanins) ); + sprintf( pName, "%sa%db%do%d", pPref[Type - BAC_BOX_SEL], nInA, nInB, nOuts ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + else if ( Type == BAC_BOX_PSEL ) + { + char * pPref[1] = { "ABCPSEL" }; + assert( nInA * nOuts == nInB ); + assert( 1 + nInA + nInB == Vec_IntSize(vFanins) ); + sprintf( pName, "%si%da%db%do%d", pPref[Type - BAC_BOX_SEL], 1, nInA, nInB, nOuts ); + iObj = Bac_BoxAlloc( p, Type, Vec_IntSize(vFanins), nOuts, Abc_NamStrFindOrAdd(p->pDesign->pMods, pName, NULL) ); + } + // add fanins + Vec_IntForEachEntry( vFanins, iFanin, i ) + Bac_ObjSetFanin( p, Bac_BoxBi(p, iObj, i), iFanin ); + return iObj; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_ObjClpWide( Bac_Ntk_t * p, int iBox ) +{ + Bac_ObjType_t Type = Bac_ObjType( p, iBox ); + int nBis = Bac_BoxBiNum(p, iBox); + int nBos = Bac_BoxBoNum(p, iBox); + int i, k, iObj; + assert( nBos > 1 ); + Vec_IntClear( &p->vArray ); + if ( BAC_BOX_BUF <= Type && Type <= BAC_BOX_INV ) + { + for ( i = 0; i < nBos; i++ ) + { + Vec_IntFill( &p->vArray2, 1, Bac_BoxFanin(p, iBox, i) ); + iObj = Bac_BoxCreate( p, Type, &p->vArray2, 1, -1, 1 ); + Vec_IntPush( &p->vArray, Bac_BoxBo(p, iObj, 0) ); + } + } + else if ( BAC_BOX_AND <= Type && Type <= BAC_BOX_XNOR ) + { + assert( nBis == 2 * nBos ); + for ( i = 0; i < nBos; i++ ) + { + Vec_IntFillTwo( &p->vArray2, 2, Bac_BoxFanin(p, iBox, i), Bac_BoxFanin(p, iBox, nBos+i) ); + iObj = Bac_BoxCreate( p, Type, &p->vArray2, 1, 1, 1 ); + Vec_IntPush( &p->vArray, Bac_BoxBo(p, iObj, 0) ); + } + } + else if ( Type == BAC_BOX_MUX ) + { + assert( nBis - 1 == 2 * nBos ); + for ( i = 0; i < nBos; i++ ) + { + Vec_IntFill( &p->vArray2, 1, Bac_BoxFanin(p, iBox, 0) ); + Vec_IntPushTwo( &p->vArray2, Bac_BoxFanin(p, iBox, 1+i), Bac_BoxFanin(p, iBox, 1+nBos+i) ); + iObj = Bac_BoxCreate( p, Type, &p->vArray2, 1, 1, 1 ); + Vec_IntPush( &p->vArray, Bac_BoxBo(p, iObj, 0) ); + } + } + else if ( Type == BAC_BOX_NMUX ) + { + int n, nIns = nBis / nBos; + assert( nBis % nBos == 0 ); + for ( n = 1; n < 32; n++ ) + if ( n + (1 << n) == nIns ) + break; + assert( n > 1 && n < 32 ); + for ( i = 0; i < nBos; i++ ) + { + Vec_IntClear( &p->vArray2 ); + for ( k = 0; k < n; k++ ) + Vec_IntPush( &p->vArray2, Bac_BoxFanin(p, iBox, k) ); + for ( k = 0; k < (1 << n); k++ ) + Vec_IntPush( &p->vArray2, Bac_BoxFanin(p, iBox, n + (1 << n) * i + k) ); + iObj = Bac_BoxCreate( p, Type, &p->vArray2, n, (1 << n), 1 ); + Vec_IntPush( &p->vArray, Bac_BoxBo(p, iObj, 0) ); + } + } + else if ( Type == BAC_BOX_SEL ) + { + } + else if ( Type == BAC_BOX_PSEL ) + { + } + else if ( Type == BAC_BOX_DFF || Type == BAC_BOX_LATCH ) + { + } + else if ( Type == BAC_BOX_DFFRS || Type == BAC_BOX_LATCHRS ) + { + } + else assert( 0 ); + Bac_BoxReplace( p, iBox, Vec_IntArray(&p->vArray), Vec_IntSize(&p->vArray) ); + return iBox; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_ObjClpArith( Bac_Ntk_t * p, int iBox ) +{ + Bac_ObjType_t Type = Bac_ObjType( p, iBox ); + int i, iObj = -1; + int nBis = 0;//Bac_NtkReadRangesPrim( Bac_BoxNtkName(p, iObj), &p->vArray, 0 ); + assert( nBis == Bac_BoxBiNum(p, iBox) ); + if ( Type == BAC_BOX_ADD ) + { + int Carry = Bac_BoxFanin(p, iBox, 0); + int nBits = Vec_IntEntry(&p->vArray, 1); + assert( Vec_IntSize(&p->vArray) == 3 ); + assert( Vec_IntEntry(&p->vArray, 0) == 1 ); + assert( Vec_IntEntry(&p->vArray, 2) == nBits ); + Vec_IntClear( &p->vArray ); + for ( i = 0; i < nBits; i++ ) + { + Vec_IntFill( &p->vArray2, 1, Carry ); + Vec_IntPushTwo( &p->vArray2, Bac_BoxFanin(p, iBox, 1+i), Bac_BoxFanin(p, iBox, 1+nBits+i) ); + iObj = Bac_BoxCreate( p, BAC_BOX_ADD, &p->vArray2, 1, 1, 1 ); + Carry = Bac_BoxBo(p, iObj, 1); + Vec_IntPush( &p->vArray, Bac_BoxBo(p, iObj, 0) ); + } + Vec_IntPush( &p->vArray, Carry ); + } + else if ( Type == BAC_BOX_SUB ) + { + int iConst, nBits = Vec_IntEntry(&p->vArray, 0); + assert( Vec_IntSize(&p->vArray) == 2 ); + assert( Vec_IntEntry(&p->vArray, 1) == nBits ); + // create inverter + Vec_IntClear( &p->vArray2 ); + for ( i = 0; i < nBits; i++ ) + Vec_IntPush( &p->vArray2, Bac_BoxFanin(p, iBox, nBits+i) ); + iObj = Bac_BoxCreate( p, BAC_BOX_INV, &p->vArray2, nBits, -1, nBits ); + // create constant + Vec_IntClear( &p->vArray2 ); + iConst = Bac_BoxCreate( p, BAC_BOX_CT, &p->vArray2, -1, -1, 1 ); + // collect fanins + Vec_IntFill( &p->vArray2, 1, iConst+1 ); + for ( i = 0; i < nBits; i++ ) + Vec_IntPush( &p->vArray2, Bac_BoxFanin(p, iBox, i) ); + for ( i = 0; i < nBits; i++ ) + Vec_IntPush( &p->vArray2, Bac_BoxBo(p, iObj, i) ); + // create adder + iObj = Bac_BoxCreate( p, BAC_BOX_ADD, &p->vArray2, nBits, nBits, nBits ); + // collect fanins + Vec_IntClear( &p->vArray ); + for ( i = 0; i < nBits; i++ ) + Vec_IntPush( &p->vArray, Bac_BoxBo(p, iObj, i) ); + } + else if ( Type == BAC_BOX_MUL ) + { + } + else if ( Type == BAC_BOX_DIV ) + { + } + else if ( Type == BAC_BOX_MOD ) + { + } + else if ( Type == BAC_BOX_REM ) + { + } + else if ( Type == BAC_BOX_POW ) + { + } + else if ( Type == BAC_BOX_MIN ) + { + } + else if ( Type == BAC_BOX_ABS ) + { + } + + else if ( Type == BAC_BOX_LTHAN ) + { + } + else if ( Type == BAC_BOX_LETHAN ) + { + } + else if ( Type == BAC_BOX_METHAN ) + { + } + else if ( Type == BAC_BOX_MTHAN ) + { + } + else if ( Type == BAC_BOX_EQU ) + { + } + else if ( Type == BAC_BOX_NEQU ) + { + } + + else if ( Type == BAC_BOX_SHIL ) + { + } + else if ( Type == BAC_BOX_SHIR ) + { + } + else if ( Type == BAC_BOX_ROTL ) + { + } + else if ( Type == BAC_BOX_ROTR ) + { + } + Bac_BoxReplace( p, iBox, Vec_IntArray(&p->vArray), Vec_IntSize(&p->vArray) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_ObjClpMemory( Bac_Ntk_t * p, int iBox ) +{ + int i, En, iNext, nItems = Bac_BoxBiNum(p, iBox); + assert( Bac_ObjType(p, iBox) == BAC_BOX_RAMBOX ); + assert( Bac_BoxBiNum(p, iBox) == Bac_BoxBoNum(p, iBox) ); + // for each fanin of RAMBOX, make sure address width is the same + Bac_BoxForEachFaninBox( p, iBox, iNext, i ) + assert( Bac_ObjType(p, iNext) == BAC_BOX_RAMWC ); + + // create decoders, selectors and flops + for ( i = 0; i < nItems; i++ ) + { + int BoxW = Bac_ObjFanin(p, Bac_BoxBi(p, iBox, i)); + int BoxR = Bac_ObjFanout(p, Bac_BoxBo(p, iBox, 0)); + assert( Bac_ObjType(p, BoxW) == BAC_BOX_RAMWC ); + assert( Bac_ObjType(p, BoxR) == BAC_BOX_RAMR ); + // create enable + Vec_IntFillTwo( &p->vArray2, 2, Bac_BoxFanin(p, BoxW, 1), Bac_BoxFanin(p, BoxR, 0) ); + En = Bac_BoxCreate( p, BAC_BOX_AND, &p->vArray2, 1, 1, 1 ); + En = Bac_BoxBo( p, En, 0 ); + // collect address + } + // for each fanout of RAMBOX, makes ure address width is the same +// Bac_BoxForEachFanoutBox( p, iBox, iNext, i ) +// assert( Bac_ObjType(p, iNext) == BAC_BOX_RAMR ); + // create selectors and connect them + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacPrs.h b/src/base/bac/bacPrs.h new file mode 100644 index 00000000..d45bceec --- /dev/null +++ b/src/base/bac/bacPrs.h @@ -0,0 +1,363 @@ +/**CFile**************************************************************** + + FileName [bacPrs.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Parser declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacPrs.h,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__base__prs__prs_h +#define ABC__base__prs__prs_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig/gia/gia.h" +#include "misc/util/utilNam.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + +// parser name types +typedef enum { + BAC_PRS_NAME = 0, // 0: name/variable + BAC_PRS_SLICE, // 1: slice + BAC_PRS_CONST, // 2: constant + BAC_PRS_CONCAT, // 3: concatentation +} Psr_ManType_t; + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// network +typedef struct Psr_Ntk_t_ Psr_Ntk_t; +struct Psr_Ntk_t_ +{ + // general info + int iModuleName; + unsigned fMapped : 1; + unsigned fSlices : 1; + unsigned fHasC0s : 1; + unsigned fHasC1s : 1; + unsigned fHasCXs : 1; + unsigned fHasCZs : 1; + Abc_Nam_t * pStrs; + // interface + Vec_Int_t vOrder; // order of signals + // signal names + Vec_Int_t vInouts; // inouts + Vec_Int_t vInputs; // inputs + Vec_Int_t vOutputs; // outputs + Vec_Int_t vWires; // wires + // signal ranges + Vec_Int_t vInoutsR; // inouts + Vec_Int_t vInputsR; // inputs + Vec_Int_t vOutputsR; // outputs + Vec_Int_t vWiresR; // wires + // slices/concatenations/objects + Vec_Int_t vSlices; // NameId + RangeId + Vec_Int_t vConcats; // array of NameId/SliceId/ConstId + Vec_Int_t vBoxes; // ModuleId + InstId + array of pairs {FormNameId, ActSignalId(NameId/SliceId/ConstId/ConcatId)} + Vec_Int_t vObjs; // box handles +}; + +// parser +typedef struct Psr_Man_t_ Psr_Man_t; +struct Psr_Man_t_ +{ + // input data + char * pName; // file name + char * pBuffer; // file contents + char * pLimit; // end of file + char * pCur; // current position + Abc_Nam_t * pStrs; // string manager + Psr_Ntk_t * pNtk; // current network + Vec_Ptr_t * vNtks; // input networks + // temporary data + Vec_Str_t vCover; // one SOP cover + Vec_Int_t vTemp; // array of tokens + Vec_Int_t vTemp2; // array of tokens + // statistics + Vec_Int_t vKnown; + Vec_Int_t vFailed; + Vec_Int_t vSucceeded; + // error handling + int fUsingTemp2; // vTemp2 is in use + char ErrorStr[1000]; // error +}; + +static inline Psr_Ntk_t * Psr_ManNtk( Vec_Ptr_t * vPrs, int i ) { return i >= 0 && i < Vec_PtrSize(vPrs) ? (Psr_Ntk_t *)Vec_PtrEntry(vPrs, i) : NULL; } +static inline Psr_Ntk_t * Psr_ManRoot( Vec_Ptr_t * vPrs ) { return Psr_ManNtk(vPrs, 0); } +static inline Abc_Nam_t * Psr_ManNameMan( Vec_Ptr_t * vPrs ) { return Psr_ManRoot(vPrs)->pStrs; } + +static inline int Psr_NtkId( Psr_Ntk_t * p ) { return p->iModuleName; } +static inline int Psr_NtkPioNum( Psr_Ntk_t * p ) { return Vec_IntSize(&p->vInouts); } +static inline int Psr_NtkPiNum( Psr_Ntk_t * p ) { return Vec_IntSize(&p->vInputs); } +static inline int Psr_NtkPoNum( Psr_Ntk_t * p ) { return Vec_IntSize(&p->vOutputs); } +static inline int Psr_NtkBoxNum( Psr_Ntk_t * p ) { return Vec_IntSize(&p->vObjs); } +static inline int Psr_NtkObjNum( Psr_Ntk_t * p ) { return Psr_NtkPioNum(p) + Psr_NtkPiNum(p) + Psr_NtkPoNum(p) + Psr_NtkBoxNum(p); } +static inline char * Psr_NtkStr( Psr_Ntk_t * p, int h ) { return Abc_NamStr(p->pStrs, h); } +static inline char * Psr_NtkName( Psr_Ntk_t * p ) { return Psr_NtkStr(p, Psr_NtkId(p)); } +static inline int Psr_NtkSigName( Psr_Ntk_t * p, int i ) { if (!p->fSlices) return i; assert(Abc_Lit2Att2(i) == BAC_PRS_NAME); return Abc_Lit2Var2(i); } + +static inline int Psr_SliceName( Psr_Ntk_t * p, int h ) { return Vec_IntEntry(&p->vSlices, h); } +static inline int Psr_SliceRange( Psr_Ntk_t * p, int h ) { return Vec_IntEntry(&p->vSlices, h+1); } + +static inline int Psr_CatSize( Psr_Ntk_t * p, int h ) { return Vec_IntEntry(&p->vConcats, h); } +static inline int * Psr_CatArray( Psr_Ntk_t * p, int h ) { return Vec_IntEntryP(&p->vConcats, h+1); } +static inline Vec_Int_t * Psr_CatSignals( Psr_Ntk_t * p, int h ) { static Vec_Int_t V; V.nSize = V.nCap = Psr_CatSize(p, h); V.pArray = Psr_CatArray(p, h); return &V; } + +static inline int Psr_BoxHand( Psr_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vObjs, i); } +static inline int Psr_BoxSize( Psr_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vBoxes, Psr_BoxHand(p, i))-2; } +static inline int Psr_BoxIONum( Psr_Ntk_t * p, int i ) { return Psr_BoxSize(p, i) / 2; } +static inline int Psr_BoxNtk( Psr_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vBoxes, Psr_BoxHand(p, i)+1); } +static inline void Psr_BoxSetNtk( Psr_Ntk_t * p, int i, int m ) { Vec_IntWriteEntry(&p->vBoxes, Psr_BoxHand(p, i)+1, m); } +static inline int Psr_BoxName( Psr_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vBoxes, Psr_BoxHand(p, i)+2); } +static inline int Psr_BoxIsNode( Psr_Ntk_t * p, int i ) { return!Vec_IntEntry(&p->vBoxes, Psr_BoxHand(p, i)+3); } // no formal names +static inline int * Psr_BoxArray( Psr_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vBoxes, Psr_BoxHand(p, i)+3); } +static inline Vec_Int_t * Psr_BoxSignals( Psr_Ntk_t * p, int i ) { static Vec_Int_t V; V.nSize = V.nCap = Psr_BoxSize(p, i); V.pArray = Psr_BoxArray(p, i); return &V; } + +#define Psr_ManForEachNameVec( vVec, p, pName, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pName) = Abc_NamStr(p->pStrs, Vec_IntEntry(vVec,i))); i++ ) + +#define Psr_NtkForEachPio( p, NameId, i ) \ + for ( i = 0; i < Psr_NtkPioNum(p) && ((NameId) = Vec_IntEntry(&p->vInouts, i)); i++ ) +#define Psr_NtkForEachPi( p, NameId, i ) \ + for ( i = 0; i < Psr_NtkPiNum(p) && ((NameId) = Vec_IntEntry(&p->vInputs, i)); i++ ) +#define Psr_NtkForEachPo( p, NameId, i ) \ + for ( i = 0; i < Psr_NtkPoNum(p) && ((NameId) = Vec_IntEntry(&p->vOutputs, i)); i++ ) +#define Psr_NtkForEachBox( p, vVec, i ) \ + for ( i = 0; i < Psr_NtkBoxNum(p) && ((vVec) = Psr_BoxSignals(p, i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +// create error message +static inline int Psr_ManErrorSet( Psr_Man_t * p, char * pError, int Value ) +{ + assert( !p->ErrorStr[0] ); + sprintf( p->ErrorStr, "%s", pError ); + return Value; +} +// clear error message +static inline void Psr_ManErrorClear( Psr_Man_t * p ) +{ + p->ErrorStr[0] = '\0'; +} +// print error message +static inline int Psr_ManErrorPrint( Psr_Man_t * p ) +{ + char * pThis; int iLine = 0; + if ( !p->ErrorStr[0] ) return 1; + for ( pThis = p->pBuffer; pThis < p->pCur; pThis++ ) + iLine += (int)(*pThis == '\n'); + printf( "Line %d: %s\n", iLine, p->ErrorStr ); + return 0; +} + +// parsing network +static inline void Psr_ManInitializeNtk( Psr_Man_t * p, int iName, int fSlices ) +{ + assert( p->pNtk == NULL ); + p->pNtk = ABC_CALLOC( Psr_Ntk_t, 1 ); + p->pNtk->iModuleName = iName; + p->pNtk->fSlices = fSlices; + p->pNtk->pStrs = Abc_NamRef( p->pStrs ); + Vec_PtrPush( p->vNtks, p->pNtk ); +} +static inline void Psr_ManFinalizeNtk( Psr_Man_t * p ) +{ + assert( p->pNtk != NULL ); + p->pNtk = NULL; +} + +// parsing slice/concatentation/box +static inline int Psr_NtkAddSlice( Psr_Ntk_t * p, int Name, int Range ) +{ + int Value = Vec_IntSize(&p->vSlices); + Vec_IntPushTwo( &p->vSlices, Name, Range ); + return Value; +} +static inline int Psr_NtkAddConcat( Psr_Ntk_t * p, Vec_Int_t * vTemp ) +{ + int Value; + if ( !(Vec_IntSize(&p->vConcats) & 1) ) + Vec_IntPush(&p->vConcats, -1); + Value = Vec_IntSize(&p->vConcats); + assert( Value & 1 ); + Vec_IntPush( &p->vConcats, Vec_IntSize(vTemp) ); + Vec_IntAppend( &p->vConcats, vTemp ); + return Value; +} +static inline void Psr_NtkAddBox( Psr_Ntk_t * p, int ModName, int InstName, Vec_Int_t * vTemp ) +{ + int Value; + assert( Vec_IntSize(vTemp) % 2 == 0 ); + if ( !(Vec_IntSize(&p->vBoxes) & 1) ) + Vec_IntPush(&p->vBoxes, -1); + Value = Vec_IntSize(&p->vBoxes); + assert( Value & 1 ); + Vec_IntPush( &p->vObjs, Value ); + // create entry + Vec_IntPush( &p->vBoxes, Vec_IntSize(vTemp)+2 ); + Vec_IntPush( &p->vBoxes, ModName ); + Vec_IntPush( &p->vBoxes, InstName ); + Vec_IntAppend( &p->vBoxes, vTemp ); +} + + +static inline char * Psr_ManLoadFile( char * pFileName, char ** ppLimit ) +{ + char * pBuffer; + int nFileSize, RetValue; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open input file.\n" ); + return NULL; + } + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + // move the file current reading position to the beginning + rewind( pFile ); + // load the contents of the file into memory + pBuffer = ABC_ALLOC( char, nFileSize + 16 ); + pBuffer[0] = '\n'; + RetValue = fread( pBuffer+1, nFileSize, 1, pFile ); + fclose( pFile ); + // terminate the string with '\0' + pBuffer[nFileSize + 1] = '\n'; + pBuffer[nFileSize + 2] = '\0'; + *ppLimit = pBuffer + nFileSize + 3; + return pBuffer; +} +static inline Psr_Man_t * Psr_ManAlloc( char * pFileName ) +{ + Psr_Man_t * p; + char * pBuffer, * pLimit; + pBuffer = Psr_ManLoadFile( pFileName, &pLimit ); + if ( pBuffer == NULL ) + return NULL; + p = ABC_CALLOC( Psr_Man_t, 1 ); + p->pName = pFileName; + p->pBuffer = pBuffer; + p->pLimit = pLimit; + p->pCur = pBuffer; + p->pStrs = Abc_NamStart( 1000, 24 ); + p->vNtks = Vec_PtrAlloc( 100 ); + return p; +} + +static inline void Psr_NtkFree( Psr_Ntk_t * p ) +{ + if ( p->pStrs ) + Abc_NamDeref( p->pStrs ); + Vec_IntErase( &p->vOrder ); + Vec_IntErase( &p->vInouts ); + Vec_IntErase( &p->vInputs ); + Vec_IntErase( &p->vOutputs ); + Vec_IntErase( &p->vWires ); + Vec_IntErase( &p->vInoutsR ); + Vec_IntErase( &p->vInputsR ); + Vec_IntErase( &p->vOutputsR ); + Vec_IntErase( &p->vWiresR ); + Vec_IntErase( &p->vSlices ); + Vec_IntErase( &p->vConcats ); + Vec_IntErase( &p->vBoxes ); + Vec_IntErase( &p->vObjs ); + ABC_FREE( p ); +} + +static inline void Psr_ManVecFree( Vec_Ptr_t * vPrs ) +{ + Psr_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Psr_Ntk_t *, vPrs, pNtk, i ) + Psr_NtkFree( pNtk ); + Vec_PtrFree( vPrs ); +} + +static inline void Psr_ManFree( Psr_Man_t * p ) +{ + if ( p->pStrs ) + Abc_NamDeref( p->pStrs ); + if ( p->vNtks ) + Psr_ManVecFree( p->vNtks ); + // temporary + Vec_StrErase( &p->vCover ); + Vec_IntErase( &p->vTemp ); + Vec_IntErase( &p->vTemp2 ); + Vec_IntErase( &p->vKnown ); + Vec_IntErase( &p->vFailed ); + Vec_IntErase( &p->vSucceeded ); + ABC_FREE( p->pBuffer ); + ABC_FREE( p ); +} + +static inline int Psr_NtkMemory( Psr_Ntk_t * p ) +{ + int nMem = sizeof(Psr_Ntk_t); + nMem += Vec_IntMemory( &p->vOrder ); + nMem += Vec_IntMemory( &p->vInouts ); + nMem += Vec_IntMemory( &p->vInputs ); + nMem += Vec_IntMemory( &p->vOutputs ); + nMem += Vec_IntMemory( &p->vWires ); + nMem += Vec_IntMemory( &p->vInoutsR ); + nMem += Vec_IntMemory( &p->vInputsR ); + nMem += Vec_IntMemory( &p->vOutputsR ); + nMem += Vec_IntMemory( &p->vWiresR ); + nMem += Vec_IntMemory( &p->vSlices ); + nMem += Vec_IntMemory( &p->vBoxes ); + nMem += Vec_IntMemory( &p->vConcats ); + return nMem; +} +static inline int Psr_ManMemory( Vec_Ptr_t * vPrs ) +{ + Psr_Ntk_t * pNtk; int i; + int nMem = Vec_PtrMemory(vPrs); + Vec_PtrForEachEntry( Psr_Ntk_t *, vPrs, pNtk, i ) + nMem += Psr_NtkMemory( pNtk ); + nMem += Abc_NamMemUsed(Psr_ManNameMan(vPrs)); + return nMem; +} + + + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== bac.c ========================================================*/ + + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/bac/bacPrsBuild.c b/src/base/bac/bacPrsBuild.c new file mode 100644 index 00000000..e5c9c354 --- /dev/null +++ b/src/base/bac/bacPrsBuild.c @@ -0,0 +1,356 @@ +/**CFile**************************************************************** + + FileName [bacPrsBuild.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Parse tree to netlist transformation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacPrsBuild.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" +#include "map/mio/mio.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Psr_ManIsMapped( Psr_Ntk_t * pNtk ) +{ + Vec_Int_t * vSigs; int iBox; + Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + if ( pLib == NULL ) + return 0; + Psr_NtkForEachBox( pNtk, vSigs, iBox ) + if ( !Psr_BoxIsNode(pNtk, iBox) ) + { + int NtkId = Psr_BoxNtk( pNtk, iBox ); + if ( Mio_LibraryReadGateByName(pLib, Psr_NtkStr(pNtk, NtkId), NULL) ) + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Psr_NtkCountObjects( Psr_Ntk_t * pNtk ) +{ + Vec_Int_t * vFanins; + int i, Count = Psr_NtkObjNum(pNtk); + Psr_NtkForEachBox( pNtk, vFanins, i ) + Count += Psr_BoxIONum(pNtk, i); + return Count; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// replaces NameIds of formal names by their index in the box model +void Psr_ManRemapOne( Vec_Int_t * vSigs, Psr_Ntk_t * pNtkBox, Vec_Int_t * vMap ) +{ + int i, NameId; + // map formal names into I/O indexes + Psr_NtkForEachPi( pNtkBox, NameId, i ) + { + assert( Vec_IntEntry(vMap, NameId) == -1 ); + Vec_IntWriteEntry( vMap, NameId, i + 1 ); // +1 to keep 1st form input non-zero + } + Psr_NtkForEachPo( pNtkBox, NameId, i ) + { + assert( Vec_IntEntry(vMap, NameId) == -1 ); + Vec_IntWriteEntry( vMap, NameId, Psr_NtkPiNum(pNtkBox) + i + 1 ); // +1 to keep 1st form input non-zero + } + // remap box + assert( Vec_IntSize(vSigs) % 2 == 0 ); + Vec_IntForEachEntry( vSigs, NameId, i ) + { + assert( Vec_IntEntry(vMap, NameId) != -1 ); + Vec_IntWriteEntry( vSigs, i++, Vec_IntEntry(vMap, NameId) ); + } + // unmap formal inputs + Psr_NtkForEachPi( pNtkBox, NameId, i ) + Vec_IntWriteEntry( vMap, NameId, -1 ); + Psr_NtkForEachPo( pNtkBox, NameId, i ) + Vec_IntWriteEntry( vMap, NameId, -1 ); +} +void Psr_ManRemapGate( Vec_Int_t * vSigs ) +{ + int i, FormId; + Vec_IntForEachEntry( vSigs, FormId, i ) + Vec_IntWriteEntry( vSigs, i, i/2 + 1 ), i++; +} +void Psr_ManRemapBoxes( Bac_Man_t * pNew, Vec_Ptr_t * vDes, Psr_Ntk_t * pNtk, Vec_Int_t * vMap ) +{ + Vec_Int_t * vSigs; int iBox; + Psr_NtkForEachBox( pNtk, vSigs, iBox ) + if ( !Psr_BoxIsNode(pNtk, iBox) ) + { + int NtkId = Psr_BoxNtk( pNtk, iBox ); + int NtkIdNew = Bac_ManNtkFindId( pNew, Psr_NtkStr(pNtk, NtkId) ); + assert( NtkIdNew > 0 ); + Psr_BoxSetNtk( pNtk, iBox, NtkIdNew ); + if ( NtkIdNew <= Bac_ManNtkNum(pNew) ) + Psr_ManRemapOne( vSigs, Psr_ManNtk(vDes, NtkIdNew-1), vMap ); + //else + // Psr_ManRemapGate( vSigs ); + } +} +void Psr_ManCleanMap( Psr_Ntk_t * pNtk, Vec_Int_t * vMap ) +{ + Vec_Int_t * vSigs; + int i, k, NameId, Sig; + Psr_NtkForEachPi( pNtk, NameId, i ) + Vec_IntWriteEntry( vMap, NameId, -1 ); + Psr_NtkForEachBox( pNtk, vSigs, i ) + Vec_IntForEachEntryDouble( vSigs, NameId, Sig, k ) + Vec_IntWriteEntry( vMap, Psr_NtkSigName(pNtk, Sig), -1 ); + Psr_NtkForEachPo( pNtk, NameId, i ) + Vec_IntWriteEntry( vMap, NameId, -1 ); +} +// create maps of NameId and boxes +void Psr_ManBuildNtk( Bac_Ntk_t * pNew, Vec_Ptr_t * vDes, Psr_Ntk_t * pNtk, Vec_Int_t * vMap, Vec_Int_t * vBoxes ) +{ + Psr_Ntk_t * pNtkBox; Vec_Int_t * vSigs; int iBox; + int i, Index, NameId, iObj, iConst0, iTerm; + int iNonDriven = -1, nNonDriven = 0; + assert( Psr_NtkPioNum(pNtk) == 0 ); + Psr_ManRemapBoxes( pNew->pDesign, vDes, pNtk, vMap ); + Bac_NtkStartNames( pNew ); + // create primary inputs + Psr_NtkForEachPi( pNtk, NameId, i ) + { + if ( Vec_IntEntry(vMap, NameId) != -1 ) + printf( "Primary inputs %d and %d have the same name.\n", Vec_IntEntry(vMap, NameId), i ); + iObj = Bac_ObjAlloc( pNew, BAC_OBJ_PI, -1 ); + Bac_ObjSetName( pNew, iObj, Abc_Var2Lit2(NameId, BAC_NAME_BIN) ); + Vec_IntWriteEntry( vMap, NameId, iObj ); + } + // create box outputs + Vec_IntClear( vBoxes ); + Psr_NtkForEachBox( pNtk, vSigs, iBox ) + if ( !Psr_BoxIsNode(pNtk, iBox) ) + { + pNtkBox = Psr_ManNtk( vDes, Psr_BoxNtk(pNtk, iBox)-1 ); + if ( pNtkBox == NULL ) + { + iObj = Bac_BoxAlloc( pNew, BAC_BOX_GATE, Vec_IntSize(vSigs)/2-1, 1, Psr_BoxNtk(pNtk, iBox) ); + Bac_ObjSetName( pNew, iObj, Abc_Var2Lit2(Psr_BoxName(pNtk, iBox), BAC_NAME_BIN) ); + // consider box output + NameId = Vec_IntEntryLast( vSigs ); + NameId = Psr_NtkSigName( pNtk, NameId ); + if ( Vec_IntEntry(vMap, NameId) != -1 ) + printf( "Box output name %d is already driven.\n", NameId ); + iTerm = Bac_BoxBo( pNew, iObj, 0 ); + Bac_ObjSetName( pNew, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) ); + Vec_IntWriteEntry( vMap, NameId, iTerm ); + } + else + { + iObj = Bac_BoxAlloc( pNew, BAC_OBJ_BOX, Psr_NtkPiNum(pNtkBox), Psr_NtkPoNum(pNtkBox), Psr_BoxNtk(pNtk, iBox) ); + Bac_ObjSetName( pNew, iObj, Abc_Var2Lit2(Psr_BoxName(pNtk, iBox), BAC_NAME_BIN) ); + Bac_NtkSetHost( Bac_ManNtk(pNew->pDesign, Psr_BoxNtk(pNtk, iBox)), Bac_NtkId(pNew), iObj ); + Vec_IntForEachEntry( vSigs, Index, i ) + { + i++; + if ( --Index < Psr_NtkPiNum(pNtkBox) ) + continue; + assert( Index - Psr_NtkPiNum(pNtkBox) < Psr_NtkPoNum(pNtkBox) ); + // consider box output + NameId = Vec_IntEntry( vSigs, i ); + NameId = Psr_NtkSigName( pNtk, NameId ); + if ( Vec_IntEntry(vMap, NameId) != -1 ) + printf( "Box output name %d is already driven.\n", NameId ); + iTerm = Bac_BoxBo( pNew, iObj, Index - Psr_NtkPiNum(pNtkBox) ); + Bac_ObjSetName( pNew, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) ); + Vec_IntWriteEntry( vMap, NameId, iTerm ); + } + } + // remember box + Vec_IntPush( vBoxes, iObj ); + } + else + { + iObj = Bac_BoxAlloc( pNew, (Bac_ObjType_t)Psr_BoxNtk(pNtk, iBox), Psr_BoxIONum(pNtk, iBox)-1, 1, -1 ); + // consider box output + NameId = Vec_IntEntryLast( vSigs ); + NameId = Psr_NtkSigName( pNtk, NameId ); + if ( Vec_IntEntry(vMap, NameId) != -1 ) + printf( "Node output name %d is already driven.\n", NameId ); + iTerm = Bac_BoxBo( pNew, iObj, 0 ); + Bac_ObjSetName( pNew, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) ); + Vec_IntWriteEntry( vMap, NameId, iTerm ); + // remember box + Vec_IntPush( vBoxes, iObj ); + } + // add fanins for box inputs + Psr_NtkForEachBox( pNtk, vSigs, iBox ) + if ( !Psr_BoxIsNode(pNtk, iBox) ) + { + pNtkBox = Psr_ManNtk( vDes, Psr_BoxNtk(pNtk, iBox)-1 ); + iObj = Vec_IntEntry( vBoxes, iBox ); + if ( pNtkBox == NULL ) + { + Vec_IntForEachEntryStop( vSigs, Index, i, Vec_IntSize(vSigs)-2 ) + { + i++; + NameId = Vec_IntEntry( vSigs, i ); + NameId = Psr_NtkSigName( pNtk, NameId ); + iTerm = Bac_BoxBi( pNew, iObj, i/2 ); + if ( Vec_IntEntry(vMap, NameId) == -1 ) + { + iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 ); + Vec_IntWriteEntry( vMap, NameId, iConst0+1 ); + if ( iNonDriven == -1 ) + iNonDriven = NameId; + nNonDriven++; + } + Bac_ObjSetFanin( pNew, iTerm, Vec_IntEntry(vMap, NameId) ); + } + } + else + { + Vec_IntForEachEntry( vSigs, Index, i ) + { + i++; + if ( --Index >= Psr_NtkPiNum(pNtkBox) ) + continue; + NameId = Vec_IntEntry( vSigs, i ); + NameId = Psr_NtkSigName( pNtk, NameId ); + iTerm = Bac_BoxBi( pNew, iObj, Index ); + if ( Vec_IntEntry(vMap, NameId) == -1 ) + { + iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 ); + Vec_IntWriteEntry( vMap, NameId, iConst0+1 ); + if ( iNonDriven == -1 ) + iNonDriven = NameId; + nNonDriven++; + } + Bac_ObjSetFanin( pNew, iTerm, Vec_IntEntry(vMap, NameId) ); + } + } + } + else + { + iObj = Vec_IntEntry( vBoxes, iBox ); + Vec_IntForEachEntryStop( vSigs, Index, i, Vec_IntSize(vSigs)-2 ) + { + NameId = Vec_IntEntry( vSigs, ++i ); + NameId = Psr_NtkSigName( pNtk, NameId ); + iTerm = Bac_BoxBi( pNew, iObj, i/2 ); + if ( Vec_IntEntry(vMap, NameId) == -1 ) + { + iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 ); + Vec_IntWriteEntry( vMap, NameId, iConst0+1 ); + if ( iNonDriven == -1 ) + iNonDriven = NameId; + nNonDriven++; + } + Bac_ObjSetFanin( pNew, iTerm, Vec_IntEntry(vMap, NameId) ); + } + } + // add fanins for primary outputs + Psr_NtkForEachPo( pNtk, NameId, i ) + if ( Vec_IntEntry(vMap, NameId) == -1 ) + { + iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 ); + Vec_IntWriteEntry( vMap, NameId, iConst0+1 ); + if ( iNonDriven == -1 ) + iNonDriven = NameId; + nNonDriven++; + } + Psr_NtkForEachPo( pNtk, NameId, i ) + iObj = Bac_ObjAlloc( pNew, BAC_OBJ_PO, Vec_IntEntry(vMap, NameId) ); + if ( nNonDriven ) + printf( "Module %s has %d non-driven nets (for example, %s).\n", Psr_NtkName(pNtk), nNonDriven, Psr_NtkStr(pNtk, iNonDriven) ); + Psr_ManCleanMap( pNtk, vMap ); + // setup info + Vec_IntForEachEntry( &pNtk->vOrder, NameId, i ) + Bac_NtkAddInfo( pNew, NameId, -1, -1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bac_Man_t * Psr_ManBuildCba( char * pFileName, Vec_Ptr_t * vDes ) +{ + Psr_Ntk_t * pNtk = Psr_ManRoot( vDes ); int i; + Bac_Man_t * pNew = Bac_ManAlloc( pFileName, Vec_PtrSize(vDes) ); + Vec_Int_t * vMap = Vec_IntStartFull( Abc_NamObjNumMax(pNtk->pStrs) + 1 ); + Vec_Int_t * vTmp = Vec_IntAlloc( Psr_NtkBoxNum(pNtk) ); + Abc_NamDeref( pNew->pStrs ); + pNew->pStrs = Abc_NamRef( pNtk->pStrs ); + Vec_PtrForEachEntry( Psr_Ntk_t *, vDes, pNtk, i ) + Bac_NtkAlloc( Bac_ManNtk(pNew, i+1), Psr_NtkId(pNtk), Psr_NtkPiNum(pNtk), Psr_NtkPoNum(pNtk), Psr_NtkCountObjects(pNtk) ); + if ( (pNtk->fMapped || (pNtk->fSlices && Psr_ManIsMapped(pNtk))) && !Bac_NtkBuildLibrary(pNew) ) + Bac_ManFree(pNew), pNew = NULL; + else + Vec_PtrForEachEntry( Psr_Ntk_t *, vDes, pNtk, i ) + Psr_ManBuildNtk( Bac_ManNtk(pNew, i+1), vDes, pNtk, vMap, vTmp ); + assert( Vec_IntCountEntry(vMap, -1) == Vec_IntSize(vMap) ); + Vec_IntFree( vMap ); + Vec_IntFree( vTmp ); +// Vec_StrPrint( &Bac_ManNtk(pNew, 1)->vType, 1 ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacPrsTrans.c b/src/base/bac/bacPrsTrans.c new file mode 100644 index 00000000..0aba3371 --- /dev/null +++ b/src/base/bac/bacPrsTrans.c @@ -0,0 +1,211 @@ +/**CFile**************************************************************** + + FileName [bacPrsTrans.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Parse tree to netlist transformation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacPrsTrans.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Bac_Trip_t_ Bac_Trip_t; +struct Bac_Trip_t_ +{ + Bac_ObjType_t Type; + char * pName; + char * pCode; + char * pSigs[6]; +}; +/* +static Bac_Trip_t s_Types[100] = +{ + { BAC_BOX_CT , "VERIFIC_PWR", "1", {"o"} }, + { BAC_BOX_CF , "VERIFIC_GND", "1", {"o"} }, + { BAC_BOX_CX , "VERIFIC_X", "1", {"o"} }, + { BAC_BOX_CZ , "VERIFIC_Z", "1", {"o"} }, + { BAC_BOX_INV , "VERIFIC_INV", "11", {"i","o"} }, + { BAC_BOX_BUF , "VERIFIC_BUF", "11", {"i","o"} }, + { BAC_BOX_AND , "VERIFIC_AND", "111", {"a0","a1","o"} }, + { BAC_BOX_NAND , "VERIFIC_NAND", "111", {"a0","a1","o"} }, + { BAC_BOX_OR , "VERIFIC_OR", "111", {"a0","a1","o"} }, + { BAC_BOX_NOR , "VERIFIC_NOR", "111", {"a0","a1","o"} }, + { BAC_BOX_XOR , "VERIFIC_XOR", "111", {"a0","a1","o"} }, + { BAC_BOX_XNOR , "VERIFIC_XNOR", "111", {"a0","a1","o"} }, + { BAC_BOX_MUX , "VERIFIC_MUX", "1111", {"c","a1","a0","o"} }, // changed order + { (Bac_ObjType_t)-1, "VERIFIC_PULLUP", "1", {"o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_PULLDOWN", "1", {"o"} }, + { BAC_BOX_TRI , "VERIFIC_TRI", "111", {"i","c","o"} }, + { BAC_BOX_LATCH , "VERIFIC_DLATCH", "11111", {"d","async_val","async_cond","gate","q"} }, // changed order + { BAC_BOX_LATCHRS , "VERIFIC_DLATCHRS", "11111", {"d","s","r","gate","q"} }, // changed order + { BAC_BOX_DFF , "VERIFIC_DFF", "11111", {"d","async_val","async_cond","clk","q"} }, // changed order + { BAC_BOX_DFFRS , "VERIFIC_DFFRS", "11111", {"d","s","r","clk","q"} }, // changed order + { (Bac_ObjType_t)-1, "VERIFIC_NMOS", "111", {"c","d","o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_PMOS", "111", {"c","d","o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_CMOS", "1111", {"d","nc","pc","o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_TRAN", "111", {"inout1","inout2","control"} }, + { BAC_BOX_ADD , "VERIFIC_FADD", "11111", {"cin","a","b","o","cout"} }, + { (Bac_ObjType_t)-1, "VERIFIC_RCMOS", "1111", {"d","nc","pc","o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_RNMOS", "111", {"c","d","o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_RPMOS", "111", {"c","d","o"} }, + { (Bac_ObjType_t)-1, "VERIFIC_RTRAN", "111", {"inout1","inout2","control"} }, + { (Bac_ObjType_t)-1, "VERIFIC_HDL_ASSERTION", "1", {"condition"} }, + { BAC_BOX_ADD , "add_", "1aba1", {"cin","a","b","o","cout"} }, + { BAC_BOX_MUL , "mult_", "ab?", {"a","b","o"} }, // ? = a * b + { BAC_BOX_DIV , "div_", "ab?", {"a","b","o"} }, // ? = + { BAC_BOX_MOD , "mod_", "ab?", {"a","b","o"} }, // ? = + { BAC_BOX_REM , "rem_", "ab?", {"a","b","o"} }, // ? = + { BAC_BOX_SHIL , "shift_left_", "1aba", {"cin","a","amount","o"} }, + { BAC_BOX_SHIR , "shift_right_", "1aba", {"cin","a","amount","o"} }, + { BAC_BOX_ROTL , "rotate_left_", "aba", {"a","amount","o"} }, + { BAC_BOX_ROTR , "rotate_right_", "aba", {"a","amount","o"} }, + { BAC_BOX_RAND , "reduce_and_", "ab1", {"a","o"} }, + { BAC_BOX_ROR , "reduce_or_", "ab1", {"a","o"} }, + { BAC_BOX_RXOR , "reduce_xor_", "ab1", {"a","o"} }, + { BAC_BOX_RNAND , "reduce_nand_", "ab1", {"a","o"} }, + { BAC_BOX_RNOR , "reduce_nor_", "ab1", {"a","o"} }, + { BAC_BOX_RXNOR , "reduce_xnor_", "ab1", {"a","o"} }, + { BAC_BOX_LTHAN , "LessThan_", "1ab1", {"cin","a","b","o"} }, + { BAC_BOX_NMUX , "Mux_", "ab1", {"sel","data","o"} }, + { BAC_BOX_SEL , "Select_", "aaa", {"sel","data","o"} }, + { BAC_BOX_DEC , "Decoder_", "a?", {"a","o"} }, // ? = (1 << a) + { BAC_BOX_EDEC , "EnabledDecoder_", "1a?", {"en","i","o"} }, // ? = (1 << a) + { BAC_BOX_PSEL , "PrioSelect_", "1aaa", {"cin","sel","data","o"} }, + { BAC_BOX_RAM , "DualPortRam_", "1abab", {"write_enable","write_address","write_data","read_address","read_data"} }, + { BAC_BOX_RAMR , "ReadPort_", "1a1b", {"read_enable", "read_address", "RAM", "read_data" } }, + { BAC_BOX_RAMW , "WritePort_", "1ab1", {"write_enable","write_address","write_data", "RAM"} }, + { BAC_BOX_RAMWC , "ClockedWritePort_", "11ab1", {"clk","write_enable","write_address","write_data", "RAM"} }, + { BAC_BOX_LUT , "lut", "?", {"i","o"} }, + { BAC_BOX_AND , "and_", "aaa", {"a","b","o"} }, + { BAC_BOX_OR , "or_", "aaa", {"a","b","o"} }, + { BAC_BOX_XOR , "xor_", "aaa", {"a","b","o"} }, + { BAC_BOX_NAND , "nand_", "aaa", {"a","b","o"} }, + { BAC_BOX_NOR , "nor_", "aaa", {"a","b","o"} }, + { BAC_BOX_XNOR , "xnor_", "aaa", {"a","b","o"} }, + { BAC_BOX_BUF , "buf_", "aa", {"i","o"} }, + { BAC_BOX_INV , "inv_", "aa", {"i","o"} }, + { BAC_BOX_TRI , "tri_", "a1a", {"i","c","o"} }, + { BAC_BOX_SUB , "sub_", "aaa", {"a","b","o"} }, + { BAC_BOX_MIN , "unary_minus_", "aa", {"i","o"} }, + { BAC_BOX_EQU , "equal_", "aa1", {"a","b","o"} }, + { BAC_BOX_NEQU , "not_equal_", "aa1", {"a","b","o"} }, + { BAC_BOX_MUX , "mux_", "1aaa", {"cond","d1","d0","o"} }, // changed order + { BAC_BOX_NMUX , "wide_mux_", "ab?", {"sel","data","o"} }, // ? = b / (1 << a) + { BAC_BOX_SEL , "wide_select_", "ab?", {"sel","data","o"} }, // ? = b / a + { BAC_BOX_DFF , "wide_dff_", "aaa1a", {"d","async_val","async_cond","clock","q"} }, + { BAC_BOX_DFFRS , "wide_dlatch_", "aaa1a", {"d","set","reset","clock","q"} }, + { BAC_BOX_LATCHRS , "wide_dffrs_", "aaa1a", {"d","set","reset","clock","q"} }, + { BAC_BOX_LATCH , "wide_dlatchrs_", "aaa1a", {"d","async_val","async_cond","clock","q"} }, + { BAC_BOX_PSEL , "wide_prio_select_", "ab??", {"sel","data","carry_in","o"} }, // ? = b / a + { BAC_BOX_POW , "pow_", "abc", {"a","b","o"} }, // ? = + { BAC_BOX_PENC , "PrioEncoder_", "a?", {"sel","o"} }, + { BAC_BOX_ABS , "abs", "aa", {"i","o"} } +}; +*/ + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Count range size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Psr_ManRangeSizeName( Psr_Ntk_t * p, int Name ) +{ + return 1; +} +static inline int Psr_ManRangeSizeRange( Psr_Ntk_t * p, int Range ) +{ + char * pStr; + int Left, Right; + if ( Range == 0 ) + return 1; + pStr = Psr_NtkStr( p, Range ); + assert( pStr[0] == '[' ); + Left = Right = atoi( pStr + 1 ); + pStr = strstr( pStr, "=" ); + if ( pStr ) + Right = atoi( pStr + 1 ); + return 1 + (Left > Right ? Left - Right : Right - Left); +} +static inline int Psr_ManRangeSizeConst( Psr_Ntk_t * p, int Const ) +{ + return atoi( Psr_NtkStr(p, Const) ); +} +static inline int Psr_ManRangeSizeConcat( Psr_Ntk_t * p, int Con ) +{ + extern int Psr_ManRangeSizeArray( Psr_Ntk_t * p, Vec_Int_t * vSlices, int Start, int Stop ); + Vec_Int_t * vSigs = Psr_CatSignals(p, Con); + return Psr_ManRangeSizeArray( p, vSigs, 0, Vec_IntSize(vSigs) ); +} +static inline int Psr_ManRangeSizeSignal( Psr_Ntk_t * p, int Sig ) +{ + int Value = Abc_Lit2Var2( Sig ); + Psr_ManType_t Type = (Psr_ManType_t)Abc_Lit2Att2( Sig ); + if ( Type == BAC_PRS_NAME ) + return Psr_ManRangeSizeName( p, Value ); + if ( Type == BAC_PRS_SLICE ) + return Psr_ManRangeSizeRange( p, Psr_SliceRange(p, Value) ); + if ( Type == BAC_PRS_CONST ) + return Psr_ManRangeSizeConst( p, Value ); + if ( Type == BAC_PRS_CONCAT ) + return Psr_ManRangeSizeConcat( p, Value ); + assert( 0 ); + return 0; +} +int Psr_ManRangeSizeArray( Psr_Ntk_t * p, Vec_Int_t * vSlices, int Start, int Stop ) +{ + int i, Sig, Count = 0; + assert( Vec_IntSize(vSlices) > 0 ); + Vec_IntForEachEntryStartStop( vSlices, Sig, i, Start, Stop ) + Count += Psr_ManRangeSizeSignal( p, Sig ); + return Count; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacPrtAbc.c b/src/base/bac/bacPrtAbc.c new file mode 100644 index 00000000..2de21149 --- /dev/null +++ b/src/base/bac/bacPrtAbc.c @@ -0,0 +1,486 @@ +/**CFile**************************************************************** + + FileName [bacPtrAbc.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Simple interface with external tools.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacPtrAbc.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "base/abc/abc.h" +#include "map/mio/mio.h" +#include "base/main/mainInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Node type conversions.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Ptr_HopToType( Abc_Obj_t * pObj ) +{ + static word uTruth, uTruths6[3] = { + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0xCCCCCCCCCCCCCCCC), + ABC_CONST(0xF0F0F0F0F0F0F0F0), + }; + assert( Abc_ObjIsNode(pObj) ); + uTruth = Hop_ManComputeTruth6( (Hop_Man_t *)Abc_ObjNtk(pObj)->pManFunc, (Hop_Obj_t *)pObj->pData, Abc_ObjFaninNum(pObj) ); +/* + if ( uTruth == 0 ) return "BAC_BOX_C0"; + if ( uTruth == ~(word)0 ) return "BAC_BOX_C1"; + if ( uTruth == uTruths6[0] ) return "BAC_BOX_BUF"; + if ( uTruth == ~uTruths6[0] ) return "BAC_BOX_INV"; + if ( uTruth == (uTruths6[0] & uTruths6[1]) ) return "BAC_BOX_AND"; + if ( uTruth ==~(uTruths6[0] & uTruths6[1]) ) return "BAC_BOX_NAND"; + if ( uTruth == (uTruths6[0] | uTruths6[1]) ) return "BAC_BOX_OR"; + if ( uTruth ==~(uTruths6[0] | uTruths6[1]) ) return "BAC_BOX_NOR"; + if ( uTruth == (uTruths6[0] ^ uTruths6[1]) ) return "BAC_BOX_XOR"; + if ( uTruth ==~(uTruths6[0] ^ uTruths6[1]) ) return "BAC_BOX_XNOR"; +*/ + if ( uTruth == 0 ) return "Const0T"; + if ( uTruth == ~(word)0 ) return "Const1T"; + if ( uTruth == uTruths6[0] ) return "BufT"; + if ( uTruth == ~uTruths6[0] ) return "InvT"; + if ( uTruth == (uTruths6[0] & uTruths6[1]) ) return "AndT"; + if ( uTruth ==~(uTruths6[0] & uTruths6[1]) ) return "NandT"; + if ( uTruth == (uTruths6[0] | uTruths6[1]) ) return "OrT"; + if ( uTruth ==~(uTruths6[0] | uTruths6[1]) ) return "NorT"; + if ( uTruth == (uTruths6[0] ^ uTruths6[1]) ) return "XorT"; + if ( uTruth ==~(uTruths6[0] ^ uTruths6[1]) ) return "XnorT"; + assert( 0 ); + return NULL; +} + + +/**Function************************************************************* + + Synopsis [Create Ptr from Abc_Ntk_t.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Ptr_AbcObjName( Abc_Obj_t * pObj ) +{ + if ( Abc_ObjIsNet(pObj) || Abc_ObjIsBox(pObj) ) + return Abc_ObjName(pObj); + if ( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) ) + return Ptr_AbcObjName(Abc_ObjFanout0(pObj)); + if ( Abc_ObjIsCo(pObj) ) + return Ptr_AbcObjName(Abc_ObjFanin0(pObj)); + assert( 0 ); + return NULL; +} +static int Ptr_CheckArray( Vec_Ptr_t * vArray ) +{ + assert( Vec_PtrSize(vArray) == Vec_PtrCap(vArray) ); + return 1; +} +Vec_Ptr_t * Ptr_AbcDeriveNode( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanin; int i; + Vec_Ptr_t * vNode = Vec_PtrAllocExact( 2 + 2 * (1 + Abc_ObjFaninNum(pObj)) ); + assert( Abc_ObjIsNode(pObj) ); + if ( Abc_NtkHasAig(pObj->pNtk) ) + Vec_PtrPush( vNode, Ptr_HopToType(pObj) ); + else if ( Abc_NtkHasSop(pObj->pNtk) ) + Vec_PtrPush( vNode, Ptr_SopToTypeName((char *)pObj->pData) ); + else assert( 0 ); + Vec_PtrPush( vNode, Ptr_AbcObjName(pObj) ); + assert( Abc_ObjFaninNum(pObj) <= 2 ); + Abc_ObjForEachFanin( pObj, pFanin, i ) + { + Vec_PtrPush( vNode, (void*)(i ? "r" : "l") ); + Vec_PtrPush( vNode, Ptr_AbcObjName(pFanin) ); + } + Vec_PtrPush( vNode, (void*)("o") ); + Vec_PtrPush( vNode, Ptr_AbcObjName(pObj) ); + assert( Ptr_CheckArray(vNode) ); + return vNode; +} +Vec_Ptr_t * Ptr_AbcDeriveBox( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pNext; int i; + Abc_Ntk_t * pNtk = Abc_ObjModel(pObj); + Vec_Ptr_t * vBox = Vec_PtrAllocExact( 2 + 2 * Abc_ObjFaninNum(pObj) + 2 * Abc_ObjFanoutNum(pObj) ); + assert( Abc_ObjIsBox(pObj) ); + Vec_PtrPush( vBox, Abc_NtkName(pNtk) ); + Vec_PtrPush( vBox, Ptr_AbcObjName(pObj) ); + Abc_ObjForEachFanin( pObj, pNext, i ) + { + Vec_PtrPush( vBox, Ptr_AbcObjName(Abc_NtkPi(pNtk, i)) ); + Vec_PtrPush( vBox, Ptr_AbcObjName(pNext) ); + } + Abc_ObjForEachFanout( pObj, pNext, i ) + { + Vec_PtrPush( vBox, Ptr_AbcObjName(Abc_NtkPo(pNtk, i)) ); + Vec_PtrPush( vBox, Ptr_AbcObjName(pNext) ); + } + assert( Ptr_CheckArray(vBox) ); + return vBox; +} +Vec_Ptr_t * Ptr_AbcDeriveBoxes( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; int i; + Vec_Ptr_t * vBoxes = Vec_PtrAllocExact( Abc_NtkBoxNum(pNtk) + Abc_NtkNodeNum(pNtk) ); + Abc_NtkForEachBox( pNtk, pObj, i ) + Vec_PtrPush( vBoxes, Ptr_AbcDeriveBox(pObj) ); + Abc_NtkForEachNode( pNtk, pObj, i ) + Vec_PtrPush( vBoxes, Ptr_AbcDeriveNode(pObj) ); + assert( Ptr_CheckArray(vBoxes) ); + return vBoxes; +} + +Vec_Ptr_t * Ptr_AbcDeriveInputs( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; int i; + Vec_Ptr_t * vSigs = Vec_PtrAllocExact( Abc_NtkPiNum(pNtk) ); + Abc_NtkForEachPi( pNtk, pObj, i ) + Vec_PtrPush( vSigs, Ptr_AbcObjName(pObj) ); + assert( Ptr_CheckArray(vSigs) ); + return vSigs; +} +Vec_Ptr_t * Ptr_AbcDeriveOutputs( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; int i; + Vec_Ptr_t * vSigs = Vec_PtrAllocExact( Abc_NtkPoNum(pNtk) ); + Abc_NtkForEachPo( pNtk, pObj, i ) + Vec_PtrPush( vSigs, Ptr_AbcObjName(pObj) ); + assert( Ptr_CheckArray(vSigs) ); + return vSigs; +} +Vec_Ptr_t * Ptr_AbcDeriveNtk( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vNtk = Vec_PtrAllocExact( 5 ); + Vec_PtrPush( vNtk, Abc_NtkName(pNtk) ); + Vec_PtrPush( vNtk, Ptr_AbcDeriveInputs(pNtk) ); + Vec_PtrPush( vNtk, Ptr_AbcDeriveOutputs(pNtk) ); + Vec_PtrPush( vNtk, Vec_PtrAllocExact(0) ); + Vec_PtrPush( vNtk, Ptr_AbcDeriveBoxes(pNtk) ); + assert( Ptr_CheckArray(vNtk) ); + return vNtk; +} +Vec_Ptr_t * Ptr_AbcDeriveDes( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vDes; + Abc_Ntk_t * pTemp; int i; + vDes = Vec_PtrAllocExact( 1 + Vec_PtrSize(pNtk->pDesign->vModules) ); + Vec_PtrPush( vDes, pNtk->pDesign->pName ); + Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i ) + Vec_PtrPush( vDes, Ptr_AbcDeriveNtk(pTemp) ); + assert( Ptr_CheckArray(vDes) ); + return vDes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ptr_ManExperiment( Abc_Ntk_t * pNtk ) +{ + abctime clk = Abc_Clock(); + char * pFileName = Extra_FileNameGenericAppend(pNtk->pDesign->pName, "_out.blif"); + Vec_Ptr_t * vDes = Ptr_AbcDeriveDes( pNtk ); + printf( "Converting to Ptr: Memory = %6.3f MB ", 1.0*Bac_PtrMemory(vDes)/(1<<20) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Bac_PtrDumpBlif( pFileName, vDes ); + printf( "Finished writing output file \"%s\". ", pFileName ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Bac_PtrFree( vDes ); +} + +/**Function************************************************************* + + Synopsis [Create Bac_Man_t from tech-ind Ptr.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ptr_NameToType( char * pSop ) +{ + if ( !strcmp(pSop, "Const0T") ) return BAC_BOX_CF; + if ( !strcmp(pSop, "Const1T") ) return BAC_BOX_CT; + if ( !strcmp(pSop, "BufT") ) return BAC_BOX_BUF; + if ( !strcmp(pSop, "InvT") ) return BAC_BOX_INV; + if ( !strcmp(pSop, "AndT") ) return BAC_BOX_AND; + if ( !strcmp(pSop, "NandT") ) return BAC_BOX_NAND; + if ( !strcmp(pSop, "OrT") ) return BAC_BOX_OR; + if ( !strcmp(pSop, "NorT") ) return BAC_BOX_NOR; + if ( !strcmp(pSop, "XorT") ) return BAC_BOX_XOR; + if ( !strcmp(pSop, "XnorT") ) return BAC_BOX_XNOR; + return BAC_OBJ_BOX; +} +int Ptr_ManCountNtk( Vec_Ptr_t * vNtk ) +{ + Vec_Ptr_t * vInputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1); + Vec_Ptr_t * vOutputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2); + Vec_Ptr_t * vNodes = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 3); + Vec_Ptr_t * vBoxes = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 4); + Vec_Ptr_t * vBox; int i, Counter = 0; + assert( Vec_PtrSize(vNodes) == 0 ); + Counter += Vec_PtrSize(vInputs); + Counter += Vec_PtrSize(vOutputs); + Vec_PtrForEachEntry( Vec_Ptr_t *, vBoxes, vBox, i ) + Counter += Vec_PtrSize(vBox)/2; + return Counter; +} +int Bac_BoxCountOutputs( Bac_Ntk_t * pNtk, char * pBoxNtk ) +{ + int ModuleId = Bac_ManNtkFindId( pNtk->pDesign, pBoxNtk ); + if ( ModuleId == 0 ) + return 1; + return Bac_NtkPoNumAlloc( Bac_ManNtk(pNtk->pDesign, ModuleId) ); +} +int Bac_NtkDeriveFromPtr( Bac_Ntk_t * pNtk, Vec_Ptr_t * vNtk, Vec_Int_t * vMap, Vec_Int_t * vBox2Id ) +{ + char * pName, * pModuleName = (char *)Vec_PtrEntry(vNtk, 0); + Vec_Ptr_t * vInputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1); + Vec_Ptr_t * vOutputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2); + Vec_Ptr_t * vBoxes = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 4), * vBox; + int i, k, iObj, iTerm, NameId; + // start network with the given name + NameId = Abc_NamStrFindOrAdd( pNtk->pDesign->pStrs, pModuleName, NULL ); + assert( Bac_NtkNameId(pNtk) == NameId ); + // map driven NameIds into their ObjIds for PIs + Vec_PtrForEachEntry( char *, vInputs, pName, i ) + { + NameId = Abc_NamStrFindOrAdd( pNtk->pDesign->pStrs, pName, NULL ); + if ( Vec_IntGetEntryFull(vMap, NameId) != -1 ) + { printf( "PI with name \"%s\" is not unique module \"%s\".\n", pName, pModuleName ); return 0; } + iObj = Bac_ObjAlloc( pNtk, BAC_OBJ_PI, -1 ); + Bac_ObjSetName( pNtk, iObj, Abc_Var2Lit2(NameId, BAC_NAME_BIN) ); + Vec_IntSetEntryFull( vMap, NameId, iObj ); + Bac_NtkAddInfo( pNtk, Abc_Var2Lit2(NameId, 1), -1, -1 ); + } + // map driven NameIds into their ObjIds for BOs + Vec_IntClear( vBox2Id ); + Vec_PtrForEachEntry( Vec_Ptr_t *, vBoxes, vBox, i ) + { + char * pBoxNtk = (char *)Vec_PtrEntry(vBox, 0); + char * pBoxName = (char *)Vec_PtrEntry(vBox, 1); + int nOutputs = Bac_BoxCountOutputs( pNtk, pBoxNtk ); + int nInputs = Vec_PtrSize(vBox)/2 - nOutputs - 1; + int NtkId = Bac_ManNtkFindId( pNtk->pDesign, pBoxNtk ); + assert( Vec_PtrSize(vBox) % 2 == 0 ); + assert( nOutputs > 0 && 2*(nOutputs + 1) <= Vec_PtrSize(vBox) ); + iObj = Bac_BoxAlloc( pNtk, (Bac_ObjType_t)Ptr_NameToType(pBoxNtk), nInputs, nOutputs, NtkId ); + if ( NtkId > 0 ) + Bac_NtkSetHost( Bac_ManNtk(pNtk->pDesign, NtkId), Bac_NtkId(pNtk), iObj ); + Bac_ObjSetName( pNtk, iObj, Abc_Var2Lit2(Abc_NamStrFindOrAdd(pNtk->pDesign->pStrs, pBoxName, NULL), BAC_NAME_BIN) ); + Bac_BoxForEachBo( pNtk, iObj, iTerm, k ) + { + pName = (char *)Vec_PtrEntry( vBox, Vec_PtrSize(vBox) - 2*(nOutputs - k) + 1 ); + NameId = Abc_NamStrFindOrAdd( pNtk->pDesign->pStrs, pName, NULL ); + if ( Vec_IntGetEntryFull(vMap, NameId) != -1 ) + { printf( "Signal \"%s\" has multiple drivers in module \"%s\".\n", pName, pModuleName ); return 0; } + Bac_ObjSetName( pNtk, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) ); + Vec_IntSetEntryFull( vMap, NameId, iTerm ); + } + Vec_IntPush( vBox2Id, iObj ); + } + assert( Vec_IntSize(vBox2Id) == Vec_PtrSize(vBoxes) ); + // connect BIs + Vec_PtrForEachEntry( Vec_Ptr_t *, vBoxes, vBox, i ) + { + iObj = Vec_IntEntry( vBox2Id, i ); + Bac_BoxForEachBi( pNtk, iObj, iTerm, k ) + { + pName = (char *)Vec_PtrEntry( vBox, 2*(k + 1) + 1 ); + NameId = Abc_NamStrFindOrAdd( pNtk->pDesign->pStrs, pName, NULL ); + if ( Vec_IntGetEntryFull(vMap, NameId) == -1 ) + printf( "Signal \"%s\" in not driven in module \"%s\".\n", pName, pModuleName ); + Bac_ObjSetFanin( pNtk, iTerm, Vec_IntGetEntryFull(vMap, NameId) ); + } + } + // connect POs + Vec_PtrForEachEntry( char *, vOutputs, pName, i ) + { + NameId = Abc_NamStrFindOrAdd( pNtk->pDesign->pStrs, pName, NULL ); + if ( Vec_IntGetEntryFull(vMap, NameId) == -1 ) + printf( "PO with name \"%s\" in not driven in module \"%s\".\n", pName, pModuleName ); + iObj = Bac_ObjAlloc( pNtk, BAC_OBJ_PO, Vec_IntGetEntryFull(vMap, NameId) ); + Bac_NtkAddInfo( pNtk, Abc_Var2Lit2(NameId, 2), -1, -1 ); + } + // update map + Bac_NtkForEachCi( pNtk, iObj ) + Vec_IntSetEntryFull( vMap, Bac_ObjNameId(pNtk, iObj), -1 ); + // double check + Vec_IntForEachEntry( vMap, iObj, i ) + assert( iObj == -1 ); + assert( Bac_NtkObjNum(pNtk) == Vec_StrCap(&pNtk->vType) ); + return 1; +} +Bac_Man_t * Bac_PtrTransformToCba( Vec_Ptr_t * vDes ) +{ + char * pName = (char *)Vec_PtrEntry(vDes, 0); + Bac_Man_t * pNew = Bac_ManAlloc( pName, Vec_PtrSize(vDes) - 1 ); + Vec_Int_t * vMap = Vec_IntStartFull( 1000 ); + Vec_Int_t * vBox2Id = Vec_IntAlloc( 1000 ); + // create interfaces + Bac_Ntk_t * pNtk; int i; + Bac_ManForEachNtk( pNew, pNtk, i ) + { + Vec_Ptr_t * vNtk = (Vec_Ptr_t *)Vec_PtrEntry(vDes, i); + Vec_Ptr_t * vInputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1); + Vec_Ptr_t * vOutputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2); + int NameId = Abc_NamStrFindOrAdd( pNew->pStrs, (char *)Vec_PtrEntry(vNtk, 0), NULL ); + Bac_NtkAlloc( pNtk, NameId, Vec_PtrSize(vInputs), Vec_PtrSize(vOutputs), Ptr_ManCountNtk(vNtk) ); + Bac_NtkStartNames( pNtk ); + } + // parse the networks + Bac_ManForEachNtk( pNew, pNtk, i ) + { + Vec_Ptr_t * vNtk = (Vec_Ptr_t *)Vec_PtrEntry(vDes, i); + if ( !Bac_NtkDeriveFromPtr( pNtk, vNtk, vMap, vBox2Id ) ) + break; + } + if ( i <= Bac_ManNtkNum(pNew) ) + Bac_ManFree(pNew), pNew = NULL; + Vec_IntFree( vBox2Id ); + Vec_IntFree( vMap ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Create Ptr from mapped Bac_Man_t.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Bac_NtkTransformToPtrBox( Bac_Ntk_t * p, int iBox ) +{ + int i, iTerm, fUser = Bac_ObjIsBoxUser( p, iBox ); + Bac_Ntk_t * pBoxNtk = Bac_BoxNtk( p, iBox ); + Mio_Library_t * pLib = (Mio_Library_t *)p->pDesign->pMioLib; + Mio_Gate_t * pGate = pLib ? Mio_LibraryReadGateByName( pLib, Bac_BoxNtkName(p, iBox), NULL ) : NULL; + Vec_Ptr_t * vBox = Vec_PtrAllocExact( 2*Bac_BoxSize(p, iBox) ); + Vec_PtrPush( vBox, Bac_BoxNtkName(p, iBox) ); + Vec_PtrPush( vBox, Bac_ObjNameStr(p, iBox) ); + Bac_BoxForEachBi( p, iBox, iTerm, i ) + { + Vec_PtrPush( vBox, fUser ? Bac_ObjNameStr(pBoxNtk, Bac_NtkPi(pBoxNtk, i)) : Mio_GateReadPinName(pGate, i) ); + Vec_PtrPush( vBox, Bac_ObjNameStr(p, iTerm) ); + } + Bac_BoxForEachBo( p, iBox, iTerm, i ) + { + Vec_PtrPush( vBox, fUser ? Bac_ObjNameStr(pBoxNtk, Bac_NtkPo(pBoxNtk, i)) : Mio_GateReadOutName(pGate) ); + Vec_PtrPush( vBox, Bac_ObjNameStr(p, iTerm) ); + } + assert( Ptr_CheckArray(vBox) ); + return vBox; +} +Vec_Ptr_t * Bac_NtkTransformToPtrBoxes( Bac_Ntk_t * p ) +{ + int iBox; + Vec_Ptr_t * vBoxes = Vec_PtrAllocExact( Bac_NtkBoxNum(p) ); + Bac_NtkForEachBox( p, iBox ) + Vec_PtrPush( vBoxes, Bac_NtkTransformToPtrBox(p, iBox) ); + assert( Ptr_CheckArray(vBoxes) ); + return vBoxes; +} + +Vec_Ptr_t * Bac_NtkTransformToPtrInputs( Bac_Ntk_t * p ) +{ + int i, iTerm; + Vec_Ptr_t * vSigs = Vec_PtrAllocExact( Bac_NtkPiNum(p) ); + Bac_NtkForEachPi( p, iTerm, i ) + Vec_PtrPush( vSigs, Bac_ObjNameStr(p, iTerm) ); + assert( Ptr_CheckArray(vSigs) ); + return vSigs; +} +Vec_Ptr_t * Bac_NtkTransformToPtrOutputs( Bac_Ntk_t * p ) +{ + int i, iTerm; + Vec_Ptr_t * vSigs = Vec_PtrAllocExact( Bac_NtkPoNum(p) ); + Bac_NtkForEachPo( p, iTerm, i ) + Vec_PtrPush( vSigs, Bac_ObjNameStr(p, iTerm) ); + assert( Ptr_CheckArray(vSigs) ); + return vSigs; +} +Vec_Ptr_t * Bac_NtkTransformToPtr( Bac_Ntk_t * p ) +{ + Vec_Ptr_t * vNtk = Vec_PtrAllocExact(5); + Vec_PtrPush( vNtk, Bac_NtkName(p) ); + Vec_PtrPush( vNtk, Bac_NtkTransformToPtrInputs(p) ); + Vec_PtrPush( vNtk, Bac_NtkTransformToPtrOutputs(p) ); + Vec_PtrPush( vNtk, Vec_PtrAllocExact(0) ); + Vec_PtrPush( vNtk, Bac_NtkTransformToPtrBoxes(p) ); + assert( Ptr_CheckArray(vNtk) ); + return vNtk; +} +Vec_Ptr_t * Bac_PtrDeriveFromCba( Bac_Man_t * p ) +{ + Vec_Ptr_t * vDes; + Bac_Ntk_t * pTemp; int i; + if ( p == NULL ) + return NULL; + if ( p->pMioLib == NULL ) + { + printf( "Cannot transform CBA network into Ptr because it is not mapped.\n" ); + return NULL; + } + Bac_ManAssignInternWordNames( p ); + vDes = Vec_PtrAllocExact( 1 + Bac_ManNtkNum(p) ); + Vec_PtrPush( vDes, p->pName ); + Bac_ManForEachNtk( p, pTemp, i ) + Vec_PtrPush( vDes, Bac_NtkTransformToPtr(pTemp) ); + assert( Ptr_CheckArray(vDes) ); + return vDes; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacPtr.c b/src/base/bac/bacPtr.c new file mode 100644 index 00000000..c3fc5fd8 --- /dev/null +++ b/src/base/bac/bacPtr.c @@ -0,0 +1,470 @@ +/**CFile**************************************************************** + + FileName [bacPtr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Simple interface with external tools.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacPtr.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "base/abc/abc.h" +#include "base/main/mainInt.h" +#include "map/mio/mio.h" +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/* +design = array containing design name (as the first entry in the array) followed by pointers to modules +module = array containing module name (as the first entry in the array) followed by pointers to 6 arrays: + {array of input names; array of output names; array of nodes; array of boxes, + array of floating-point input-arrival times; array of floating-point output-required times} +node = array containing output name, followed by node type, followed by input names +box = array containing model name, instance name, followed by pairs of formal/actual names for each port + + Comments: + - in describing boxes + - input formal/actual name pairs should be listed before output name pairs + - the order of formal names should be the same as the order of inputs/outputs in the module description + - all formal names present in the module description should be listed + - if an input pin is not driven or an output pin has no fanout, the actual pin name is NULL + - word-level formal name "a" is written as bit-level names (a[0]. a[1], etc) ordered LSB to MSB + - the boxes can appear in any order (topological order is not expected) + - in description of nodes and boxes, primitive names should be given as char*-strings ("AndT", "OrT", etc) + - constant 0/1 nets should be driven by constant nodes having primitive names "Const0T" and "Const1T" + - primitive modules should not be written, but the list of primitives and formal names should be provided + - currently only "boxes" are supported (the array of "nodes" should contain no entries) + - arrays of input-arrival/output-required times in the module description are optional +*/ + +// elementary gates +typedef enum { + PTR_GATE_NONE = 0, + PTR_GATE_C0, // Const0T + PTR_GATE_C1, // Const1T + PTR_GATE_BUF, // BufT + PTR_GATE_INV, // InvT + PTR_GATE_AND, // AndT + PTR_GATE_NAND, // NandT + PTR_GATE_OR, // OrT + PTR_GATE_NOR, // NorT + PTR_GATE_XOR, // XorT + PTR_GATE_XNOR, // XnorT + PTR_GATE_UNKNOWN +} Ptr_ObjType_t; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Free Ptr.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_PtrFreeNtk( Vec_Ptr_t * vNtk ) +{ + Vec_PtrFree( (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1) ); + Vec_PtrFree( (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2) ); + Vec_VecFree( (Vec_Vec_t *)Vec_PtrEntry(vNtk, 3) ); + Vec_VecFree( (Vec_Vec_t *)Vec_PtrEntry(vNtk, 4) ); + if ( Vec_PtrSize(vNtk) > 5 ) + Vec_FltFree( (Vec_Flt_t *)Vec_PtrEntry(vNtk, 5) ); + if ( Vec_PtrSize(vNtk) > 6 ) + Vec_FltFree( (Vec_Flt_t *)Vec_PtrEntry(vNtk, 6) ); + Vec_PtrFree( vNtk ); +} +void Bac_PtrFree( Vec_Ptr_t * vDes ) +{ + Vec_Ptr_t * vNtk; int i; + if ( !vDes ) return; + Vec_PtrForEachEntryStart( Vec_Ptr_t *, vDes, vNtk, i, 1 ) + Bac_PtrFreeNtk( vNtk ); + Vec_PtrFree( vDes ); +} + +/**Function************************************************************* + + Synopsis [Count memory used by Ptr.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bac_PtrMemoryArray( Vec_Ptr_t * vArray ) +{ + return (int)Vec_PtrMemory(vArray); +} +int Bac_PtrMemoryArrayArray( Vec_Ptr_t * vArrayArray ) +{ + Vec_Ptr_t * vArray; int i, nBytes = 0; + Vec_PtrForEachEntry( Vec_Ptr_t *, vArrayArray, vArray, i ) + nBytes += Bac_PtrMemoryArray(vArray); + return nBytes; +} +int Bac_PtrMemoryNtk( Vec_Ptr_t * vNtk ) +{ + int nBytes = (int)Vec_PtrMemory(vNtk); + nBytes += Bac_PtrMemoryArray( (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1) ); + nBytes += Bac_PtrMemoryArray( (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2) ); + nBytes += Bac_PtrMemoryArrayArray( (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 3) ); + nBytes += Bac_PtrMemoryArrayArray( (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 4) ); + return nBytes; +} +int Bac_PtrMemory( Vec_Ptr_t * vDes ) +{ + Vec_Ptr_t * vNtk; int i, nBytes = (int)Vec_PtrMemory(vDes); + Vec_PtrForEachEntryStart( Vec_Ptr_t *, vDes, vNtk, i, 1 ) + nBytes += Bac_PtrMemoryNtk(vNtk); + return nBytes; +} + +/**Function************************************************************* + + Synopsis [Dumping Ptr into a BLIF file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_PtrDumpSignalsBlif( FILE * pFile, Vec_Ptr_t * vSigs, int fSkipLastComma ) +{ + char * pSig; int i; + Vec_PtrForEachEntry( char *, vSigs, pSig, i ) + fprintf( pFile, " %s", pSig ); +} +void Bac_PtrDumpBoxBlif( FILE * pFile, Vec_Ptr_t * vBox ) +{ + char * pName; int i; + fprintf( pFile, ".subckt" ); + fprintf( pFile, " %s", (char *)Vec_PtrEntry(vBox, 0) ); + //fprintf( pFile, " %s", (char *)Vec_PtrEntry(vBox, 1) ); // do not write intance name in BLIF + Vec_PtrForEachEntryStart( char *, vBox, pName, i, 2 ) + fprintf( pFile, " %s=%s", pName, (char *)Vec_PtrEntry(vBox, i+1) ), i++; + fprintf( pFile, "\n" ); +} +void Bac_PtrDumpBoxesBlif( FILE * pFile, Vec_Ptr_t * vBoxes ) +{ + Vec_Ptr_t * vBox; int i; + Vec_PtrForEachEntry( Vec_Ptr_t *, vBoxes, vBox, i ) + Bac_PtrDumpBoxBlif( pFile, vBox ); +} +void Bac_PtrDumpModuleBlif( FILE * pFile, Vec_Ptr_t * vNtk ) +{ + fprintf( pFile, ".model %s\n", (char *)Vec_PtrEntry(vNtk, 0) ); + fprintf( pFile, ".inputs" ); + Bac_PtrDumpSignalsBlif( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1), 0 ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs" ); + Bac_PtrDumpSignalsBlif( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2), 1 ); + fprintf( pFile, "\n" ); + assert( Vec_PtrSize((Vec_Ptr_t *)Vec_PtrEntry(vNtk, 3)) == 0 ); // no nodes; only boxes + Bac_PtrDumpBoxesBlif( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 4) ); + fprintf( pFile, ".end\n\n" ); +} +void Bac_PtrDumpBlif( char * pFileName, Vec_Ptr_t * vDes ) +{ + FILE * pFile; + Vec_Ptr_t * vNtk; int i; + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "// Design \"%s\" written via Ptr in ABC on %s\n\n", (char *)Vec_PtrEntry(vDes, 0), Extra_TimeStamp() ); + Vec_PtrForEachEntryStart( Vec_Ptr_t *, vDes, vNtk, i, 1 ) + Bac_PtrDumpModuleBlif( pFile, vNtk ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Dumping Ptr into a Verilog file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_PtrDumpSignalsVerilog( FILE * pFile, Vec_Ptr_t * vSigs, int fAlwaysComma ) +{ + char * pSig; int i; + Vec_PtrForEachEntry( char *, vSigs, pSig, i ) + fprintf( pFile, " %s%s", pSig, (fAlwaysComma || i < Vec_PtrSize(vSigs) - 1) ? ",":"" ); +} +void Bac_PtrDumpBoxVerilog( FILE * pFile, Vec_Ptr_t * vBox ) +{ + char * pName; int i; + fprintf( pFile, " %s", (char *)Vec_PtrEntry(vBox, 0) ); + fprintf( pFile, " %s (", (char *)Vec_PtrEntry(vBox, 1) ); // write intance name in Verilog + Vec_PtrForEachEntryStart( char *, vBox, pName, i, 2 ) + fprintf( pFile, ".%s(%s)%s", pName, (char *)Vec_PtrEntry(vBox, i+1), i < Vec_PtrSize(vBox) - 2 ? ", ":"" ), i++; + fprintf( pFile, ");\n" ); +} +void Bac_PtrDumpBoxesVerilog( FILE * pFile, Vec_Ptr_t * vBoxes ) +{ + Vec_Ptr_t * vBox; int i; + Vec_PtrForEachEntry( Vec_Ptr_t *, vBoxes, vBox, i ) + Bac_PtrDumpBoxVerilog( pFile, vBox ); +} +void Bac_PtrDumpModuleVerilog( FILE * pFile, Vec_Ptr_t * vNtk ) +{ + fprintf( pFile, "module %s (\n ", (char *)Vec_PtrEntry(vNtk, 0) ); + Bac_PtrDumpSignalsVerilog( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1), 1 ); + Bac_PtrDumpSignalsVerilog( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2), 0 ); + fprintf( pFile, "\n );\n" ); + fprintf( pFile, " input" ); + Bac_PtrDumpSignalsVerilog( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1), 0 ); + fprintf( pFile, ";\n" ); + fprintf( pFile, " output" ); + Bac_PtrDumpSignalsVerilog( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2), 0 ); + fprintf( pFile, ";\n" ); + assert( Vec_PtrSize((Vec_Ptr_t *)Vec_PtrEntry(vNtk, 3)) == 0 ); // no nodes; only boxes + Bac_PtrDumpBoxesVerilog( pFile, (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 4) ); + fprintf( pFile, "endmodule\n\n" ); +} +void Bac_PtrDumpVerilog( char * pFileName, Vec_Ptr_t * vDes ) +{ + FILE * pFile; + Vec_Ptr_t * vNtk; int i; + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "// Design \"%s\" written via Ptr in ABC on %s\n\n", (char *)Vec_PtrEntry(vDes, 0), Extra_TimeStamp() ); + Vec_PtrForEachEntryStart( Vec_Ptr_t *, vDes, vNtk, i, 1 ) + Bac_PtrDumpModuleVerilog( pFile, vNtk ); + fclose( pFile ); +} + + +/**Function************************************************************* + + Synopsis [Collect elementary gates from the library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_ManCollectGateNameOne( Mio_Library_t * pLib, Ptr_ObjType_t Type, word Truth, Vec_Ptr_t * vGateNames ) +{ + Mio_Gate_t * pGate = Mio_LibraryReadGateByTruth( pLib, Truth ); + if ( pGate != NULL ) + Vec_PtrWriteEntry( vGateNames, Type, Mio_GateReadName(pGate) ); +} +Vec_Ptr_t * Bac_ManCollectGateNamesByTruth( Mio_Library_t * pLib ) +{ + static word uTruths6[3] = { + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0xCCCCCCCCCCCCCCCC), + ABC_CONST(0xF0F0F0F0F0F0F0F0), + }; + Vec_Ptr_t * vGateNames = Vec_PtrStart( PTR_GATE_UNKNOWN ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_C0, 0, vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_C1, ~(word)0, vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_BUF, uTruths6[0], vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_INV, ~uTruths6[0], vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_AND, (uTruths6[0] & uTruths6[1]), vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_NAND, ~(uTruths6[0] & uTruths6[1]), vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_OR, (uTruths6[0] | uTruths6[1]), vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_NOR, ~(uTruths6[0] | uTruths6[1]), vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_XOR, (uTruths6[0] ^ uTruths6[1]), vGateNames ); + Bac_ManCollectGateNameOne( pLib, PTR_GATE_XNOR, ~(uTruths6[0] ^ uTruths6[1]), vGateNames ); + return vGateNames; +} + +/**Function************************************************************* + + Synopsis [This procedure transforms tech-ind Ptr into mapped Ptr.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_PtrUpdateBox( Vec_Ptr_t * vBox, Vec_Ptr_t * vGatesNames ) +{ + Mio_Gate_t * pGate; Mio_Pin_t * pPin; int i = 1; + Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + // update gate name + char * pNameNew, * pName = (char *)Vec_PtrEntry(vBox, 0); + if ( !strcmp(pName, "Const0T") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_C0); + else if ( !strcmp(pName, "Const1T") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_C1); + else if ( !strcmp(pName, "BufT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_BUF); + else if ( !strcmp(pName, "InvT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_INV); + else if ( !strcmp(pName, "AndT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_AND); + else if ( !strcmp(pName, "NandT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_NAND); + else if ( !strcmp(pName, "OrT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_OR); + else if ( !strcmp(pName, "NorT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_NOR); + else if ( !strcmp(pName, "XorT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_XOR); + else if ( !strcmp(pName, "XnorT") ) + pNameNew = (char *)Vec_PtrEntry(vGatesNames, PTR_GATE_XNOR); + else // user hierarchy + return; + ABC_FREE( pName ); + Vec_PtrWriteEntry( vBox, 0, Abc_UtilStrsav(pNameNew) ); + // remove instance name + pName = (char *)Vec_PtrEntry(vBox, 1); + ABC_FREE( pName ); + Vec_PtrWriteEntry( vBox, 1, NULL ); + // update formal input names + pGate = Mio_LibraryReadGateByName( pLib, pNameNew, NULL ); + Mio_GateForEachPin( pGate, pPin ) + { + pName = (char *)Vec_PtrEntry( vBox, 2 * i ); + ABC_FREE( pName ); + pNameNew = Mio_PinReadName(pPin); + Vec_PtrWriteEntry( vBox, 2 * i++, Abc_UtilStrsav(pNameNew) ); + } + // update output name + pName = (char *)Vec_PtrEntry( vBox, 2 * i ); + pNameNew = Mio_GateReadOutName(pGate); + Vec_PtrWriteEntry( vBox, 2 * i++, Abc_UtilStrsav(pNameNew) ); + assert( 2 * i == Vec_PtrSize(vBox) ); +} +Vec_Ptr_t * Bac_PtrTransformSigs( Vec_Ptr_t * vSig ) +{ + char * pName; int i; + Vec_Ptr_t * vNew = Vec_PtrAllocExact( Vec_PtrSize(vSig) ); + Vec_PtrForEachEntry( char *, vSig, pName, i ) + Vec_PtrPush( vNew, Abc_UtilStrsav(pName) ); + return vNew; +} +Vec_Ptr_t * Bac_PtrTransformBox( Vec_Ptr_t * vBox, Vec_Ptr_t * vGatesNames ) +{ + char * pName; int i; + Vec_Ptr_t * vNew = Vec_PtrAllocExact( Vec_PtrSize(vBox) ); + Vec_PtrForEachEntry( char *, vBox, pName, i ) + Vec_PtrPush( vNew, Abc_UtilStrsav(pName) ); + if ( vGatesNames ) + Bac_PtrUpdateBox( vNew, vGatesNames ); + return vNew; +} +Vec_Ptr_t * Bac_PtrTransformBoxes( Vec_Ptr_t * vBoxes, Vec_Ptr_t * vGatesNames ) +{ + Vec_Ptr_t * vBox; int i; + Vec_Ptr_t * vNew = Vec_PtrAllocExact( Vec_PtrSize(vBoxes) ); + Vec_PtrForEachEntry( Vec_Ptr_t *, vBoxes, vBox, i ) + Vec_PtrPush( vNew, Bac_PtrTransformBox(vBox, vGatesNames) ); + return vNew; +} +Vec_Ptr_t * Bac_PtrTransformNtk( Vec_Ptr_t * vNtk, Vec_Ptr_t * vGatesNames ) +{ + char * pName = (char *)Vec_PtrEntry(vNtk, 0); + Vec_Ptr_t * vInputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 1); + Vec_Ptr_t * vOutputs = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 2); + Vec_Ptr_t * vBoxes = (Vec_Ptr_t *)Vec_PtrEntry(vNtk, 4); + Vec_Ptr_t * vNew = Vec_PtrAllocExact( Vec_PtrSize(vNtk) ); + Vec_PtrPush( vNew, Abc_UtilStrsav(pName) ); + Vec_PtrPush( vNew, Bac_PtrTransformSigs(vInputs) ); + Vec_PtrPush( vNew, Bac_PtrTransformSigs(vOutputs) ); + Vec_PtrPush( vNew, Vec_PtrAllocExact(0) ); + Vec_PtrPush( vNew, Bac_PtrTransformBoxes(vBoxes, vGatesNames) ); + return vNew; +} +Vec_Ptr_t * Bac_PtrTransformTest( Vec_Ptr_t * vDes ) +{ + Mio_Library_t * pLib; + Vec_Ptr_t * vGatesNames; + Vec_Ptr_t * vNtk, * vNew; int i; + // dump BLIF before transformation + Bac_PtrDumpBlif( "test1.blif", vDes ); + if ( Abc_FrameGetGlobalFrame() == NULL ) + { + printf( "ABC framework is not started.\n" ); + return NULL; + } + pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + if ( pLib == NULL ) + { + printf( "Standard cell library is not entered.\n" ); + return NULL; + } + vGatesNames = Bac_ManCollectGateNamesByTruth( pLib ); + // transform + vNew = Vec_PtrAllocExact( Vec_PtrSize(vDes) ); + Vec_PtrPush( vNew, Abc_UtilStrsav((char *)Vec_PtrEntry(vDes, 0)) ); + Vec_PtrForEachEntryStart( Vec_Ptr_t *, vDes, vNtk, i, 1 ) + Vec_PtrPush( vNew, Bac_PtrTransformNtk(vNtk, vGatesNames) ); + // dump BLIF after transformation + Bac_PtrDumpBlif( "test2.blif", vNew ); + Vec_PtrFree( vGatesNames ); + return vNew; +} + +/**Function************************************************************* + + Synopsis [Test the testing procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_PtrTransformTestTest() +{ + char * pFileName = "c/hie/dump/1/netlist_1.v"; + Abc_Ntk_t * pNtk = Io_ReadNetlist( pFileName, Io_ReadFileType(pFileName), 0 ); + extern Vec_Ptr_t * Ptr_AbcDeriveDes( Abc_Ntk_t * pNtk ); + Vec_Ptr_t * vDes = Ptr_AbcDeriveDes( pNtk ); + Vec_Ptr_t * vNew = Bac_PtrTransformTest( vDes ); + Bac_PtrFree( vDes ); + Bac_PtrFree( vNew ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacReadBlif.c b/src/base/bac/bacReadBlif.c new file mode 100644 index 00000000..4a1839b6 --- /dev/null +++ b/src/base/bac/bacReadBlif.c @@ -0,0 +1,453 @@ +/**CFile**************************************************************** + + FileName [bacReadBlif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [BLIF parser.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacReadBlif.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// BLIF keywords +typedef enum { + PRS_BLIF_NONE = 0, // 0: unused + PRS_BLIF_MODEL, // 1: .model + PRS_BLIF_INOUTS, // 2: .inouts + PRS_BLIF_INPUTS, // 3: .inputs + PRS_BLIF_OUTPUTS, // 4: .outputs + PRS_BLIF_NAMES, // 5: .names + PRS_BLIF_SUBCKT, // 6: .subckt + PRS_BLIF_GATE, // 7: .gate + PRS_BLIF_LATCH, // 8: .latch + PRS_BLIF_SHORT, // 9: .short + PRS_BLIF_END, // 10: .end + PRS_BLIF_UNKNOWN // 11: unknown +} Bac_BlifType_t; + +static const char * s_BlifTypes[PRS_BLIF_UNKNOWN+1] = { + NULL, // 0: unused + ".model", // 1: .model + ".inouts", // 2: .inputs + ".inputs", // 3: .inputs + ".outputs", // 4: .outputs + ".names", // 5: .names + ".subckt", // 6: .subckt + ".gate", // 7: .gate + ".latch", // 8: .latch + ".short", // 9: .short + ".end", // 10: .end + NULL // 11: unknown +}; + +static inline void Psr_NtkAddBlifDirectives( Psr_Man_t * p ) +{ + int i; + for ( i = 1; s_BlifTypes[i]; i++ ) + Abc_NamStrFindOrAdd( p->pStrs, (char *)s_BlifTypes[i], NULL ); + assert( Abc_NamObjNumMax(p->pStrs) == i ); +} + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Reading characters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Psr_CharIsSpace( char c ) { return c == ' ' || c == '\t' || c == '\r'; } +static inline int Psr_CharIsStop( char c ) { return c == '#' || c == '\\' || c == '\n' || c == '='; } +static inline int Psr_CharIsLit( char c ) { return c == '0' || c == '1' || c == '-'; } + +static inline int Psr_ManIsSpace( Psr_Man_t * p ) { return Psr_CharIsSpace(*p->pCur); } +static inline int Psr_ManIsStop( Psr_Man_t * p ) { return Psr_CharIsStop(*p->pCur); } +static inline int Psr_ManIsLit( Psr_Man_t * p ) { return Psr_CharIsLit(*p->pCur); } + +static inline int Psr_ManIsChar( Psr_Man_t * p, char c ) { return *p->pCur == c; } +static inline int Psr_ManIsChar2( Psr_Man_t * p, char c ) { return *p->pCur++ == c; } + +static inline void Psr_ManSkip( Psr_Man_t * p ) { p->pCur++; } +static inline char Psr_ManSkip2( Psr_Man_t * p ) { return *p->pCur++; } + + +/**Function************************************************************* + + Synopsis [Reading names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Psr_ManSkipToChar( Psr_Man_t * p, char c ) +{ + while ( !Psr_ManIsChar(p, c) ) + Psr_ManSkip(p); +} +static inline void Psr_ManSkipSpaces( Psr_Man_t * p ) +{ + while ( 1 ) + { + while ( Psr_ManIsSpace(p) ) + Psr_ManSkip(p); + if ( Psr_ManIsChar(p, '\\') ) + { + Psr_ManSkipToChar( p, '\n' ); + Psr_ManSkip(p); + continue; + } + if ( Psr_ManIsChar(p, '#') ) + Psr_ManSkipToChar( p, '\n' ); + break; + } + assert( !Psr_ManIsSpace(p) ); +} +static inline int Psr_ManReadName( Psr_Man_t * p ) +{ + char * pStart; + Psr_ManSkipSpaces( p ); + if ( Psr_ManIsChar(p, '\n') ) + return 0; + pStart = p->pCur; + while ( !Psr_ManIsSpace(p) && !Psr_ManIsStop(p) ) + Psr_ManSkip(p); + if ( pStart == p->pCur ) + return 0; + return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL ); +} +static inline int Psr_ManReadList( Psr_Man_t * p, Vec_Int_t * vOrder, int Type ) +{ + int iToken; + Vec_IntClear( &p->vTemp ); + while ( (iToken = Psr_ManReadName(p)) ) + { + Vec_IntPush( &p->vTemp, iToken ); + Vec_IntPush( vOrder, Abc_Var2Lit2(iToken, Type) ); + } + if ( Vec_IntSize(&p->vTemp) == 0 ) return Psr_ManErrorSet(p, "Signal list is empty.", 1); + return 0; +} +static inline int Psr_ManReadList2( Psr_Man_t * p ) +{ + int iToken; + Vec_IntClear( &p->vTemp ); + while ( (iToken = Psr_ManReadName(p)) ) + Vec_IntPushTwo( &p->vTemp, 0, iToken ); + if ( Vec_IntSize(&p->vTemp) == 0 ) return Psr_ManErrorSet(p, "Signal list is empty.", 1); + return 0; +} +static inline int Psr_ManReadList3( Psr_Man_t * p ) +{ + Vec_IntClear( &p->vTemp ); + while ( !Psr_ManIsChar(p, '\n') ) + { + int iToken = Psr_ManReadName(p); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read formal name.", 1); + Vec_IntPush( &p->vTemp, iToken ); + Psr_ManSkipSpaces( p ); + if ( !Psr_ManIsChar2(p, '=') ) return Psr_ManErrorSet(p, "Cannot find symbol \"=\".", 1); + iToken = Psr_ManReadName(p); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read actual name.", 1); + Vec_IntPush( &p->vTemp, iToken ); + Psr_ManSkipSpaces( p ); + } + if ( Vec_IntSize(&p->vTemp) == 0 ) return Psr_ManErrorSet(p, "Cannot read a list of formal/actual names.", 1); + if ( Vec_IntSize(&p->vTemp) % 2 ) return Psr_ManErrorSet(p, "The number of formal/actual names is not even.", 1); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Psr_ManReadCube( Psr_Man_t * p ) +{ + assert( Psr_ManIsLit(p) ); + while ( Psr_ManIsLit(p) ) + Vec_StrPush( &p->vCover, Psr_ManSkip2(p) ); + Psr_ManSkipSpaces( p ); + if ( Psr_ManIsChar(p, '\n') ) + { + if ( Vec_StrSize(&p->vCover) != 1 ) return Psr_ManErrorSet(p, "Cannot read cube.", 1); + // fix single literal cube by adding space + Vec_StrPush( &p->vCover, Vec_StrEntry(&p->vCover,0) ); + Vec_StrWriteEntry( &p->vCover, 0, ' ' ); + Vec_StrPush( &p->vCover, '\n' ); + return 0; + } + if ( !Psr_ManIsLit(p) ) return Psr_ManErrorSet(p, "Cannot read output literal.", 1); + Vec_StrPush( &p->vCover, ' ' ); + Vec_StrPush( &p->vCover, Psr_ManSkip2(p) ); + Vec_StrPush( &p->vCover, '\n' ); + Psr_ManSkipSpaces( p ); + if ( !Psr_ManIsChar(p, '\n') ) return Psr_ManErrorSet(p, "Cannot read end of cube.", 1); + return 0; +} +static inline void Psr_ManSaveCover( Psr_Man_t * p ) +{ + int iToken; + if ( Vec_StrSize(&p->vCover) == 0 ) + p->pNtk->fHasC0s = 1; + else if ( Vec_StrSize(&p->vCover) == 2 ) + { + if ( Vec_StrEntryLast(&p->vCover) == '0' ) + p->pNtk->fHasC0s = 1; + else if ( Vec_StrEntryLast(&p->vCover) == '1' ) + p->pNtk->fHasC1s = 1; + else assert( 0 ); + } + assert( Vec_StrSize(&p->vCover) > 0 ); + Vec_StrPush( &p->vCover, '\0' ); + //iToken = Abc_NamStrFindOrAdd( p->pStrs, Vec_StrArray(&p->vCover), NULL ); + iToken = Ptr_SopToType( Vec_StrArray(&p->vCover) ); + Vec_StrClear( &p->vCover ); + // set the cover to the module of this box + assert( Psr_BoxNtk(p->pNtk, Psr_NtkBoxNum(p->pNtk)-1) == 1 ); // default const 0 + Psr_BoxSetNtk( p->pNtk, Psr_NtkBoxNum(p->pNtk)-1, iToken ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Psr_ManReadInouts( Psr_Man_t * p ) +{ + if ( Psr_ManReadList(p, &p->pNtk->vOrder, 3) ) return 1; + Vec_IntAppend( &p->pNtk->vInouts, &p->vTemp ); + return 0; +} +static inline int Psr_ManReadInputs( Psr_Man_t * p ) +{ + if ( Psr_ManReadList(p, &p->pNtk->vOrder, 1) ) return 1; + Vec_IntAppend( &p->pNtk->vInputs, &p->vTemp ); + return 0; +} +static inline int Psr_ManReadOutputs( Psr_Man_t * p ) +{ + if ( Psr_ManReadList(p, &p->pNtk->vOrder, 2) ) return 1; + Vec_IntAppend( &p->pNtk->vOutputs, &p->vTemp ); + return 0; +} +static inline int Psr_ManReadNode( Psr_Man_t * p ) +{ + if ( Psr_ManReadList2(p) ) return 1; + // save results + Psr_NtkAddBox( p->pNtk, 1, 0, &p->vTemp ); // default const 0 function + return 0; +} +static inline int Psr_ManReadBox( Psr_Man_t * p, int fGate ) +{ + int iToken = Psr_ManReadName(p); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read model name.", 1); + if ( Psr_ManReadList3(p) ) return 1; + // save results + Psr_NtkAddBox( p->pNtk, iToken, 0, &p->vTemp ); + if ( fGate ) p->pNtk->fMapped = 1; + return 0; +} +static inline int Psr_ManReadLatch( Psr_Man_t * p ) +{ + int iToken = Psr_ManReadName(p); + Vec_IntClear( &p->vTemp ); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read latch input.", 1); + Vec_IntWriteEntry( &p->vTemp, 1, iToken ); + iToken = Psr_ManReadName(p); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read latch output.", 1); + Vec_IntWriteEntry( &p->vTemp, 0, iToken ); + Psr_ManSkipSpaces( p ); + if ( Psr_ManIsChar(p, '0') ) + iToken = 0; + else if ( Psr_ManIsChar(p, '1') ) + iToken = 1; + else + iToken = 2; + Psr_ManSkipToChar( p, '\n' ); + // save results + Psr_NtkAddBox( p->pNtk, -1, iToken, &p->vTemp ); // -1 stands for latch + return 0; +} +static inline int Psr_ManReadShort( Psr_Man_t * p ) +{ + int iToken = Psr_ManReadName(p); + Vec_IntClear( &p->vTemp ); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read .short input.", 1); + Vec_IntWriteEntry( &p->vTemp, 1, iToken ); + iToken = Psr_ManReadName(p); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read .short output.", 1); + Vec_IntWriteEntry( &p->vTemp, 0, iToken ); + Psr_ManSkipSpaces( p ); + if ( !Psr_ManIsChar(p, '\n') ) return Psr_ManErrorSet(p, "Trailing symbols on .short line.", 1); + // save results + iToken = Abc_NamStrFindOrAdd( p->pStrs, "1 1\n", NULL ); + Psr_NtkAddBox( p->pNtk, iToken, 0, &p->vTemp ); + return 0; +} +static inline int Psr_ManReadModel( Psr_Man_t * p ) +{ + int iToken; + if ( p->pNtk != NULL ) return Psr_ManErrorSet(p, "Parsing previous model is unfinished.", 1); + iToken = Psr_ManReadName(p); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read model name.", 1); + Psr_ManInitializeNtk( p, iToken, 0 ); + Psr_ManSkipSpaces( p ); + if ( !Psr_ManIsChar(p, '\n') ) return Psr_ManErrorSet(p, "Trailing symbols on .model line.", 1); + return 0; +} +static inline int Psr_ManReadEnd( Psr_Man_t * p ) +{ + if ( p->pNtk == 0 ) return Psr_ManErrorSet(p, "Directive .end without .model.", 1); + //printf( "Saving model \"%s\".\n", Abc_NamStr(p->pStrs, p->iModuleName) ); + Psr_ManFinalizeNtk( p ); + Psr_ManSkipSpaces( p ); + if ( !Psr_ManIsChar(p, '\n') ) return Psr_ManErrorSet(p, "Trailing symbols on .end line.", 1); + return 0; +} + +static inline int Psr_ManReadDirective( Psr_Man_t * p ) +{ + int iToken; + if ( !Psr_ManIsChar(p, '.') ) + return Psr_ManReadCube( p ); + if ( Vec_StrSize(&p->vCover) > 0 ) // SOP was specified for the previous node + Psr_ManSaveCover( p ); + iToken = Psr_ManReadName( p ); + if ( iToken == PRS_BLIF_MODEL ) + return Psr_ManReadModel( p ); + if ( iToken == PRS_BLIF_INOUTS ) + return Psr_ManReadInouts( p ); + if ( iToken == PRS_BLIF_INPUTS ) + return Psr_ManReadInputs( p ); + if ( iToken == PRS_BLIF_OUTPUTS ) + return Psr_ManReadOutputs( p ); + if ( iToken == PRS_BLIF_NAMES ) + return Psr_ManReadNode( p ); + if ( iToken == PRS_BLIF_SUBCKT ) + return Psr_ManReadBox( p, 0 ); + if ( iToken == PRS_BLIF_GATE ) + return Psr_ManReadBox( p, 1 ); + if ( iToken == PRS_BLIF_LATCH ) + return Psr_ManReadLatch( p ); + if ( iToken == PRS_BLIF_SHORT ) + return Psr_ManReadShort( p ); + if ( iToken == PRS_BLIF_END ) + return Psr_ManReadEnd( p ); + printf( "Cannot read directive \"%s\".\n", Abc_NamStr(p->pStrs, iToken) ); + return 1; +} +static inline int Psr_ManReadLines( Psr_Man_t * p ) +{ + while ( p->pCur[1] != '\0' ) + { + assert( Psr_ManIsChar(p, '\n') ); + Psr_ManSkip(p); + Psr_ManSkipSpaces( p ); + if ( Psr_ManIsChar(p, '\n') ) + continue; + if ( Psr_ManReadDirective(p) ) + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Psr_ManReadBlif( char * pFileName ) +{ + Vec_Ptr_t * vPrs = NULL; + Psr_Man_t * p = Psr_ManAlloc( pFileName ); + if ( p == NULL ) + return NULL; + Psr_NtkAddBlifDirectives( p ); + Psr_ManReadLines( p ); + if ( Psr_ManErrorPrint(p) ) + ABC_SWAP( Vec_Ptr_t *, vPrs, p->vNtks ); + Psr_ManFree( p ); + return vPrs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Psr_ManReadBlifTest() +{ + abctime clk = Abc_Clock(); + extern void Psr_ManWriteBlif( char * pFileName, Vec_Ptr_t * vPrs ); +// Vec_Ptr_t * vPrs = Psr_ManReadBlif( "aga/ray/ray_hie_oper.blif" ); + Vec_Ptr_t * vPrs = Psr_ManReadBlif( "c/hie/dump/1/netlist_1_out8.blif" ); + if ( !vPrs ) return; + printf( "Finished reading %d networks. ", Vec_PtrSize(vPrs) ); + printf( "NameIDs = %d. ", Abc_NamObjNumMax(Psr_ManNameMan(vPrs)) ); + printf( "Memory = %.2f MB. ", 1.0*Psr_ManMemory(vPrs)/(1<<20) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +// Abc_NamPrint( p->pStrs ); + Psr_ManWriteBlif( "c/hie/dump/1/netlist_1_out8_out.blif", vPrs ); + Psr_ManVecFree( vPrs ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacReadSmt.c b/src/base/bac/bacReadSmt.c new file mode 100644 index 00000000..56fdaaea --- /dev/null +++ b/src/base/bac/bacReadSmt.c @@ -0,0 +1,42 @@ +/**CFile**************************************************************** + + FileName [bacReadSmt.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [BLIF parser.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacReadSmt.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacReadVec.c b/src/base/bac/bacReadVec.c new file mode 100644 index 00000000..676b090d --- /dev/null +++ b/src/base/bac/bacReadVec.c @@ -0,0 +1,875 @@ +/**CFile**************************************************************** + + FileName [bacReadVer.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [BLIF writer.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacReadVer.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// Verilog keywords +typedef enum { + PRS_VER_NONE = 0, // 0: unused + PRS_VER_INPUT, // 1: input + PRS_VER_OUTPUT, // 2: output + PRS_VER_INOUT, // 3: inout + PRS_VER_WIRE, // 4: wire + PRS_VER_MODULE, // 5: module + PRS_VER_ASSIGN, // 6: assign + PRS_VER_REG, // 7: reg + PRS_VER_ALWAYS, // 8: always + PRS_VER_DEFPARAM, // 9: always + PRS_VER_BEGIN, // 10: begin + PRS_VER_END, // 11: end + PRS_VER_ENDMODULE, // 12: endmodule + PRS_VER_UNKNOWN // 13: unknown +} Bac_VerType_t; + +static const char * s_VerTypes[PRS_VER_UNKNOWN+1] = { + NULL, // 0: unused + "input", // 1: input + "output", // 2: output + "inout", // 3: inout + "wire", // 4: wire + "module", // 5: module + "assign", // 6: assign + "reg", // 7: reg + "always", // 8: always + "defparam", // 9: defparam + "begin", // 10: begin + "end", // 11: end + "endmodule", // 12: endmodule + NULL // 13: unknown +}; + +static inline void Psr_NtkAddVerilogDirectives( Psr_Man_t * p ) +{ + int i; + for ( i = 1; s_VerTypes[i]; i++ ) + Abc_NamStrFindOrAdd( p->pStrs, (char *)s_VerTypes[i], NULL ); + assert( Abc_NamObjNumMax(p->pStrs) == i ); +} + + +// character recognition +static inline int Psr_CharIsSpace( char c ) { return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); } +static inline int Psr_CharIsDigit( char c ) { return (c >= '0' && c <= '9'); } +static inline int Psr_CharIsDigitB( char c ) { return (c == '0' || c == '1' || c == 'x' || c == 'z'); } +static inline int Psr_CharIsDigitH( char c ) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); } +static inline int Psr_CharIsChar( char c ) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } +static inline int Psr_CharIsSymb1( char c ) { return Psr_CharIsChar(c) || c == '_'; } +static inline int Psr_CharIsSymb2( char c ) { return Psr_CharIsSymb1(c) || Psr_CharIsDigit(c) || c == '$'; } + +static inline int Psr_ManIsChar( Psr_Man_t * p, char c ) { return p->pCur[0] == c; } +static inline int Psr_ManIsChar1( Psr_Man_t * p, char c ) { return p->pCur[1] == c; } +static inline int Psr_ManIsDigit( Psr_Man_t * p ) { return Psr_CharIsDigit(*p->pCur); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +// collect predefined modules names +static const char * s_VerilogModules[100] = +{ + "const0", // BAC_BOX_CF, + "const1", // BAC_BOX_CT, + "constX", // BAC_BOX_CX, + "constZ", // BAC_BOX_CZ, + "buf", // BAC_BOX_BUF, + "not", // BAC_BOX_INV, + "and", // BAC_BOX_AND, + "nand", // BAC_BOX_NAND, + "or", // BAC_BOX_OR, + "nor", // BAC_BOX_NOR, + "xor", // BAC_BOX_XOR, + "xnor", // BAC_BOX_XNOR, + "sharp", // BAC_BOX_SHARP, + "mux", // BAC_BOX_MUX, + "maj", // BAC_BOX_MAJ, + NULL +}; +static const char * s_KnownModules[100] = +{ + "VERIFIC_", + "add_", + "mult_", + "div_", + "mod_", + "rem_", + "shift_left_", + "shift_right_", + "rotate_left_", + "rotate_right_", + "reduce_and_", + "reduce_or_", + "reduce_xor_", + "reduce_nand_", + "reduce_nor_", + "reduce_xnor_", + "LessThan_", + "Mux_", + "Select_", + "Decoder_", + "EnabledDecoder_", + "PrioSelect_", + "DualPortRam_", + "ReadPort_", + "WritePort_", + "ClockedWritePort_", + "lut", + "and_", + "or_", + "xor_", + "nand_", + "nor_", + "xnor_", + "buf_", + "inv_", + "tri_", + "sub_", + "unary_minus_", + "equal_", + "not_equal_", + "mux_", + "wide_mux_", + "wide_select_", + "wide_dff_", + "wide_dlatch_", + "wide_dffrs_", + "wide_dlatchrs_", + "wide_prio_select_", + "pow_", + "PrioEncoder_", + "abs", + NULL +}; + +// check if it is a Verilog predefined module +static inline int Psr_ManIsVerilogModule( Psr_Man_t * p, char * pName ) +{ + int i; + for ( i = 0; s_VerilogModules[i]; i++ ) + if ( !strcmp(pName, s_VerilogModules[i]) ) + return BAC_BOX_CF + i; + return 0; +} +// check if it is a known module +static inline int Psr_ManIsKnownModule( Psr_Man_t * p, char * pName ) +{ + int i; + for ( i = 0; s_KnownModules[i]; i++ ) + if ( !strncmp(pName, s_KnownModules[i], strlen(s_KnownModules[i])) ) + return i; + return 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +// skips Verilog comments (returns 1 if some comments were skipped) +static inline int Psr_ManUtilSkipComments( Psr_Man_t * p ) +{ + if ( !Psr_ManIsChar(p, '/') ) + return 0; + if ( Psr_ManIsChar1(p, '/') ) + { + for ( p->pCur += 2; p->pCur < p->pLimit; p->pCur++ ) + if ( Psr_ManIsChar(p, '\n') ) + { p->pCur++; return 1; } + } + else if ( Psr_ManIsChar1(p, '*') ) + { + for ( p->pCur += 2; p->pCur < p->pLimit; p->pCur++ ) + if ( Psr_ManIsChar(p, '*') && Psr_ManIsChar1(p, '/') ) + { p->pCur++; p->pCur++; return 1; } + } + return 0; +} +static inline int Psr_ManUtilSkipName( Psr_Man_t * p ) +{ + if ( !Psr_ManIsChar(p, '\\') ) + return 0; + for ( p->pCur++; p->pCur < p->pLimit; p->pCur++ ) + if ( Psr_ManIsChar(p, ' ') ) + { p->pCur++; return 1; } + return 0; +} + +// skip any number of spaces and comments +static inline int Psr_ManUtilSkipSpaces( Psr_Man_t * p ) +{ + while ( p->pCur < p->pLimit ) + { + while ( Psr_CharIsSpace(*p->pCur) ) + p->pCur++; + if ( !*p->pCur ) + return Psr_ManErrorSet(p, "Unexpectedly reached end-of-file.", 1); + if ( !Psr_ManUtilSkipComments(p) ) + return 0; + } + return Psr_ManErrorSet(p, "Unexpectedly reached end-of-file.", 1); +} +// skip everything including comments until the given char +static inline int Psr_ManUtilSkipUntil( Psr_Man_t * p, char c ) +{ + while ( p->pCur < p->pLimit ) + { + if ( Psr_ManIsChar(p, c) ) + return 1; + if ( Psr_ManUtilSkipComments(p) ) + continue; + if ( Psr_ManUtilSkipName(p) ) + continue; + p->pCur++; + } + return 0; +} +// skip everything including comments until the given word +static inline int Psr_ManUtilSkipUntilWord( Psr_Man_t * p, char * pWord ) +{ + char * pPlace = strstr( p->pCur, pWord ); + if ( pPlace == NULL ) return 1; + p->pCur = pPlace + strlen(pWord); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Psr_ManReadName( Psr_Man_t * p ) +{ + char * pStart = p->pCur; + if ( Psr_ManIsChar(p, '\\') ) // escaped name + { + pStart = ++p->pCur; + while ( !Psr_ManIsChar(p, ' ') ) + p->pCur++; + } + else if ( Psr_CharIsSymb1(*p->pCur) ) // simple name + { + p->pCur++; + while ( Psr_CharIsSymb2(*p->pCur) ) + p->pCur++; + } + else + return 0; + return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL ); +} +static inline int Psr_ManReadNameList( Psr_Man_t * p, Vec_Int_t * vTemp, char LastSymb ) +{ + Vec_IntClear( vTemp ); + while ( 1 ) + { + int Item = Psr_ManReadName(p); + if ( Item == 0 ) return Psr_ManErrorSet(p, "Cannot read name in the list.", 0); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 1.", 0); + if ( Item == PRS_VER_WIRE ) + continue; + Vec_IntPush( vTemp, Item ); + if ( Psr_ManIsChar(p, LastSymb) ) break; + if ( !Psr_ManIsChar(p, ',') ) return Psr_ManErrorSet(p, "Expecting comma in the list.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 2.", 0); + } + return 1; +} +static inline int Psr_ManReadConstant( Psr_Man_t * p ) +{ + char * pStart = p->pCur; + assert( Psr_ManIsDigit(p) ); + while ( Psr_ManIsDigit(p) ) + p->pCur++; + if ( !Psr_ManIsChar(p, '\'') ) return Psr_ManErrorSet(p, "Cannot read constant.", 0); + p->pCur++; + if ( Psr_ManIsChar(p, 'b') ) + { + p->pCur++; + while ( Psr_CharIsDigitB(*p->pCur) ) + { + if ( *p->pCur == '0' ) + p->pNtk->fHasC0s = 1; + else if ( *p->pCur == '1' ) + p->pNtk->fHasC1s = 1; + else if ( *p->pCur == 'x' ) + p->pNtk->fHasCXs = 1; + else if ( *p->pCur == 'z' ) + p->pNtk->fHasCZs = 1; + p->pCur++; + } + } + else if ( Psr_ManIsChar(p, 'h') ) + { + p->pCur++; + p->pNtk->fHasC0s = 1; + while ( Psr_CharIsDigitH(*p->pCur) ) + { + if ( *p->pCur != '0' ) + p->pNtk->fHasC1s = 1; + p->pCur++; + } + } + else if ( Psr_ManIsChar(p, 'd') ) + { + p->pCur++; + p->pNtk->fHasC0s = 1; + while ( Psr_ManIsDigit(p) ) + { + if ( *p->pCur != '0' ) + p->pNtk->fHasC1s = 1; + p->pCur++; + } + } + else return Psr_ManErrorSet(p, "Cannot read radix of constant.", 0); + return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL ); +} +static inline int Psr_ManReadRange( Psr_Man_t * p ) +{ + assert( Psr_ManIsChar(p, '[') ); + Vec_StrClear( &p->vCover ); + Vec_StrPush( &p->vCover, *p->pCur++ ); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 3.", 0); + if ( !Psr_ManIsDigit(p) ) return Psr_ManErrorSet(p, "Cannot read digit in range specification.", 0); + while ( Psr_ManIsDigit(p) ) + Vec_StrPush( &p->vCover, *p->pCur++ ); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 4.", 0); + if ( Psr_ManIsChar(p, ':') ) + { + Vec_StrPush( &p->vCover, *p->pCur++ ); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 5.", 0); + if ( !Psr_ManIsDigit(p) ) return Psr_ManErrorSet(p, "Cannot read digit in range specification.", 0); + while ( Psr_ManIsDigit(p) ) + Vec_StrPush( &p->vCover, *p->pCur++ ); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 6.", 0); + } + if ( !Psr_ManIsChar(p, ']') ) return Psr_ManErrorSet(p, "Cannot read closing brace in range specification.", 0); + Vec_StrPush( &p->vCover, *p->pCur++ ); + Vec_StrPush( &p->vCover, '\0' ); + return Abc_NamStrFindOrAdd( p->pStrs, Vec_StrArray(&p->vCover), NULL ); +} +static inline int Psr_ManReadConcat( Psr_Man_t * p, Vec_Int_t * vTemp2 ) +{ + extern int Psr_ManReadSignalList( Psr_Man_t * p, Vec_Int_t * vTemp, char LastSymb, int fAddForm ); + assert( Psr_ManIsChar(p, '{') ); + p->pCur++; + if ( !Psr_ManReadSignalList( p, vTemp2, '}', 0 ) ) return Psr_ManErrorSet(p, "Error number 7.", 0); + // check final + assert( Psr_ManIsChar(p, '}') ); + p->pCur++; + // return special case + assert( Vec_IntSize(vTemp2) > 0 ); + if ( Vec_IntSize(vTemp2) == 1 ) + return Vec_IntEntry(vTemp2, 0); + return Abc_Var2Lit2( Psr_NtkAddConcat(p->pNtk, vTemp2), BAC_PRS_CONCAT ); +} +static inline int Psr_ManReadSignal( Psr_Man_t * p ) +{ + int Item; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 8.", 0); + if ( Psr_ManIsDigit(p) ) + { + Item = Psr_ManReadConstant(p); + if ( Item == 0 ) return Psr_ManErrorSet(p, "Error number 9.", 0); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 10.", 0); + return Abc_Var2Lit2( Item, BAC_PRS_CONST ); + } + if ( Psr_ManIsChar(p, '{') ) + { + if ( p->fUsingTemp2 ) return Psr_ManErrorSet(p, "Cannot read nested concatenations.", 0); + p->fUsingTemp2 = 1; + Item = Psr_ManReadConcat(p, &p->vTemp2); + p->fUsingTemp2 = 0; + if ( Item == 0 ) return Psr_ManErrorSet(p, "Error number 11.", 0); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 12.", 0); + return Item; + } + else + { + Item = Psr_ManReadName( p ); + if ( Item == 0 ) return Psr_ManErrorSet(p, "Error number 13.", 0); // was return 1; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 14.", 0); + if ( Psr_ManIsChar(p, '[') ) + { + int Range = Psr_ManReadRange(p); + if ( Range == 0 ) return Psr_ManErrorSet(p, "Error number 15.", 0); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 16.", 0); + return Abc_Var2Lit2( Psr_NtkAddSlice(p->pNtk, Item, Range), BAC_PRS_SLICE ); + } + return Abc_Var2Lit2( Item, BAC_PRS_NAME ); + } +} +static int Psr_ManReadSignalList( Psr_Man_t * p, Vec_Int_t * vTemp, char LastSymb, int fAddForm ) +{ + Vec_IntClear( vTemp ); + while ( 1 ) + { + int Item = Psr_ManReadSignal(p); + if ( Item == 0 ) return Psr_ManErrorSet(p, "Cannot read signal in the list.", 0); + if ( fAddForm ) + Vec_IntPush( vTemp, 0 ); + Vec_IntPush( vTemp, Item ); + if ( Psr_ManIsChar(p, LastSymb) ) break; + if ( !Psr_ManIsChar(p, ',') ) return Psr_ManErrorSet(p, "Expecting comma in the list.", 0); + p->pCur++; + } + return 1; +} +static inline int Psr_ManReadSignalList2( Psr_Man_t * p, Vec_Int_t * vTemp ) +{ + int FormId, ActItem; + Vec_IntClear( vTemp ); + assert( Psr_ManIsChar(p, '.') ); + while ( Psr_ManIsChar(p, '.') ) + { + p->pCur++; + FormId = Psr_ManReadName( p ); + if ( FormId == 0 ) return Psr_ManErrorSet(p, "Cannot read formal name of the instance.", 0); + if ( !Psr_ManIsChar(p, '(') ) return Psr_ManErrorSet(p, "Cannot read \"(\" in the instance.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 17.", 0); + ActItem = Psr_ManReadSignal( p ); + if ( ActItem == 0 ) return Psr_ManErrorSet(p, "Cannot read actual name of the instance.", 0); + if ( !Psr_ManIsChar(p, ')') ) return Psr_ManErrorSet(p, "Cannot read \")\" in the instance.", 0); + p->pCur++; + Vec_IntPushTwo( vTemp, FormId, ActItem ); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 18.", 0); + if ( Psr_ManIsChar(p, ')') ) break; + if ( !Psr_ManIsChar(p, ',') ) return Psr_ManErrorSet(p, "Expecting comma in the instance.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 19.", 0); + } + assert( Vec_IntSize(vTemp) > 0 ); + assert( Vec_IntSize(vTemp) % 2 == 0 ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Psr_ManReadDeclaration( Psr_Man_t * p, int Type ) +{ + int i, NameId, RangeId = 0; + Vec_Int_t * vNames[4] = { &p->pNtk->vInputs, &p->pNtk->vOutputs, &p->pNtk->vInouts, &p->pNtk->vWires }; + Vec_Int_t * vNamesR[4] = { &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vInoutsR, &p->pNtk->vWiresR }; + assert( Type >= PRS_VER_INPUT && Type <= PRS_VER_WIRE ); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 20.", 0); + if ( Psr_ManIsChar(p, '[') && !(RangeId = Psr_ManReadRange(p)) ) return Psr_ManErrorSet(p, "Error number 21.", 0); + if ( !Psr_ManReadNameList( p, &p->vTemp, ';' ) ) return Psr_ManErrorSet(p, "Error number 22.", 0); + Vec_IntForEachEntry( &p->vTemp, NameId, i ) + { + Vec_IntPush( vNames[Type - PRS_VER_INPUT], NameId ); + Vec_IntPush( vNamesR[Type - PRS_VER_INPUT], RangeId ); + if ( Type < PRS_VER_WIRE ) + Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(NameId, Type) ); + } + return 1; +} +static inline int Psr_ManReadAssign( Psr_Man_t * p ) +{ + int OutItem, InItem, fCompl = 0, fCompl2 = 0, Oper = 0; + // read output name + OutItem = Psr_ManReadSignal( p ); + if ( OutItem == 0 ) return Psr_ManErrorSet(p, "Cannot read output in assign-statement.", 0); + if ( !Psr_ManIsChar(p, '=') ) return Psr_ManErrorSet(p, "Expecting \"=\" in assign-statement.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 23.", 0); + if ( Psr_ManIsChar(p, '~') ) + { + fCompl = 1; + p->pCur++; + } + // read first name + InItem = Psr_ManReadSignal( p ); + if ( InItem == 0 ) return Psr_ManErrorSet(p, "Cannot read first input name in the assign-statement.", 0); + Vec_IntClear( &p->vTemp ); + Vec_IntPush( &p->vTemp, 0 ); + Vec_IntPush( &p->vTemp, InItem ); + // check unary operator + if ( Psr_ManIsChar(p, ';') ) + { + Vec_IntPush( &p->vTemp, 0 ); + Vec_IntPush( &p->vTemp, OutItem ); + Oper = fCompl ? BAC_BOX_INV : BAC_BOX_BUF; + Psr_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp ); + return 1; + } + if ( Psr_ManIsChar(p, '&') ) + Oper = BAC_BOX_AND; + else if ( Psr_ManIsChar(p, '|') ) + Oper = BAC_BOX_OR; + else if ( Psr_ManIsChar(p, '^') ) + Oper = BAC_BOX_XOR; + else if ( Psr_ManIsChar(p, '?') ) + Oper = BAC_BOX_MUX; + else return Psr_ManErrorSet(p, "Unrecognized operator in the assign-statement.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 24.", 0); + if ( Psr_ManIsChar(p, '~') ) + { + fCompl2 = 1; + p->pCur++; + } + // read second name + InItem = Psr_ManReadSignal( p ); + if ( InItem == 0 ) return Psr_ManErrorSet(p, "Cannot read second input name in the assign-statement.", 0); + Vec_IntPush( &p->vTemp, 0 ); + Vec_IntPush( &p->vTemp, InItem ); + // read third argument + if ( Oper == BAC_BOX_MUX ) + { + assert( fCompl == 0 ); + if ( !Psr_ManIsChar(p, ':') ) return Psr_ManErrorSet(p, "Expected colon in the MUX assignment.", 0); + p->pCur++; + // read third name + InItem = Psr_ManReadSignal( p ); + if ( InItem == 0 ) return Psr_ManErrorSet(p, "Cannot read third input name in the assign-statement.", 0); + Vec_IntPush( &p->vTemp, 0 ); + Vec_IntPush( &p->vTemp, InItem ); + if ( !Psr_ManIsChar(p, ';') ) return Psr_ManErrorSet(p, "Expected semicolon at the end of the assign-statement.", 0); + } + else + { + // figure out operator + if ( Oper == BAC_BOX_AND ) + { + if ( fCompl && !fCompl2 ) + Oper = BAC_BOX_SHARPL; + else if ( !fCompl && fCompl2 ) + Oper = BAC_BOX_SHARP; + else if ( fCompl && fCompl2 ) + Oper = BAC_BOX_NOR; + } + else if ( Oper == BAC_BOX_OR ) + { + if ( fCompl && fCompl2 ) + Oper = BAC_BOX_NAND; + else assert( !fCompl && !fCompl2 ); + } + else if ( Oper == BAC_BOX_XOR ) + { + if ( fCompl && !fCompl2 ) + Oper = BAC_BOX_XNOR; + else assert( !fCompl && !fCompl2 ); + } + } + // write binary operator + Vec_IntPush( &p->vTemp, 0 ); + Vec_IntPush( &p->vTemp, OutItem ); + Psr_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp ); + return 1; +} +static inline int Psr_ManReadInstance( Psr_Man_t * p, int Func ) +{ + int InstId, Status; +/* + static Counter = 0; + if ( ++Counter == 7 ) + { + int s=0; + } +*/ + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 25.", 0); + if ( (InstId = Psr_ManReadName(p)) ) + if (Psr_ManUtilSkipSpaces(p)) return Psr_ManErrorSet(p, "Error number 26.", 0); + if ( !Psr_ManIsChar(p, '(') ) return Psr_ManErrorSet(p, "Expecting \"(\" in module instantiation.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 27.", 0); + if ( Psr_ManIsChar(p, '.') ) // box + Status = Psr_ManReadSignalList2(p, &p->vTemp); + else // node + { + //char * s = Abc_NamStr(p->pStrs, Func); + // translate elementary gate + int iFuncNew = Psr_ManIsVerilogModule(p, Abc_NamStr(p->pStrs, Func)); + if ( iFuncNew == 0 ) return Psr_ManErrorSet(p, "Cannot find elementary gate.", 0); + Func = iFuncNew; + Status = Psr_ManReadSignalList( p, &p->vTemp, ')', 1 ); + } + if ( Status == 0 ) return Psr_ManErrorSet(p, "Error number 28.", 0); + assert( Psr_ManIsChar(p, ')') ); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 29.", 0); + if ( !Psr_ManIsChar(p, ';') ) return Psr_ManErrorSet(p, "Expecting semicolon in the instance.", 0); + // add box + Psr_NtkAddBox( p->pNtk, Func, InstId, &p->vTemp ); + return 1; +} +static inline int Psr_ManReadArguments( Psr_Man_t * p ) +{ + int iRange = 0, iType = -1; + Vec_Int_t * vSigs[3] = { &p->pNtk->vInputs, &p->pNtk->vOutputs, &p->pNtk->vInouts }; + Vec_Int_t * vSigsR[3] = { &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vInoutsR }; + assert( Psr_ManIsChar(p, '(') ); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 30.", 0); + while ( 1 ) + { + int iName = Psr_ManReadName( p ); + if ( iName == 0 ) return Psr_ManErrorSet(p, "Error number 31.", 0); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 32.", 0); + if ( iName >= PRS_VER_INPUT && iName <= PRS_VER_INOUT ) // declaration + { + iType = iName; + if ( Psr_ManIsChar(p, '[') ) + { + iRange = Psr_ManReadRange(p); + if ( iRange == 0 ) return Psr_ManErrorSet(p, "Error number 33.", 0); + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 34.", 0); + } + iName = Psr_ManReadName( p ); + if ( iName == 0 ) return Psr_ManErrorSet(p, "Error number 35.", 0); + } + if ( iType > 0 ) + { + Vec_IntPush( vSigs[iType - PRS_VER_INPUT], iName ); + Vec_IntPush( vSigsR[iType - PRS_VER_INPUT], iRange ); + Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(iName, iType) ); + } + if ( Psr_ManIsChar(p, ')') ) + break; + if ( !Psr_ManIsChar(p, ',') ) return Psr_ManErrorSet(p, "Expecting comma in the instance.", 0); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 36.", 0); + } + // check final + assert( Psr_ManIsChar(p, ')') ); + return 1; +} +// this procedure can return: +// 0 = reached end-of-file; 1 = successfully parsed; 2 = recognized as primitive; 3 = failed and skipped; 4 = error (failed and could not skip) +static inline int Psr_ManReadModule( Psr_Man_t * p ) +{ + int iToken, Status; + if ( p->pNtk != NULL ) return Psr_ManErrorSet(p, "Parsing previous module is unfinished.", 4); + if ( Psr_ManUtilSkipSpaces(p) ) + { + Psr_ManErrorClear( p ); + return 0; + } + // read keyword + iToken = Psr_ManReadName( p ); + if ( iToken != PRS_VER_MODULE ) return Psr_ManErrorSet(p, "Cannot read \"module\" keyword.", 4); + if ( Psr_ManUtilSkipSpaces(p) ) return 4; + // read module name + iToken = Psr_ManReadName( p ); + if ( iToken == 0 ) return Psr_ManErrorSet(p, "Cannot read module name.", 4); + if ( Psr_ManIsKnownModule(p, Abc_NamStr(p->pStrs, iToken)) ) + { + if ( Psr_ManUtilSkipUntilWord( p, "endmodule" ) ) return Psr_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4); + //printf( "Warning! Skipped known module \"%s\".\n", Abc_NamStr(p->pStrs, iToken) ); + Vec_IntPush( &p->vKnown, iToken ); + return 2; + } + Psr_ManInitializeNtk( p, iToken, 1 ); + // skip arguments + if ( Psr_ManUtilSkipSpaces(p) ) return 4; + if ( !Psr_ManIsChar(p, '(') ) return Psr_ManErrorSet(p, "Cannot find \"(\" in the argument declaration.", 4); + if ( !Psr_ManReadArguments(p) ) return 4; + assert( *p->pCur == ')' ); + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return 4; + // read declarations and instances + while ( Psr_ManIsChar(p, ';') ) + { + p->pCur++; + if ( Psr_ManUtilSkipSpaces(p) ) return 4; + iToken = Psr_ManReadName( p ); + if ( iToken == PRS_VER_ENDMODULE ) + { + Vec_IntPush( &p->vSucceeded, p->pNtk->iModuleName ); + Psr_ManFinalizeNtk( p ); + return 1; + } + if ( iToken >= PRS_VER_INPUT && iToken <= PRS_VER_WIRE ) // declaration + Status = Psr_ManReadDeclaration( p, iToken ); + else if ( iToken == PRS_VER_REG || iToken == PRS_VER_DEFPARAM ) // unsupported keywords + Status = Psr_ManUtilSkipUntil( p, ';' ); + else // read instance + { + if ( iToken == PRS_VER_ASSIGN ) + Status = Psr_ManReadAssign( p ); + else + Status = Psr_ManReadInstance( p, iToken ); + if ( Status == 0 ) + { + if ( Psr_ManUtilSkipUntilWord( p, "endmodule" ) ) return Psr_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4); + //printf( "Warning! Failed to parse \"%s\". Adding module \"%s\" as blackbox.\n", + // Abc_NamStr(p->pStrs, iToken), Abc_NamStr(p->pStrs, p->pNtk->iModuleName) ); + Vec_IntPush( &p->vFailed, p->pNtk->iModuleName ); + // cleanup + Vec_IntErase( &p->pNtk->vWires ); + Vec_IntErase( &p->pNtk->vWiresR ); + Vec_IntErase( &p->pNtk->vSlices ); + Vec_IntErase( &p->pNtk->vConcats ); + Vec_IntErase( &p->pNtk->vBoxes ); + Vec_IntErase( &p->pNtk->vObjs ); + p->fUsingTemp2 = 0; + // add + Psr_ManFinalizeNtk( p ); + Psr_ManErrorClear( p ); + return 3; + } + } + if ( !Status ) return 4; + if ( Psr_ManUtilSkipSpaces(p) ) return 4; + } + return Psr_ManErrorSet(p, "Cannot find \";\" in the module definition.", 4); +} +static inline int Psr_ManReadDesign( Psr_Man_t * p ) +{ + while ( 1 ) + { + int RetValue = Psr_ManReadModule( p ); + if ( RetValue == 0 ) // end of file + break; + if ( RetValue == 1 ) // successfully parsed + continue; + if ( RetValue == 2 ) // recognized as primitive + continue; + if ( RetValue == 3 ) // failed and skipped + continue; + if ( RetValue == 4 ) // error + return 0; + assert( 0 ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Psr_ManPrintModules( Psr_Man_t * p ) +{ + char * pName; int i; + printf( "Succeeded parsing %d models:\n", Vec_IntSize(&p->vSucceeded) ); + Psr_ManForEachNameVec( &p->vSucceeded, p, pName, i ) + printf( " %s", pName ); + printf( "\n" ); + printf( "Skipped %d known models:\n", Vec_IntSize(&p->vKnown) ); + Psr_ManForEachNameVec( &p->vKnown, p, pName, i ) + printf( " %s", pName ); + printf( "\n" ); + printf( "Skipped %d failed models:\n", Vec_IntSize(&p->vFailed) ); + Psr_ManForEachNameVec( &p->vFailed, p, pName, i ) + printf( " %s", pName ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Psr_ManReadVerilog( char * pFileName ) +{ + Vec_Ptr_t * vPrs = NULL; + Psr_Man_t * p = Psr_ManAlloc( pFileName ); + if ( p == NULL ) + return NULL; + Psr_NtkAddVerilogDirectives( p ); + Psr_ManReadDesign( p ); + //Psr_ManPrintModules( p ); + if ( Psr_ManErrorPrint(p) ) + ABC_SWAP( Vec_Ptr_t *, vPrs, p->vNtks ); + Psr_ManFree( p ); + return vPrs; +} + +void Psr_ManReadVerilogTest( char * pFileName ) +{ + abctime clk = Abc_Clock(); + extern void Psr_ManWriteVerilog( char * pFileName, Vec_Ptr_t * p ); + Vec_Ptr_t * vPrs = Psr_ManReadVerilog( "c/hie/dump/1/netlist_1.v" ); +// Vec_Ptr_t * vPrs = Psr_ManReadVerilog( "aga/me/me_wide.v" ); +// Vec_Ptr_t * vPrs = Psr_ManReadVerilog( "aga/ray/ray_wide.v" ); + if ( !vPrs ) return; + printf( "Finished reading %d networks. ", Vec_PtrSize(vPrs) ); + printf( "NameIDs = %d. ", Abc_NamObjNumMax(Psr_ManNameMan(vPrs)) ); + printf( "Memory = %.2f MB. ", 1.0*Psr_ManMemory(vPrs)/(1<<20) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Psr_ManWriteVerilog( "c/hie/dump/1/netlist_1_out_new.v", vPrs ); +// Psr_ManWriteVerilog( "aga/me/me_wide_out.v", vPrs ); +// Psr_ManWriteVerilog( "aga/ray/ray_wide_out.v", vPrs ); +// Abc_NamPrint( p->pStrs ); + Psr_ManVecFree( vPrs ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacWriteBlif.c b/src/base/bac/bacWriteBlif.c new file mode 100644 index 00000000..ba2d2e50 --- /dev/null +++ b/src/base/bac/bacWriteBlif.c @@ -0,0 +1,236 @@ +/**CFile**************************************************************** + + FileName [bacWriteBlif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Verilog parser.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacWriteBlif.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" +#include "map/mio/mio.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Writing parser state into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void Psr_ManWriteBlifArray( FILE * pFile, Psr_Ntk_t * p, Vec_Int_t * vFanins ) +{ + int i, NameId; + Vec_IntForEachEntry( vFanins, NameId, i ) + fprintf( pFile, " %s", Psr_NtkStr(p, NameId) ); + fprintf( pFile, "\n" ); +} +static void Psr_ManWriteBlifLines( FILE * pFile, Psr_Ntk_t * p ) +{ + Vec_Int_t * vBox; + int i, k, FormId, ActId; + Psr_NtkForEachBox( p, vBox, i ) + { + int NtkId = Psr_BoxNtk(p, i); + assert( Psr_BoxIONum(p, i) > 0 ); + assert( Vec_IntSize(vBox) % 2 == 0 ); + if ( NtkId == -1 ) // latch + { + fprintf( pFile, ".latch" ); + fprintf( pFile, " %s", Psr_NtkStr(p, Vec_IntEntry(vBox, 1)) ); + fprintf( pFile, " %s", Psr_NtkStr(p, Vec_IntEntry(vBox, 3)) ); + fprintf( pFile, " %c\n", '0' + Psr_BoxName(p, i) ); + } + else if ( Psr_BoxIsNode(p, i) ) // node + { + fprintf( pFile, ".names" ); + Vec_IntForEachEntryDouble( vBox, FormId, ActId, k ) + fprintf( pFile, " %s", Psr_NtkStr(p, ActId) ); + fprintf( pFile, "\n%s", Psr_NtkStr(p, NtkId) ); + } + else // box + { + fprintf( pFile, ".subckt" ); + fprintf( pFile, " %s", Psr_NtkStr(p, NtkId) ); + Vec_IntForEachEntryDouble( vBox, FormId, ActId, k ) + fprintf( pFile, " %s=%s", Psr_NtkStr(p, FormId), Psr_NtkStr(p, ActId) ); + fprintf( pFile, "\n" ); + } + } +} +static void Psr_ManWriteBlifNtk( FILE * pFile, Psr_Ntk_t * p ) +{ + // write header + fprintf( pFile, ".model %s\n", Psr_NtkStr(p, p->iModuleName) ); + if ( Vec_IntSize(&p->vInouts) ) + fprintf( pFile, ".inouts" ); + if ( Vec_IntSize(&p->vInouts) ) + Psr_ManWriteBlifArray( pFile, p, &p->vInouts ); + fprintf( pFile, ".inputs" ); + Psr_ManWriteBlifArray( pFile, p, &p->vInputs ); + fprintf( pFile, ".outputs" ); + Psr_ManWriteBlifArray( pFile, p, &p->vOutputs ); + // write objects + Psr_ManWriteBlifLines( pFile, p ); + fprintf( pFile, ".end\n\n" ); +} +void Psr_ManWriteBlif( char * pFileName, Vec_Ptr_t * vPrs ) +{ + Psr_Ntk_t * pNtk = Psr_ManRoot(vPrs); + FILE * pFile = fopen( pFileName, "wb" ); int i; + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "# Design \"%s\" written by ABC on %s\n\n", Psr_NtkStr(pNtk, pNtk->iModuleName), Extra_TimeStamp() ); + Vec_PtrForEachEntry( Psr_Ntk_t *, vPrs, pNtk, i ) + Psr_ManWriteBlifNtk( pFile, pNtk ); + fclose( pFile ); +} + + + +/**Function************************************************************* + + Synopsis [Write elaborated design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bac_ManWriteBlifGate( FILE * pFile, Bac_Ntk_t * p, Mio_Gate_t * pGate, Vec_Int_t * vFanins, int iObj ) +{ + int iFanin, i; + Vec_IntForEachEntry( vFanins, iFanin, i ) + fprintf( pFile, " %s=%s", Mio_GateReadPinName(pGate, i), Bac_ObjNameStr(p, iFanin) ); + fprintf( pFile, " %s=%s", Mio_GateReadOutName(pGate), Bac_ObjNameStr(p, iObj) ); + fprintf( pFile, "\n" ); +} +void Bac_ManWriteBlifArray( FILE * pFile, Bac_Ntk_t * p, Vec_Int_t * vFanins, int iObj ) +{ + int iFanin, i; + Vec_IntForEachEntry( vFanins, iFanin, i ) + fprintf( pFile, " %s", Bac_ObjNameStr(p, iFanin) ); + if ( iObj >= 0 ) + fprintf( pFile, " %s", Bac_ObjNameStr(p, iObj) ); + fprintf( pFile, "\n" ); +} +void Bac_ManWriteBlifArray2( FILE * pFile, Bac_Ntk_t * p, int iObj ) +{ + int iTerm, i; + Bac_Ntk_t * pModel = Bac_BoxNtk( p, iObj ); + Bac_NtkForEachPi( pModel, iTerm, i ) + fprintf( pFile, " %s=%s", Bac_ObjNameStr(pModel, iTerm), Bac_ObjNameStr(p, Bac_BoxBi(p, iObj, i)) ); + Bac_NtkForEachPo( pModel, iTerm, i ) + fprintf( pFile, " %s=%s", Bac_ObjNameStr(pModel, iTerm), Bac_ObjNameStr(p, Bac_BoxBo(p, iObj, i)) ); + fprintf( pFile, "\n" ); +} +void Bac_ManWriteBlifLines( FILE * pFile, Bac_Ntk_t * p ) +{ + int i, k, iTerm; + Bac_NtkForEachBox( p, i ) + { + if ( Bac_ObjIsBoxUser(p, i) ) + { + fprintf( pFile, ".subckt" ); + fprintf( pFile, " %s", Bac_NtkName(Bac_BoxNtk(p, i)) ); + Bac_ManWriteBlifArray2( pFile, p, i ); + } + else if ( Bac_ObjIsGate(p, i) ) + { + char * pGateName = Abc_NamStr(p->pDesign->pMods, Bac_BoxNtkId(p, i)); + Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + Mio_Gate_t * pGate = Mio_LibraryReadGateByName( pLib, pGateName, NULL ); + fprintf( pFile, ".gate %s", pGateName ); + Bac_BoxForEachBi( p, i, iTerm, k ) + fprintf( pFile, " %s=%s", Mio_GateReadPinName(pGate, k), Bac_ObjNameStr(p, iTerm) ); + Bac_BoxForEachBo( p, i, iTerm, k ) + fprintf( pFile, " %s=%s", Mio_GateReadOutName(pGate), Bac_ObjNameStr(p, iTerm) ); + fprintf( pFile, "\n" ); + } + else + { + fprintf( pFile, ".names" ); + Bac_BoxForEachBi( p, i, iTerm, k ) + fprintf( pFile, " %s", Bac_ObjNameStr(p, Bac_ObjFanin(p, iTerm)) ); + Bac_BoxForEachBo( p, i, iTerm, k ) + fprintf( pFile, " %s", Bac_ObjNameStr(p, iTerm) ); + fprintf( pFile, "\n%s", Ptr_TypeToSop(Bac_ObjType(p, i)) ); + } + } +} +void Bac_ManWriteBlifNtk( FILE * pFile, Bac_Ntk_t * p ) +{ + assert( Vec_IntSize(&p->vFanin) == Bac_NtkObjNum(p) ); + // write header + fprintf( pFile, ".model %s\n", Bac_NtkName(p) ); + fprintf( pFile, ".inputs" ); + Bac_ManWriteBlifArray( pFile, p, &p->vInputs, -1 ); + fprintf( pFile, ".outputs" ); + Bac_ManWriteBlifArray( pFile, p, &p->vOutputs, -1 ); + // write objects + Bac_ManWriteBlifLines( pFile, p ); + fprintf( pFile, ".end\n\n" ); +} +void Bac_ManWriteBlif( char * pFileName, Bac_Man_t * p ) +{ + FILE * pFile; + Bac_Ntk_t * pNtk; + int i; + // check the library + if ( p->pMioLib && p->pMioLib != Abc_FrameReadLibGen() ) + { + printf( "Genlib library used in the mapped design is not longer a current library.\n" ); + return; + } + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "# Design \"%s\" written via CBA package in ABC on %s\n\n", Bac_ManName(p), Extra_TimeStamp() ); + Bac_ManAssignInternWordNames( p ); + Bac_ManForEachNtk( p, pNtk, i ) + Bac_ManWriteBlifNtk( pFile, pNtk ); + fclose( pFile ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacWriteSmt.c b/src/base/bac/bacWriteSmt.c new file mode 100644 index 00000000..eacc5a06 --- /dev/null +++ b/src/base/bac/bacWriteSmt.c @@ -0,0 +1,52 @@ +/**CFile**************************************************************** + + FileName [bacWriteSmt.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Verilog parser.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacWriteSmt.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/bacWriteVer.c b/src/base/bac/bacWriteVer.c new file mode 100644 index 00000000..83826fe7 --- /dev/null +++ b/src/base/bac/bacWriteVer.c @@ -0,0 +1,703 @@ +/**CFile**************************************************************** + + FileName [bacWriteVer.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Verilog writer.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 29, 2014.] + + Revision [$Id: bacWriteVer.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bac.h" +#include "bacPrs.h" +#include "map/mio/mio.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Writing parser state into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void Psr_ManWriteVerilogConcat( FILE * pFile, Psr_Ntk_t * p, int Con ) +{ + extern void Psr_ManWriteVerilogArray( FILE * pFile, Psr_Ntk_t * p, Vec_Int_t * vSigs, int Start, int Stop, int fOdd ); + Vec_Int_t * vSigs = Psr_CatSignals(p, Con); + fprintf( pFile, "{" ); + Psr_ManWriteVerilogArray( pFile, p, vSigs, 0, Vec_IntSize(vSigs), 0 ); + fprintf( pFile, "}" ); +} +static void Psr_ManWriteVerilogSignal( FILE * pFile, Psr_Ntk_t * p, int Sig ) +{ + int Value = Abc_Lit2Var2( Sig ); + Psr_ManType_t Type = (Psr_ManType_t)Abc_Lit2Att2( Sig ); + if ( Type == BAC_PRS_NAME || Type == BAC_PRS_CONST ) + fprintf( pFile, "%s", Psr_NtkStr(p, Value) ); + else if ( Type == BAC_PRS_SLICE ) + fprintf( pFile, "%s%s", Psr_NtkStr(p, Psr_SliceName(p, Value)), Psr_NtkStr(p, Psr_SliceRange(p, Value)) ); + else if ( Type == BAC_PRS_CONCAT ) + Psr_ManWriteVerilogConcat( pFile, p, Value ); + else assert( 0 ); +} +static void Psr_ManWriteVerilogArray( FILE * pFile, Psr_Ntk_t * p, Vec_Int_t * vSigs, int Start, int Stop, int fOdd ) +{ + int i, Sig; + assert( Vec_IntSize(vSigs) > 0 ); + Vec_IntForEachEntryStartStop( vSigs, Sig, i, Start, Stop ) + { + if ( fOdd && !(i & 1) ) + continue; + Psr_ManWriteVerilogSignal( pFile, p, Sig ); + fprintf( pFile, "%s", i == Stop - 1 ? "" : ", " ); + } +} +static void Psr_ManWriteVerilogArray2( FILE * pFile, Psr_Ntk_t * p, Vec_Int_t * vSigs ) +{ + int i, FormId, ActSig; + assert( Vec_IntSize(vSigs) % 2 == 0 ); + Vec_IntForEachEntryDouble( vSigs, FormId, ActSig, i ) + { + fprintf( pFile, "." ); + fprintf( pFile, "%s", Psr_NtkStr(p, FormId) ); + fprintf( pFile, "(" ); + Psr_ManWriteVerilogSignal( pFile, p, ActSig ); + fprintf( pFile, ")%s", (i == Vec_IntSize(vSigs) - 2) ? "" : ", " ); + } +} +static void Psr_ManWriteVerilogMux( FILE * pFile, Psr_Ntk_t * p, Vec_Int_t * vSigs ) +{ + int i, FormId, ActSig; + char * pStrs[4] = { " = ", " ? ", " : ", ";\n" }; + assert( Vec_IntSize(vSigs) == 8 ); + fprintf( pFile, " assign " ); + Psr_ManWriteVerilogSignal( pFile, p, Vec_IntEntryLast(vSigs) ); + fprintf( pFile, "%s", pStrs[0] ); + Vec_IntForEachEntryDouble( vSigs, FormId, ActSig, i ) + { + Psr_ManWriteVerilogSignal( pFile, p, ActSig ); + fprintf( pFile, "%s", pStrs[1+i/2] ); + if ( i == 4 ) + break; + } +} +static void Psr_ManWriteVerilogBoxes( FILE * pFile, Psr_Ntk_t * p ) +{ + Vec_Int_t * vBox; int i; + Psr_NtkForEachBox( p, vBox, i ) + { + Bac_ObjType_t NtkId = Psr_BoxNtk(p, i); + if ( NtkId == BAC_BOX_MUX ) + Psr_ManWriteVerilogMux( pFile, p, vBox ); + else if ( Psr_BoxIsNode(p, i) ) // node ------- check order of fanins + { + fprintf( pFile, " %s (", Ptr_TypeToName(NtkId) ); + Psr_ManWriteVerilogSignal( pFile, p, Vec_IntEntryLast(vBox) ); + if ( Psr_BoxIONum(p, i) > 1 ) + fprintf( pFile, ", " ); + Psr_ManWriteVerilogArray( pFile, p, vBox, 0, Vec_IntSize(vBox)-2, 1 ); + fprintf( pFile, ");\n" ); + } + else // box + { + //char * s = Psr_NtkStr(p, Vec_IntEntry(vBox, 0)); + fprintf( pFile, " %s %s (", Psr_NtkStr(p, NtkId), Psr_BoxName(p, i) ? Psr_NtkStr(p, Psr_BoxName(p, i)) : "" ); + Psr_ManWriteVerilogArray2( pFile, p, vBox ); + fprintf( pFile, ");\n" ); + } + } +} +static void Psr_ManWriteVerilogIos( FILE * pFile, Psr_Ntk_t * p, int SigType ) +{ + int NameId, RangeId, i; + char * pSigNames[4] = { "inout", "input", "output", "wire" }; + Vec_Int_t * vSigs[4] = { &p->vInouts, &p->vInputs, &p->vOutputs, &p->vWires }; + Vec_Int_t * vSigsR[4] = { &p->vInoutsR, &p->vInputsR, &p->vOutputsR, &p->vWiresR }; + if ( SigType == 3 ) + fprintf( pFile, "\n" ); + Vec_IntForEachEntryTwo( vSigs[SigType], vSigsR[SigType], NameId, RangeId, i ) + fprintf( pFile, " %s %s%s;\n", pSigNames[SigType], RangeId ? Psr_NtkStr(p, RangeId) : "", Psr_NtkStr(p, NameId) ); +} +static void Psr_ManWriteVerilogIoOrder( FILE * pFile, Psr_Ntk_t * p, Vec_Int_t * vOrder ) +{ + int i, NameId; + Vec_IntForEachEntry( vOrder, NameId, i ) + fprintf( pFile, "%s%s", Psr_NtkStr(p, NameId), i == Vec_IntSize(vOrder) - 1 ? "" : ", " ); +} +static void Psr_ManWriteVerilogNtk( FILE * pFile, Psr_Ntk_t * p ) +{ + int s; + // write header + fprintf( pFile, "module %s (\n ", Psr_NtkStr(p, p->iModuleName) ); + Psr_ManWriteVerilogIoOrder( pFile, p, &p->vOrder ); + fprintf( pFile, "\n );\n" ); + // write declarations + for ( s = 0; s < 4; s++ ) + Psr_ManWriteVerilogIos( pFile, p, s ); + fprintf( pFile, "\n" ); + // write objects + Psr_ManWriteVerilogBoxes( pFile, p ); + fprintf( pFile, "endmodule\n\n" ); +} +void Psr_ManWriteVerilog( char * pFileName, Vec_Ptr_t * vPrs ) +{ + Psr_Ntk_t * pNtk = Psr_ManRoot(vPrs); int i; + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "// Design \"%s\" written by ABC on %s\n\n", Psr_NtkStr(pNtk, pNtk->iModuleName), Extra_TimeStamp() ); + Vec_PtrForEachEntry( Psr_Ntk_t *, vPrs, pNtk, i ) + Psr_ManWriteVerilogNtk( pFile, pNtk ); + fclose( pFile ); +} + + + +/**Function************************************************************* + + Synopsis [Writing word-level Verilog.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// compute range of a name (different from range of a multi-bit wire) +static inline int Bac_ObjGetRange( Bac_Ntk_t * p, int iObj ) +{ + int i, NameId = Bac_ObjName(p, iObj); + assert( Bac_ObjIsCi(p, iObj) ); +// if ( Bac_NameType(NameId) == BAC_NAME_INDEX ) +// NameId = Bac_ObjName(p, iObj - Abc_Lit2Var2(NameId)); + assert( Bac_NameType(NameId) == BAC_NAME_WORD || Bac_NameType(NameId) == BAC_NAME_INFO ); + for ( i = iObj + 1; i < Bac_NtkObjNum(p); i++ ) + if ( !Bac_ObjIsCi(p, i) || Bac_ObjNameType(p, i) != BAC_NAME_INDEX ) + break; + return i - iObj; +} + +static inline void Bac_ManWriteVar( Bac_Ntk_t * p, int RealName ) +{ + Vec_StrPrintStr( p->pDesign->vOut, Bac_NtkStr(p, RealName) ); +} +static inline void Bac_ManWriteRange( Bac_Ntk_t * p, int Beg, int End ) +{ + Vec_Str_t * vStr = p->pDesign->vOut; + Vec_StrPrintStr( vStr, "[" ); + if ( End >= 0 ) + { + Vec_StrPrintNum( vStr, End ); + Vec_StrPrintStr( vStr, ":" ); + } + Vec_StrPrintNum( vStr, Beg ); + Vec_StrPrintStr( vStr, "]" ); +} +static inline void Bac_ManWriteConstBit( Bac_Ntk_t * p, int iObj, int fHead ) +{ + Vec_Str_t * vStr = p->pDesign->vOut; + int Const = Bac_ObjGetConst(p, iObj); + assert( Const ); + if ( fHead ) + Vec_StrPrintStr( vStr, "1\'b" ); + if ( Const == BAC_BOX_CF ) + Vec_StrPush( vStr, '0' ); + else if ( Const == BAC_BOX_CT ) + Vec_StrPush( vStr, '1' ); + else if ( Const == BAC_BOX_CX ) + Vec_StrPush( vStr, 'x' ); + else if ( Const == BAC_BOX_CZ ) + Vec_StrPush( vStr, 'z' ); + else assert( 0 ); +} +static inline int Bac_ManFindRealNameId( Bac_Ntk_t * p, int iObj ) +{ + int NameId = Bac_ObjName(p, iObj); + assert( Bac_ObjIsCi(p, iObj) ); + if ( Bac_NameType(NameId) == BAC_NAME_INDEX ) + NameId = Bac_ObjName(p, iObj - Abc_Lit2Var2(NameId)); + if ( Bac_NameType(NameId) == BAC_NAME_INFO ) + return Bac_NtkInfoName(p, Abc_Lit2Var2(NameId)); + assert( Bac_NameType(NameId) == BAC_NAME_BIN || Bac_NameType(NameId) == BAC_NAME_WORD ); + return Abc_Lit2Var2(NameId); +} +static inline int Bac_ManFindRealIndex( Bac_Ntk_t * p, int iObj ) +{ + int iBit = 0, NameId = Bac_ObjName(p, iObj); + assert( Bac_ObjIsCi(p, iObj) ); + assert( Bac_NameType(NameId) != BAC_NAME_BIN ); + if ( Bac_NameType(NameId) == BAC_NAME_INDEX ) + NameId = Bac_ObjName(p, iObj - (iBit = Abc_Lit2Var2(NameId))); + if ( Bac_NameType(NameId) == BAC_NAME_INFO ) + return Bac_NtkInfoIndex(p, Abc_Lit2Var2(NameId), iBit); + assert( Bac_NameType(NameId) == BAC_NAME_WORD ); + return iBit; +} +static inline void Bac_ManWriteSig( Bac_Ntk_t * p, int iObj ) +{ + if ( Bac_ObjIsCo(p, iObj) ) + iObj = Bac_ObjFanin(p, iObj); + assert( Bac_ObjIsCi(p, iObj) ); + if ( Bac_ObjGetConst(p, iObj) ) + Bac_ManWriteConstBit( p, iObj, 1 ); + else + { + int NameId = Bac_ObjName(p, iObj); + if ( Bac_NameType(NameId) == BAC_NAME_BIN ) + Bac_ManWriteVar( p, Abc_Lit2Var2(NameId) ); + else + { + Bac_ManWriteVar( p, Bac_ManFindRealNameId(p, iObj) ); + Bac_ManWriteRange( p, Bac_ManFindRealIndex(p, iObj), -1 ); + } + } +} +static inline void Bac_ManWriteConcat( Bac_Ntk_t * p, int iStart, int nObjs ) +{ + Vec_Str_t * vStr = p->pDesign->vOut; + assert( nObjs >= 1 ); + if ( nObjs == 1 ) + { + Bac_ManWriteSig( p, iStart ); + return; + } + Vec_StrPrintStr( vStr, "{" ); + if ( Bac_ObjIsBo(p, iStart) ) // box output + { + int i; + for ( i = iStart + nObjs - 1; i >= iStart; i-- ) + { + if ( Bac_ObjNameType(p, i) == BAC_NAME_INDEX ) + continue; + if ( Vec_StrEntryLast(vStr) != '{' ) + Vec_StrPrintStr( vStr, ", " ); + Bac_ManWriteVar( p, Bac_ManFindRealNameId(p, i) ); + } + } + else if ( Bac_ObjIsBi(p, iStart) ) // box input + { + int e, b, k, NameId; + for ( e = iStart - nObjs + 1; e <= iStart; ) + { + if ( Vec_StrEntryLast(vStr) != '{' ) + Vec_StrPrintStr( vStr, ", " ); + // write constant + if ( Bac_ObjGetConst(p, Bac_ObjFanin(p, e)) ) + { + int fBinary = Bac_ObjIsConstBin(p, Bac_ObjFanin(p, e)-1); + for ( b = e + 1; b <= iStart; b++ ) + { + if ( !Bac_ObjGetConst(p, Bac_ObjFanin(p, b)) ) + break; + if ( !Bac_ObjIsConstBin(p, Bac_ObjFanin(p, b)-1) ) + fBinary = 0; + } + Vec_StrPrintNum( vStr, b - e ); + if ( fBinary && b - e > 8 ) // write hex if more than 8 bits + { + int Digit = 0, nBits = ((b - e) & 3) ? (b - e) & 3 : 4; + Vec_StrPrintStr( vStr, "\'h" ); + for ( k = e; k < b; k++ ) + { + Digit = 2*Digit + Bac_ObjGetConst(p, Bac_ObjFanin(p, k)) - BAC_BOX_CF; + assert( Digit < 16 ); + if ( --nBits == 0 ) + { + Vec_StrPush( vStr, (char)(Digit < 10 ? '0' + Digit : 'a' + Digit - 10) ); + nBits = 4; + Digit = 0; + } + } + assert( nBits == 4 ); + assert( Digit == 0 ); + } + else + { + Vec_StrPrintStr( vStr, "\'b" ); + for ( k = e; k < b; k++ ) + Bac_ManWriteConstBit( p, Bac_ObjFanin(p, k), 0 ); + } + e = b; + continue; + } + // try replication + for ( b = e + 1; b <= iStart; b++ ) + if ( Bac_ObjFanin(p, b) != Bac_ObjFanin(p, e) ) + break; + if ( b > e + 2 ) // more than two + { + Vec_StrPrintNum( vStr, b - e ); + Vec_StrPrintStr( vStr, "{" ); + Bac_ManWriteSig( p, e ); + Vec_StrPrintStr( vStr, "}" ); + e = b; + continue; + } + NameId = Bac_ObjName(p, Bac_ObjFanin(p, e)); + if ( Bac_NameType(NameId) == BAC_NAME_BIN ) + { + Bac_ManWriteVar( p, Abc_Lit2Var2(NameId) ); + e++; + continue; + } + // find end of the slice + for ( b = e + 1; b <= iStart; b++ ) + if ( Bac_ObjFanin(p, e) - Bac_ObjFanin(p, b) != b - e ) + break; + // write signal name + Bac_ManWriteVar( p, Bac_ManFindRealNameId(p, Bac_ObjFanin(p, e)) ); + if ( b == e + 1 ) // literal + Bac_ManWriteRange( p, Bac_ManFindRealIndex(p, Bac_ObjFanin(p, e)), -1 ); + else // slice or complete variable + { + // consider first variable of the slice + int f = Bac_ObjFanin( p, b-1 ); + assert( Bac_ObjNameType(p, f) != BAC_NAME_BIN ); + if ( Bac_ObjNameType(p, f) == BAC_NAME_INDEX || Bac_ObjGetRange(p, f) != b - e ) // slice + Bac_ManWriteRange( p, Bac_ManFindRealIndex(p, f), Bac_ManFindRealIndex(p, Bac_ObjFanin(p, e)) ); + // else this is complete variable + } + e = b; + } + } + else assert( 0 ); + Vec_StrPrintStr( vStr, "}" ); +} +static inline void Bac_ManWriteGate( Bac_Ntk_t * p, int iObj ) +{ + Vec_Str_t * vStr = p->pDesign->vOut; int iTerm, k; + char * pGateName = Abc_NamStr(p->pDesign->pMods, Bac_BoxNtkId(p, iObj)); + Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + Mio_Gate_t * pGate = Mio_LibraryReadGateByName( pLib, pGateName, NULL ); + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, pGateName ); + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, Bac_ObjName(p, iObj) ? Bac_ObjNameStr(p, iObj) : "" ); + Vec_StrPrintStr( vStr, " (" ); + Bac_BoxForEachBi( p, iObj, iTerm, k ) + { + Vec_StrPrintStr( vStr, k ? ", ." : "." ); + Vec_StrPrintStr( vStr, Mio_GateReadPinName(pGate, k) ); + Vec_StrPrintStr( vStr, "(" ); + Bac_ManWriteSig( p, iTerm ); + Vec_StrPrintStr( vStr, ")" ); + } + Bac_BoxForEachBo( p, iObj, iTerm, k ) + { + Vec_StrPrintStr( vStr, Bac_BoxBiNum(p, iObj) ? ", ." : "." ); + Vec_StrPrintStr( vStr, Mio_GateReadOutName(pGate) ); + Vec_StrPrintStr( vStr, "(" ); + Bac_ManWriteSig( p, iTerm ); + Vec_StrPrintStr( vStr, ")" ); + } + Vec_StrPrintStr( vStr, ");\n" ); +} +static inline void Bac_ManWriteAssign( Bac_Ntk_t * p, int iObj ) +{ + Vec_Str_t * vStr = p->pDesign->vOut; + Bac_ObjType_t Type = Bac_ObjType(p, iObj); + int nInputs = Bac_BoxBiNum(p, iObj); + int nOutputs = Bac_BoxBoNum(p, iObj); + assert( nOutputs == 1 ); + Vec_StrPrintStr( vStr, " assign " ); + Bac_ManWriteSig( p, iObj + 1 ); + Vec_StrPrintStr( vStr, " = " ); + if ( nInputs == 0 ) + { + if ( Type == BAC_BOX_CF ) + Vec_StrPrintStr( vStr, "1\'b0" ); + else if ( Type == BAC_BOX_CT ) + Vec_StrPrintStr( vStr, "1\'b1" ); + else if ( Type == BAC_BOX_CX ) + Vec_StrPrintStr( vStr, "1\'bx" ); + else if ( Type == BAC_BOX_CZ ) + Vec_StrPrintStr( vStr, "1\'bz" ); + else assert( 0 ); + } + else if ( nInputs == 1 ) + { + if ( Type == BAC_BOX_INV ) + Vec_StrPrintStr( vStr, "~" ); + else assert( Type == BAC_BOX_BUF ); + Bac_ManWriteSig( p, iObj - 1 ); + } + else if ( nInputs == 2 ) + { + if ( Type == BAC_BOX_NAND || Type == BAC_BOX_NOR || Type == BAC_BOX_XNOR || Type == BAC_BOX_SHARPL ) + Vec_StrPrintStr( vStr, "~" ); + Bac_ManWriteSig( p, iObj - 1 ); + if ( Type == BAC_BOX_AND || Type == BAC_BOX_SHARPL ) + Vec_StrPrintStr( vStr, " & " ); + else if ( Type == BAC_BOX_SHARP || Type == BAC_BOX_NOR ) + Vec_StrPrintStr( vStr, " & ~" ); + else if ( Type == BAC_BOX_OR ) + Vec_StrPrintStr( vStr, " | " ); + else if ( Type == BAC_BOX_NAND ) + Vec_StrPrintStr( vStr, " | ~" ); + else if ( Type == BAC_BOX_XOR || Type == BAC_BOX_XNOR ) + Vec_StrPrintStr( vStr, " ^ " ); + else assert( 0 ); + Bac_ManWriteSig( p, iObj - 2 ); + } + Vec_StrPrintStr( vStr, ";\n" ); +} +void Bac_ManWriteVerilogBoxes( Bac_Ntk_t * p, int fUseAssign ) +{ + Vec_Str_t * vStr = p->pDesign->vOut; + int iObj, k, i, o, StartPos; + Bac_NtkForEachBox( p, iObj ) // .subckt/.gate/box (formal/actual binding) + { + // skip constants + if ( Bac_ObjIsConst(p, iObj) ) + continue; + // write mapped + if ( Bac_ObjIsGate(p, iObj) ) + { + Bac_ManWriteGate( p, iObj ); + continue; + } + // write primitives as assign-statements + if ( !Bac_ObjIsBoxUser(p, iObj) && fUseAssign ) + { + Bac_ManWriteAssign( p, iObj ); + continue; + } + // write header + StartPos = Vec_StrSize(vStr); + if ( Bac_ObjIsBoxUser(p, iObj) ) + { + int Value, Beg, End, Range; + Bac_Ntk_t * pModel = Bac_BoxNtk( p, iObj ); + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, Bac_NtkName(pModel) ); + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, Bac_ObjName(p, iObj) ? Bac_ObjNameStr(p, iObj) : "" ); + Vec_StrPrintStr( vStr, " (" ); + // write arguments + i = o = 0; + assert( Bac_NtkInfoNum(pModel) ); + Vec_IntForEachEntryTriple( &pModel->vInfo, Value, Beg, End, k ) + { + int NameId = Abc_Lit2Var2( Value ); + int Type = Abc_Lit2Att2( Value ); + Vec_StrPrintStr( vStr, k ? ", " : "" ); + if ( Vec_StrSize(vStr) > StartPos + 70 ) + { + StartPos = Vec_StrSize(vStr); + Vec_StrPrintStr( vStr, "\n " ); + } + Vec_StrPrintStr( vStr, "." ); + Vec_StrPrintStr( vStr, Bac_NtkStr(p, NameId) ); + Vec_StrPrintStr( vStr, "(" ); + Range = Bac_InfoRange( Beg, End ); + assert( Range > 0 ); + if ( Type == 1 ) + Bac_ManWriteConcat( p, Bac_BoxBi(p, iObj, i), Range ), i += Range; + else if ( Type == 2 ) + Bac_ManWriteConcat( p, Bac_BoxBo(p, iObj, o), Range ), o += Range; + else assert( 0 ); + Vec_StrPrintStr( vStr, ")" ); + } + assert( i == Bac_BoxBiNum(p, iObj) ); + assert( o == Bac_BoxBoNum(p, iObj) ); + } + else + { + int iTerm, k, Range, iSig = 0; + Vec_Int_t * vBits = Bac_BoxCollectRanges( p, iObj ); + char * pName = Bac_NtkGenerateName( p, Bac_ObjType(p, iObj), vBits ); + char * pSymbs = Bac_ManPrimSymb( p->pDesign, Bac_ObjType(p, iObj) ); + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, pName ); + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, Bac_ObjName(p, iObj) ? Bac_ObjNameStr(p, iObj) : "" ); + Vec_StrPrintStr( vStr, " (" ); + // write inputs + Bac_BoxForEachBiMain( p, iObj, iTerm, k ) + { + Range = Vec_IntEntry( vBits, iSig ); + Vec_StrPrintStr( vStr, iSig ? ", " : "" ); + if ( Vec_StrSize(vStr) > StartPos + 70 ) + { + StartPos = Vec_StrSize(vStr); + Vec_StrPrintStr( vStr, "\n " ); + } + Vec_StrPrintStr( vStr, "." ); + Vec_StrPush( vStr, pSymbs[iSig] ); + Vec_StrPrintStr( vStr, "(" ); + Bac_ManWriteConcat( p, iTerm, Range ); + Vec_StrPrintStr( vStr, ")" ); + iSig++; + } + Bac_BoxForEachBoMain( p, iObj, iTerm, k ) + { + Range = Vec_IntEntry( vBits, iSig ); + Vec_StrPrintStr( vStr, iSig ? ", " : "" ); + if ( Vec_StrSize(vStr) > StartPos + 70 ) + { + StartPos = Vec_StrSize(vStr); + Vec_StrPrintStr( vStr, "\n " ); + } + Vec_StrPrintStr( vStr, "." ); + Vec_StrPush( vStr, pSymbs[iSig] ); + Vec_StrPrintStr( vStr, "(" ); + Bac_ManWriteConcat( p, iTerm, Range ); + Vec_StrPrintStr( vStr, ")" ); + iSig++; + } + assert( iSig == Vec_IntSize(vBits) ); + } + Vec_StrPrintStr( vStr, ");\n" ); + } +} +void Bac_ManWriteVerilogNtk( Bac_Ntk_t * p, int fUseAssign ) +{ + char * pKeyword[4] = { "wire ", "input ", "output ", "inout " }; + Vec_Str_t * vStr = p->pDesign->vOut; + int k, iObj, iTerm, Value, Beg, End, Length, fHaveWires, StartPos; +// assert( Bac_NtkInfoNum(p) ); + assert( Vec_IntSize(&p->vFanin) == Bac_NtkObjNum(p) ); +// Bac_NtkPrint( p ); + // write header + Vec_StrPrintStr( vStr, "module " ); + Vec_StrPrintStr( vStr, Bac_NtkName(p) ); + Vec_StrPrintStr( vStr, " (\n " ); + StartPos = Vec_StrSize(vStr); + Vec_IntForEachEntryTriple( &p->vInfo, Value, Beg, End, k ) + if ( Abc_Lit2Att2(Value) != 0 ) + { + Vec_StrPrintStr( vStr, k ? ", " : "" ); + if ( Vec_StrSize(vStr) > StartPos + 70 ) + { + StartPos = Vec_StrSize(vStr); + Vec_StrPrintStr( vStr, "\n " ); + } + Bac_ManWriteVar( p, Abc_Lit2Var2(Value) ); + } + Vec_StrPrintStr( vStr, "\n );\n" ); + // write inputs/outputs + Vec_IntForEachEntryTriple( &p->vInfo, Value, Beg, End, k ) + if ( Abc_Lit2Att2(Value) != 0 ) + { + Vec_StrPrintStr( vStr, " " ); + Vec_StrPrintStr( vStr, pKeyword[Abc_Lit2Att2(Value)] ); + if ( Beg >= 0 ) + Bac_ManWriteRange( p, Beg, End ); + Bac_ManWriteVar( p, Abc_Lit2Var2(Value) ); + Vec_StrPrintStr( vStr, ";\n" ); + } + Vec_StrPrintStr( vStr, "\n" ); + // write word-level wires + Bac_NtkForEachBox( p, iObj ) + if ( !Bac_ObjIsConst(p, iObj) ) + Bac_BoxForEachBo( p, iObj, iTerm, k ) + if ( Bac_ObjNameType(p, iTerm) == BAC_NAME_WORD || Bac_ObjNameType(p, iTerm) == BAC_NAME_INFO ) + { + Vec_StrPrintStr( vStr, " wire " ); + Bac_ManWriteRange( p, Bac_ManFindRealIndex(p, iTerm), Bac_ManFindRealIndex(p, iTerm + Bac_ObjGetRange(p, iTerm) - 1) ); + Bac_ManWriteVar( p, Bac_ManFindRealNameId(p, iTerm) ); + Vec_StrPrintStr( vStr, ";\n" ); + } + // check if there are any wires left + fHaveWires = 0; + Bac_NtkForEachBox( p, iObj ) + if ( !Bac_ObjIsConst(p, iObj) ) + Bac_BoxForEachBo( p, iObj, iTerm, k ) + if ( Bac_ObjNameType(p, iTerm) == BAC_NAME_BIN ) + { fHaveWires = 1; iObj = Bac_NtkObjNum(p); break; } + // write bit-level wires + if ( fHaveWires ) + { + Length = 7; + Vec_StrPrintStr( vStr, "\n wire " ); + Bac_NtkForEachBox( p, iObj ) + if ( !Bac_ObjIsConst(p, iObj) ) + Bac_BoxForEachBo( p, iObj, iTerm, k ) + if ( Bac_ObjNameType(p, iTerm) == BAC_NAME_BIN ) + { + if ( Length > 72 ) + Vec_StrPrintStr( vStr, ";\n wire " ), Length = 7; + if ( Length > 7 ) + Vec_StrPrintStr( vStr, ", " ); + Vec_StrPrintStr( vStr, Bac_ObjNameStr(p, iTerm) ); + Length += strlen(Bac_ObjNameStr(p, iTerm)); + } + Vec_StrPrintStr( vStr, ";\n" ); + } + Vec_StrPrintStr( vStr, "\n" ); + // write objects + Bac_ManWriteVerilogBoxes( p, fUseAssign ); + Vec_StrPrintStr( vStr, "endmodule\n\n" ); +} +void Bac_ManWriteVerilog( char * pFileName, Bac_Man_t * p, int fUseAssign ) +{ + Bac_Ntk_t * pNtk; int i; + // check the library + if ( p->pMioLib && p->pMioLib != Abc_FrameReadLibGen() ) + { + printf( "Genlib library used in the mapped design is not longer a current library.\n" ); + return; + } + // derive the stream + p->vOut = Vec_StrAlloc( 10000 ); + p->vOut2 = Vec_StrAlloc( 1000 ); + Vec_StrPrintStr( p->vOut, "// Design \"" ); + Vec_StrPrintStr( p->vOut, Bac_ManName(p) ); + Vec_StrPrintStr( p->vOut, "\" written via CBA package in ABC on " ); + Vec_StrPrintStr( p->vOut, Extra_TimeStamp() ); + Vec_StrPrintStr( p->vOut, "\n\n" ); + Bac_ManAssignInternWordNames( p ); + Bac_ManForEachNtk( p, pNtk, i ) + Bac_ManWriteVerilogNtk( pNtk, fUseAssign ); + // dump into file + if ( p->vOut && Vec_StrSize(p->vOut) > 0 ) + { + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + else + { + fwrite( Vec_StrArray(p->vOut), 1, Vec_StrSize(p->vOut), pFile ); + fclose( pFile ); + } + } + Vec_StrFreeP( &p->vOut ); + Vec_StrFreeP( &p->vOut2 ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/bac/module.make b/src/base/bac/module.make new file mode 100644 index 00000000..c0b81045 --- /dev/null +++ b/src/base/bac/module.make @@ -0,0 +1,15 @@ +SRC += src/base/bac/bacBlast.c \ + src/base/bac/bacBac.c \ + src/base/bac/bacCom.c \ + src/base/bac/bacLib.c \ + src/base/bac/bacNtk.c \ + src/base/bac/bacPrsBuild.c \ + src/base/bac/bacPrsTrans.c \ + src/base/bac/bacPtr.c \ + src/base/bac/bacPtrAbc.c \ + src/base/bac/bacReadBlif.c \ + src/base/bac/bacReadSmt.c \ + src/base/bac/bacReadVer.c \ + src/base/bac/bacWriteBlif.c \ + src/base/bac/bacWriteSmt.c \ + src/base/bac/bacWriteVer.c |