diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abc/abcShow.c | 10 | ||||
-rw-r--r-- | src/base/io/io.c | 57 | ||||
-rw-r--r-- | src/base/main/mainInit.c | 4 | ||||
-rw-r--r-- | src/base/main/mainInt.h | 1 | ||||
-rw-r--r-- | src/base/wlc/module.make | 6 | ||||
-rw-r--r-- | src/base/wlc/wlc.c | 52 | ||||
-rw-r--r-- | src/base/wlc/wlc.h | 273 | ||||
-rw-r--r-- | src/base/wlc/wlcBlast.c | 363 | ||||
-rw-r--r-- | src/base/wlc/wlcCom.c | 311 | ||||
-rw-r--r-- | src/base/wlc/wlcNtk.c | 283 | ||||
-rw-r--r-- | src/base/wlc/wlcReadVer.c | 711 | ||||
-rw-r--r-- | src/base/wlc/wlcWriteVer.c | 204 | ||||
-rw-r--r-- | src/misc/util/utilTruth.h | 29 |
13 files changed, 2243 insertions, 61 deletions
diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c index d209a9ce..a1136ef7 100644 --- a/src/base/abc/abcShow.c +++ b/src/base/abc/abcShow.c @@ -309,10 +309,12 @@ void Abc_ShowFile( char * FileNameDot ) if ( _spawnl( _P_NOWAIT, pGsNameWin, pGsNameWin, FileNamePs, NULL ) == -1 ) if ( _spawnl( _P_NOWAIT, "C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe", "C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe", FileNamePs, NULL ) == -1 ) - { - fprintf( stdout, "Cannot find \"%s\".\n", pGsNameWin ); - return; - } + if ( _spawnl( _P_NOWAIT, "C:\\Program Files\\Ghostgum\\gsview\\gsview64.exe", + "C:\\Program Files\\Ghostgum\\gsview\\gsview64.exe", FileNamePs, NULL ) == -1 ) + { + fprintf( stdout, "Cannot find \"%s\".\n", pGsNameWin ); + return; + } #else { char CommandPs[1000]; diff --git a/src/base/io/io.c b/src/base/io/io.c index 23996a1f..257acc30 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -46,7 +46,6 @@ static int IoCommandReadTruth ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadStatus ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadGig ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int IoCommandReadWord ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteHie ( Abc_Frame_t * pAbc, int argc, char **argv ); @@ -111,7 +110,6 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "read_verilog", IoCommandReadVerilog, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_status", IoCommandReadStatus, 0 ); Cmd_CommandAdd( pAbc, "I/O", "&read_gig", IoCommandReadGig, 0 ); - Cmd_CommandAdd( pAbc, "I/O", "read_word", IoCommandReadWord, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write", IoCommandWrite, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_hie", IoCommandWriteHie, 0 ); @@ -1193,61 +1191,6 @@ usage: return 1; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int IoCommandReadWord( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern void Io_ReadWordTest( char * pFileName ); - char * pFileName; - FILE * pFile; - int c; - - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) - { - switch ( c ) - { - case 'h': - goto usage; - default: - goto usage; - } - } - if ( argc != globalUtilOptind + 1 ) - { - goto usage; - } - - // get the input file name - pFileName = argv[globalUtilOptind]; - if ( (pFile = fopen( pFileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". \n", pFileName ); - return 1; - } - fclose( pFile ); - - // set the new network -// Io_ReadWordTest( pFileName ); - return 0; - -usage: - fprintf( pAbc->Err, "usage: read_word [-h] <file>\n" ); - fprintf( pAbc->Err, "\t reads design in word-level Verilog\n" ); - fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); - fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); - return 1; -} - /**Function************************************************************* diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c index bbe0bbd1..f99a5653 100644 --- a/src/base/main/mainInit.c +++ b/src/base/main/mainInit.c @@ -50,6 +50,8 @@ extern void Load_Init( Abc_Frame_t * pAbc ); extern void Load_End( Abc_Frame_t * pAbc ); extern void Scl_Init( Abc_Frame_t * pAbc ); extern void Scl_End( Abc_Frame_t * pAbc ); +extern void Wlc_Init( Abc_Frame_t * pAbc ); +extern void Wlc_End( Abc_Frame_t * pAbc ); extern void Test_Init( Abc_Frame_t * pAbc ); extern void Test_End( Abc_Frame_t * pAbc ); extern void Abc2_Init( Abc_Frame_t * pAbc ); @@ -85,6 +87,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc ) Libs_Init( pAbc ); Load_Init( pAbc ); Scl_Init( pAbc ); + Wlc_Init( pAbc ); Test_Init( pAbc ); #ifdef USE_ABC2 Abc2_Init( pAbc ); @@ -119,6 +122,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc ) Libs_End( pAbc ); Load_End( pAbc ); Scl_End( pAbc ); + Wlc_End( pAbc ); Test_End( pAbc ); #ifdef USE_ABC2 Abc2_End( pAbc ); diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index 50a52090..aa7a7d90 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -126,6 +126,7 @@ struct Abc_Frame_t_ void * pAbc85Ntl2; void * pAbc85Best; void * pAbc85Delay; + void * pAbcWlc; EXT_ABC_FRAME // plugin for external functionality }; diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make new file mode 100644 index 00000000..c1bda69a --- /dev/null +++ b/src/base/wlc/module.make @@ -0,0 +1,6 @@ +SRC += src/base/wlc/wlc.c \ + src/base/wlc/wlcBlast.c \ + src/base/wlc/wlcCom.c \ + src/base/wlc/wlcNtk.c \ + src/base/wlc/wlcReadVer.c \ + src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.c b/src/base/wlc/wlc.c new file mode 100644 index 00000000..65cdaf88 --- /dev/null +++ b/src/base/wlc/wlc.c @@ -0,0 +1,52 @@ +/**CFile**************************************************************** + + FileName [wlc.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 - August 22, 2014.] + + Revision [$Id: wlc.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.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/wlc/wlc.h b/src/base/wlc/wlc.h new file mode 100644 index 00000000..c400a03c --- /dev/null +++ b/src/base/wlc/wlc.h @@ -0,0 +1,273 @@ +/**CFile**************************************************************** + + FileName [wlc.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlc.h,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__base__wlc__wlc_h +#define ABC__base__wlc__wlc_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig/gia/gia.h" +#include "misc/extra/extra.h" +#include "misc/util/utilNam.h" +#include "misc/mem/mem.h" +#include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + +// object types +typedef enum { + WLC_OBJ_NONE = 0, // 00: unknown + WLC_OBJ_PI, // 01: primary input terminal + WLC_OBJ_PO, // 02: primary output terminal + WLC_OBJ_BO, // 03: box output + WLC_OBJ_BI, // 04: box input + WLC_OBJ_FF, // 05: flop + WLC_OBJ_CONST, // 06: constant + WLC_OBJ_BUF, // 07: buffer + WLC_OBJ_MUX, // 08: multiplexer + WLC_OBJ_SHIFT_R, // 09: shift right + WLC_OBJ_SHIFT_RA, // 10: shift right (arithmetic) + WLC_OBJ_SHIFT_L, // 11: shift left + WLC_OBJ_SHIFT_LA, // 12: shift left (arithmetic) + WLC_OBJ_BIT_NOT, // 13: bitwise NOT + WLC_OBJ_BIT_AND, // 14: bitwise AND + WLC_OBJ_BIT_OR, // 15: bitwise OR + WLC_OBJ_BIT_XOR, // 16: bitwise XOR + WLC_OBJ_BIT_SELECT, // 17: bit selection + WLC_OBJ_BIT_CONCAT, // 18: bit concatenation + WLC_OBJ_BIT_ZEROPAD, // 19: zero padding + WLC_OBJ_BIT_SIGNEXT, // 20: sign extension + WLC_OBJ_LOGIC_NOT, // 21: logic NOT + WLC_OBJ_LOGIC_AND, // 22: logic AND + WLC_OBJ_LOGIC_OR, // 23: logic OR + WLC_OBJ_COMP_EQU, // 24: compare equal + WLC_OBJ_COMP_NOT, // 25: compare not equal + WLC_OBJ_COMP_LESS, // 26: compare less + WLC_OBJ_COMP_MORE, // 27: compare more + WLC_OBJ_COMP_LESSEQU, // 28: compare less or equal + WLC_OBJ_COMP_MOREEQU, // 29: compare more or equal + WLC_OBJ_REDUCT_AND, // 30: reduction AND + WLC_OBJ_REDUCT_OR, // 31: reduction OR + WLC_OBJ_REDUCT_XOR, // 32: reduction XOR + WLC_OBJ_ARI_ADD, // 33: arithmetic addition + WLC_OBJ_ARI_SUB, // 34: arithmetic subtraction + WLC_OBJ_ARI_MULTI, // 35: arithmetic multiplier + WLC_OBJ_ARI_DIVIDE, // 36: arithmetic division + WLC_OBJ_ARI_MODULUS, // 37: arithmetic modulus + WLC_OBJ_ARI_POWER, // 38: arithmetic power + WLC_OBJ_NUMBER // 39: unused +} Abc_ObjType_t; + +// object types +static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { + NULL, // 00: unknown + "pi", // 01: primary input + "po", // 02: primary output + "bo", // 03: box output + "bi", // 04: box input + "ff", // 05: flop + "const", // 06: constant + "buf", // 07: buffer + "mux", // 08: multiplexer + ">>", // 09: shift right + ">>>", // 10: shift right (arithmetic) + "<<", // 11: shift left + "<<<", // 12: shift left (arithmetic) + "~", // 13: bitwise NOT + "&", // 14: bitwise AND + "|", // 15: bitwise OR + "^", // 16: bitwise XOR + "[:]", // 17: bit selection + "{,}", // 18: bit concatenation + "BitPad", // 19: zero padding + "SgnExt", // 20: sign extension + "!", // 21: logic NOT + "&&", // 22: logic AND + "||", // 23: logic OR + "==", // 24: compare equal + "!=", // 25: compare not equal + "<", // 26: compare less + ">", // 27: compare more + "<=", // 28: compare less or equal + ">=", // 29: compare more or equal + "&", // 30: reduction AND + "|", // 31: reduction OR + "^", // 32: reduction XOR + "+", // 33: arithmetic addition + "-", // 34: arithmetic subtraction + "*", // 35: arithmetic multiplier + "//", // 36: arithmetic division + "%%", // 37: arithmetic modulus + "**", // 38: arithmetic power + NULL // 39: unused +}; + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Wlc_Ntk_t_ Wlc_Ntk_t; +typedef struct Wlc_Obj_t_ Wlc_Obj_t; +typedef struct Wlc_Prs_t_ Wlc_Prs_t; + +struct Wlc_Obj_t_ // 16 bytes +{ + unsigned Type : 6; // node type + unsigned Signed : 1; // signed + unsigned Mark : 1; // user mark + unsigned nFanins : 24; // fanin count + unsigned End : 16; // range end + unsigned Beg : 16; // range begin + union { int Fanins[2]; // fanin IDs + int * pFanins[1]; }; +}; + +struct Wlc_Ntk_t_ +{ + char * pName; // model name + Vec_Int_t vPis; // primary inputs + Vec_Int_t vPos; // primary outputs + Vec_Int_t vCis; // combinational inputs + Vec_Int_t vCos; // combinational outputs + Vec_Int_t vFfs; // flops + int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type + // memory for objects + Wlc_Obj_t * pObjs; + int iObj; + int nObjsAlloc; + Mem_Flex_t * pMemFanin; + // object names + Abc_Nam_t * pManName; // object names + Vec_Int_t vNameIds; // object name IDs + // object attributes + int nTravIds; // counter of traversal IDs + Vec_Int_t vTravIds; // trav IDs of the objects + Vec_Int_t vCopies; // object first bits +}; + +static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } +static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } +static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } +static inline int Wlc_NtkPoNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPos); } +static inline int Wlc_NtkCiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vCis); } +static inline int Wlc_NtkCoNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vCos); } +static inline int Wlc_NtkFfNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vFfs); } + +static inline Wlc_Obj_t * Wlc_NtkObj( Wlc_Ntk_t * p, int Id ) { assert(Id > 0 && Id < p->nObjsAlloc); return p->pObjs + Id; } +static inline Wlc_Obj_t * Wlc_NtkPi( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vPis, i) ); } +static inline Wlc_Obj_t * Wlc_NtkPo( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vPos, i) ); } +static inline Wlc_Obj_t * Wlc_NtkCi( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCis, i) ); } +static inline Wlc_Obj_t * Wlc_NtkCo( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCos, i) ); } +static inline Wlc_Obj_t * Wlc_NtkFf( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs, i) ); } + +static inline int Wlc_ObjId( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return pObj - p->pObjs; } +static inline int Wlc_ObjPioId( Wlc_Obj_t * p ) { assert(p->Type==WLC_OBJ_PI||p->Type==WLC_OBJ_PO);return p->Fanins[1]; } +static inline int Wlc_ObjFaninNum( Wlc_Obj_t * p ) { return p->nFanins; } +static inline int Wlc_ObjHasArray( Wlc_Obj_t * p ) { return p->nFanins > 2 || p->Type == WLC_OBJ_CONST; } +static inline int * Wlc_ObjFanins( Wlc_Obj_t * p ) { return Wlc_ObjHasArray(p) ? p->pFanins[0] : p->Fanins; } +static inline int Wlc_ObjFaninId( Wlc_Obj_t * p, int i ) { return Wlc_ObjFanins(p)[i]; } +static inline int Wlc_ObjFaninId0( Wlc_Obj_t * p ) { return Wlc_ObjFanins(p)[0]; } +static inline int Wlc_ObjFaninId1( Wlc_Obj_t * p ) { return Wlc_ObjFanins(p)[1]; } +static inline int Wlc_ObjFaninId2( Wlc_Obj_t * p ) { return Wlc_ObjFanins(p)[2]; } +static inline Wlc_Obj_t * Wlc_ObjFanin( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int i ) { return Wlc_NtkObj( p, Wlc_ObjFaninId(pObj, i) ); } +static inline Wlc_Obj_t * Wlc_ObjFanin0( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_NtkObj( p, Wlc_ObjFaninId(pObj, 0) ); } +static inline Wlc_Obj_t * Wlc_ObjFanin1( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_NtkObj( p, Wlc_ObjFaninId(pObj, 1) ); } +static inline Wlc_Obj_t * Wlc_ObjFanin2( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_NtkObj( p, Wlc_ObjFaninId(pObj, 2) ); } + +static inline int Wlc_ObjRange( Wlc_Obj_t * p ) { return p->End - p->Beg + 1; } +static inline int Wlc_ObjRangeEnd( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->Fanins[1] >> 16; } +static inline int Wlc_ObjRangeBeg( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->Fanins[1] & 0xFFFF; } +static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); } + +static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); } +static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; } +static inline void Wlc_ObjSetCopy( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vCopies, iObj, i ); } +static inline int Wlc_ObjCopy( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vCopies, iObj ); } + +static inline void Wlc_NtkCleanNameId( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vNameIds, p->nObjsAlloc, 0 ); } +static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vNameIds ) > 0; } +static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); } +static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); } + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +#define Wlc_NtkForEachObj( p, pObj, i ) \ + for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ ) +#define Wlc_NtkForEachPi( p, pPi, i ) \ + for ( i = 0; (i < Wlc_NtkPiNum(p)) && (((pPi) = Wlc_NtkPi(p, i)), 1); i++ ) +#define Wlc_NtkForEachPo( p, pPo, i ) \ + for ( i = 0; (i < Wlc_NtkPoNum(p)) && (((pPo) = Wlc_NtkPo(p, i)), 1); i++ ) +#define Wlc_NtkForEachCi( p, pCi, i ) \ + for ( i = 0; (i < Wlc_NtkCiNum(p)) && (((pCi) = Wlc_NtkCi(p, i)), 1); i++ ) +#define Wlc_NtkForEachCo( p, pCo, i ) \ + for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ ) + +#define Wlc_ObjForEachFanin( pObj, iFanin, i ) \ + for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ ) +#define Wlc_ObjForEachFaninReverse( pObj, iFanin, i ) \ + for ( i = Wlc_ObjFaninNum(pObj) - 1; (i >= 0) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i-- ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== wlcBlast.c ========================================================*/ +extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ); +/*=== wlcNtk.c ========================================================*/ +extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); +extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); +extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ); +extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ); +extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ); +extern void Wlc_NtkFree( Wlc_Ntk_t * p ); +extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); +extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fVerbose ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ); +extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +/*=== wlcReadWord.c ========================================================*/ +extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName ); +/*=== wlcWriteWord.c ========================================================*/ +extern void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName ); + + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c new file mode 100644 index 00000000..1e536014 --- /dev/null +++ b/src/base/wlc/wlcBlast.c @@ -0,0 +1,363 @@ +/**CFile**************************************************************** + + FileName [wlcBlast.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Bit-blasting.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcBlast.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPrepareBits( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, nBits = 0; + Wlc_NtkCleanCopy( p ); + Wlc_NtkForEachObj( p, pObj, i ) + { + Wlc_ObjSetCopy( p, i, nBits ); + nBits += Wlc_ObjRange(pObj); + } + return nBits; +} +int Wlc_NtkComputeReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type ) +{ + if ( Type == WLC_OBJ_REDUCT_AND ) + { + int k, iLit = 1; + for ( k = 0; k < nFans; k++ ) + iLit = Gia_ManHashAnd( pNew, iLit, pFans[k] ); + return iLit; + } + if ( Type == WLC_OBJ_REDUCT_OR ) + { + int k, iLit = 0; + for ( k = 0; k < nFans; k++ ) + iLit = Gia_ManHashOr( pNew, iLit, pFans[k] ); + return iLit; + } + if ( Type == WLC_OBJ_REDUCT_XOR ) + { + int k, iLit = 0; + for ( k = 0; k < nFans; k++ ) + iLit = Gia_ManHashXor( pNew, iLit, pFans[k] ); + return iLit; + } + assert( 0 ); + return -1; +} +int Wlc_NtkMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift ) +{ + int iLit0, iLit1; + if ( nCtrl == 0 ) + return Vec_IntEntry( vData, Shift ); + iLit0 = Wlc_NtkMuxTree_rec( pNew, pCtrl, nCtrl-1, vData, Shift ); + iLit1 = Wlc_NtkMuxTree_rec( pNew, pCtrl, nCtrl-1, vData, Shift + (1<<(nCtrl-1)) ); + return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 ); +} +void Wlc_NtkAdderChain( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) +{ + int iCarry = 0, iTerm1, iTerm2, iTerm3, iSum, b; + for ( b = 0; b < nBits; b++ ) + { + iSum = Gia_ManHashXor( pNew, iCarry, Gia_ManHashXor(pNew, pAdd0[b], pAdd1[b]) ); + iTerm1 = Gia_ManHashAnd( pNew, pAdd0[b], pAdd1[b] ); + iTerm2 = Gia_ManHashAnd( pNew, pAdd0[b], iCarry ); + iTerm3 = Gia_ManHashAnd( pNew, pAdd1[b], iCarry ); + iCarry = Gia_ManHashOr( pNew, iTerm1, Gia_ManHashOr(pNew, iTerm2, iTerm3) ); + pAdd0[b] = iSum; + } +} +Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) +{ + Gia_Man_t * pTemp, * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vBits, * vTemp0, * vTemp1, * vTemp2, * vTemp3; + int nBits = Wlc_NtkPrepareBits( p ); + int nRange, nRange0, nRange1, nRange2; + int i, k, b, iLit, * pFans0, * pFans1, * pFans2; + vBits = Vec_IntAlloc( nBits ); + vTemp0 = Vec_IntAlloc( 1000 ); + vTemp1 = Vec_IntAlloc( 1000 ); + vTemp2 = Vec_IntAlloc( 1000 ); + vTemp3 = Vec_IntAlloc( 1000 ); + // craete AIG manager + pNew = Gia_ManStart( 5 * Wlc_NtkObjNum(p) + 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + // create primary inputs + Wlc_NtkForEachObj( p, pObj, i ) + { + char * pName = Wlc_ObjName(p, i); + nRange = Wlc_ObjRange( pObj ); + nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1; + nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1; + nRange2 = Wlc_ObjFaninNum(pObj) > 2 ? Wlc_ObjRange( Wlc_ObjFanin2(p, pObj) ) : -1; + pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; + pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; + pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; + if ( pObj->Type == WLC_OBJ_PI ) + { + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Gia_ManAppendCi(pNew) ); + } + else if ( pObj->Type == WLC_OBJ_PO || pObj->Type == WLC_OBJ_BUF ) + { +// assert( nRange <= nRange0 ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, k < nRange0 ? pFans0[k] : 0 ); + } + else if ( pObj->Type == WLC_OBJ_CONST ) + { + word * pTruth = (word *)Wlc_ObjFanins(pObj); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Abc_TtGetBit(pTruth, k) ); + } + else if ( pObj->Type == WLC_OBJ_MUX ) + { + assert( nRange0 == 1 ); + assert( nRange1 == nRange ); + assert( nRange2 == nRange ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Gia_ManHashMux(pNew, pFans0[0], pFans1[k], pFans2[k]) ); + } + else if ( pObj->Type == WLC_OBJ_SHIFT_R || pObj->Type == WLC_OBJ_SHIFT_RA ) + { + // prepare data + int Fill = pObj->Type == WLC_OBJ_SHIFT_R ? 0 : pFans0[nRange0-1]; + int nTotal = nRange + (1 << nRange1); + Vec_IntClear( vTemp0 ); + for ( k = 0; k < nRange0; k++ ) + Vec_IntPush( vTemp0, pFans0[k] ); + for ( k = 0; k < nTotal; k++ ) + Vec_IntPush( vTemp0, Fill ); + // derive the result + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Wlc_NtkMuxTree_rec(pNew, pFans1, nRange1, vTemp0, k) ); + } + else if ( pObj->Type == WLC_OBJ_SHIFT_L || pObj->Type == WLC_OBJ_SHIFT_LA ) + { + // prepare data + int Fill = pObj->Type == WLC_OBJ_SHIFT_L ? 0 : pFans0[0]; + int nTotal = nRange + (1 << nRange1); + Vec_IntClear( vTemp0 ); + for ( k = 0; k < nRange0; k++ ) + Vec_IntPush( vTemp0, pFans0[k] ); + for ( k = 0; k < nTotal; k++ ) + Vec_IntPush( vTemp0, Fill ); + // derive the result + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Wlc_NtkMuxTree_rec(pNew, pFans1, nRange1, vTemp0, k) ); + } + else if ( pObj->Type == WLC_OBJ_BIT_NOT ) + { + assert( nRange == nRange0 ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Abc_LitNot(pFans0[k]) ); + } + else if ( pObj->Type == WLC_OBJ_BIT_AND ) + { + assert( nRange0 == nRange && nRange1 == nRange ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Gia_ManHashAnd(pNew, pFans0[k], pFans1[k]) ); + } + else if ( pObj->Type == WLC_OBJ_BIT_OR ) + { + assert( nRange0 == nRange && nRange1 == nRange ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Gia_ManHashOr(pNew, pFans0[k], pFans1[k]) ); + } + else if ( pObj->Type == WLC_OBJ_BIT_XOR ) + { + assert( nRange0 == nRange && nRange1 == nRange ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, Gia_ManHashXor(pNew, pFans0[k], pFans1[k]) ); + } + else if ( pObj->Type == WLC_OBJ_BIT_SELECT ) + { + int End = Wlc_ObjRangeEnd(pObj); + int Beg = Wlc_ObjRangeBeg(pObj); + assert( nRange == End - Beg + 1 ); + for ( k = Beg; k <= End; k++ ) + Vec_IntPush( vBits, pFans0[k] ); + } + else if ( pObj->Type == WLC_OBJ_BIT_CONCAT ) + { + int iFanin, nTotal = 0; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + nTotal += Wlc_ObjRange( Wlc_NtkObj(p, iFanin) ); + assert( nRange == nTotal ); + Wlc_ObjForEachFaninReverse( pObj, iFanin, k ) + { + nRange0 = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) ); + pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, iFanin) ); + for ( b = 0; b < nRange0; b++ ) + Vec_IntPush( vBits, pFans0[b] ); + } + } + else if ( pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT ) + { + int Pad = pObj->Type == WLC_OBJ_BIT_ZEROPAD ? 0 : pFans0[nRange0-1]; + assert( nRange0 < nRange ); + for ( k = 0; k < nRange0; k++ ) + Vec_IntPush( vBits, pFans0[k] ); + for ( ; k < nRange; k++ ) + Vec_IntPush( vBits, Pad ); + } + else if ( pObj->Type == WLC_OBJ_LOGIC_NOT ) + { + iLit = Wlc_NtkComputeReduction( pNew, pFans0, nRange, WLC_OBJ_REDUCT_OR ); + assert( nRange == 1 ); + Vec_IntPush( vBits, Abc_LitNot(iLit) ); + } + else if ( pObj->Type == WLC_OBJ_LOGIC_AND ) + { + int iLit0 = Wlc_NtkComputeReduction( pNew, pFans0, nRange, WLC_OBJ_REDUCT_OR ); + int iLit1 = Wlc_NtkComputeReduction( pNew, pFans0, nRange, WLC_OBJ_REDUCT_OR ); + assert( nRange == 1 ); + Vec_IntPush( vBits, Gia_ManHashAnd(pNew, iLit0, iLit1) ); + } + else if ( pObj->Type == WLC_OBJ_LOGIC_OR ) + { + int iLit0 = Wlc_NtkComputeReduction( pNew, pFans0, nRange, WLC_OBJ_REDUCT_OR ); + int iLit1 = Wlc_NtkComputeReduction( pNew, pFans0, nRange, WLC_OBJ_REDUCT_OR ); + assert( nRange == 1 ); + Vec_IntPush( vBits, Gia_ManHashOr(pNew, iLit0, iLit1) ); + } + else if ( pObj->Type == WLC_OBJ_COMP_EQU || pObj->Type == WLC_OBJ_COMP_NOT ) + { + int iLit = 0; + assert( nRange == 1 ); + assert( nRange0 == nRange1 ); + for ( k = 0; k < nRange0; k++ ) + iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, pFans0[k], pFans1[k]) ); + Vec_IntPush( vBits, Abc_LitNotCond(iLit, pObj->Type == WLC_OBJ_COMP_EQU) ); + } + else if ( pObj->Type == WLC_OBJ_COMP_LESS || pObj->Type == WLC_OBJ_COMP_MOREEQU || + pObj->Type == WLC_OBJ_COMP_MORE || pObj->Type == WLC_OBJ_COMP_LESSEQU ) + { + int iTerm, iEqu = 1, iLit = 0; + assert( nRange == 1 ); + assert( nRange0 == nRange1 ); + if ( pObj->Type == WLC_OBJ_COMP_MORE || pObj->Type == WLC_OBJ_COMP_LESSEQU ) + ABC_SWAP( int *, pFans0, pFans1 ); + for ( k = nRange0 - 1; k >= 0; k-- ) + { + iTerm = Gia_ManHashAnd( pNew, Abc_LitNot(pFans0[k]), pFans1[k] ); + iTerm = Gia_ManHashAnd( pNew, iTerm, iEqu ); + iLit = Gia_ManHashOr( pNew, iLit, iTerm ); + iEqu = Abc_LitNot( Gia_ManHashXor( pNew, pFans0[k], pFans1[k] ) ); + } + Vec_IntPush( vBits, Abc_LitNotCond(iLit, pObj->Type == WLC_OBJ_COMP_MOREEQU) ); + } + else if ( pObj->Type == WLC_OBJ_REDUCT_AND || pObj->Type == WLC_OBJ_REDUCT_OR || pObj->Type == WLC_OBJ_REDUCT_XOR ) + Vec_IntPush( vBits, Wlc_NtkComputeReduction( pNew, pFans0, nRange, pObj->Type ) ); + else if ( pObj->Type == WLC_OBJ_ARI_ADD ) + { + int Pad0 = Wlc_ObjFanin0(p, pObj)->Signed ? pFans0[nRange0-1] : 0; + int Pad1 = Wlc_ObjFanin1(p, pObj)->Signed ? pFans1[nRange1-1] : 0; + assert( nRange0 <= nRange && nRange1 <= nRange ); + Vec_IntClear( vTemp0 ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vTemp0, k < nRange0 ? pFans0[k] : Pad0 ); + Vec_IntClear( vTemp1 ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vTemp1, k < nRange1 ? pFans1[k] : Pad1 ); + Wlc_NtkAdderChain( pNew, Vec_IntArray(vTemp0), Vec_IntArray(vTemp1), nRange ); + Vec_IntAppend( vBits, vTemp0 ); + } + else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + { + int Pad0 = Wlc_ObjFanin0(p, pObj)->Signed ? pFans0[nRange0-1] : 0; + int Pad1 = Wlc_ObjFanin1(p, pObj)->Signed ? pFans1[nRange1-1] : 0; + assert( nRange0 <= nRange && nRange1 <= nRange ); + Vec_IntClear( vTemp0 ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vTemp0, k < nRange0 ? pFans0[k] : Pad0 ); + Vec_IntClear( vTemp1 ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vTemp1, k < nRange1 ? pFans1[k] : Pad1 ); + // iterate + Vec_IntFill( vTemp3, nRange, 0 ); + for ( k = 0; k < nRange; k++ ) + { + Vec_IntFill( vTemp2, k, 0 ); + Vec_IntForEachEntry( vTemp0, iLit, b ) + { + Vec_IntPush( vTemp2, Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vTemp1, k)) ); + if ( Vec_IntSize(vTemp2) == nRange ) + break; + } + assert( Vec_IntSize(vTemp2) == nRange ); + Wlc_NtkAdderChain( pNew, Vec_IntArray(vTemp3), Vec_IntArray(vTemp2), nRange ); + } + assert( Vec_IntSize(vTemp3) == nRange ); + Vec_IntAppend( vBits, vTemp3 ); + } + else assert( 0 ); + } + assert( nBits == Vec_IntSize(vBits) ); + Vec_IntFree( vTemp0 ); + Vec_IntFree( vTemp1 ); + Vec_IntFree( vTemp2 ); + Vec_IntFree( vTemp3 ); + // create POs + Wlc_NtkForEachPo( p, pObj, i ) + { + nRange = Wlc_ObjRange( pObj ); + nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1; + assert( nRange == nRange0 ); + pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) ); + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, pFans0[k] ); + } + Vec_IntFree( vBits ); + Vec_IntErase( &p->vCopies ); + // finalize and cleanup + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c new file mode 100644 index 00000000..a23d0192 --- /dev/null +++ b/src/base/wlc/wlcCom.c @@ -0,0 +1,311 @@ +/**CFile**************************************************************** + + FileName [wlcCom.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Command handlers.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcCom.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" +#include "base/main/mainInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Abc_CommandReadVer ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandWriteVer ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } +static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } +static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Wlc_Init( Abc_Frame_t * pAbc ) +{ + Cmd_CommandAdd( pAbc, "Word level", "%read_ver", Abc_CommandReadVer, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%write_ver", Abc_CommandWriteVer, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Wlc_End( Abc_Frame_t * pAbc ) +{ + Wlc_AbcFreeNtk( pAbc ); +} + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pFile; + Wlc_Ntk_t * pNtk = NULL; + char * pFileName = NULL; + 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 ( argc != globalUtilOptind + 1 ) + { + printf( "Abc_CommandReadVer(): 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", ".smt", NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + + // perform reading + pNtk = Wlc_ReadVer( pFileName ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%read_ver [-vh] <file_name>\n" ); + Abc_Print( -2, "\t reads word-level design from Verilog file\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 Abc_CommandWriteVer( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + char * pFileName = NULL; + 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 ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandWriteVer(): There is no current design.\n" ); + return 0; + } + if ( argc == globalUtilOptind ) + pFileName = Extra_FileNameGenericAppend( pNtk->pName, "_out.v" ); + else if ( argc == globalUtilOptind + 1 ) + pFileName = argv[globalUtilOptind]; + else + { + printf( "Output file name should be given on the command line.\n" ); + return 0; + } + Wlc_WriteVer( pNtk, pFileName ); + return 0; +usage: + Abc_Print( -2, "usage: %%write_ver [-vh]\n" ); + Abc_Print( -2, "\t writes the design into a file\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 Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int fShowMulti = 0; + int fShowAdder = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "mavh" ) ) != EOF ) + { + switch ( c ) + { + case 'm': + fShowMulti ^= 1; + break; + case 'a': + fShowAdder ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" ); + return 0; + } + Wlc_NtkPrintStats( pNtk, fVerbose ); + if ( fShowMulti ) + Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_MULTI ); + if ( fShowAdder ) + Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_ADD ); + return 0; +usage: + Abc_Print( -2, "usage: %%ps [-mavh]\n" ); + Abc_Print( -2, "\t prints statistics\n" ); + Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "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 Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Gia_Man_t * pNew = NULL; + 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 ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandBlast(): There is no current design.\n" ); + return 0; + } + // transform + pNew = Wlc_NtkBitBlast( pNtk ); + if ( pNew == NULL ) + { + Abc_Print( 1, "Abc_CommandBlast(): Bit-blasting has failed.\n" ); + return 0; + } + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; +usage: + Abc_Print( -2, "usage: %%blast [-vh]\n" ); + Abc_Print( -2, "\t performs bit-blasting of the word-level 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; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c new file mode 100644 index 00000000..026f6b21 --- /dev/null +++ b/src/base/wlc/wlcNtk.c @@ -0,0 +1,283 @@ +/**CFile**************************************************************** + + FileName [wlcNtk.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Network data-structure.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcNtk.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Working with models.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ) +{ + Wlc_Ntk_t * p; + p = ABC_CALLOC( Wlc_Ntk_t, 1 ); + p->pName = Extra_FileNameGeneric( pName ); + Vec_IntGrow( &p->vPis, 111 ); + Vec_IntGrow( &p->vPos, 111 ); + Vec_IntGrow( &p->vCis, 111 ); + Vec_IntGrow( &p->vCos, 111 ); + Vec_IntGrow( &p->vFfs, 111 ); + p->pMemFanin = Mem_FlexStart(); + p->nObjsAlloc = nObjsAlloc; + p->pObjs = ABC_CALLOC( Wlc_Obj_t, p->nObjsAlloc ); + p->iObj = 1; + return p; +} +int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ) +{ + Wlc_Obj_t * pObj; + if ( p->iObj == p->nObjsAlloc ) + { + p->pObjs = ABC_REALLOC( Wlc_Obj_t, p->pObjs, 2 * p->nObjsAlloc ); + memset( p->pObjs + p->nObjsAlloc, 0, sizeof(Wlc_Obj_t) * p->nObjsAlloc ); + p->nObjsAlloc *= 2; + } + pObj = Wlc_NtkObj( p, p->iObj ); + pObj->Type = Type; + pObj->Signed = Signed; + pObj->End = End; + pObj->Beg = Beg; + if ( Type == WLC_OBJ_PI ) + { + pObj->Fanins[1] = Vec_IntSize(&p->vPis); + Vec_IntPush( &p->vPis, p->iObj ); + } + else if ( Type == WLC_OBJ_PO ) + { + pObj->Fanins[1] = Vec_IntSize(&p->vPos); + Vec_IntPush( &p->vPos, p->iObj ); + } + p->nObjs[Type]++; + return p->iObj++; +} +char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ) +{ + static char Buffer[100]; + if ( Wlc_NtkHasNameId(p) && Wlc_ObjNameId(p, iObj) ) + return Abc_NamStr( p->pManName, Wlc_ObjNameId(p, iObj) ); + sprintf( Buffer, "n%d", iObj ); + return Buffer; +} +void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ) +{ + if ( pObj->Type == WLC_OBJ_PO ) + { + assert( Type == WLC_OBJ_BUF ); + return; + } + p->nObjs[pObj->Type]--; + pObj->Type = Type; + p->nObjs[pObj->Type]++; +} +void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ) +{ + assert( pObj->nFanins == 0 ); + pObj->nFanins = Vec_IntSize(vFanins); + if ( Wlc_ObjHasArray(pObj) ) + pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); + memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); + // special treatment of CONST and SELECT + if ( pObj->Type == WLC_OBJ_CONST ) + pObj->nFanins = 0; + else if ( pObj->Type == WLC_OBJ_BIT_SELECT ) + pObj->nFanins = 1; +} +void Wlc_NtkFree( Wlc_Ntk_t * p ) +{ + if ( p->pManName ) + Abc_NamStop( p->pManName ); + if ( p->pMemFanin ) + Mem_FlexStop( p->pMemFanin, 0 ); + ABC_FREE( p->vPis.pArray ); + ABC_FREE( p->vPos.pArray ); + ABC_FREE( p->vCis.pArray ); + ABC_FREE( p->vCos.pArray ); + ABC_FREE( p->vFfs.pArray ); + ABC_FREE( p->vTravIds.pArray ); + ABC_FREE( p->vNameIds.pArray ); + ABC_FREE( p->vCopies.pArray ); + ABC_FREE( p->pObjs ); + ABC_FREE( p->pName ); + ABC_FREE( p ); +} +int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) +{ + int Mem = sizeof(Wlc_Ntk_t); + Mem += 4 * p->vPis.nCap; + Mem += 4 * p->vPos.nCap; + Mem += 4 * p->vCis.nCap; + Mem += 4 * p->vCos.nCap; + Mem += 4 * p->vFfs.nCap; + Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc; + Mem += Abc_NamMemUsed(p->pManName); + Mem += Mem_FlexReadMemUsage(p->pMemFanin); + return Mem; +} +void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ) +{ + Wlc_Obj_t * pObj; + int i, Counter = 0; + printf( "Operation %s\n", Wlc_Names[Type] ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( (int)pObj->Type != Type ) + continue; + printf( "%8d :", Counter++ ); + printf( "%8d : ", i ); + printf( "%3d%s = ", Wlc_ObjRange(pObj), pObj->Signed ? "s" : " " ); + printf( "%3d%s %s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjFanin0(p, pObj)->Signed ? "s" : " ", Wlc_Names[Type] ); + printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)), Wlc_ObjFanin1(p, pObj)->Signed ? "s" : " " ); + printf( " : " ); + printf( "%-12s = ", Wlc_ObjName(p, i) ); + printf( "%-12s %s ", Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), Wlc_Names[Type] ); + printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) ); + printf( "\n" ); + } +} +void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fVerbose ) +{ + int i; + printf( "%-20s : ", p->pName ); + printf( "PI = %4d ", Wlc_NtkPiNum(p) ); + printf( "PO = %4d ", Wlc_NtkPoNum(p) ); + printf( "FF = %4d ", Wlc_NtkFfNum(p) ); + printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); + printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) ); + printf( "\n" ); + if ( !fVerbose ) + return; + printf( "Node type statisticts:\n" ); + for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) + if ( p->nObjs[i] ) + printf( "%2d : %6d %-8s\n", i, p->nObjs[i], Wlc_Names[i] ); +// Wlc_NtkPrintNodes( p, WLC_OBJ_ARI_MULTI ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the network in a topological order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ObjCollectCopyFanins( Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) +{ + int i, iFanin; + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iObj ); + Vec_IntClear( vFanins ); + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Vec_IntPush( vFanins, Wlc_ObjCopy(p, iFanin) ); + // special treatment of CONST and SELECT + if ( pObj->Type == WLC_OBJ_CONST ) + { + int * pInts = Wlc_ObjConstValue( pObj ); + int nInts = Abc_BitWordNum( Wlc_ObjRange(pObj) ); + for ( i = 0; i < nInts; i++ ) + Vec_IntPush( vFanins, pInts[i] ); + } + else if ( pObj->Type == WLC_OBJ_BIT_SELECT ) + { + assert( Vec_IntSize(vFanins) == 1 ); + Vec_IntPush( vFanins, pObj->Fanins[1] ); + } +} +int Wlc_ObjDup( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) +{ + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iObj ); + int iFaninNew = Wlc_ObjAlloc( pNew, pObj->Type, pObj->Signed, pObj->End, pObj->Beg ); + Wlc_Obj_t * pObjNew = Wlc_NtkObj(pNew, iFaninNew); + Wlc_ObjCollectCopyFanins( p, iObj, vFanins ); + Wlc_ObjAddFanins( pNew, pObjNew, vFanins ); + Wlc_ObjSetCopy( p, iObj, iFaninNew ); + return iFaninNew; +} +void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) +{ + Wlc_Obj_t * pObj; + int i, iFanin; + if ( Wlc_ObjCopy(p, iObj) ) + return; + pObj = Wlc_NtkObj( p, iObj ); + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); + Wlc_ObjDup( pNew, p, iObj, vFanins ); +} +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) +{ + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vFanins; + int i; + Wlc_NtkCleanCopy( p ); + vFanins = Vec_IntAlloc( 100 ); + pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); + Wlc_NtkForEachPi( p, pObj, i ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjFaninId0(pObj), vFanins ); + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + Vec_IntFree( vFanins ); + return pNew; +} +void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) +{ + int i; + assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); + assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); + assert( pNew->pManName == NULL && p->pManName != NULL ); + Wlc_NtkCleanNameId( pNew ); + for ( i = 0; i < p->nObjsAlloc; i++ ) + if ( Wlc_ObjCopy(p, i) && Wlc_ObjNameId(p, i) ) + Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); + pNew->pManName = p->pManName; + p->pManName = NULL; + Vec_IntErase( &p->vNameIds ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c new file mode 100644 index 00000000..cf880cd5 --- /dev/null +++ b/src/base/wlc/wlcReadVer.c @@ -0,0 +1,711 @@ +/**CFile**************************************************************** + + FileName [wlcReadVer.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 - August 22, 2014.] + + Revision [$Id: wlcReadVer.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// Word-level Verilog file parser +#define WLV_PRS_MAX_LINE 1000 + +typedef struct Wlc_Prs_t_ Wlc_Prs_t; +struct Wlc_Prs_t_ +{ + int nFileSize; + char * pFileName; + char * pBuffer; + Vec_Int_t * vLines; + Vec_Int_t * vStarts; + Vec_Int_t * vFanins; + Wlc_Ntk_t * pNtk; + char sError[WLV_PRS_MAX_LINE]; +}; + +static inline int Wlc_PrsOffset( Wlc_Prs_t * p, char * pStr ) { return pStr - p->pBuffer; } +static inline char * Wlc_PrsStr( Wlc_Prs_t * p, int iOffset ) { return p->pBuffer + iOffset; } +static inline int Wlc_PrsStrCmp( char * pStr, char * pWhat ) { return !strncmp( pStr, pWhat, strlen(pWhat)); } + +#define Wlc_PrsForEachLine( p, pLine, i ) \ + for ( i = 0; (i < Vec_IntSize((p)->vStarts)) && ((pLine) = Wlc_PrsStr(p, Vec_IntEntry((p)->vStarts, i))); i++ ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Prs_t * Wlc_PrsStart( char * pFileName ) +{ + Wlc_Prs_t * p; + if ( !Extra_FileCheck( pFileName ) ) + return NULL; + p = ABC_CALLOC( Wlc_Prs_t, 1 ); + p->pFileName = pFileName; + p->pBuffer = Extra_FileReadContents( pFileName ); + p->nFileSize = strlen(p->pBuffer); assert( p->nFileSize > 0 ); + p->vLines = Vec_IntAlloc( p->nFileSize / 50 ); + p->vStarts = Vec_IntAlloc( p->nFileSize / 50 ); + p->vFanins = Vec_IntAlloc( 100 ); + return p; +} +void Wlc_PrsStop( Wlc_Prs_t * p ) +{ + if ( p->pNtk ) + Wlc_NtkFree( p->pNtk ); + Vec_IntFree( p->vLines ); + Vec_IntFree( p->vStarts ); + Vec_IntFree( p->vFanins ); + ABC_FREE( p->pBuffer ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Prints the error message including the file name and line number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_PrsWriteErrorMessage( Wlc_Prs_t * p, char * pCur, const char * format, ... ) +{ + char * pMessage; + // derive message + va_list args; + va_start( args, format ); + pMessage = vnsprintf( format, args ); + va_end( args ); + // print messsage + assert( strlen(pMessage) < WLV_PRS_MAX_LINE - 100 ); + assert( p->sError[0] == 0 ); + if ( pCur == NULL ) // the line number is not given + sprintf( p->sError, "%s: %s\n", p->pFileName, pMessage ); + else // print the error message with the line number + { + int Entry, iLine = 0; + Vec_IntForEachEntry( p->vLines, Entry, iLine ) + if ( Entry > pCur - p->pBuffer ) + break; + sprintf( p->sError, "%s (line %d): %s\n", p->pFileName, iLine+1, pMessage ); + } + free( pMessage ); + return 0; +} +void Wlc_PrsPrintErrorMessage( Wlc_Prs_t * p ) +{ + if ( p->sError[0] == 0 ) + return; + fprintf( stdout, "%s", p->sError ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Wlc_PrsIsDigit( char * pStr ) +{ + return (pStr[0] >= '0' && pStr[0] <= '9'); +} +static inline int Wlc_PrsIsChar( char * pStr ) +{ + return (pStr[0] >= 'a' && pStr[0] <= 'z') || + (pStr[0] >= 'A' && pStr[0] <= 'Z') || + (pStr[0] >= '0' && pStr[0] <= '9') || + pStr[0] == '_' || pStr[0] == '$'; +} +static inline char * Wlc_PrsSkipSpaces( char * pStr ) +{ + while ( *pStr && *pStr == ' ' ) + pStr++; + return pStr; +} +static inline char * Wlc_PrsFindSymbol( char * pStr, char Symb ) +{ + for ( ; *pStr; pStr++ ) + if ( *pStr == Symb ) + return pStr; + return NULL; +} +static inline char * Wlc_PrsFindSymbolTwo( char * pStr, char Symb, char Symb2 ) +{ + for ( ; pStr[1]; pStr++ ) + if ( pStr[0] == Symb && pStr[1] == Symb2 ) + return pStr; + return NULL; +} +static inline char * Wlc_PrsFindClosingParanthesis( char * pStr, char Open, char Close ) +{ + int Counter = 0; + int fNotName = 1; + assert( *pStr == Open ); + for ( ; *pStr; pStr++ ) + { + if ( fNotName ) + { + if ( *pStr == Open ) + Counter++; + if ( *pStr == Close ) + Counter--; + if ( Counter == 0 ) + return pStr; + } + if ( *pStr == '\\' ) + fNotName = 0; + else if ( !fNotName && *pStr == ' ' ) + fNotName = 1; + } + return NULL; +} +int Wlc_PrsRemoveComments( Wlc_Prs_t * p ) +{ + int fSpecifyFound = 0; + char * pCur, * pNext, * pEnd = p->pBuffer + p->nFileSize; + for ( pCur = p->pBuffer; pCur < pEnd; pCur++ ) + { + // regular comment (//) + if ( *pCur == '/' && pCur[1] == '/' ) + { + if ( pCur + 5 < pEnd && pCur[2] == 'a' && pCur[3] == 'b' && pCur[4] == 'c' && pCur[5] == '2' ) + pCur[0] = pCur[1] = pCur[2] = pCur[3] = pCur[4] = pCur[5] = ' '; + else + { + pNext = Wlc_PrsFindSymbol( pCur, '\n' ); + if ( pNext == NULL ) + return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find end-of-line after symbols \"//\"." ); + for ( ; pCur < pNext; pCur++ ) + *pCur = ' '; + } + } + // skip preprocessor directive (`timescale, `celldefine, etc) + else if ( *pCur == '`' ) + { + pNext = Wlc_PrsFindSymbol( pCur, '\n' ); + if ( pNext == NULL ) + return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find end-of-line after symbols \"`\"." ); + for ( ; pCur < pNext; pCur++ ) + *pCur = ' '; + } + // regular comment (/* ... */) + else if ( *pCur == '/' && pCur[1] == '*' ) + { + pNext = Wlc_PrsFindSymbolTwo( pCur, '*', '/' ); + if ( pNext == NULL ) + return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find symbols \"*/\" after symbols \"/*\"." ); + // overwrite comment + for ( ; pCur < pNext + 2; pCur++ ) + *pCur = ' '; + } + // 'specify' treated as comments + else if ( *pCur == 's' && pCur[1] == 'p' && pCur[2] == 'e' && !strncmp(pCur, "specify", 7) ) + { + for ( pNext = pCur; pNext < pEnd - 10; pNext++ ) + if ( *pNext == 'e' && pNext[1] == 'n' && pNext[2] == 'd' && !strncmp(pNext, "endspecify", 10) ) + { + // overwrite comment + for ( ; pCur < pNext + 10; pCur++ ) + *pCur = ' '; + if ( fSpecifyFound == 0 ) + Abc_Print( 0, "Ignoring specify/endspecify directives.\n" ); + fSpecifyFound = 1; + break; + } + } + // insert semicolons + else if ( *pCur == 'e' && pCur[1] == 'n' && pCur[2] == 'd' && !strncmp(pCur, "endmodule", 9) ) + pCur[strlen("endmodule")] = ';'; + // overwrite end-of-lines with spaces (less checking to do later on) + if ( *pCur == '\n' || *pCur == '\r' || *pCur == '\t' ) + *pCur = ' '; + } + return 1; +} +int Wlc_PrsPrepare( Wlc_Prs_t * p ) +{ + int fPrettyPrint = 0; + int fNotName = 1; + char * pTemp, * pPrev, * pThis; + // collect info about lines + assert( Vec_IntSize(p->vLines) == 0 ); + for ( pTemp = p->pBuffer; *pTemp; pTemp++ ) + if ( *pTemp == '\n' ) + Vec_IntPush( p->vLines, pTemp - p->pBuffer ); + // delete comments and insert breaks + if ( !Wlc_PrsRemoveComments( p ) ) + return 0; + // collect info about breaks + assert( Vec_IntSize(p->vStarts) == 0 ); + for ( pPrev = pThis = p->pBuffer; *pThis; pThis++ ) + { + if ( fNotName && *pThis == ';' ) + { + *pThis = 0; + Vec_IntPush( p->vStarts, Wlc_PrsOffset(p, Wlc_PrsSkipSpaces(pPrev)) ); + pPrev = pThis + 1; + } + if ( *pThis == '\\' ) + fNotName = 0; + else if ( !fNotName && *pThis == ' ' ) + fNotName = 1; + } + + if ( fPrettyPrint ) + { + int i, k; + // print the line types + Wlc_PrsForEachLine( p, pTemp, i ) + { + if ( Wlc_PrsStrCmp( pTemp, "module" ) ) + printf( "\n" ); + if ( !Wlc_PrsStrCmp( pTemp, "module" ) && !Wlc_PrsStrCmp( pTemp, "endmodule" ) ) + printf( " " ); + printf( "%c", pTemp[0] ); + for ( k = 1; pTemp[k]; k++ ) + if ( pTemp[k] != ' ' || pTemp[k-1] != ' ' ) + printf( "%c", pTemp[k] ); + printf( ";\n" ); + } +/* + // print the line types + Wlc_PrsForEachLine( p, pTemp, i ) + { + int k; + if ( !Wlc_PrsStrCmp( pTemp, "module" ) ) + continue; + printf( "%3d : ", i ); + for ( k = 0; k < 40; k++ ) + printf( "%c", pTemp[k] ? pTemp[k] : ' ' ); + printf( "\n" ); + } +*/ + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline char * Wlc_PrsFindRange( char * pStr, int * End, int * Beg ) +{ + *End = *Beg = 0; + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( pStr[0] != '[' ) + return pStr; + pStr = Wlc_PrsSkipSpaces( pStr+1 ); + if ( !Wlc_PrsIsDigit(pStr) ) + return NULL; + *End = *Beg = atoi( pStr ); + if ( Wlc_PrsFindSymbol( pStr, ':' ) == NULL ) + { + pStr = Wlc_PrsFindSymbol( pStr, ']' ); + if ( pStr == NULL ) + return NULL; + } + else + { + pStr = Wlc_PrsFindSymbol( pStr, ':' ); + pStr = Wlc_PrsSkipSpaces( pStr+1 ); + if ( !Wlc_PrsIsDigit(pStr) ) + return NULL; + *Beg = atoi( pStr ); + pStr = Wlc_PrsFindSymbol( pStr, ']' ); + if ( pStr == NULL ) + return NULL; + } + assert( *End >= *Beg ); + return pStr + 1; +} +static inline char * Wlc_PrsFindWord( char * pStr, char * pWord, int * fFound ) +{ + *fFound = 0; + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( !Wlc_PrsStrCmp(pStr, pWord) ) + return pStr; + *fFound = 1; + return pStr + strlen(pWord); +} +static inline char * Wlc_PrsFindName( char * pStr, char ** ppPlace ) +{ + static char Buffer[WLV_PRS_MAX_LINE]; + char * pThis = *ppPlace = Buffer; + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( !Wlc_PrsIsChar(pStr) ) + return NULL; + while ( Wlc_PrsIsChar(pStr) ) + *pThis++ = *pStr++; + *pThis = 0; + return pStr; +} +static inline char * Wlc_PrsReadName( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins ) +{ + char * pName; + int NameId, fFound; + pStr = Wlc_PrsFindName( pStr, &pName ); + if ( pStr == NULL ) + return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name." ); + NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + if ( !fFound ) + return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is used but not declared.", pName ); + Vec_IntPush( vFanins, NameId ); + return Wlc_PrsSkipSpaces( pStr ); +} +static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins ) +{ + char * pName; + int Type = WLC_OBJ_NONE; + Vec_IntClear( vFanins ); + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( pStr[0] != '=' ) + return 0; + pStr = Wlc_PrsSkipSpaces( pStr+1 ); + if ( pStr[0] == '(' ) + { + char * pClose = Wlc_PrsFindClosingParanthesis( pStr, '(', ')' ); + if ( pClose == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting closing paranthesis." ); + *pStr = *pClose = ' '; + pStr = Wlc_PrsSkipSpaces( pStr ); + } + if ( Wlc_PrsIsDigit(pStr) ) + { + int nDigits, nBits = atoi( pStr ); + pStr = Wlc_PrsFindSymbol( pStr, '\'' ); + if ( pStr == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting constant symbol (\')." ); + if ( pStr[1] == 's' ) + pStr++; + if ( pStr[1] != 'h' ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting hexadecimal constant and not \"%c\".", pStr[1] ); + Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); + nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 ); + if ( nDigits != (nBits + 3)/4 ) + return Wlc_PrsWriteErrorMessage( p, pStr, "The length of contant does not match." ); + pStr += nDigits + 2; + Type = WLC_OBJ_CONST; + } + else if ( pStr[0] == '!' || pStr[0] == '~' ) + { + if ( pStr[0] == '!' ) + Type = WLC_OBJ_LOGIC_NOT; + else if ( pStr[0] == '~' ) + Type = WLC_OBJ_BIT_NOT; + else assert( 0 ); + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after !." ); + } + else if ( pStr[0] == '&' || pStr[0] == '|' || pStr[0] == '^' ) + { + if ( pStr[0] == '&' ) + Type = WLC_OBJ_REDUCT_AND; + else if ( pStr[0] == '|' ) + Type = WLC_OBJ_REDUCT_OR; + else if ( pStr[0] == '^' ) + Type = WLC_OBJ_REDUCT_XOR; + else assert( 0 ); + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after reduction operator." ); + } + else if ( pStr[0] == '{' ) + { + // THIS IS SHORTCUT TO DETECT zero padding AND sign extension + if ( Wlc_PrsFindSymbol(pStr+1, '{') ) + { + if ( Wlc_PrsFindSymbol(pStr+1, '\'') ) + Type = WLC_OBJ_BIT_ZEROPAD; + else + Type = WLC_OBJ_BIT_SIGNEXT; + pStr = Wlc_PrsFindSymbol(pStr+1, ','); + if ( pStr == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting one comma in this line." ); + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in sign-extension." ); + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( pStr[0] != '}' ) + return Wlc_PrsWriteErrorMessage( p, pStr, "There is no closing brace (})." ); + } + else // concatenation + { + while ( 1 ) + { + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in concatenation." ); + if ( pStr[0] == '}' ) + break; + if ( pStr[0] != ',' ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Expected comma (,) in this place." ); + } + Type = WLC_OBJ_BIT_CONCAT; + } + assert( pStr[0] == '}' ); + pStr++; + } + else + { + if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) ) + return 0; + // get the next symbol + if ( pStr[0] == 0 ) + Type = WLC_OBJ_BUF; + else if ( pStr[0] == '?' ) + { + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in MUX." ); + if ( pStr[0] != ':' ) + return Wlc_PrsWriteErrorMessage( p, pStr, "MUX lacks the colon symbol (:)." ); + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in MUX." ); + Type = WLC_OBJ_MUX; + } + else if ( pStr[0] == '[' ) + { + int End, Beg; + pStr = Wlc_PrsFindRange( pStr, &End, &Beg ); + Vec_IntPush( vFanins, (End << 16) | Beg ); + Type = WLC_OBJ_BIT_SELECT; + } + else + { + if ( pStr[0] == '>' && pStr[1] == '>' && pStr[2] != '>' ) pStr += 2, Type = WLC_OBJ_SHIFT_R; + else if ( pStr[0] == '>' && pStr[1] == '>' && pStr[2] == '>' ) pStr += 3, Type = WLC_OBJ_SHIFT_RA; + else if ( pStr[0] == '<' && pStr[1] == '<' && pStr[2] != '<' ) pStr += 2, Type = WLC_OBJ_SHIFT_L; + else if ( pStr[0] == '<' && pStr[1] == '<' && pStr[2] == '<' ) pStr += 3, Type = WLC_OBJ_SHIFT_LA; + else if ( pStr[0] == '&' && pStr[1] != '&' ) pStr += 1, Type = WLC_OBJ_BIT_AND; + else if ( pStr[0] == '|' && pStr[1] != '|' ) pStr += 1, Type = WLC_OBJ_BIT_OR; + else if ( pStr[0] == '^' && pStr[1] != '^' ) pStr += 1, Type = WLC_OBJ_BIT_XOR; + else if ( pStr[0] == '&' && pStr[1] == '&' ) pStr += 2, Type = WLC_OBJ_LOGIC_AND; + else if ( pStr[0] == '|' && pStr[1] == '|' ) pStr += 2, Type = WLC_OBJ_LOGIC_OR; + else if ( pStr[0] == '=' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_EQU; + else if ( pStr[0] == '!' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_NOT; + else if ( pStr[0] == '<' && pStr[1] != '=' ) pStr += 1, Type = WLC_OBJ_COMP_LESS; + else if ( pStr[0] == '>' && pStr[1] != '=' ) pStr += 1, Type = WLC_OBJ_COMP_MORE; + else if ( pStr[0] == '<' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_LESSEQU; + else if ( pStr[0] == '>' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_MOREEQU; + else if ( pStr[0] == '+' ) pStr += 1, Type = WLC_OBJ_ARI_ADD; + else if ( pStr[0] == '-' ) pStr += 1, Type = WLC_OBJ_ARI_SUB; + else if ( pStr[0] == '*' && pStr[1] != '*' ) pStr += 1, Type = WLC_OBJ_ARI_MULTI; + else if ( pStr[0] == '/' ) pStr += 1, Type = WLC_OBJ_ARI_DIVIDE; + else if ( pStr[0] == '%' ) pStr += 1, Type = WLC_OBJ_ARI_MODULUS; + else if ( pStr[0] == '*' && pStr[1] == '*' ) pStr += 2, Type = WLC_OBJ_ARI_POWER; + else return Wlc_PrsWriteErrorMessage( p, pStr, "Unsupported operation (%c).", pStr[0] ); + if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + return 0; + } + } + // make sure there is nothing left there + if ( pStr ) + { + pStr = Wlc_PrsFindName( pStr, &pName ); + if ( pStr != NULL ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is left at the end of the line.", pName ); + } + return Type; +} +int Wlc_PrsDerive( Wlc_Prs_t * p ) +{ + char * pStart, * pName; + int i; + // go through the directives + Wlc_PrsForEachLine( p, pStart, i ) + { + if ( Wlc_PrsStrCmp( pStart, "module" ) ) + { + // get module name + pName = strtok( pStart + strlen("module"), " (" ); + if ( pName == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read model name." ); + if ( p->pNtk != NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Network is already defined." ); + p->pNtk = Wlc_NtkAlloc( pName, Vec_IntSize(p->vStarts) ); + p->pNtk->pManName = Abc_NamStart( Vec_IntSize(p->vStarts), 20 ); + } + else if ( Wlc_PrsStrCmp( pStart, "endmodule" ) ) + { + Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(p->pNtk) ); + Vec_IntAppend( &p->pNtk->vNameIds, vTemp ); + Vec_IntFree( vTemp ); + break; + } + // these are read as part of the interface + else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) ) + { + int fFound = 0, Type = WLC_OBJ_NONE, iObj; + int Signed = 0, Beg = 0, End = 0, NameId; + if ( Wlc_PrsStrCmp( pStart, "input" ) ) + Type = WLC_OBJ_PI, pStart += strlen("input"); + else if ( Wlc_PrsStrCmp( pStart, "output" ) ) + Type = WLC_OBJ_PO, pStart += strlen("output"); + pStart = Wlc_PrsSkipSpaces( pStart ); + if ( Wlc_PrsStrCmp( pStart, "wire" ) ) + pStart += strlen("wire"); + // read 'signed' + pStart = Wlc_PrsFindWord( pStart, "signed", &Signed ); + // read range + pStart = Wlc_PrsFindRange( pStart, &End, &Beg ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read range." ); + while ( 1 ) + { + // read name + pStart = Wlc_PrsFindName( pStart, &pName ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name." ); + NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + if ( fFound ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is declared more than once.", pName ); + iObj = Wlc_ObjAlloc( p->pNtk, Type, Signed, End, Beg ); + assert( iObj == NameId ); + // check next definition + pStart = Wlc_PrsSkipSpaces( pStart ); + if ( pStart[0] == ',' ) + { + pStart++; + continue; + } + // check definition + Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins ); + if ( Type ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, iObj ); + Wlc_ObjUpdateType( p->pNtk, pObj, Type ); + Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); + } + break; + } + } + else if ( Wlc_PrsStrCmp( pStart, "assign" ) ) + { + int Type, NameId, fFound; + pStart += strlen("assign"); + // read name + pStart = Wlc_PrsFindName( pStart, &pName ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after assign." ); + NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + if ( !fFound ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName ); + // read definition + Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins ); + if ( Type ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, NameId ); + Wlc_ObjUpdateType( p->pNtk, pObj, Type ); + Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); + } + else + return 0; + } +// else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) ) + else + { + pStart = Wlc_PrsFindName( pStart, &pName ); + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line beginning with %s.", pName ); + } + } + return 1; +} +Wlc_Ntk_t * Wlc_ReadVer( char * pFileName ) +{ + Wlc_Prs_t * p; + Wlc_Ntk_t * pNtk = NULL; + // start the parser + p = Wlc_PrsStart( pFileName ); + if ( p == NULL ) + return NULL; + // detect lines + if ( !Wlc_PrsPrepare( p ) ) + goto finish; + // parse models + if ( !Wlc_PrsDerive( p ) ) + goto finish; + // derive topological order + pNtk = Wlc_NtkDupDfs( p->pNtk ); + Wlc_NtkTransferNames( pNtk, p->pNtk ); +finish: + Wlc_PrsPrintErrorMessage( p ); + Wlc_PrsStop( p ); + return pNtk; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_ReadWordTest( char * pFileName ) +{ + Gia_Man_t * pNew; + Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName ); + if ( pNtk == NULL ) + return; + Wlc_WriteVer( pNtk, "test.v" ); + + pNew = Wlc_NtkBitBlast( pNtk ); + Gia_AigerWrite( pNew, "test.aig", 0, 0 ); + Gia_ManStop( pNew ); + + Wlc_NtkFree( pNtk ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c new file mode 100644 index 00000000..57d2654a --- /dev/null +++ b/src/base/wlc/wlcWriteVer.c @@ -0,0 +1,204 @@ +/**CFile**************************************************************** + + FileName [wlcWriteVer.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Writes word-level Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcWriteVer.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_WriteVerIntVec( FILE * pFile, Wlc_Ntk_t * p, Vec_Int_t * vVec, int Start ) +{ + char * pName; + int LineLength = Start; + int NameCounter = 0; + int AddedLength, i, iObj; + Vec_IntForEachEntry( vVec, iObj, i ) + { + pName = Wlc_ObjName( p, iObj ); + // get the line length after this name is written + AddedLength = strlen(pName) + 2; + if ( NameCounter && LineLength + AddedLength + 3 > 70 ) + { // write the line extender + fprintf( pFile, "\n " ); + // reset the line length + LineLength = Start; + NameCounter = 0; + } + fprintf( pFile, " %s%s", pName, (i==Vec_IntSize(vVec)-1)? "" : "," ); + LineLength += AddedLength; + NameCounter++; + } +} +void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin; + char Range[100]; + fprintf( pFile, "module %s ( ", p->pName ); + fprintf( pFile, "\n " ); + if ( Wlc_NtkPiNum(p) > 0 ) + { + Wlc_WriteVerIntVec( pFile, p, &p->vPis, 3 ); + fprintf( pFile, ",\n " ); + } + if ( Wlc_NtkPoNum(p) > 0 ) + Wlc_WriteVerIntVec( pFile, p, &p->vPos, 3 ); + fprintf( pFile, " );\n" ); + Wlc_NtkForEachObj( p, pObj, i ) + { + char * pName = Wlc_ObjName(p, i); + char * pName0 = Wlc_ObjFaninNum(pObj) ? Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)) : NULL; + int nDigits = Abc_Base10Log(pObj->End+1) + Abc_Base10Log(pObj->Beg+1); + sprintf( Range, "%s[%d:%d]%*s", pObj->Signed ? "signed ":" ", pObj->End, pObj->Beg, 8-nDigits, "" ); + fprintf( pFile, " " ); + if ( pObj->Type == WLC_OBJ_PI ) + fprintf( pFile, "input wire %s %-16s", Range, pName ); + else if ( pObj->Type == WLC_OBJ_PO ) + fprintf( pFile, "output wire %s %-16s = %s", Range, pName, pName0 ); + else if ( pObj->Type == WLC_OBJ_CONST ) + { + fprintf( pFile, " wire %s %-16s = %d\'%sh", Range, pName, Wlc_ObjRange(pObj), pObj->Signed ? "s":"" ); + Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pObj), (Wlc_ObjRange(pObj) + 3) / 4 ); + } + else + { + fprintf( pFile, " wire %s %-16s = ", Range, Wlc_ObjName(p, i) ); + if ( pObj->Type == WLC_OBJ_BUF ) + fprintf( pFile, "%s", pName0 ); + else if ( pObj->Type == WLC_OBJ_MUX ) + fprintf( pFile, "%s ? %s : %s", pName0, Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)) ); + else if ( pObj->Type == WLC_OBJ_BIT_NOT ) + fprintf( pFile, "~%s", pName0 ); + else if ( pObj->Type == WLC_OBJ_LOGIC_NOT ) + fprintf( pFile, "!%s", pName0 ); + else if ( pObj->Type == WLC_OBJ_REDUCT_AND ) + fprintf( pFile, "&%s", pName0 ); + else if ( pObj->Type == WLC_OBJ_REDUCT_OR ) + fprintf( pFile, "|%s", pName0 ); + else if ( pObj->Type == WLC_OBJ_REDUCT_XOR ) + fprintf( pFile, "^%s", pName0 ); + else if ( pObj->Type == WLC_OBJ_BIT_SELECT ) + fprintf( pFile, "%s [%d:%d]", pName0, Wlc_ObjRangeEnd(pObj), Wlc_ObjRangeBeg(pObj) ); + else if ( pObj->Type == WLC_OBJ_BIT_SIGNEXT ) + fprintf( pFile, "{ {%d{%s[%d]}}, %s }", Wlc_ObjRange(pObj) - Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), pName0, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1, pName0 ); + else if ( pObj->Type == WLC_OBJ_BIT_ZEROPAD ) + fprintf( pFile, "{ {%d{1\'b0}}, %s }", Wlc_ObjRange(pObj) - Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), pName0 ); + else if ( pObj->Type == WLC_OBJ_BIT_CONCAT ) + { + fprintf( pFile, "{" ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + fprintf( pFile, " %s%s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)), k == Wlc_ObjFaninNum(pObj)-1 ? "":"," ); + fprintf( pFile, " }" ); + } + else + { + fprintf( pFile, "%s ", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 0)) ); + if ( pObj->Type == WLC_OBJ_SHIFT_R ) + fprintf( pFile, ">>" ); + else if ( pObj->Type == WLC_OBJ_SHIFT_RA ) + fprintf( pFile, ">>>" ); + else if ( pObj->Type == WLC_OBJ_SHIFT_L ) + fprintf( pFile, "<<" ); + else if ( pObj->Type == WLC_OBJ_SHIFT_LA ) + fprintf( pFile, "<<<" ); + else if ( pObj->Type == WLC_OBJ_BIT_AND ) + fprintf( pFile, "&" ); + else if ( pObj->Type == WLC_OBJ_BIT_OR ) + fprintf( pFile, "|" ); + else if ( pObj->Type == WLC_OBJ_BIT_XOR ) + fprintf( pFile, "^" ); + else if ( pObj->Type == WLC_OBJ_LOGIC_AND ) + fprintf( pFile, "&&" ); + else if ( pObj->Type == WLC_OBJ_LOGIC_OR ) + fprintf( pFile, "||" ); + else if ( pObj->Type == WLC_OBJ_COMP_EQU ) + fprintf( pFile, "==" ); + else if ( pObj->Type == WLC_OBJ_COMP_NOT ) + fprintf( pFile, "!=" ); + else if ( pObj->Type == WLC_OBJ_COMP_LESS ) + fprintf( pFile, "<" ); + else if ( pObj->Type == WLC_OBJ_COMP_MORE ) + fprintf( pFile, ">" ); + else if ( pObj->Type == WLC_OBJ_COMP_LESSEQU ) + fprintf( pFile, "<=" ); + else if ( pObj->Type == WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, ">=" ); + else if ( pObj->Type == WLC_OBJ_ARI_ADD ) + fprintf( pFile, "+" ); + else if ( pObj->Type == WLC_OBJ_ARI_SUB ) + fprintf( pFile, "-" ); + else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + fprintf( pFile, "*" ); + else if ( pObj->Type == WLC_OBJ_ARI_DIVIDE ) + fprintf( pFile, "//" ); + else if ( pObj->Type == WLC_OBJ_ARI_MODULUS ) + fprintf( pFile, "%" ); + else if ( pObj->Type == WLC_OBJ_ARI_POWER ) + fprintf( pFile, "**" ); + else assert( 0 ); + fprintf( pFile, " %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 1)) ); + } + } + fprintf( pFile, " ;\n" ); + } + fprintf( pFile, "endmodule\n\n" ); +} +void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName ) +{ + FILE * pFile; + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Wlc_WriteVer(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", p->pName, Extra_TimeStamp() ); + fprintf( pFile, "\n" ); + Wlc_WriteVerInt( pFile, p ); + fprintf( pFile, "\n" ); + fclose( pFile ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index ee1784fb..8468ffcc 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -732,6 +732,13 @@ static inline char Abc_TtPrintDigit( int Digit ) return '0' + Digit; return 'A' + Digit-10; } +static inline char Abc_TtPrintDigitLower( int Digit ) +{ + assert( Digit >= 0 && Digit < 16 ); + if ( Digit < 10 ) + return '0' + Digit; + return 'a' + Digit-10; +} static inline int Abc_TtReadHexDigit( char HexChar ) { if ( HexChar >= '0' && HexChar <= '9' ) @@ -796,6 +803,12 @@ static inline int Abc_TtWriteHexRev( char * pStr, word * pTruth, int nVars ) *pStr++ = Abc_TtPrintDigit( (int)(pThis[0] >> (k << 2)) & 15 ); return pStr - pStrInit; } +static inline void Abc_TtPrintHexArrayRev( FILE * pFile, word * pTruth, int nDigits ) +{ + int k; + for ( k = nDigits - 1; k >= 0; k-- ) + fprintf( pFile, "%c", Abc_TtPrintDigitLower( Abc_TtGetHex(pTruth, k) ) ); +} /**Function************************************************************* @@ -848,6 +861,22 @@ static inline int Abc_TtReadHex( word * pTruth, char * pString ) pTruth[0] = Abc_Tt6Stretch( pTruth[0], nVars ); return nVars; } +static inline int Abc_TtReadHexNumber( word * pTruth, char * pString ) +{ + // count the number of hex digits + int k, Digit, nDigits = 0; + for ( k = 0; Abc_TtIsHexDigit(pString[k]); k++ ) + nDigits++; + // read hexadecimal digits in the reverse order + // (the last symbol in the string is the least significant digit) + for ( k = 0; k < nDigits; k++ ) + { + Digit = Abc_TtReadHexDigit( pString[nDigits - 1 - k] ); + assert( Digit >= 0 && Digit < 16 ); + Abc_TtSetHex( pTruth, k, Digit ); + } + return nDigits; +} /**Function************************************************************* |