Commit 69bd3554 by Alan Mishchenko

Support for sequential designs in word-level Verilog.

parent 6aa1c94e
...@@ -43,10 +43,10 @@ ABC_NAMESPACE_HEADER_START ...@@ -43,10 +43,10 @@ ABC_NAMESPACE_HEADER_START
typedef enum { typedef enum {
WLC_OBJ_NONE = 0, // 00: unknown WLC_OBJ_NONE = 0, // 00: unknown
WLC_OBJ_PI, // 01: primary input WLC_OBJ_PI, // 01: primary input
WLC_OBJ_PO, // 02: primary output WLC_OBJ_PO, // 02: primary output (unused)
WLC_OBJ_BO, // 03: box output WLC_OBJ_FO, // 03: flop output
WLC_OBJ_BI, // 04: box input WLC_OBJ_FI, // 04: flop input (unused)
WLC_OBJ_FF, // 05: flop WLC_OBJ_FF, // 05: flop (unused)
WLC_OBJ_CONST, // 06: constant WLC_OBJ_CONST, // 06: constant
WLC_OBJ_BUF, // 07: buffer WLC_OBJ_BUF, // 07: buffer
WLC_OBJ_MUX, // 08: multiplexer WLC_OBJ_MUX, // 08: multiplexer
...@@ -88,6 +88,10 @@ typedef enum { ...@@ -88,6 +88,10 @@ typedef enum {
} Wlc_ObjType_t; } Wlc_ObjType_t;
// Unlike AIG managers and logic networks in ABC, this network treats POs and FIs
// as attributes of internal nodes and *not* as separate types of objects.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// BASIC TYPES /// /// BASIC TYPES ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -98,7 +102,9 @@ struct Wlc_Obj_t_ // 16 bytes ...@@ -98,7 +102,9 @@ struct Wlc_Obj_t_ // 16 bytes
unsigned Type : 6; // node type unsigned Type : 6; // node type
unsigned Signed : 1; // signed unsigned Signed : 1; // signed
unsigned Mark : 1; // user mark unsigned Mark : 1; // user mark
unsigned nFanins : 24; // fanin count unsigned fIsPo : 1; // this is PO
unsigned fIsFi : 1; // this is FI
unsigned nFanins : 22; // fanin count
unsigned End : 16; // range end unsigned End : 16; // range end
unsigned Beg : 16; // range begin unsigned Beg : 16; // range begin
union { int Fanins[2]; // fanin IDs union { int Fanins[2]; // fanin IDs
...@@ -138,7 +144,7 @@ static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) ...@@ -138,7 +144,7 @@ static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p )
static inline int Wlc_NtkPoNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPos); } 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_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_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 int Wlc_NtkFfNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vCis) - Vec_IntSize(&p->vPis); }
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_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_NtkPi( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vPis, i) ); }
...@@ -147,8 +153,13 @@ static inline Wlc_Obj_t * Wlc_NtkCi( Wlc_Ntk_t * p, int i ) ...@@ -147,8 +153,13 @@ static inline Wlc_Obj_t * Wlc_NtkCi( Wlc_Ntk_t * p, int 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_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 Wlc_Obj_t * Wlc_NtkFf( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs, i) ); }
static inline int Wlc_ObjIsPi( Wlc_Obj_t * p ) { return p->Type == WLC_OBJ_PI; }
static inline int Wlc_ObjIsPo( Wlc_Obj_t * p ) { return p->fIsPo; }
static inline int Wlc_ObjIsCi( Wlc_Obj_t * p ) { return p->Type == WLC_OBJ_PI || p->Type == WLC_OBJ_FO; }
static inline int Wlc_ObjIsCo( Wlc_Obj_t * p ) { return p->fIsPo || p->fIsFi; }
static inline int Wlc_ObjId( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return pObj - p->pObjs; } 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_ObjCiId( Wlc_Obj_t * p ) { assert( Wlc_ObjIsCi(p) ); return p->Fanins[1]; }
static inline int Wlc_ObjFaninNum( Wlc_Obj_t * p ) { return p->nFanins; } 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_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_ObjFanins( Wlc_Obj_t * p ) { return Wlc_ObjHasArray(p) ? p->pFanins[0] : p->Fanins; }
...@@ -174,12 +185,15 @@ static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) ...@@ -174,12 +185,15 @@ static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p )
static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 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 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 int Wlc_ObjCopy( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vCopies, iObj ); }
static inline Wlc_Obj_t * Wlc_ObjCopyObj(Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, Wlc_Obj_t * pObj) {return Wlc_NtkObj(pNew, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)));}
static inline void Wlc_NtkCleanNameId( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vNameIds, p->nObjsAlloc, 0 ); } 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 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 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 ); } static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); }
static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -198,6 +212,8 @@ static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) ...@@ -198,6 +212,8 @@ static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj )
for ( i = 0; (i < Wlc_NtkCiNum(p)) && (((pCi) = Wlc_NtkCi(p, i)), 1); i++ ) for ( i = 0; (i < Wlc_NtkCiNum(p)) && (((pCi) = Wlc_NtkCi(p, i)), 1); i++ )
#define Wlc_NtkForEachCo( p, pCo, i ) \ #define Wlc_NtkForEachCo( p, pCo, i ) \
for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ ) for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ )
#define Wlc_NtkForEachFf( p, pFf, i ) \
for ( i = 0; (i < Vec_IntSize(&p->vFfs)) && (((pFf) = Wlc_NtkFf(p, i)), 1); i++ )
#define Wlc_ObjForEachFanin( pObj, iFanin, i ) \ #define Wlc_ObjForEachFanin( pObj, iFanin, i ) \
for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ ) for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ )
...@@ -214,6 +230,8 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ); ...@@ -214,6 +230,8 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p );
/*=== wlcNtk.c ========================================================*/ /*=== wlcNtk.c ========================================================*/
extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); 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 int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg );
extern void Wlc_ObjSetCi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj );
extern void Wlc_ObjSetCo( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int fFlopInput );
extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ); 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_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_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins );
......
...@@ -343,6 +343,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) ...@@ -343,6 +343,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )
int nBits = Wlc_NtkPrepareBits( p ); int nBits = Wlc_NtkPrepareBits( p );
int nRange, nRange0, nRange1, nRange2; int nRange, nRange0, nRange1, nRange2;
int i, k, b, iFanin, iLit, * pFans0, * pFans1, * pFans2; int i, k, b, iFanin, iLit, * pFans0, * pFans1, * pFans2;
int nFFins = 0, nFFouts = 0;
vBits = Vec_IntAlloc( nBits ); vBits = Vec_IntAlloc( nBits );
vTemp0 = Vec_IntAlloc( 1000 ); vTemp0 = Vec_IntAlloc( 1000 );
vTemp1 = Vec_IntAlloc( 1000 ); vTemp1 = Vec_IntAlloc( 1000 );
...@@ -357,8 +358,8 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) ...@@ -357,8 +358,8 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )
// create primary inputs // create primary inputs
Wlc_NtkForEachObj( p, pObj, i ) Wlc_NtkForEachObj( p, pObj, i )
{ {
int nAndPrev = Gia_ManObjNum(pNew);
// char * pName = Wlc_ObjName(p, i); // char * pName = Wlc_ObjName(p, i);
int nAndPrev = Gia_ManAndNum(pNew);
nRange = Wlc_ObjRange( pObj ); nRange = Wlc_ObjRange( pObj );
nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1; nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1;
nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1; nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1;
...@@ -367,14 +368,16 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) ...@@ -367,14 +368,16 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )
pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(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; pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL;
Vec_IntClear( vRes ); Vec_IntClear( vRes );
if ( pObj->Type == WLC_OBJ_PI ) if ( Wlc_ObjIsCi(pObj) )
{ {
for ( k = 0; k < nRange; k++ ) for ( k = 0; k < nRange; k++ )
Vec_IntPush( vRes, Gia_ManAppendCi(pNew) ); Vec_IntPush( vRes, Gia_ManAppendCi(pNew) );
if ( pObj->Type == WLC_OBJ_FO )
nFFouts += Vec_IntSize(vRes);
} }
else if ( pObj->Type == WLC_OBJ_PO || pObj->Type == WLC_OBJ_BUF ) else if ( pObj->Type == WLC_OBJ_BUF )
{ {
if ( pObj->Type == WLC_OBJ_BUF && pObj->Signed && !Wlc_ObjFanin0(p, pObj)->Signed ) // unsign->sign if ( pObj->Signed && !Wlc_ObjFanin0(p, pObj)->Signed ) // unsign->sign
{ {
int nRangeMax = Abc_MaxInt( nRange0, nRange ); int nRangeMax = Abc_MaxInt( nRange0, nRange );
int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, 0 ); int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, 0 );
...@@ -533,19 +536,23 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) ...@@ -533,19 +536,23 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )
Vec_IntPush( vRes, Wlc_BlastReduction( pNew, pFans0, nRange, pObj->Type ) ); Vec_IntPush( vRes, Wlc_BlastReduction( pNew, pFans0, nRange, pObj->Type ) );
else if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ) else if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
{ {
int * pArg0 = Wlc_VecLoadFanins( vRes, pFans0, nRange0, nRange, Wlc_ObjFanin0(p, pObj)->Signed ); int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRange, Wlc_ObjFanin1(p, pObj)->Signed ); int * pArg0 = Wlc_VecLoadFanins( vRes, pFans0, nRange0, nRangeMax, Wlc_ObjFanin0(p, pObj)->Signed );
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjFanin1(p, pObj)->Signed );
if ( pObj->Type == WLC_OBJ_ARI_ADD ) if ( pObj->Type == WLC_OBJ_ARI_ADD )
Wlc_BlastAdder( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) Wlc_BlastAdder( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
else else
Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
Vec_IntShrink( vRes, nRange );
} }
else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
{ {
int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange, Wlc_ObjFanin0(p, pObj)->Signed ); int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRange, Wlc_ObjFanin1(p, pObj)->Signed ); int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjFanin0(p, pObj)->Signed );
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjFanin1(p, pObj)->Signed );
assert( nRange0 <= nRange && nRange1 <= nRange ); assert( nRange0 <= nRange && nRange1 <= nRange );
Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRange, vTemp2, vRes ); Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRange, vTemp2, vRes );
Vec_IntShrink( vRes, nRange );
} }
else if ( pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_MODULUS ) else if ( pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_MODULUS )
{ {
...@@ -567,8 +574,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) ...@@ -567,8 +574,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )
assert( Vec_IntSize(vBits) == Wlc_ObjCopy(p, i) ); assert( Vec_IntSize(vBits) == Wlc_ObjCopy(p, i) );
Vec_IntAppend( vBits, vRes ); Vec_IntAppend( vBits, vRes );
pPrev = pObj; pPrev = pObj;
if ( pObj->Type != WLC_OBJ_PI && pObj->Type != WLC_OBJ_PO ) p->nAnds[pObj->Type] += Gia_ManAndNum(pNew) - nAndPrev;
p->nAnds[pObj->Type] += Gia_ManObjNum(pNew) - nAndPrev;
} }
p->nAnds[0] = Gia_ManAndNum(pNew); p->nAnds[0] = Gia_ManAndNum(pNew);
assert( nBits == Vec_IntSize(vBits) ); assert( nBits == Vec_IntSize(vBits) );
...@@ -576,18 +582,21 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) ...@@ -576,18 +582,21 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )
Vec_IntFree( vTemp1 ); Vec_IntFree( vTemp1 );
Vec_IntFree( vTemp2 ); Vec_IntFree( vTemp2 );
Vec_IntFree( vRes ); Vec_IntFree( vRes );
// create POs // create COs
Wlc_NtkForEachPo( p, pObj, i ) Wlc_NtkForEachCo( p, pObj, i )
{ {
nRange = Wlc_ObjRange( pObj ); 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)) ); pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) );
for ( k = 0; k < nRange; k++ ) for ( k = 0; k < nRange; k++ )
Gia_ManAppendCo( pNew, pFans0[k] ); Gia_ManAppendCo( pNew, pFans0[k] );
if ( pObj->fIsFi )
nFFins += nRange;
} }
Vec_IntFree( vBits ); Vec_IntFree( vBits );
Vec_IntErase( &p->vCopies ); Vec_IntErase( &p->vCopies );
// set the number of registers
assert( nFFins == nFFouts );
Gia_ManSetRegNum( pNew, nFFins );
// finalize and cleanup // finalize and cleanup
pNew = Gia_ManCleanup( pTemp = pNew ); pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp ); Gia_ManStop( pTemp );
......
...@@ -107,9 +107,30 @@ Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ) ...@@ -107,9 +107,30 @@ Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc )
p->iObj = 1; p->iObj = 1;
return p; return p;
} }
void Wlc_ObjSetCi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
{
assert( Wlc_ObjIsCi(pObj) );
assert( Wlc_ObjFaninNum(pObj) == 0 );
pObj->Fanins[1] = Vec_IntSize(&p->vCis);
Vec_IntPush( &p->vCis, Wlc_ObjId(p, pObj) );
if ( pObj->Type == WLC_OBJ_PI )
Vec_IntPush( &p->vPis, Wlc_ObjId(p, pObj) );
}
void Wlc_ObjSetCo( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int fFlopInput )
{
// pObj->Fanins[1] = Vec_IntSize(&p->vCos);
Vec_IntPush( &p->vCos, Wlc_ObjId(p, pObj) );
if ( !fFlopInput )
Vec_IntPush( &p->vPos, Wlc_ObjId(p, pObj) );
if ( fFlopInput )
pObj->fIsFi = 1;
else
pObj->fIsPo = 1;
}
int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ) int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg )
{ {
Wlc_Obj_t * pObj; Wlc_Obj_t * pObj;
assert( Type != WLC_OBJ_PO && Type != WLC_OBJ_FI );
if ( p->iObj == p->nObjsAlloc ) if ( p->iObj == p->nObjsAlloc )
{ {
p->pObjs = ABC_REALLOC( Wlc_Obj_t, p->pObjs, 2 * p->nObjsAlloc ); p->pObjs = ABC_REALLOC( Wlc_Obj_t, p->pObjs, 2 * p->nObjsAlloc );
...@@ -121,16 +142,8 @@ int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ) ...@@ -121,16 +142,8 @@ int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg )
pObj->Signed = Signed; pObj->Signed = Signed;
pObj->End = End; pObj->End = End;
pObj->Beg = Beg; pObj->Beg = Beg;
if ( Type == WLC_OBJ_PI ) if ( Wlc_ObjIsCi(pObj) )
{ Wlc_ObjSetCi( p, pObj );
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]++; p->nObjs[Type]++;
return p->iObj++; return p->iObj++;
} }
...@@ -144,13 +157,7 @@ char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ) ...@@ -144,13 +157,7 @@ char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj )
} }
void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ) void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type )
{ {
if ( pObj->Type == WLC_OBJ_PO ) assert( pObj->Type == WLC_OBJ_NONE );
{
// if ( Type != WLC_OBJ_BUF )
// printf( "Primary outputs should be driven by buffers.\n" );
assert( Type == WLC_OBJ_BUF );
return;
}
p->nObjs[pObj->Type]--; p->nObjs[pObj->Type]--;
pObj->Type = Type; pObj->Type = Type;
p->nObjs[pObj->Type]++; p->nObjs[pObj->Type]++;
...@@ -274,20 +281,18 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) ...@@ -274,20 +281,18 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
Wlc_NtkForEachObj( p, pObj, i ) Wlc_NtkForEachObj( p, pObj, i )
{ {
// char * pName = Wlc_ObjName(p, i); // char * pName = Wlc_ObjName(p, i);
// if ( pObj->Type == WLC_OBJ_ARI_MULTI )
if ( Wlc_ObjSign(pObj) > 0x1FFFFF ) if ( Wlc_ObjSign(pObj) > 0x1FFFFF )
printf( "Object %6d has range %d, which is reduced to %d in the statistics.\n", printf( "Object %6d has range %d, which is reduced to %d in the statistics.\n",
i, Wlc_ObjRange(pObj), Wlc_ObjRange(pObj) & 0xFFFFF ); i, Wlc_ObjRange(pObj), Wlc_ObjRange(pObj) & 0xFFFFF );
if ( pObj->Beg ) if ( pObj->Beg )
printf( "Object %6d has non-standard range %d=[%d:%d]\n", i, Wlc_ObjRange(pObj), pObj->End, pObj->Beg ); printf( "Object %6d has non-standard range %d=[%d:%d]\n", i, Wlc_ObjRange(pObj), pObj->End, pObj->Beg );
// 0-input types // 0-input types
if ( pObj->Type == WLC_OBJ_PI || pObj->Type == WLC_OBJ_CONST || pObj->Type == WLC_OBJ_BIT_CONCAT ) if ( Wlc_ObjIsCi(pObj) || pObj->Type == WLC_OBJ_CONST || pObj->Type == WLC_OBJ_BIT_CONCAT )
Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), 0, 0 ); Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), 0, 0 );
// 1-input types // 1-input types
else if ( pObj->Type == WLC_OBJ_BUF || pObj->Type == WLC_OBJ_PO || pObj->Type == WLC_OBJ_BI || else if ( pObj->Type == WLC_OBJ_BUF || pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE ||
pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT || pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT ||
pObj->Type == WLC_OBJ_BIT_NOT || pObj->Type == WLC_OBJ_LOGIC_NOT || pObj->Type == WLC_OBJ_ARI_MINUS || pObj->Type == WLC_OBJ_BIT_NOT || pObj->Type == WLC_OBJ_LOGIC_NOT || pObj->Type == WLC_OBJ_ARI_MINUS )
pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE )
Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), Wlc_ObjSign(Wlc_ObjFanin0(p, pObj)), 0 ); Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), Wlc_ObjSign(Wlc_ObjFanin0(p, pObj)), 0 );
// 2-input types (including MUX) // 2-input types (including MUX)
else else
...@@ -296,7 +301,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) ...@@ -296,7 +301,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
Wlc_NtkPrintDistribAddOne( vTypes, vOccurs, pObj->Type, Sign ); Wlc_NtkPrintDistribAddOne( vTypes, vOccurs, pObj->Type, Sign );
} }
// print by occurrence // print by occurrence
printf( "Format: type ID : occurance name ... (occurrence)<output_range>=<input_range>.<input_range>\n" ); printf( "ID : name occurrence (occurrence)<output_range>=<input_range>.<input_range> ...\n" );
for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
{ {
Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i );
...@@ -436,12 +441,12 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) ...@@ -436,12 +441,12 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p )
Wlc_NtkCleanCopy( p ); Wlc_NtkCleanCopy( p );
vFanins = Vec_IntAlloc( 100 ); vFanins = Vec_IntAlloc( 100 );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
Wlc_NtkForEachPi( p, pObj, i ) Wlc_NtkForEachCi( 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 ); Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
Vec_IntFree( vFanins ); Vec_IntFree( vFanins );
return pNew; return pNew;
} }
......
...@@ -658,11 +658,11 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * ...@@ -658,11 +658,11 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t *
int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart ) int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
{ {
int fFound = 0, Type = WLC_OBJ_NONE, iObj; int fFound = 0, Type = WLC_OBJ_NONE, iObj;
int Signed = 0, Beg = 0, End = 0, NameId; int Signed = 0, Beg = 0, End = 0, NameId, fIsPo = 0;
if ( Wlc_PrsStrCmp( pStart, "input" ) ) if ( Wlc_PrsStrCmp( pStart, "input" ) )
Type = WLC_OBJ_PI, pStart += strlen("input"); pStart += strlen("input"), Type = WLC_OBJ_PI;
else if ( Wlc_PrsStrCmp( pStart, "output" ) ) else if ( Wlc_PrsStrCmp( pStart, "output" ) )
Type = WLC_OBJ_PO, pStart += strlen("output"); pStart += strlen("output"), fIsPo = 1;
pStart = Wlc_PrsSkipSpaces( pStart ); pStart = Wlc_PrsSkipSpaces( pStart );
if ( Wlc_PrsStrCmp( pStart, "wire" ) ) if ( Wlc_PrsStrCmp( pStart, "wire" ) )
pStart += strlen("wire"); pStart += strlen("wire");
...@@ -685,6 +685,7 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart ) ...@@ -685,6 +685,7 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
if ( fFound ) if ( fFound )
return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is declared more than once.", pName ); return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is declared more than once.", pName );
iObj = Wlc_ObjAlloc( p->pNtk, Type, Signed, End, Beg ); iObj = Wlc_ObjAlloc( p->pNtk, Type, Signed, End, Beg );
if ( fIsPo ) Wlc_ObjSetCo( p->pNtk, Wlc_NtkObj(p->pNtk, iObj), 0 );
assert( iObj == NameId ); assert( iObj == NameId );
// check next definition // check next definition
pStart = Wlc_PrsSkipSpaces( pStart ); pStart = Wlc_PrsSkipSpaces( pStart );
...@@ -707,6 +708,7 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart ) ...@@ -707,6 +708,7 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
} }
int Wlc_PrsDerive( Wlc_Prs_t * p ) int Wlc_PrsDerive( Wlc_Prs_t * p )
{ {
Wlc_Obj_t * pObj;
char * pStart, * pName; char * pStart, * pName;
int i; int i;
// go through the directives // go through the directives
...@@ -719,9 +721,21 @@ startword: ...@@ -719,9 +721,21 @@ startword:
pName = strtok( pStart + strlen("module"), " \r\n\t(,)" ); pName = strtok( pStart + strlen("module"), " \r\n\t(,)" );
if ( pName == NULL ) if ( pName == NULL )
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read model name." ); return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read model name." );
// THIS IS A HACK to skip definitions of modules beginning with "CPL_"
if ( Wlc_PrsStrCmp( pName, "CPL_" ) )
{
while ( ++i < Vec_IntSize(p->vStarts) )
{
pStart = Wlc_PrsStr(p, Vec_IntEntry(p->vStarts, i));
pStart = strstr( pStart, "endmodule" );
if ( pStart != NULL )
break;
}
continue;
}
if ( Wlc_PrsStrCmp( pName, "table" ) ) if ( Wlc_PrsStrCmp( pName, "table" ) )
{ {
// THIS IS A HACK TO DETECT tables // THIS IS A HACK to detect table module descriptions
int Width1 = -1, Width2 = -1; int Width1 = -1, Width2 = -1;
int v, b, Value, nBits, nInts; int v, b, Value, nBits, nInts;
unsigned * pTable; unsigned * pTable;
...@@ -784,6 +798,14 @@ startword: ...@@ -784,6 +798,14 @@ startword:
Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(p->pNtk) ); Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(p->pNtk) );
Vec_IntAppend( &p->pNtk->vNameIds, vTemp ); Vec_IntAppend( &p->pNtk->vNameIds, vTemp );
Vec_IntFree( vTemp ); Vec_IntFree( vTemp );
// move FO/FI to be part of CI/CO
assert( (Vec_IntSize(&p->pNtk->vFfs) & 1) == 0 );
Wlc_NtkForEachFf( p->pNtk, pObj, i )
if ( i & 1 )
Wlc_ObjSetCo( p->pNtk, pObj, 1 );
else
Wlc_ObjSetCi( p->pNtk, pObj );
Vec_IntClear( &p->pNtk->vFfs );
break; break;
} }
// these are read as part of the interface // these are read as part of the interface
...@@ -807,7 +829,7 @@ startword: ...@@ -807,7 +829,7 @@ startword:
Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins ); Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins );
if ( Type ) if ( Type )
{ {
Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, NameId ); pObj = Wlc_NtkObj( p->pNtk, NameId );
Wlc_ObjUpdateType( p->pNtk, pObj, Type ); Wlc_ObjUpdateType( p->pNtk, pObj, Type );
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
} }
...@@ -816,7 +838,7 @@ startword: ...@@ -816,7 +838,7 @@ startword:
} }
else if ( Wlc_PrsStrCmp( pStart, "table" ) ) else if ( Wlc_PrsStrCmp( pStart, "table" ) )
{ {
// THIS IS A HACK TO DETECT tables // THIS IS A HACK to detect tables
int NameId, fFound, iTable = atoi( pStart + strlen("table") ); int NameId, fFound, iTable = atoi( pStart + strlen("table") );
// find opening // find opening
pStart = Wlc_PrsFindSymbol( pStart, '(' ); pStart = Wlc_PrsFindSymbol( pStart, '(' );
...@@ -844,15 +866,13 @@ startword: ...@@ -844,15 +866,13 @@ startword:
NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
if ( !fFound ) if ( !fFound )
return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName ); return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
{ pObj = Wlc_NtkObj( p->pNtk, NameId );
Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, NameId ); Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_TABLE );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_TABLE ); Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
}
} }
else if ( Wlc_PrsStrCmp( pStart, "always" ) ) else if ( Wlc_PrsStrCmp( pStart, "always" ) )
{ {
// THIS IS A HACK TO DETECT tables // THIS IS A HACK to detect always statement representing combinational MUX
int NameId, NameIdOut = -1, fFound; int NameId, NameIdOut = -1, fFound;
// find control // find control
pStart = Wlc_PrsFindWord( pStart, "case", &fFound ); pStart = Wlc_PrsFindWord( pStart, "case", &fFound );
...@@ -918,18 +938,58 @@ startword: ...@@ -918,18 +938,58 @@ startword:
break; break;
} }
// check range of the control // check range of the control
pObj = Wlc_NtkObj( p->pNtk, Vec_IntEntry(p->vFanins, 0) );
if ( (1 << Wlc_ObjRange(pObj)) != Vec_IntSize(p->vFanins) - 1 )
return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName );
pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_MUX );
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
goto startword;
}
else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) )
{
int NameId = -1, NameIdOut = -1, fFound, nBits = 1, fFlopOut;
pStart += strlen("CPL_FF");
if ( pStart[0] == '#' )
nBits = atoi(pStart+1);
// read names
while ( 1 )
{ {
Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, Vec_IntEntry(p->vFanins, 0) ); pStart = Wlc_PrsFindSymbol( pStart, '.' );
if ( (1 << Wlc_ObjRange(pObj)) != Vec_IntSize(p->vFanins) - 1 ) if ( pStart == NULL )
return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName ); break;
pObj = Wlc_NtkObj( p->pNtk, NameIdOut ); pStart = Wlc_PrsSkipSpaces( pStart+1 );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_MUX ); if ( pStart[0] != 'd' && (pStart[0] != 'q' || pStart[1] == 'b') )
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); continue;
goto startword; fFlopOut = (pStart[0] == 'd');
pStart = Wlc_PrsFindSymbol( pStart, '(' );
if ( pStart == NULL )
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening paranthesis in the flop description." );
pStart = Wlc_PrsFindName( pStart+1, &pName );
if ( pStart == NULL )
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
if ( fFlopOut )
NameIdOut = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else
NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
if ( !fFound )
return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
} }
if ( NameId == -1 || NameIdOut == -1 )
return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." );
// create flop output
pObj = Wlc_NtkObj( p->pNtk, NameId );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FO );
Vec_IntPush( &p->pNtk->vFfs, NameId );
if ( nBits != Wlc_ObjRange(pObj) )
printf( "Warning! Flop input has bit-width (%d) that differs from the declaration (%d)\n", nBits, Wlc_ObjRange(pObj) );
// create flop input
pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
Vec_IntPush( &p->pNtk->vFfs, NameIdOut );
if ( nBits != Wlc_ObjRange(pObj) )
printf( "Warning! Flop output has bit-width (%d) that differs from the declaration (%d)\n", nBits, Wlc_ObjRange(pObj) );
} }
// else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) ) else if ( pStart[0] != '`' )
else
{ {
pStart = Wlc_PrsFindName( pStart, &pName ); pStart = Wlc_PrsFindName( pStart, &pName );
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line beginning with %s.", pName ); return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line beginning with %s.", pName );
......
...@@ -151,17 +151,21 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) ...@@ -151,17 +151,21 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p )
sprintf( Range, "%s[%d:%d]%*s", pObj->Signed ? "signed ":" ", pObj->End, pObj->Beg, 8-nDigits, "" ); sprintf( Range, "%s[%d:%d]%*s", pObj->Signed ? "signed ":" ", pObj->End, pObj->Beg, 8-nDigits, "" );
fprintf( pFile, " " ); fprintf( pFile, " " );
if ( pObj->Type == WLC_OBJ_PI ) if ( pObj->Type == WLC_OBJ_PI )
fprintf( pFile, "input wire %s %s", Range, pName ); fprintf( pFile, "input " );
else if ( pObj->Type == WLC_OBJ_PO ) else if ( pObj->fIsPo )
fprintf( pFile, "output wire %s %-16s = %s", Range, pName, pName0 ); fprintf( pFile, "output " );
else
fprintf( pFile, " " );
if ( Wlc_ObjIsCi(pObj) )
fprintf( pFile, "wire %s %s", Range, pName );
else if ( pObj->Type == WLC_OBJ_TABLE ) else if ( pObj->Type == WLC_OBJ_TABLE )
{ {
// wire [3:0] s4972; table0 s4972_Index(s4971, s4972); // wire [3:0] s4972; table0 s4972_Index(s4971, s4972);
fprintf( pFile, " wire %s %s ; table%d s%d_Index(%s, %s)", Range, pName, Wlc_ObjTableId(pObj), i, pName0, pName ); fprintf( pFile, "wire %s %s ; table%d s%d_Index(%s, %s)", Range, pName, Wlc_ObjTableId(pObj), i, pName0, pName );
} }
else if ( pObj->Type == WLC_OBJ_CONST ) else if ( pObj->Type == WLC_OBJ_CONST )
{ {
fprintf( pFile, " wire %s %-16s = %d\'%sh", Range, pName, Wlc_ObjRange(pObj), pObj->Signed ? "s":"" ); 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 ); Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pObj), (Wlc_ObjRange(pObj) + 3) / 4 );
} }
else if ( pObj->Type == WLC_OBJ_ROTATE_R || pObj->Type == WLC_OBJ_ROTATE_L ) else if ( pObj->Type == WLC_OBJ_ROTATE_R || pObj->Type == WLC_OBJ_ROTATE_L )
...@@ -172,7 +176,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) ...@@ -172,7 +176,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p )
int Num1 = Wlc_ObjRange(pObj) - Num0; int Num1 = Wlc_ObjRange(pObj) - Num0;
assert( pShift->Type == WLC_OBJ_CONST ); assert( pShift->Type == WLC_OBJ_CONST );
assert( Num0 > 0 && Num0 < Wlc_ObjRange(pObj) ); assert( Num0 > 0 && Num0 < Wlc_ObjRange(pObj) );
fprintf( pFile, " wire %s %-16s = ", Range, Wlc_ObjName(p, i) ); fprintf( pFile, "wire %s %-16s = ", Range, Wlc_ObjName(p, i) );
if ( pObj->Type == WLC_OBJ_ROTATE_R ) if ( pObj->Type == WLC_OBJ_ROTATE_R )
fprintf( pFile, "(%s >> %d) | (%s << %d)", pName0, Num0, pName0, Num1 ); fprintf( pFile, "(%s >> %d) | (%s << %d)", pName0, Num0, pName0, Num1 );
else else
...@@ -180,7 +184,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) ...@@ -180,7 +184,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p )
} }
else if ( pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3 ) else if ( pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3 )
{ {
fprintf( pFile, " reg %s ;\n", pName ); fprintf( pFile, "reg %s ;\n", pName );
fprintf( pFile, " " ); fprintf( pFile, " " );
fprintf( pFile, "always @( " ); fprintf( pFile, "always @( " );
Wlc_ObjForEachFanin( pObj, iFanin, k ) Wlc_ObjForEachFanin( pObj, iFanin, k )
...@@ -204,11 +208,11 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) ...@@ -204,11 +208,11 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p )
} }
else else
{ {
fprintf( pFile, " wire %s %-16s = ", Range, Wlc_ObjName(p, i) ); fprintf( pFile, "wire %s %-16s = ", Range, Wlc_ObjName(p, i) );
if ( pObj->Type == WLC_OBJ_BUF ) if ( pObj->Type == WLC_OBJ_BUF )
fprintf( pFile, "%s", pName0 ); fprintf( pFile, "%s", pName0 );
else if ( pObj->Type == WLC_OBJ_MUX ) 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)) ); fprintf( pFile, "%s ? %s : %s", pName0, Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) );
else if ( pObj->Type == WLC_OBJ_BIT_NOT ) else if ( pObj->Type == WLC_OBJ_BIT_NOT )
fprintf( pFile, "~%s", pName0 ); fprintf( pFile, "~%s", pName0 );
else if ( pObj->Type == WLC_OBJ_LOGIC_NOT ) else if ( pObj->Type == WLC_OBJ_LOGIC_NOT )
...@@ -283,6 +287,27 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) ...@@ -283,6 +287,27 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p )
} }
fprintf( pFile, " ;\n" ); fprintf( pFile, " ;\n" );
} }
Wlc_NtkForEachCi( p, pObj, i )
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
assert( i == Wlc_ObjCiId(pObj) );
if ( pObj->Type == WLC_OBJ_PI )
continue;
// CPL_FF#9 I_32890_reg ( .q ( E_42304 ) , .qbar ( ) , .d ( E_42305 ) , .clk ( E_65040 ) ,
// .arst ( E_65037 ) , .arstval ( E_62126 ) );
fprintf( pFile, " " );
fprintf( pFile, "CPL_FF" );
if ( Wlc_ObjRange(pObj) > 1 )
fprintf( pFile, "#%d", Wlc_ObjRange(pObj) );
fprintf( pFile, " %reg%d (", i );
fprintf( pFile, " .q( %s ),", pName );
fprintf( pFile, " .qbar()," );
fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) );
fprintf( pFile, " .clk( %s ),", "1\'b0" );
fprintf( pFile, " .arst( %s ),", "1\'b0" );
fprintf( pFile, " .arstval( %s )", "1\'b0" );
fprintf( pFile, " ) ;\n" );
}
fprintf( pFile, "endmodule\n\n" ); fprintf( pFile, "endmodule\n\n" );
} }
void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName ) void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment