mirror of https://github.com/YosysHQ/abc.git
New word-level representation package.
This commit is contained in:
parent
ae7e286213
commit
dcb7d0d3fc
2
Makefile
2
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 \
|
||||
|
|
|
|||
36
abclib.dsp
36
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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ struct Abc_Frame_t_
|
|||
void * pAbc85Ntl2;
|
||||
void * pAbc85Best;
|
||||
void * pAbc85Delay;
|
||||
void * pAbcWlc;
|
||||
|
||||
EXT_ABC_FRAME // plugin for external functionality
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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*************************************************************
|
||||
|
|
|
|||
Loading…
Reference in New Issue