summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--abclib.dsp36
-rw-r--r--src/base/abc/abcShow.c10
-rw-r--r--src/base/io/io.c57
-rw-r--r--src/base/main/mainInit.c4
-rw-r--r--src/base/main/mainInt.h1
-rw-r--r--src/base/wlc/module.make6
-rw-r--r--src/base/wlc/wlc.c52
-rw-r--r--src/base/wlc/wlc.h273
-rw-r--r--src/base/wlc/wlcBlast.c363
-rw-r--r--src/base/wlc/wlcCom.c311
-rw-r--r--src/base/wlc/wlcNtk.c283
-rw-r--r--src/base/wlc/wlcReadVer.c711
-rw-r--r--src/base/wlc/wlcWriteVer.c204
-rw-r--r--src/misc/util/utilTruth.h29
15 files changed, 2276 insertions, 66 deletions
diff --git a/Makefile b/Makefile
index 77266a2c..11ac44bb 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ PROG := abc
MODULES := \
$(wildcard src/ext) src/misc/ext \
src/base/abc src/base/abci src/base/cmd src/base/io \
- src/base/main src/base/ver src/base/test \
+ src/base/main src/base/ver src/base/wlc src/base/test \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse \
src/bdd/reo src/bdd/cas \
src/map/mapper src/map/mio src/map/super src/map/if \
diff --git a/abclib.dsp b/abclib.dsp
index 3981b1ee..9243be2d 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -599,10 +599,6 @@ SOURCE=.\src\base\io\ioReadVerilog.c
# End Source File
# Begin Source File
-SOURCE=.\src\base\io\ioReadWord.c
-# End Source File
-# Begin Source File
-
SOURCE=.\src\base\io\ioUtil.c
# End Source File
# Begin Source File
@@ -746,6 +742,38 @@ SOURCE=.\src\base\test\test.c
# PROP Default_Filter ""
# End Group
+# Begin Group "wlc"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlcBlast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlcCom.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlcNtk.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlcReadVer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\base\wlc\wlcWriteVer.c
+# End Source File
+# End Group
# End Group
# Begin Group "bdd"
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*************************************************************