Version abc51114

This commit is contained in:
Alan Mishchenko 2005-11-14 08:01:00 -08:00
parent e2619aa120
commit 85f42d0ebd
81 changed files with 4399 additions and 4518 deletions

View File

@ -6,7 +6,7 @@ CP := cp
PROG := abc
MODULES := src/base/abc src/base/abci src/base/abcs src/base/cmd src/base/io src/base/main \
MODULES := src/base/abc src/base/abci src/base/seq src/base/cmd src/base/io src/base/main \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \
src/map/fpga src/map/pga src/map/mapper src/map/mio src/map/super \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/vec \

112
abc.dsp
View File

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mapp" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mapp" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mapp" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mapp" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
@ -273,54 +273,6 @@ SOURCE=.\src\base\abci\abcVanImp.c
SOURCE=.\src\base\abci\abcVerify.c
# End Source File
# End Group
# Begin Group "abcs"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\base\abcs\abcFpgaDelay.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcFpgaSeq.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcRetCore.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcRetDelay.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcRetImpl.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcRetUtil.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcs.h
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcSeq.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcSeqMan.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcShare.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcUtils.c
# End Source File
# End Group
# Begin Group "cmd"
# PROP Default_Filter ""
@ -438,6 +390,10 @@ SOURCE=.\src\base\io\ioWriteGml.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWriteList.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWritePla.c
# End Source File
# End Group
@ -473,6 +429,62 @@ SOURCE=.\src\base\main\mainInt.h
SOURCE=.\src\base\main\mainUtils.c
# End Source File
# End Group
# Begin Group "seq"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\base\seq\seq.h
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqCreate.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqFpgaCore.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqFpgaIter.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqInt.h
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqLatch.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqMan.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqMapCore.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqMapIter.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqRetCore.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqRetIter.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqShare.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqUtil.c
# End Source File
# End Group
# End Group
# Begin Group "bdd"

BIN
abc.opt

Binary file not shown.

1272
abc.plg

File diff suppressed because it is too large Load Diff

1
abc.rc
View File

@ -70,4 +70,5 @@ alias thin "rwz; rfz; b; ps"
alias reti "st; seq; ret; unseq; st"
alias retis "st; seq; ret; unseq -s; st"
alias choice "fraig_store; resyn; fraig_store; resyn2; fraig_store; fraig_restore"
alias stest "st; ps; seq; ps; unseq; st; ps; sec"

1236
abclib.plg

File diff suppressed because it is too large Load Diff

18
copyright.txt Normal file
View File

@ -0,0 +1,18 @@
Copyright (c) 1990-2004 The Regents of the University of California. All rights reserved.
Permission is hereby granted, without written agreement and without license or
royalty fees, to use, copy, modify, and distribute this software and its
documentation for any purpose, provided that the above copyright notice and
the following two paragraphs appear in all copies of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

View File

@ -82,7 +82,8 @@ typedef enum {
ABC_OBJ_LATCH, // 3: latch
ABC_OBJ_PI, // 4: primary input terminal
ABC_OBJ_PO, // 5: primary output terminal
ABC_OBJ_OTHER // 6: unused
ABC_OBJ_BOX, // 6: abstract box
ABC_OBJ_OTHER // 7: unused
} Abc_ObjType_t;
// latch initial values
@ -90,7 +91,8 @@ typedef enum {
ABC_INIT_NONE = 0, // 0: unknown
ABC_INIT_ZERO, // 1: zero
ABC_INIT_ONE, // 2: one
ABC_INIT_DC // 3: don't-care
ABC_INIT_DC, // 3: don't-care
ABC_INIT_OTHER // 4: unused
} Abc_InitType_t;
////////////////////////////////////////////////////////////////////////
@ -154,6 +156,7 @@ struct Abc_Ntk_t_
Vec_Ptr_t * vCis; // the array of combinational inputs (PIs followed by latches)
Vec_Ptr_t * vCos; // the array of combinational outputs (POs followed by latches)
Vec_Ptr_t * vLats; // the array of latches (or the cutset in the sequential network)
Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG)
// the stats about the number of living objects
int nObjs; // the number of live objs
int nNets; // the number of live nets
@ -177,8 +180,6 @@ struct Abc_Ntk_t_
Vec_Ptr_t * vSupps;
// the satisfiable assignment of the miter
int * pModel;
// initial states
Vec_Int_t * vInits;
// the external don't-care if given
Abc_Ntk_t * pExdc; // the EXDC network
// miscellaneous data members
@ -205,6 +206,10 @@ struct Abc_Ntk_t_
#define ABC_MAX(a,b) (((a) > (b))? (a) : (b))
#define ABC_INFINITY (10000000)
// transforming floats into ints and back
static inline int Abc_Float2Int( float Val ) { return *((int *)&Val); }
static inline float Abc_Int2Float( int Num ) { return *((float *)&Num); }
// checking the network type
static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_NETLIST; }
static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_LOGIC; }
@ -224,12 +229,13 @@ static inline bool Abc_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pN
static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return pNtk->nLatches == 0; }
// reading data members of the network
static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; }
static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; }
static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; }
static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; }
static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; }
static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; }
static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; }
static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; }
static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; }
static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; }
static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; }
static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; }
static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return pNtk->vObjs->pArray[0]; }
// setting data members of the network
static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; }
@ -243,18 +249,20 @@ static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pN
static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; }
static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; }
static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nLatches; }
static inline int Abc_NtkCutSetNodeNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCutSet); }
static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return pNtk->nPis; }
static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return pNtk->nPos; }
static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return pNtk->vCis->nSize; }
static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return pNtk->vCos->nSize; }
// reading objects
static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vObjs) ); return (Abc_Obj_t *)pNtk->vObjs->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vLats) ); return (Abc_Obj_t *)pNtk->vLats->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCis->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCos->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCiNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCis->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCoNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCos->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vObjs, i ); }
static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vLats, i ); }
static inline Abc_Obj_t * Abc_NtkCutSetNode( Abc_Ntk_t * pNtk, int i){ return Vec_PtrEntry( pNtk->vCutSet, i ); }
static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCis, i ); }
static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCos, i ); }
static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return Abc_NtkCi( pNtk, i ); }
static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return Abc_NtkCo( pNtk, i ); }
// reading data members of the object
static inline unsigned Abc_ObjType( Abc_Obj_t * pObj ) { return pObj->Type; }
@ -293,6 +301,7 @@ static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pO
static inline int Abc_ObjFaninId( Abc_Obj_t * pObj, int i) { return pObj->vFanins.pArray[i].iFan; }
static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].iFan; }
static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].iFan; }
static inline int Abc_ObjFanoutEdgeNum( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( Abc_NtkHasAig(pObj->pNtk) ); if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) return 0; if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) return 1; assert( 0 ); return -1; }
static inline Abc_Obj_t * Abc_ObjFanout( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[i].iFan ]; }
static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[0].iFan ]; }
static inline Abc_Obj_t * Abc_ObjFanin( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[i].iFan ]; }
@ -303,7 +312,6 @@ static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return (A
static inline bool Abc_ObjFaninC( Abc_Obj_t * pObj, int i ) { return pObj->vFanins.pArray[i].fCompl; }
static inline bool Abc_ObjFaninC0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].fCompl; }
static inline bool Abc_ObjFaninC1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].fCompl; }
static inline bool Abc_ObjFanoutC( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjFaninC0(pFanout) : Abc_ObjFaninC1(pFanout); }
static inline int Abc_ObjFaninL( Abc_Obj_t * pObj, int i ) { return pObj->vFanins.pArray[i].nLats; }
static inline int Abc_ObjFaninL0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].nLats; }
static inline int Abc_ObjFaninL1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].nLats; }
@ -315,8 +323,6 @@ static inline Abc_Obj_t * Abc_ObjChild1( Abc_Obj_t * pObj ) { return Ab
static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Abc_ObjNotCond( Abc_ObjFanin(pObj,i)->pCopy, Abc_ObjFaninC(pObj,i) );}
static inline Abc_Obj_t * Abc_ObjChild0Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); }
static inline Abc_Obj_t * Abc_ObjChild1Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC1(pObj) ); }
static inline Abc_Obj_t * Abc_ObjGetCopy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjRegular(pObj)->pCopy, Abc_ObjIsComplement(pObj) ); }
static inline Abc_Obj_t * Abc_ObjFanoutFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjChild0(pFanout) : Abc_ObjChild1(pFanout); }
static inline void Abc_ObjSetFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl = 1; }
static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl ^= 1; }
static inline void Abc_ObjSetFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats = nLats; }
@ -325,6 +331,9 @@ static inline void Abc_ObjSetFaninL1( Abc_Obj_t * pObj, int nLats )
static inline void Abc_ObjAddFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats += nLats; }
static inline void Abc_ObjAddFaninL0( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[0].nLats += nLats; }
static inline void Abc_ObjAddFaninL1( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[1].nLats += nLats; }
static inline int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { return Abc_ObjFaninL( pFanout, Abc_ObjFanoutEdgeNum(pObj,pFanout) ); }
static inline void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) { Abc_ObjSetFaninL( pFanout, Abc_ObjFanoutEdgeNum(pObj,pFanout), nLats ); }
static inline void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) { Abc_ObjAddFaninL( pFanout, Abc_ObjFanoutEdgeNum(pObj,pFanout), nLats ); }
// checking the node type
static inline bool Abc_NodeIsAigAnd( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; }
@ -361,42 +370,42 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab
////////////////////////////////////////////////////////////////////////
// objects of the network
#define Abc_NtkForEachObj( pNtk, pObj, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
if ( pObj = Abc_NtkObj(pNtk, i) )
#define Abc_NtkForEachNet( pNtk, pNet, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
if ( (pNet = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNet(pNet) )
#define Abc_NtkForEachNode( pNtk, pNode, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNode(pNode) )
#define Abc_NtkForEachLatch( pNtk, pObj, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \
if ( pObj = Abc_NtkLatch(pNtk, i) )
#define Abc_AigForEachAnd( pNtk, pNode, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_NodeIsAigAnd(pNode) )
#define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \
if ( (pNode = Abc_NtkLatch(pNtk, i)) )
#define Abc_NtkForEachObj( pNtk, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pObj) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pObj) == NULL ) {} else
#define Abc_NtkForEachNet( pNtk, pNet, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNet) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNet) == NULL || !Abc_ObjIsNet(pNet) ) {} else
#define Abc_NtkForEachLatch( pNtk, pLatch, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vLats)) && (((pLatch) = Abc_NtkLatch(pNtk, i)), 1); i++ )\
if ( (pLatch) == NULL ) {} else
#define Abc_NtkForEachNode( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else
#define Abc_AigForEachAnd( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_NodeIsAigAnd(pNode) ) {} else
#define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \
for ( i = 0; (i < Abc_NtkCutSetNodeNum(pNtk)) && (((pNode) = Abc_NtkCutSetNode(pNtk, i)), 1); i++ )\
if ( (pNode) == NULL ) {} else
// inputs and outputs
#define Abc_NtkForEachPi( pNtk, pPi, i ) \
#define Abc_NtkForEachPi( pNtk, pPi, i ) \
for ( i = 0; (i < Abc_NtkPiNum(pNtk)) && (((pPi) = Abc_NtkPi(pNtk, i)), 1); i++ )
#define Abc_NtkForEachPo( pNtk, pPo, i ) \
#define Abc_NtkForEachPo( pNtk, pPo, i ) \
for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(pNtk, i)), 1); i++ )
#define Abc_NtkForEachCi( pNtk, pCi, i ) \
#define Abc_NtkForEachCi( pNtk, pCi, i ) \
for ( i = 0; (i < Abc_NtkCiNum(pNtk)) && (((pCi) = Abc_NtkCi(pNtk, i)), 1); i++ )
#define Abc_NtkForEachCo( pNtk, pCo, i ) \
#define Abc_NtkForEachCo( pNtk, pCo, i ) \
for ( i = 0; (i < Abc_NtkCoNum(pNtk)) && (((pCo) = Abc_NtkCo(pNtk, i)), 1); i++ )
// fanin and fanouts
#define Abc_ObjForEachFanin( pObj, pFanin, i ) \
#define Abc_ObjForEachFanin( pObj, pFanin, i ) \
for ( i = 0; (i < Abc_ObjFaninNum(pObj)) && (((pFanin) = Abc_ObjFanin(pObj, i)), 1); i++ )
#define Abc_ObjForEachFanout( pObj, pFanout, i ) \
#define Abc_ObjForEachFanout( pObj, pFanout, i ) \
for ( i = 0; (i < Abc_ObjFanoutNum(pObj)) && (((pFanout) = Abc_ObjFanout(pObj, i)), 1); i++ )
// cubes and literals
#define Abc_SopForEachCube( pSop, nFanins, pCube ) \
#define Abc_SopForEachCube( pSop, nFanins, pCube ) \
for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 )
#define Abc_CubeForEachVar( pCube, Value, i ) \
#define Abc_CubeForEachVar( pCube, Value, i ) \
for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ )
@ -406,12 +415,10 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab
/*=== abcAig.c ==========================================================*/
extern Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtk );
extern Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew );
extern void Abc_AigFree( Abc_Aig_t * pMan );
extern int Abc_AigCleanup( Abc_Aig_t * pMan );
extern bool Abc_AigCheck( Abc_Aig_t * pMan );
extern int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan );
extern Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
@ -496,8 +503,6 @@ extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial );
/*=== abcObj.c ==========================================================*/
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew );
extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
@ -515,6 +520,9 @@ extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFani
extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern void Abc_ObjAdd( Abc_Obj_t * pObj );
/*=== abcNames.c ====================================================*/
extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName );
extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix );
@ -632,7 +640,7 @@ extern char * Abc_SopFromTruthBin( char * pTruth );
extern char * Abc_SopFromTruthHex( char * pTruth );
/*=== abcStrash.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup );
extern Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
/*=== abcSweep.c ==========================================================*/
extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose );

View File

@ -30,6 +30,8 @@
- there are no dangling nodes (the nodes without fanout)
- the level of each AND gate reflects the levels of this fanins
- the EXOR-status of each node is up-to-date
- the AND nodes are in the topological order
- the constant 1 node has always number 0 in the object list
The operations that are performed on AIGs:
- building new nodes (Abc_AigAnd)
- performing elementary Boolean operations (Abc_AigOr, Abc_AigXor, etc)
@ -48,8 +50,6 @@
struct Abc_Aig_t_
{
Abc_Ntk_t * pNtkAig; // the AIG network
Abc_Obj_t * pConst1; // the constant 1 node
// Abc_Obj_t * pReset; // the sequential reset node
Abc_Obj_t ** pBins; // the table bins
int nBins; // the size of the table
int nEntries; // the total number of entries in the table
@ -123,72 +123,9 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
pMan->vLevelsR = Vec_VecAlloc( 100 );
// save the current network
pMan->pNtkAig = pNtkAig;
// allocate constant nodes
pMan->pConst1 = Abc_NtkCreateNode( pNtkAig );
// subtract these nodes from the total number
pNtkAig->nNodes -= 1;
return pMan;
}
/**Function*************************************************************
Synopsis [Duplicated the AIG manager.]
Description [Assumes that CI/CO nodes are already created.
Transfers the latch attributes on the edges.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkCiNum(pMan->pNtkAig) == Abc_NtkCiNum(pManNew->pNtkAig) );
assert( Abc_NtkCoNum(pMan->pNtkAig) == Abc_NtkCoNum(pManNew->pNtkAig) );
assert( Abc_NtkLatchNum(pMan->pNtkAig) == Abc_NtkLatchNum(pManNew->pNtkAig) );
// set mapping of the constant nodes
Abc_AigConst1( pMan )->pCopy = Abc_AigConst1( pManNew );
// set the mapping of CIs/COs
Abc_NtkForEachPi( pMan->pNtkAig, pObj, i )
pObj->pCopy = Abc_NtkPi( pManNew->pNtkAig, i );
Abc_NtkForEachPo( pMan->pNtkAig, pObj, i )
pObj->pCopy = Abc_NtkPo( pManNew->pNtkAig, i );
Abc_NtkForEachLatch( pMan->pNtkAig, pObj, i )
pObj->pCopy = Abc_NtkLatch( pManNew->pNtkAig, i );
// copy internal nodes
vNodes = Abc_AigDfs( pMan->pNtkAig, 0, 0 );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( !Abc_NodeIsAigAnd(pObj) )
continue;
pObj->pCopy = Abc_AigAnd( pManNew, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
// printf( "Old = %4d. New = %4d.\n", pObj->Id, pObj->pCopy->Id );
// transfer latch attributes
Abc_ObjSetFaninL0( pObj->pCopy, Abc_ObjFaninL0(pObj) );
Abc_ObjSetFaninL1( pObj->pCopy, Abc_ObjFaninL1(pObj) );
}
// relink the choice nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
Vec_PtrFree( vNodes );
// relink the CO nodes
Abc_NtkForEachCo( pMan->pNtkAig, pObj, i )
{
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
Abc_ObjSetFaninL0( pObj->pCopy, Abc_ObjFaninL0(pObj) );
}
// get the number of nodes before and after
if ( Abc_NtkNodeNum(pMan->pNtkAig) != Abc_NtkNodeNum(pManNew->pNtkAig) )
printf( "Warning: Structural hashing during duplication reduced %d nodes (to fix later).\n",
Abc_NtkNodeNum(pMan->pNtkAig) - Abc_NtkNodeNum(pManNew->pNtkAig) );
return pManNew;
}
/**Function*************************************************************
Synopsis [Deallocates the local AIG manager.]
@ -263,7 +200,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan )
nFanins = Abc_ObjFaninNum(pObj);
if ( nFanins == 0 )
{
if ( pObj != pMan->pConst1 )
if ( pObj != Abc_NtkConst1(pMan->pNtkAig) )
{
printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" );
return 0;
@ -323,23 +260,6 @@ int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk )
return LevelsMax;
}
/**Function*************************************************************
Synopsis [Read the constant 1 node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan )
{
return pMan->pConst1;
}
/**Function*************************************************************
@ -429,24 +349,25 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t *
***********************************************************************/
Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
{
Abc_Obj_t * pAnd;
Abc_Obj_t * pAnd, * pConst1;
unsigned Key;
// check for trivial cases
pConst1 = Abc_NtkConst1(pMan->pNtkAig);
if ( p0 == p1 )
return p0;
if ( p0 == Abc_ObjNot(p1) )
return Abc_ObjNot(pMan->pConst1);
if ( Abc_ObjRegular(p0) == pMan->pConst1 )
return Abc_ObjNot(pConst1);
if ( Abc_ObjRegular(p0) == pConst1 )
{
if ( p0 == pMan->pConst1 )
if ( p0 == pConst1 )
return p1;
return Abc_ObjNot(pMan->pConst1);
return Abc_ObjNot(pConst1);
}
if ( Abc_ObjRegular(p1) == pMan->pConst1 )
if ( Abc_ObjRegular(p1) == pConst1 )
{
if ( p1 == pMan->pConst1 )
if ( p1 == pConst1 )
return p0;
return Abc_ObjNot(pMan->pConst1);
return Abc_ObjNot(pConst1);
}
// order the arguments
if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id )
@ -667,7 +588,7 @@ Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
int i;
assert( vPairs->nSize % 2 == 0 );
// go through the cubes of the node's SOP
pMiter = Abc_ObjNot(pMan->pConst1);
pMiter = Abc_ObjNot( Abc_NtkConst1(pMan->pNtkAig) );
for ( i = 0; i < vPairs->nSize; i += 2 )
{
pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] );
@ -1252,7 +1173,7 @@ void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsDfsOrdered(pNtk) );
Abc_AigConst1(pNtk->pManFunc)->fPhase = 1;
Abc_NtkConst1(pNtk)->fPhase = 1;
// Abc_NtkForEachCi( pNtk, pObj, i )
// pObj->fPhase = 0;
Abc_NtkForEachPi( pNtk, pObj, i )

View File

@ -219,8 +219,8 @@ void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
***********************************************************************/
bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i;
Abc_Obj_t * pNode, * pFanin;
int i, k;
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
// mark the CIs
@ -229,12 +229,11 @@ bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk )
// go through the nodes
Abc_NtkForEachNode( pNtk, pNode, i )
{
if ( Abc_ObjFaninNum(pNode) == 0 )
continue;
if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) )
return 0;
if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) )
return 0;
Abc_ObjForEachFanin( pNode, pFanin, k )
{
if ( !Abc_NodeIsTravIdCurrent(pFanin) )
return 0;
}
Abc_NodeSetTravIdCurrent( pNode );
}
return 1;
@ -672,7 +671,7 @@ int Abc_AigSetChoiceLevels( Abc_Ntk_t * pNtk )
Abc_NodeSetTravIdCurrent( pObj );
pObj->pCopy = NULL;
}
pObj = Abc_AigConst1( pNtk->pManFunc );
pObj = Abc_NtkConst1( pNtk );
Abc_NodeSetTravIdCurrent( pObj );
pObj->pCopy = NULL;
// set levels of all other nodes

View File

@ -43,11 +43,6 @@
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== abcObj.c ==========================================================*/
extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern void Abc_ObjAdd( Abc_Obj_t * pObj );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -19,7 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "abcs.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -158,10 +158,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
Abc_NtkBddToSop(pNtk);
// start the netlist by creating PI/PO/Latch objects
if ( Abc_NtkIsSopLogic(pNtk) )
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, ABC_FUNC_SOP );
else
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, ABC_FUNC_BDD );
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, pNtk->ntkFunc );
// create the CI nets and remember them in the new CI nodes
Abc_NtkForEachCi( pNtk, pObj, i )
@ -240,8 +237,6 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsStrash(pNtk) );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
// create the constant node
Abc_NtkDupConst1( pNtk, pNtkNew );
// duplicate the nodes and create node functions
Abc_NtkForEachNode( pNtk, pObj, i )
{
@ -317,8 +312,6 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
printf( "Warning: Choice nodes are skipped.\n" );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
// create the constant node
Abc_NtkDupConst1( pNtk, pNtkNew );
// collect the nodes to be used (marks all nodes with current TravId)
vNodes = Abc_NtkDfs( pNtk, 0 );
// create inverters for the CI and remember them

View File

@ -22,6 +22,7 @@
#include "abcInt.h"
#include "main.h"
#include "mio.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -52,6 +53,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vLats = Vec_PtrAlloc( 100 );
pNtk->vCutSet = Vec_PtrAlloc( 100 );
pNtk->vCis = Vec_PtrAlloc( 100 );
pNtk->vCos = Vec_PtrAlloc( 100 );
pNtk->vPtrTemp = Vec_PtrAlloc( 100 );
@ -75,11 +77,22 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
{
if ( Abc_NtkIsStrash(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else
pNtk->pManFunc = Seq_Create( pNtk );
}
else if ( Abc_NtkHasMapping(pNtk) )
pNtk->pManFunc = Abc_FrameReadLibGen();
else
assert( 0 );
// allocate constant node
if ( !Abc_NtkIsNetlist(pNtk) )
{
Abc_NodeCreateConst1( pNtk );
// do not count this node towards the total number of nodes
pNtk->nNodes -= 1;
}
else
Vec_PtrPush( pNtk->vObjs, NULL );
return pNtk;
}
@ -106,6 +119,12 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
// duplicate the name and the spec
pNtkNew->pName = util_strsav(pNtk->pName);
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
// clean the node copy fields
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// clone the PIs/POs/latches
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
@ -117,12 +136,13 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
Vec_PtrPush( pNtkNew->vCis, pObjNew );
Vec_PtrPush( pNtkNew->vCos, pObjNew );
}
// clean the node copy fields
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// transfer the names
Abc_NtkDupCioNamesTable( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
// check that the CI/CO/latches are copied correctly
assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) );
assert( Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
return pNtkNew;
}
@ -270,7 +290,43 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// copy the internal nodes
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigDup( pNtk->pManFunc, pNtkNew->pManFunc );
{
// copy the AND gates
Abc_AigForEachAnd( pNtk, pObj, i )
pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
// relink the choice nodes
Abc_AigForEachAnd( pNtk, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
// relink the CO nodes
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
// get the number of nodes before and after
if ( Abc_NtkNodeNum(pNtk) != Abc_NtkNodeNum(pNtkNew) )
printf( "Warning: Structural hashing during duplication reduced %d nodes (this is a minor bug).\n",
Abc_NtkNodeNum(pNtk) - Abc_NtkNodeNum(pNtkNew) );
}
else if ( Abc_NtkIsSeq(pNtk) )
{
// start the storage for initial states
Seq_Resize( pNtkNew->pManFunc, Abc_NtkObjNumMax(pNtk) );
// copy the nodes
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL )
Abc_NtkDupObj(pNtkNew, pObj);
// connect the nodes
Abc_NtkForEachObj( pNtk, pObj, i )
{
Abc_ObjForEachFanin( pObj, pFanin, k )
{
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
if ( Abc_ObjFaninC(pObj, k) )
Abc_ObjSetFaninC( pObj->pCopy, k );
if ( Abc_ObjFaninL(pObj, k) > 0 )
Seq_NodeDupLats( pObj->pCopy, pObj, k );
}
}
}
else
{
// duplicate the nets and nodes (CIs/COs/latches already dupped)
@ -281,23 +337,6 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// if it is a sequential networ, transfer attributes on edges
if ( Abc_NtkIsSeq(pNtk) )
{
pNtkNew->vInits = Vec_IntStart( 2 * Abc_NtkObjNumMax(pNtkNew) );
Abc_NtkForEachObj( pNtk, pObj, i )
{
Abc_ObjForEachFanin( pObj, pFanin, k )
{
if ( Abc_ObjFaninC(pObj, k) )
Abc_ObjSetFaninC( pObj->pCopy, k );
if ( Abc_ObjFaninL(pObj, k) > 0 )
Abc_ObjSetFaninL( pObj->pCopy, k, Abc_ObjFaninL(pObj, k) );
}
Vec_IntWriteEntry( pNtkNew->vInits, 2*pObj->pCopy->Id+0, Vec_IntEntry(pNtk->vInits, 2*pObj->Id+0) );
Vec_IntWriteEntry( pNtkNew->vInits, 2*pObj->pCopy->Id+1, Vec_IntEntry(pNtk->vInits, 2*pObj->Id+1) );
}
}
}
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
@ -335,7 +374,10 @@ Abc_Ntk_t * Abc_NtkCreateOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAl
sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) );
pNtkNew->pName = util_strsav(Buffer);
// collect the nodes in the TFI of the output
// establish connection between the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// collect the nodes in the TFI of the output (mark the TFI)
vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 );
// create the PIs
Abc_NtkForEachCi( pNtk, pObj, i )
@ -346,9 +388,6 @@ Abc_Ntk_t * Abc_NtkCreateOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAl
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
}
// establish connection between the constant nodes
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc);
// copy the nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
@ -412,11 +451,11 @@ Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t *
}
// copy the nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pCopy = Abc_NodeStrash( pNtkNew->pManFunc, pObj );
pObj->pCopy = Abc_NodeStrash( pNtkNew, pObj );
Vec_PtrFree( vNodes );
// add the PO
pFinal = Abc_AigConst1( pNtkNew->pManFunc );
pFinal = Abc_NtkConst1( pNtkNew );
Vec_PtrForEachEntry( vRoots, pObj, i )
{
if ( Abc_ObjIsCo(pObj) )
@ -558,14 +597,14 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
if ( pNtk->pExdc )
Abc_NtkDelete( pNtk->pExdc );
// free the arrays
Vec_PtrFree( pNtk->vObjs );
Vec_PtrFree( pNtk->vLats );
Vec_PtrFree( pNtk->vCis );
Vec_PtrFree( pNtk->vCos );
Vec_PtrFree( pNtk->vObjs );
Vec_PtrFree( pNtk->vLats );
Vec_PtrFree( pNtk->vCutSet );
Vec_PtrFree( pNtk->vPtrTemp );
Vec_IntFree( pNtk->vIntTemp );
Vec_StrFree( pNtk->vStrTemp );
if ( pNtk->vInits ) Vec_IntFree( pNtk->vInits );
if ( pNtk->pModel ) free( pNtk->pModel );
// free the hash table of Obj name into Obj ID
stmm_free_table( pNtk->tName2Net );
@ -591,6 +630,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
{
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigFree( pNtk->pManFunc );
else
Seq_Delete( pNtk->pManFunc );
}
else if ( !Abc_NtkHasMapping(pNtk) )
assert( 0 );

View File

@ -158,7 +158,7 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData);
else if ( Abc_NtkHasMapping(pNtkNew) )
pObjNew->pData = pObj->pData;
else if ( Abc_NtkIsStrash(pNtkNew) )
else if ( !Abc_NtkHasAig(pNtkNew) )
assert( 0 );
}
}
@ -172,34 +172,6 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
return pObjNew;
}
/**Function*************************************************************
Synopsis [Creates a new constant node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew )
{
Abc_Obj_t * pConst1;
assert( Abc_NtkHasAig(pNtkAig) );
assert( Abc_NtkIsLogic(pNtkNew) );
pConst1 = Abc_AigConst1(pNtkAig->pManFunc);
if ( Abc_ObjFanoutNum(pConst1) > 0 )
pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew );
else
{
// skip the 0-th entry to allow one-to-one match of object IDs
if ( pConst1->Id == 0 && pNtkNew->nNodes == 0 )
Vec_PtrPush( pNtkNew->vObjs, NULL );
}
return pConst1->pCopy;
}
/**Function*************************************************************
@ -518,9 +490,9 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
if ( Abc_NtkHasAig(pNtk) )
return Abc_AigConst1(pNtk->pManFunc);
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkHasAig(pNtk) )
return pNode;
if ( Abc_NtkHasSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
@ -759,7 +731,7 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode )
if ( Abc_NtkHasBdd(pNtk) )
return Cudd_IsComplement(pNode->pData);
if ( Abc_NtkHasAig(pNtk) )
return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc);
return Abc_ObjNot(pNode) == Abc_NtkConst1(pNode->pNtk);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper());
assert( 0 );
@ -787,7 +759,7 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode )
if ( Abc_NtkHasBdd(pNtk) )
return !Cudd_IsComplement(pNode->pData);
if ( Abc_NtkHasAig(pNtk) )
return pNode == Abc_AigConst1(pNode->pNtk->pManFunc);
return pNode == Abc_NtkConst1(pNode->pNtk);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper());
assert( 0 );

View File

@ -22,7 +22,7 @@
#include "main.h"
#include "mio.h"
#include "dec.h"
#include "abcs.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -938,18 +938,15 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Vec_Ptr_t * vObjsNew;
Abc_Obj_t * pNode, * pTemp;
Abc_Obj_t * pConst1 = NULL, * pReset = NULL;
Abc_Obj_t * pNode, * pTemp, * pConst1;
int i, k;
assert( Abc_NtkIsStrash(pNtk) );
// start the array of objects with new IDs
vObjsNew = Vec_PtrAlloc( pNtk->nObjs );
// put constant nodes (if present) first
if ( Abc_NtkIsStrash(pNtk) )
{
pConst1 = Abc_AigConst1(pNtk->pManFunc);
pConst1->Id = Vec_PtrSize( vObjsNew );
Vec_PtrPush( vObjsNew, pConst1 );
}
// put constant node first
pConst1 = Abc_NtkConst1(pNtk);
assert( pConst1->Id == 0 );
Vec_PtrPush( vObjsNew, pConst1 );
// put PI nodes next
Abc_NtkForEachPi( pNtk, pNode, i )
{
@ -972,7 +969,7 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
vNodes = Abc_NtkDfs( pNtk, 1 );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( pNode == pReset || pNode == pConst1 )
if ( pNode == pConst1 )
continue;
pNode->Id = Vec_PtrSize( vObjsNew );
Vec_PtrPush( vObjsNew, pNode );
@ -992,6 +989,9 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
// replace the array of objs
Vec_PtrFree( pNtk->vObjs );
pNtk->vObjs = vObjsNew;
// rehash the AIG
Abc_AigRehash( pNtk->pManFunc );
}
////////////////////////////////////////////////////////////////////////

View File

@ -25,7 +25,7 @@
#include "fpga.h"
#include "pga.h"
#include "cut.h"
#include "abcs.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -4474,6 +4474,7 @@ int Abc_CommandPga( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
// strash and balance the network
@ -4599,7 +4600,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Abc_NtkIsComb(pNtk) )
{
fprintf( pErr, "The current network is combinational.\n" );
return 1;
return 0;
}
if ( fZeros )
@ -4712,7 +4713,7 @@ int Abc_CommandPipe( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pErr, "usage: pipe [-L num] [-h]\n" );
fprintf( pErr, "\t inserts the given number of latches at the PIs\n" );
fprintf( pErr, "\t inserts the given number of latches at each PI for pipelining\n" );
fprintf( pErr, "\t-L num : the number of latches to insert [default = %d]\n", nLatches );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@ -4758,8 +4759,11 @@ int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
// printf( "This command is not yet implemented.\n" );
// return 0;
if ( Abc_NtkIsSeq(pNtk) )
{
fprintf( pErr, "The current network is already a sequential AIG.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
@ -4769,7 +4773,7 @@ int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Abc_NtkCountSelfFeedLatches(pNtk) )
{
fprintf( pErr, "Works AIG has self-feeding latches. Cannot continue.\n" );
fprintf( pErr, "Sequential AIG cannot be created for designs with self-feeding latches.\n" );
return 1;
}
@ -4844,7 +4848,7 @@ int Abc_CommandUnseq( Abc_Frame_t * pAbc, int argc, char ** argv )
// share the latches on the fanout edges
if ( fShare )
Abc_NtkSeqShareFanouts(pNtk);
Seq_NtkSeqShareFanouts(pNtk);
// get the new network
pNtkRes = Abc_NtkSeqToLogicSop( pNtk );
@ -4893,7 +4897,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
fForward = 0;
fBackward = 0;
fInitial = 0;
fInitial = 1;
fVerbose = 0;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "fbivh" ) ) != EOF )
@ -4933,21 +4937,19 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( fForward )
Abc_NtkSeqRetimeForward( pNtk, fVerbose );
Seq_NtkSeqRetimeForward( pNtk, fInitial, fVerbose );
else if ( fBackward )
Abc_NtkSeqRetimeBackward( pNtk, fVerbose );
else if ( fInitial )
Abc_NtkSeqRetimeInitial( pNtk, fVerbose );
Seq_NtkSeqRetimeBackward( pNtk, fInitial, fVerbose );
else
Abc_NtkSeqRetimeDelay( pNtk, fVerbose );
Seq_NtkSeqRetimeDelay( pNtk, fInitial, fVerbose );
return 0;
usage:
fprintf( pErr, "usage: retime [-fbh]\n" );
fprintf( pErr, "usage: retime [-fbih]\n" );
fprintf( pErr, "\t retimes sequential AIG (default is Pan's delay-optimal retiming)\n" );
fprintf( pErr, "\t-f : toggle forward retiming [default = %s]\n", fForward? "yes": "no" );
fprintf( pErr, "\t-b : toggle backward retiming [default = %s]\n", fBackward? "yes": "no" );
// fprintf( pErr, "\t-i : toggle retiming for initial state [default = %s]\n", fInitial? "yes": "no" );
fprintf( pErr, "\t-i : toggle computation of initial state [default = %s]\n", fInitial? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
@ -5003,7 +5005,10 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Works only for sequential AIG (run \"seq\").\n" );
return 1;
}
return 0;
printf( "This command is not yet implemented.\n" );
return 0;
// get the new network
pNtkRes = Abc_NtkFpgaSeq( pNtk, fVerbose );
@ -5075,7 +5080,11 @@ int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Works only for sequential AIG (run \"seq\").\n" );
return 1;
}
return 0;
printf( "This command is not yet implemented.\n" );
return 0;
// get the new network
pNtkRes = Abc_NtkMapSeq( pNtk, fVerbose );

View File

@ -83,8 +83,6 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica
Abc_Obj_t * pNode, * pDriver;
int i;
// copy the constant node
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc);
// set the level of PIs of AIG according to the arrival times of the old network
Abc_NtkSetNodeLevelsArrival( pNtk );
// allocate temporary storage for supergates
@ -128,7 +126,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate );
if ( vSuper->nSize == 0 )
{ // it means that the supergate contains two nodes in the opposite polarity
pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan));
pNodeOld->pCopy = Abc_ObjNot(Abc_NtkConst1(pNtkNew));
return pNodeOld->pCopy;
}
// for each old node, derive the new well-balanced node

View File

@ -56,6 +56,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
assert( Abc_NtkIsStrash(pNtk) );
if ( pParams->fMulti )
Abc_NtkBalanceAttach(pNtk);

View File

@ -168,7 +168,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
{
Dsd_Node_t ** ppNodesDsd;
Dsd_Node_t * pNodeDsd;
Abc_Obj_t * pNode, * pNodeNew, * pDriver, * pConst1;
Abc_Obj_t * pNode, * pNodeNew, * pDriver;
int i, nNodesDsd;
// save the CI nodes in the DSD nodes
@ -177,10 +177,6 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
pNodeDsd = Dsd_ManagerReadInput( pManDsd, i );
Dsd_NodeSetMark( pNodeDsd, (int)pNode->pCopy );
}
// set the constant node
pConst1 = Abc_AigConst1(pNtk->pManFunc);
if ( Abc_ObjFanoutNum(pConst1) > 0 )
pConst1->pCopy = Abc_NodeCreateConst1(pNtkNew);
// collect DSD nodes in DFS order (leaves and const1 are not collected)
ppNodesDsd = Dsd_TreeCollectNodesDfs( pManDsd, &nNodesDsd );

View File

@ -150,7 +150,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching,
// consider the case of a constant
if ( Abc_NodeIsConst(pNode) )
{
Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
continue;
}
// add the node to the mapper
@ -204,8 +204,7 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachCi( pNtk, pNode, i )
Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
// set the constant node
if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 )
Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) );
Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkConst1(pNtkNew) );
// process the nodes in topological order
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )

View File

@ -35,7 +35,7 @@ static void Abc_NtkFraigRemapUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t
static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk );
static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -110,7 +110,7 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExd
// map the constant node
Abc_NtkCleanCopy( pNtk );
Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
// create PIs and remember them in the old nodes
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
@ -165,7 +165,7 @@ Fraig_Node_t * Abc_NtkToFraigExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtkMain, Abc
// strash the EXDC network
pNtkStrash = Abc_NtkStrash( pNtkExdc, 0, 0 );
Abc_NtkCleanCopy( pNtkStrash );
Abc_AigConst1(pNtkStrash->pManFunc)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
Abc_NtkConst1(pNtkStrash)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
// set the mapping of the PI nodes
ppNames = Abc_NtkCollectCioNames( pNtkMain, 0 );
Abc_NtkForEachCi( pNtkStrash, pObj, i )
@ -282,7 +282,7 @@ Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachCi( pNtk, pNode, i )
Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy );
// set the constant node
Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew->pManFunc) );
Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_NtkConst1(pNtkNew) );
// process the nodes in topological order
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
@ -380,7 +380,7 @@ Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
// map the nodes into their lowest level representives
tTable = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
pNode = Abc_AigConst1(pNtk->pManFunc);
pNode = Abc_NtkConst1(pNtk);
if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) )
*ppSlot = pNode;
Abc_NtkForEachCi( pNtk, pNode, i )
@ -408,7 +408,6 @@ Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc);
// perform strashing
Abc_AigSetNodePhases( pNtk );
@ -552,7 +551,6 @@ int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk )
void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
ProgressBar * pProgress;
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pObj;
int i;
@ -566,7 +564,7 @@ void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
// get the node
assert( Abc_ObjIsNode(pNode) );
// strash the node
pNodeNew = Abc_NodeFraigTrust( pMan, pNode );
pNodeNew = Abc_NodeFraigTrust( pNtkNew, pNode );
// get the old object
if ( Abc_NtkIsNetlist(pNtk) )
pObj = Abc_ObjFanout0( pNode ); // the fanout net
@ -592,10 +590,9 @@ void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
{
Abc_Obj_t * pSum, * pFanin;
Abc_Obj_t * pConst1 = Abc_AigConst1(pMan);
void ** ppTail;
int i, nFanins, fCompl;
@ -605,11 +602,11 @@ Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
assert( nFanins == Abc_SopGetVarNum(pNode->pData) );
// check if it is a constant
if ( nFanins == 0 )
return Abc_ObjNotCond( pConst1, Abc_SopIsConst0(pNode->pData) );
return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pNode->pData) );
if ( nFanins == 1 )
return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) );
if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) )
return Abc_AigAnd( pMan,
return Abc_AigAnd( pNtkNew->pManFunc,
Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,0) ),
Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,1) ) );
assert( Abc_SopIsOrType(pNode->pData) );

View File

@ -56,11 +56,11 @@ static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Sup
***********************************************************************/
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose )
{
int fShowSwitching = 1;
Abc_Ntk_t * pNtkNew;
Map_Man_t * pMan;
Vec_Int_t * vSwitching;
float * pSwitching = NULL;
int fShowSwitching = 0;
int clk;
assert( Abc_NtkIsStrash(pNtk) );
@ -176,7 +176,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
// consider the case of a constant
if ( Abc_NodeIsConst(pNode) )
{
Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
continue;
}
// add the node to the mapper
@ -231,8 +231,7 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachCi( pNtk, pNode, i )
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
// set the constant node
if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 )
Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NodeCreateConst1(pNtkNew) );
Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NtkConst1(pNtkNew) );
// assign the mapping of the required phase to the POs
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );

View File

@ -29,7 +29,7 @@ static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Ab
static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter );
static void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode );
static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes );
static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame );
// to be exported
typedef void (*AddFrameMapping)( Abc_Obj_t*, Abc_Obj_t*, int, void*);
@ -126,6 +126,9 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
// clean the copy field in all objects
// Abc_NtkCleanCopy( pNtk1 );
// Abc_NtkCleanCopy( pNtk2 );
Abc_NtkConst1(pNtk1)->pCopy = Abc_NtkConst1(pNtkMiter);
Abc_NtkConst1(pNtk2)->pCopy = Abc_NtkConst1(pNtkMiter);
if ( fComb )
{
// create new PIs and remember them in the old PIs
@ -194,26 +197,11 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
***********************************************************************/
void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter )
{
ProgressBar * pProgress;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pConst1, * pConst1New;
Abc_Obj_t * pNode;
int i;
// get the constant nodes
pConst1 = Abc_AigConst1( pNtk->pManFunc );
pConst1New = Abc_AigConst1( pNtkMiter->pManFunc );
// perform strashing
vNodes = Abc_NtkDfs( pNtk, 0 );
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( pNode == pConst1 )
pNode->pCopy = pConst1New;
else
pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}
Vec_PtrFree( vNodes );
Extra_ProgressBarStop( pProgress );
assert( Abc_NtkIsDfsOrdered(pNtk) );
Abc_AigForEachAnd( pNtk, pNode, i )
pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}
/**Function*************************************************************
@ -230,22 +218,15 @@ void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter )
void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New;
Abc_Obj_t * pNode;
int i;
// get the constant nodes
pConst1 = Abc_AigConst1( pNtk->pManFunc );
pConst1New = Abc_AigConst1( pNtkMiter->pManFunc );
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkMiter);
// perform strashing
vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 );
for ( i = 0; i < vNodes->nSize; i++ )
{
pNode = vNodes->pArray[i];
if ( pNode == pConst1 )
pNodeNew = pConst1New;
else
pNodeNew = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
pNode->pCopy = pNodeNew;
}
Vec_PtrForEachEntry( vNodes, pNode, i )
if ( Abc_NodeIsAigAnd(pNode) )
pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
Vec_PtrFree( vNodes );
}
@ -335,9 +316,9 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In
// perform strashing
Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
// set the first cofactor
Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
Abc_NtkCi(pNtk, In2)->pCopy = Abc_NtkConst1( pNtkMiter );
// add the first cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
@ -345,9 +326,9 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In
pOutput1 = Abc_ObjFanin0(pRoot)->pCopy;
// set the second cofactor
Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
Abc_NtkCi(pNtk, In1)->pCopy = Abc_NtkConst1( pNtkMiter );
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
// add the second cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
@ -395,7 +376,7 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter )
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
{
assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter->pManFunc) );
assert( Abc_ObjRegular(pChild) == Abc_NtkConst1(pMiter) );
if ( !Abc_ObjIsComplement(pChild) )
{
// if the miter is constant 1, return immediately
@ -475,11 +456,11 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
char Buffer[100];
ProgressBar * pProgress;
Abc_Ntk_t * pNtkFrames;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pLatch, * pLatchNew;
int i, Counter;
assert( nFrames > 0 );
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkIsDfsOrdered(pNtk) );
// start the new network
pNtkFrames = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
sprintf( Buffer, "%s_%d_frames", pNtk->pName, nFrames );
@ -502,22 +483,20 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
Counter++;
}
else
pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) );
pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) );
}
if ( Counter )
printf( "Warning: %d uninitialized latches are replaced by free PI variables.\n", Counter );
}
// create the timeframes
vNodes = Abc_NtkDfs( pNtk, 0 );
pProgress = Extra_ProgressBarStart( stdout, nFrames );
for ( i = 0; i < nFrames; i++ )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
Abc_NtkAddFrame( pNtkFrames, pNtk, i, vNodes );
Abc_NtkAddFrame( pNtkFrames, pNtk, i );
}
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
// connect the new latches to the outputs of the last frame
if ( !fInitial )
@ -561,38 +540,26 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
SeeAlso []
***********************************************************************/
void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes )
void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame )
{
char Buffer[10];
Abc_Obj_t * pNode, * pNodeNew, * pLatch;
Abc_Obj_t * pConst1, * pConst1New;
Abc_Obj_t * pNode, * pLatch;
int i;
// get the constant nodes
pConst1 = Abc_AigConst1( pNtk->pManFunc );
pConst1New = Abc_AigConst1( pNtkFrames->pManFunc );
// create the prefix to be added to the node names
sprintf( Buffer, "_%02d", iFrame );
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames);
// add the new PI nodes
Abc_NtkForEachPi( pNtk, pNode, i )
{
pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer );
}
Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer );
// add the internal nodes
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( pNode == pConst1 )
pNodeNew = pConst1New;
else
pNodeNew = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
pNode->pCopy = pNodeNew;
}
Abc_AigForEachAnd( pNtk, pNode, i )
pNode->pCopy = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
// add the new POs
Abc_NtkForEachPo( pNtk, pNode, i )
{
pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
Abc_ObjAddFanin( pNodeNew, Abc_ObjChild0Copy(pNode) );
Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer );
Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer );
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
}
// transfer the implementation of the latch drivers to the latches
Abc_NtkForEachLatch( pNtk, pLatch, i )
@ -648,7 +615,7 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram
Counter++;
}
else {
pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) );
pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) );
}
if (addFrameMapping) addFrameMapping(pLatch->pCopy, pLatch, 0, arg);
@ -718,8 +685,8 @@ void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec
Abc_Obj_t * pConst1, * pConst1New;
int i;
// get the constant nodes
pConst1 = Abc_AigConst1( pNtk->pManFunc );
pConst1New = Abc_AigConst1( pNtkFrames->pManFunc );
pConst1 = Abc_NtkConst1( pNtk );
pConst1New = Abc_NtkConst1( pNtkFrames );
// create the prefix to be added to the node names
sprintf( Buffer, "_%02d", iFrame );
// add the new PI nodes

View File

@ -25,7 +25,7 @@
////////////////////////////////////////////////////////////////////////
static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 );
static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node );
static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode );
@ -149,11 +149,9 @@ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
ProgressBar * pProgress;
DdManager * dd = pNtk->pManFunc;
Abc_Obj_t * pNode, * pNodeNew, * pConst1;
Abc_Obj_t * pNode, * pNodeNew;
Vec_Ptr_t * vNodes;
int i;
// create the constant one node
pConst1 = Abc_NodeCreateConst1( pNtkNew );
// perform conversion in the topological order
vNodes = Abc_NtkDfs( pNtk, 0 );
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
@ -162,7 +160,7 @@ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
Extra_ProgressBarUpdate( pProgress, i, NULL );
// convert one node
assert( Abc_ObjIsNode(pNode) );
pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew, pConst1 );
pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew );
// mark the old node with the new one
assert( pNode->pCopy == NULL );
pNode->pCopy = pNodeNew;
@ -182,7 +180,7 @@ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 )
Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew )
{
DdManager * dd = pNodeOld->pNtk->pManFunc;
DdNode * bFunc = pNodeOld->pData;
@ -192,7 +190,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_O
// create the table mapping BDD nodes into the ABC nodes
tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash );
// add the constant and the elementary vars
st_insert( tBdd2Node, (char *)b1, (char *)pConst1 );
st_insert( tBdd2Node, (char *)b1, (char *)Abc_NtkConst1(pNtkNew) );
Abc_ObjForEachFanin( pNodeOld, pFaninOld, i )
st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy );
// create the new nodes recursively
@ -266,7 +264,7 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly )
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)dd->vars[i];
// assign the constant node BDD
pNode = Abc_AigConst1( pNtk->pManFunc );
pNode = Abc_NtkConst1( pNtk );
pNode->pCopy = (Abc_Obj_t *)dd->one; Cudd_Ref( dd->one );
// collect the global functions of the COs

View File

@ -112,10 +112,6 @@ Abc_Ntk_t * Abc_NtkFromPga( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodeCuts )
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
dd = pNtkNew->pManFunc;
// set the constant node
pNode = Abc_AigConst1(pNtk->pManFunc);
if ( Abc_ObjFanoutNum(pNode) > 0 )
pNode->pCopy = Abc_NodeCreateConst1(pNtkNew);
// add new nodes in topologic order
vLeaves = Vec_PtrAlloc( 6 );
vVisited = Vec_PtrAlloc( 100 );

View File

@ -20,7 +20,7 @@
#include "abc.h"
#include "dec.h"
#include "abcs.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -51,7 +51,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
if ( !Abc_NtkIsSeq(pNtk) )
fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
else
fprintf( pFile, " lat = %4d(%d)", Abc_NtkSeqLatchNum(pNtk), Abc_NtkSeqLatchNumShared(pNtk) );
fprintf( pFile, " lat = %4d(%d,%d)", Seq_NtkLatchNum(pNtk), Seq_NtkLatchNumShared(pNtk), Seq_NtkLatchNumMax(pNtk) );
if ( Abc_NtkIsNetlist(pNtk) )
{
@ -150,7 +150,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
assert( !Abc_NtkIsNetlist(pNtk) );
if ( Abc_NtkIsSeq(pNtk) )
{
Abc_NtkSeqLatchGetInitNums( pNtk, InitNums );
Seq_NtkLatchGetInitNums( pNtk, InitNums );
fprintf( pFile, "%-15s: ", pNtk->pName );
fprintf( pFile, "Latch = %6d. No = %4d. Zero = %4d. One = %4d. DC = %4d.\n",
Abc_NtkLatchNum(pNtk), InitNums[0], InitNums[1], InitNums[2], InitNums[3] );

View File

@ -144,7 +144,6 @@ pManRef->timeTotal = clock() - clkStart;
Abc_NtkManRefStop( pManRef );
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
Abc_AigRehash( pNtk->pManFunc );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
// fix the levels
if ( fUpdateLevel )

View File

@ -121,7 +121,7 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
int i;
// set the constant node
pConst1 = Abc_AigConst1(pNtk->pManFunc);
pConst1 = Abc_NtkConst1(pNtk);
if ( Abc_ObjFanoutNum(pConst1) > 0 )
{
pNodeNew = Abc_NtkCreateNode( pNtkNew );

View File

@ -115,7 +115,6 @@ Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart );
pNtk->pManCut = NULL;
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
Abc_AigRehash( pNtk->pManFunc );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
// fix the levels
if ( fUpdateLevel )

View File

@ -28,8 +28,8 @@
// static functions
static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes );
static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop );
extern char * Mio_GateReadSop( void * pGate );
@ -55,6 +55,7 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
int nNodes;
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk);
// print warning about choice nodes
@ -62,13 +63,15 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
// perform strashing
pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = NULL;
Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes );
Abc_NtkFinalize( pNtk, pNtkAig );
// print warning about self-feed latches
if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
printf( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
printf( "Cleanup has removed %d nodes.\n", nNodes );
printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
// duplicate EXDC
if ( pNtk->pExdc )
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
@ -139,7 +142,6 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes )
{
ProgressBar * pProgress;
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pObj;
int i;
@ -153,7 +155,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes
// get the node
assert( Abc_ObjIsNode(pNode) );
// strash the node
pNodeNew = Abc_NodeStrash( pMan, pNode );
pNodeNew = Abc_NodeStrash( pNtkNew, pNode );
// get the old object
pObj = Abc_ObjFanout0Ntk( pNode );
// make sure the node is not yet strashed
@ -176,7 +178,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
{
int fUseFactor = 1;
char * pSop;
@ -187,8 +189,8 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
if ( Abc_NtkIsStrash(pNode->pNtk) )
{
if ( Abc_NodeIsConst(pNode) )
return Abc_AigConst1(pMan);
return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
return Abc_NtkConst1(pNtkNew);
return Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}
// get the SOP of the node
@ -199,12 +201,12 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
// consider the constant node
if ( Abc_NodeIsConst(pNode) )
return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) );
return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pSop) );
// decide when to use factoring
if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
return Abc_NodeStrashFactor( pMan, pNode, pSop );
return Abc_NodeStrashSop( pMan, pNode, pSop );
return Abc_NodeStrashFactor( pNtkNew, pNode, pSop );
return Abc_NodeStrashSop( pNtkNew, pNode, pSop );
}
/**Function*************************************************************
@ -218,10 +220,10 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop )
Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop )
{
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Abc_Obj_t * pFanin, * pAnd, * pSum;
Abc_Obj_t * pConst1 = Abc_AigConst1(pMan);
char * pCube;
int i, nFanins;
@ -229,11 +231,11 @@ Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop
nFanins = Abc_ObjFaninNum( pNode );
assert( nFanins == Abc_SopGetVarNum(pSop) );
// go through the cubes of the node's SOP
pSum = Abc_ObjNot(pConst1);
pSum = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
Abc_SopForEachCube( pSop, nFanins, pCube )
{
// create the AND of literals
pAnd = pConst1;
pAnd = Abc_NtkConst1(pNtkNew);
Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
{
if ( pCube[i] == '1' )
@ -261,7 +263,7 @@ Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop )
Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char * pSop )
{
Dec_Graph_t * pFForm;
Dec_Node_t * pNode;
@ -273,7 +275,7 @@ Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pS
Dec_GraphForEachLeaf( pFForm, pNode, i )
pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy;
// perform strashing
pAnd = Dec_GraphToNetwork( pMan, pFForm );
pAnd = Dec_GraphToNetwork( pNtkNew, pFForm );
Dec_GraphFree( pFForm );
return pAnd;
}

View File

@ -459,7 +459,7 @@ int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
Vec_PtrFree( vNodes );
// if it is an AIG, also mark the constant 1 node
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigConst1(pNtk->pManFunc)->fMarkA = 1;
Abc_NtkConst1(pNtk)->fMarkA = 1;
// remove the non-marked nodes
Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )

View File

@ -526,7 +526,7 @@ Abc_Ntk_t * Abc_NtkVanEijkFrames( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCorresp, int nF
pNtkFrames->pName = util_strsav(Buffer);
}
// map the constant nodes
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkFrames->pManFunc);
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames);
// create new latches and remember them in the new latches
Abc_NtkForEachLatch( pNtk, pLatch, i )
Abc_NtkDupObj( pNtkFrames, pLatch );
@ -591,7 +591,7 @@ void Abc_NtkVanEijkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFram
// remember the CI mapping
if ( vCorresp )
{
pNode = Abc_AigConst1(pNtk->pManFunc);
pNode = Abc_NtkConst1(pNtk);
Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) );
Abc_NtkForEachCi( pNtk, pNode, i )
Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) );
@ -669,7 +669,7 @@ Fraig_Man_t * Abc_NtkVanEijkFraig( Abc_Ntk_t * pMulti, int fInit )
// clean the copy fields in the old network
Abc_NtkCleanCopy( pMulti );
// map the constant nodes
Abc_AigConst1(pMulti->pManFunc)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
Abc_NtkConst1(pMulti)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
if ( fInit )
{
// map the PI nodes
@ -726,14 +726,14 @@ Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses )
pNtkNew->pSpec = NULL;
// map the constant nodes
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc);
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// for each CI, create PI
Abc_NtkForEachCi( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj) );
// cannot add latches here because pLatch->pCopy pointers are used
// create the cones for each pair of nodes in an equivalence class
pTotal = Abc_ObjNot( Abc_AigConst1(pNtkNew->pManFunc) );
pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
Vec_PtrForEachEntry( vClasses, pClass, i )
{
assert( pClass->pNext );

View File

@ -487,7 +487,7 @@ printf( "PO = %d\n", pNode1->Id );
// go through the pairs of signals in the frames
pProgress = Extra_ProgressBarStart( stdout, p->nIdMax );
pConst1 = Abc_AigConst1( p->pNtkSingle->pManFunc );
pConst1 = Abc_NtkConst1( p->pNtkSingle );
p->vImps = Vec_IntAlloc( 100 );
p->vZeros = Vec_PtrAlloc( 100 );
Abc_NtkForEachObj( p->pNtkSingle, pNode1, i )
@ -882,14 +882,14 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I
pNtkNew->pSpec = NULL;
// map the constant nodes
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc);
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// for each CI, create PI
Abc_NtkForEachCi( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj) );
// cannot add latches here because pLatch->pCopy pointers are used
// build logic cone for zero nodes
pTotal = Abc_ObjNot( Abc_AigConst1(pNtkNew->pManFunc) );
pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
Vec_PtrForEachEntry( vZeros, pNode, i )
{
// build the logic cone for the node

View File

@ -1,327 +0,0 @@
/**CFile****************************************************************
FileName [abcFpgaDelay.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Utilities working sequential AIGs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcFpgaDelay.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
#include "cut.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// the internal procedures
static int Abc_NtkFpgaRetimeSearch_rec( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
static int Abc_NtkFpgaRetimeForPeriod( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int Fi, int fVerbose );
static int Abc_NodeFpgaUpdateLValue( Seq_FpgaMan_t * p, Abc_Obj_t * pObj, int Fi );
static void Abc_NtkFpgaCollect( Seq_FpgaMan_t * p );
// node status after updating its arrival time
enum { ABC_FPGA_UPDATE_FAIL, ABC_FPGA_UPDATE_NO, ABC_FPGA_UPDATE_YES };
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Retimes AIG for optimal delay.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFpgaSeqRetimeDelayLags( Seq_FpgaMan_t * p )
{
Abc_Ntk_t * pNtk = p->pNtk;
int fVerbose = p->fVerbose;
Abc_Obj_t * pNode;
int i, FiMax, FiBest, RetValue;
// start storage for sequential arrival times
assert( pNtk->pData == NULL );
pNtk->pData = p->vArrivals;
// get the upper bound on the clock period
// FiMax = Abc_NtkNodeNum(pNtk);
FiMax = 0;
Abc_AigForEachAnd( pNtk, pNode, i )
if ( FiMax < (int)pNode->Level )
FiMax = pNode->Level;
FiMax += 2;
// make sure this clock period is feasible
assert( Abc_NtkFpgaRetimeForPeriod( p, pNtk, FiMax, fVerbose ) );
// search for the optimal clock period between 0 and nLevelMax
FiBest = Abc_NtkFpgaRetimeSearch_rec( p, pNtk, 0, FiMax, fVerbose );
// recompute the best LValues
RetValue = Abc_NtkFpgaRetimeForPeriod( p, pNtk, FiBest, fVerbose );
assert( RetValue );
// print the result
if ( fVerbose )
printf( "The best clock period is %3d.\n", FiBest );
// convert to lags
Abc_AigForEachAnd( pNtk, pNode, i )
Vec_StrWriteEntry( p->vLagsMap, i, (char)Abc_NodeGetLag(Abc_NodeReadLValue(pNode), FiBest) );
/*
printf( "LValues : " );
Abc_AigForEachAnd( pNtk, pNode, i )
printf( "%d=%d ", i, Abc_NodeReadLValue(pNode) );
printf( "\n" );
printf( "Lags : " );
Abc_AigForEachAnd( pNtk, pNode, i )
if ( Vec_StrEntry(vLags,i) != 0 )
printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(vLags,i), Abc_NodeReadLValue(pNode), Abc_NodeReadLValue(pNode) - FiBest * Vec_StrEntry(vLags,i) );
printf( "\n" );
*/
Abc_NtkFpgaCollect( p );
pNtk->pData = NULL;
Cut_ManStop( p->pMan );
p->pMan = NULL;
}
/**Function*************************************************************
Synopsis [Performs binary search for the optimal clock period.]
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkFpgaRetimeSearch_rec( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose )
{
int Median;
assert( FiMin < FiMax );
if ( FiMin + 1 == FiMax )
return FiMax;
Median = FiMin + (FiMax - FiMin)/2;
if ( Abc_NtkFpgaRetimeForPeriod( p, pNtk, Median, fVerbose ) )
return Abc_NtkFpgaRetimeSearch_rec( p, pNtk, FiMin, Median, fVerbose ); // Median is feasible
else
return Abc_NtkFpgaRetimeSearch_rec( p, pNtk, Median, FiMax, fVerbose ); // Median is infeasible
}
/**Function*************************************************************
Synopsis [Returns 1 if retiming with this clock period is feasible.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkFpgaRetimeForPeriod( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int Fi, int fVerbose )
{
Abc_Obj_t * pObj;
int i, c, RetValue, fChange, Counter;
char * pReason = "";
// set l-values of all nodes to be minus infinity
Vec_IntFill( p->vArrivals, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY );
Vec_PtrFill( p->vBestCuts, Abc_NtkObjNumMax(pNtk), NULL );
// set l-values for the constant and PIs
pObj = Abc_NtkObj( pNtk, 0 );
Abc_NodeSetLValue( pObj, 0 );
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NodeSetLValue( pObj, 0 );
// update all values iteratively
Counter = 0;
for ( c = 0; c < 20; c++ )
{
fChange = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjIsPi(pObj) )
continue;
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
RetValue = Abc_NodeFpgaUpdateLValue( p, pObj, Fi );
Counter++;
if ( RetValue == ABC_FPGA_UPDATE_FAIL )
break;
if ( RetValue == ABC_FPGA_UPDATE_NO )
continue;
fChange = 1;
}
if ( RetValue == ABC_FPGA_UPDATE_FAIL )
break;
if ( fChange == 0 )
break;
}
if ( c == 20 )
{
RetValue = ABC_FPGA_UPDATE_FAIL;
pReason = "(timeout)";
}
// report the results
if ( fVerbose )
{
if ( RetValue == ABC_FPGA_UPDATE_FAIL )
printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason );
else
printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter );
}
return RetValue != ABC_FPGA_UPDATE_FAIL;
}
/**Function*************************************************************
Synopsis [Computes the l-value of the node.]
Description [The node can be internal or a PO.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeFpgaUpdateLValue( Seq_FpgaMan_t * p, Abc_Obj_t * pObj, int Fi )
{
Abc_Obj_t * pFanin;
Cut_Cut_t * pList, * pCut, * pCutBest;
int lValueNew, lValueOld, lValueCur, lValueFan;
int i;
assert( !Abc_ObjIsPi(pObj) );
assert( Abc_ObjFaninNum(pObj) > 0 );
if ( Abc_ObjIsPo(pObj) )
{
lValueOld = Abc_NodeReadLValue(Abc_ObjFanin0(pObj));
lValueNew = lValueOld - Fi * Abc_ObjFaninL0(pObj);
return (lValueNew > Fi)? ABC_FPGA_UPDATE_FAIL : ABC_FPGA_UPDATE_NO;
}
pCutBest = NULL;
lValueNew = ABC_INFINITY;
pList = Abc_NodeReadCuts( p->pMan, pObj );
for ( pCut = pList; pCut; pCut = pCut->pNext )
{
if ( pCut->nLeaves < 2 )
continue;
lValueCur = -ABC_INFINITY;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
{
pFanin = Abc_NtkObj( pObj->pNtk, (pCut->pLeaves[i] >> CUT_SHIFT) );
lValueFan = Abc_NodeReadLValue(pFanin) - Fi * (pCut->pLeaves[i] & CUT_MASK);
lValueCur = ABC_MAX( lValueCur, lValueFan );
}
lValueCur += 1;
lValueNew = ABC_MIN( lValueNew, lValueCur );
if ( lValueNew == lValueCur )
pCutBest = pCut;
}
lValueOld = Abc_NodeReadLValue(pObj);
// if ( lValueNew == lValueOld )
if ( lValueNew <= lValueOld )
return ABC_FPGA_UPDATE_NO;
Abc_NodeSetLValue( pObj, lValueNew );
Vec_PtrWriteEntry( p->vBestCuts, pObj->Id, pCutBest );
return ABC_FPGA_UPDATE_YES;
}
/**Function*************************************************************
Synopsis [Select nodes visible in the mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeFpgaCollect_rec( Seq_FpgaMan_t * p, Abc_Obj_t * pNode )
{
Cut_Cut_t * pCutBest;
Abc_Obj_t * pFanin;
Vec_Int_t * vLeaves;
int i;
// skip the CI
if ( Abc_ObjIsCi(pNode) )
return;
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// get the best cut of the node
pCutBest = Vec_PtrEntry( p->vBestCuts, pNode->Id );
for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
{
pFanin = Abc_NtkObj( pNode->pNtk, (pCutBest->pLeaves[i] >> CUT_SHIFT) );
Abc_NodeFpgaCollect_rec( p, pFanin );
}
// collect the node and its cut
vLeaves = Vec_IntAlloc( pCutBest->nLeaves );
for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
Vec_IntPush( vLeaves, pCutBest->pLeaves[i] );
Vec_PtrPush( p->vMapCuts, vLeaves );
Vec_PtrPush( p->vMapping, pNode );
}
/**Function*************************************************************
Synopsis [Select nodes visible in the mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFpgaCollect( Seq_FpgaMan_t * p )
{
Abc_Ntk_t * pNtk = p->pNtk;
Abc_Obj_t * pObj;
int i;
Vec_PtrClear( p->vMapping );
Vec_PtrClear( p->vMapCuts );
Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NodeFpgaCollect_rec( p, Abc_ObjFanin0(pObj) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,201 +0,0 @@
/**CFile****************************************************************
FileName [abcFpgaSeq.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Mapping for FPGAs using sequential cuts.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcFpgaSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
Abc_Ntk_t * Abc_NtkMapSeq( Abc_Ntk_t * pNtk, int fVerbose ) { return 0; }
extern Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams );
extern void Abc_NtkFpgaSeqRetimeDelayLags( Seq_FpgaMan_t * p );
static Seq_FpgaMan_t * Abc_NtkFpgaSeqStart( Abc_Ntk_t * pNtk, int fVerbose );
static void Abc_NtkFpgaSeqStop( Seq_FpgaMan_t * p );
static Abc_Ntk_t * Abc_NtkFpgaSeqConstruct( Seq_FpgaMan_t * p );
static void Abc_NtkFpgaSeqRetime( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtkNew );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Retimes AIG for optimal delay.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFpgaSeq( Abc_Ntk_t * pNtk, int fVerbose )
{
Abc_Ntk_t * pNtkNew;
Seq_FpgaMan_t * p;
Cut_Params_t Params, * pParams = &Params;
int clk;
assert( Abc_NtkIsSeq( pNtk ) );
// get the sequential FPGA manager
p = Abc_NtkFpgaSeqStart( pNtk, fVerbose );
// create the cuts
memset( pParams, 0, sizeof(Cut_Params_t) );
pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts)
pParams->nKeepMax = 1000; // the max number of cuts kept at a node
pParams->fTruth = 0; // compute truth tables
pParams->fFilter = 1; // filter dominated cuts
pParams->fSeq = 1; // compute sequential cuts
pParams->fVerbose = 0; // the verbosiness flag
clk = clock();
p->pMan = Abc_NtkSeqCuts( pNtk, pParams );
p->timeCuts += clock() - clk;
// find best arrival times (p->vArrivals) and free the cuts
// select mapping (p->vMapping) and remember best cuts (p->vMapCuts)
clk = clock();
Abc_NtkFpgaSeqRetimeDelayLags( p );
p->timeDelay += clock() - clk;
return NULL;
// construct the network
clk = clock();
pNtkNew = Abc_NtkFpgaSeqConstruct( p );
p->timeNtk += clock() - clk;
// retime the network
clk = clock();
Abc_NtkFpgaSeqRetime( p, pNtkNew );
p->timeRet += clock() - clk;
// remove temporaries
Abc_NtkFpgaSeqStop( p );
// check the resulting network
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkFpgaSeq(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Starts sequential FPGA mapper.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Seq_FpgaMan_t * Abc_NtkFpgaSeqStart( Abc_Ntk_t * pNtk, int fVerbose )
{
Seq_FpgaMan_t * p;
// create the FPGA mapping manager
p = ALLOC( Seq_FpgaMan_t, 1 );
memset( p, 0, sizeof(Seq_FpgaMan_t) );
p->pNtk = pNtk;
p->pMan = NULL;
p->vArrivals = Vec_IntAlloc( 0 );
p->vBestCuts = Vec_PtrAlloc( 0 );
p->vMapping = Vec_PtrAlloc( 0 );
p->vMapCuts = Vec_PtrAlloc( 0 );
p->vLagsMap = Vec_StrStart( Abc_NtkObjNumMax(pNtk) );
p->fVerbose = fVerbose;
return p;
}
/**Function*************************************************************
Synopsis [Stops sequential FPGA mapper.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFpgaSeqStop( Seq_FpgaMan_t * p )
{
if ( p->fVerbose )
{
printf( "Sequential FPGA mapping stats:\n" );
// printf( "Total allocated = %8d.\n", p->nCutsAlloc );
// printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes );
PRT( "Cuts ", p->timeCuts );
PRT( "Arrival", p->timeDelay );
PRT( "Network", p->timeNtk );
PRT( "Retime ", p->timeRet );
}
Vec_IntFree( p->vArrivals );
Vec_PtrFree( p->vBestCuts );
Vec_PtrFree( p->vMapping );
Vec_VecFree( (Vec_Vec_t *)p->vMapCuts );
Vec_StrFree( p->vLagsMap );
free( p );
}
/**Function*************************************************************
Synopsis [Construct the final network after mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFpgaSeqConstruct( Seq_FpgaMan_t * p )
{
Abc_Ntk_t * pNtk = NULL;
return pNtk;
}
/**Function*************************************************************
Synopsis [Retimes the final network after mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFpgaSeqRetime( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtkNew )
{
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,145 +0,0 @@
/**CFile****************************************************************
FileName [abcForBack.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Simple forward/backward retiming procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcForBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*
Retiming can be represented in three equivalent forms:
- as a set of integer lags for each node (array of chars by node ID)
- as a set of node numbers with lag for each, fwd and bwd (two arrays of Abc_RetStep_t_)
- as a set of node moves, fwd and bwd (two arrays arrays of Abc_Obj_t *)
*/
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs most forward retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fVerbose )
{
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i;
// get the forward moves
vMoves = Abc_NtkUtilRetimingTry( pNtk, 1 );
// undo the forward moves
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeBackwardTry( pNode, 1 );
// implement this forward retiming
Abc_NtkImplementRetimingForward( pNtk, vMoves );
Vec_PtrFree( vMoves );
}
/**Function*************************************************************
Synopsis [Performs most backward retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose )
{
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i, RetValue;
// get the backward moves
vMoves = Abc_NtkUtilRetimingTry( pNtk, 0 );
// undo the backward moves
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeForwardTry( pNode, 1 );
// implement this backward retiming
RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose );
Vec_PtrFree( vMoves );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
/**Function*************************************************************
Synopsis [Performs performs optimal delay retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fVerbose )
{
Vec_Str_t * vLags;
int RetValue;
// get the retiming vector
vLags = Abc_NtkSeqRetimeDelayLags( pNtk, fVerbose );
// implement this retiming
RetValue = Abc_NtkImplementRetiming( pNtk, vLags, fVerbose );
Vec_StrFree( vLags );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
/**Function*************************************************************
Synopsis [Performs retiming for initial state computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk, int fVerbose )
{
Vec_Str_t * vLags;
int RetValue;
// get the retiming vector
vLags = Abc_NtkSeqRetimeDelayLags( pNtk, fVerbose );
// implement this retiming
RetValue = Abc_NtkImplementRetiming( pNtk, vLags, fVerbose );
Vec_StrFree( vLags );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,504 +0,0 @@
/**CFile****************************************************************
FileName [abcSeqRetime.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Peforms retiming for optimal clock cycle.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcSeqRetime.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// the internal procedures
static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose );
static int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
// node status after updating its arrival time
enum { ABC_UPDATE_FAIL, ABC_UPDATE_NO, ABC_UPDATE_YES };
static void Abc_RetimingExperiment( Abc_Ntk_t * pNtk, Vec_Str_t * vLags );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Retimes AIG for optimal delay.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose )
{
Vec_Str_t * vLags;
Abc_Obj_t * pNode;
int i, FiMax, FiBest, RetValue;
assert( Abc_NtkIsSeq( pNtk ) );
// start storage for sequential arrival times
assert( pNtk->pData == NULL );
pNtk->pData = Vec_IntAlloc( 0 );
// get the upper bound on the clock period
// FiMax = Abc_NtkNodeNum(pNtk);
FiMax = 0;
Abc_AigForEachAnd( pNtk, pNode, i )
if ( FiMax < (int)pNode->Level )
FiMax = pNode->Level;
FiMax += 2;
// make sure this clock period is feasible
assert( Abc_NtkRetimeForPeriod( pNtk, FiMax, fVerbose ) );
// search for the optimal clock period between 0 and nLevelMax
FiBest = Abc_NtkRetimeSearch_rec( pNtk, 0, FiMax, fVerbose );
// recompute the best LValues
RetValue = Abc_NtkRetimeForPeriod( pNtk, FiBest, fVerbose );
assert( RetValue );
// print the result
if ( fVerbose )
printf( "The best clock period is %3d.\n", FiBest );
// convert to lags
vLags = Vec_StrStart( Abc_NtkObjNumMax(pNtk) );
Abc_AigForEachAnd( pNtk, pNode, i )
Vec_StrWriteEntry( vLags, i, (char)Abc_NodeGetLag(Abc_NodeReadLValue(pNode), FiBest) );
/*
printf( "LValues : " );
Abc_AigForEachAnd( pNtk, pNode, i )
printf( "%d=%d ", i, Abc_NodeReadLValue(pNode) );
printf( "\n" );
printf( "Lags : " );
Abc_AigForEachAnd( pNtk, pNode, i )
if ( Vec_StrEntry(vLags,i) != 0 )
printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(vLags,i), Abc_NodeReadLValue(pNode), Abc_NodeReadLValue(pNode) - FiBest * Vec_StrEntry(vLags,i) );
printf( "\n" );
*/
// free storage
Vec_IntFree( pNtk->pData );
pNtk->pData = NULL;
return vLags;
}
/**Function*************************************************************
Synopsis [Performs binary search for the optimal clock period.]
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose )
{
int Median;
assert( FiMin < FiMax );
if ( FiMin + 1 == FiMax )
return FiMax;
Median = FiMin + (FiMax - FiMin)/2;
if ( Abc_NtkRetimeForPeriod( pNtk, Median, fVerbose ) )
return Abc_NtkRetimeSearch_rec( pNtk, FiMin, Median, fVerbose ); // Median is feasible
else
return Abc_NtkRetimeSearch_rec( pNtk, Median, FiMax, fVerbose ); // Median is infeasible
}
/**Function*************************************************************
Synopsis [Returns 1 if retiming with this clock period is feasible.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeForPeriod2( Abc_Ntk_t * pNtk, int Fi )
{
Vec_Ptr_t * vFrontier;
Abc_Obj_t * pObj, * pFanout;
char * pReason = "";
int RetValue, i, k;
int Limit;
// set l-values of all nodes to be minus infinity
Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY );
// start the frontier by setting PI l-values to 0 and including PI fanouts
vFrontier = Vec_PtrAlloc( 100 );
pObj = Abc_NtkObj( pNtk, 0 );
if ( Abc_ObjFanoutNum(pObj) > 0 )
{
Abc_NodeSetLValue( pObj, 0 );
Abc_ObjForEachFanout( pObj, pFanout, k )
if ( pFanout->fMarkA == 0 )
{
Vec_PtrPush( vFrontier, pFanout );
pFanout->fMarkA = 1;
}
}
Abc_NtkForEachPi( pNtk, pObj, i )
{
Abc_NodeSetLValue( pObj, 0 );
Abc_ObjForEachFanout( pObj, pFanout, k )
if ( pFanout->fMarkA == 0 )
{
Vec_PtrPush( vFrontier, pFanout );
pFanout->fMarkA = 1;
}
}
// iterate until convergence
Limit = Abc_NtkObjNumMax(pNtk) * 20;
Vec_PtrForEachEntry( vFrontier, pObj, i )
{
pObj->fMarkA = 0;
RetValue = Abc_NodeUpdateLValue( pObj, Fi );
if ( RetValue == ABC_UPDATE_FAIL )
break;
if ( i == Limit )
{
RetValue = ABC_UPDATE_FAIL;
pReason = "(timeout)";
break;
}
if ( RetValue == ABC_UPDATE_NO )
continue;
assert( RetValue == ABC_UPDATE_YES );
// arrival times have changed - add fanouts to the frontier
Abc_ObjForEachFanout( pObj, pFanout, k )
if ( pFanout->fMarkA == 0 && pFanout != pObj )
{
Vec_PtrPush( vFrontier, pFanout );
pFanout->fMarkA = 1;
}
}
// clean the nodes
Vec_PtrForEachEntryStart( vFrontier, pObj, k, i )
pObj->fMarkA = 0;
// report the results
if ( RetValue == ABC_UPDATE_FAIL )
printf( "Period = %3d. Updated nodes = %6d. Infeasible %s\n", Fi, vFrontier->nSize, pReason );
else
printf( "Period = %3d. Updated nodes = %6d. Feasible\n", Fi, vFrontier->nSize );
Vec_PtrFree( vFrontier );
return RetValue != ABC_UPDATE_FAIL;
}
/**Function*************************************************************
Synopsis [Returns 1 if retiming with this clock period is feasible.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
{
Abc_Obj_t * pObj;
int i, c, RetValue, fChange, Counter;
char * pReason = "";
// set l-values of all nodes to be minus infinity
Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY );
// set l-values for the constant and PIs
pObj = Abc_NtkObj( pNtk, 0 );
Abc_NodeSetLValue( pObj, 0 );
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NodeSetLValue( pObj, 0 );
// update all values iteratively
Counter = 0;
for ( c = 0; c < 20; c++ )
{
fChange = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjIsPi(pObj) )
continue;
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
RetValue = Abc_NodeUpdateLValue( pObj, Fi );
Counter++;
if ( RetValue == ABC_UPDATE_FAIL )
break;
if ( RetValue == ABC_UPDATE_NO )
continue;
fChange = 1;
}
if ( RetValue == ABC_UPDATE_FAIL )
break;
if ( fChange == 0 )
break;
}
if ( c == 20 )
{
RetValue = ABC_UPDATE_FAIL;
pReason = "(timeout)";
}
// report the results
if ( fVerbose )
{
if ( RetValue == ABC_UPDATE_FAIL )
printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason );
else
printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter );
}
return RetValue != ABC_UPDATE_FAIL;
}
/**Function*************************************************************
Synopsis [Computes the l-value of the node.]
Description [The node can be internal or a PO.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
{
int lValueNew, lValueOld, lValue0, lValue1;
assert( !Abc_ObjIsPi(pObj) );
assert( Abc_ObjFaninNum(pObj) > 0 );
lValue0 = Abc_NodeReadLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj);
if ( Abc_ObjIsPo(pObj) )
return (lValue0 > Fi)? ABC_UPDATE_FAIL : ABC_UPDATE_NO;
if ( Abc_ObjFaninNum(pObj) == 2 )
lValue1 = Abc_NodeReadLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj);
else
lValue1 = -ABC_INFINITY;
lValueNew = 1 + ABC_MAX( lValue0, lValue1 );
lValueOld = Abc_NodeReadLValue(pObj);
// if ( lValueNew == lValueOld )
if ( lValueNew <= lValueOld )
return ABC_UPDATE_NO;
Abc_NodeSetLValue( pObj, lValueNew );
return ABC_UPDATE_YES;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_RetimingPrint_rec( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanin0, * pFanin1;
int Depth0, Depth1;
if ( Abc_ObjIsPi(pObj) )
{
printf( "%d -> ", pObj->Id );
return 0;
}
pFanin0 = Abc_ObjFanin0(pObj);
pFanin1 = Abc_ObjFanin1(pObj);
if ( Abc_ObjFaninL0(pObj) == 0 && Abc_ObjFaninL1(pObj) > 0 )
Abc_RetimingPrint_rec( pFanin0 );
else if ( Abc_ObjFaninL1(pObj) == 0 && Abc_ObjFaninL0(pObj) > 0 )
Abc_RetimingPrint_rec( pFanin1 );
else if ( Abc_ObjFaninL0(pObj) == 0 && Abc_ObjFaninL1(pObj) == 0 )
{
Depth0 = (int)pFanin0->pCopy;
Depth1 = (int)pFanin1->pCopy;
if ( Depth0 > Depth1 )
Abc_RetimingPrint_rec( pFanin0 );
else
Abc_RetimingPrint_rec( pFanin1 );
}
printf( "%d (%d) -> ", pObj->Id, (int)pObj->pCopy );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_Retiming_rec( Abc_Obj_t * pObj )
{
int Depth0, Depth1, Depth;
if ( Abc_ObjIsPi(pObj) )
{
pObj->pCopy = 0;
return 0;
}
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pObj ) )
return (int)pObj->pCopy;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pObj );
if ( Abc_ObjFaninL0(pObj) == 0 )
Depth0 = Abc_Retiming_rec( Abc_ObjFanin0(pObj) );
else
Depth0 = 0;
if ( Abc_ObjFaninL1(pObj) == 0 )
Depth1 = Abc_Retiming_rec( Abc_ObjFanin1(pObj) );
else
Depth1 = 0;
Depth = 1 + ABC_MAX( Depth0, Depth1 );
pObj->pCopy = (void *)Depth;
return Depth;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetiming( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Depth;
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjFaninNum(pObj) != 2 )
continue;
if ( Abc_ObjFaninL0(pObj) > 0 )
{
Abc_NtkIncrementTravId(pNtk);
Depth = Abc_Retiming_rec( Abc_ObjFanin0(pObj) );
if ( Depth > 30 )
{
printf( "Depth is %d. ", Depth );
Abc_RetimingPrint_rec( Abc_ObjFanin0(pObj) );
printf( "\n\n" );
}
}
if ( Abc_ObjFaninL1(pObj) > 0 )
{
Abc_NtkIncrementTravId(pNtk);
Depth = Abc_Retiming_rec( Abc_ObjFanin1(pObj) );
if ( Depth > 30 )
{
printf( "Depth is %d. ", Depth );
Abc_RetimingPrint_rec( Abc_ObjFanin1(pObj) );
printf( "\n\n" );
}
}
}
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_RetimingExperiment( Abc_Ntk_t * pNtk, Vec_Str_t * vLags )
{
Abc_Obj_t * pObj;
char Lag;
int i;
Vec_StrForEachEntry( vLags, Lag, i )
{
if ( Lag == 0 )
continue;
pObj = Abc_NtkObj( pNtk, i );
if ( Lag < 0 )
Abc_ObjRetimeForwardTry( pObj, -Lag );
else
Abc_ObjRetimeBackwardTry( pObj, Lag );
}
// make sure there are no negative latches
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
assert( Abc_ObjFaninL0(pObj) >= 0 );
if ( Abc_ObjFaninNum(pObj) == 1 )
continue;
assert( Abc_ObjFaninL1(pObj) >= 0 );
// printf( "%d=(%d,%d) ", i, Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) );
}
// printf( "\n" );
Abc_NtkRetiming( pNtk );
Vec_StrForEachEntry( vLags, Lag, i )
{
if ( Lag == 0 )
continue;
pObj = Abc_NtkObj( pNtk, i );
if ( Lag < 0 )
Abc_ObjRetimeBackwardTry( pObj, -Lag );
else
Abc_ObjRetimeForwardTry( pObj, Lag );
}
// Abc_NtkSeqRetimeDelayLags( pNtk );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,450 +0,0 @@
/**CFile****************************************************************
FileName [abcRetImpl.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Implementation of retiming.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcRetImpl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Abc_ObjRetimeForward( Abc_Obj_t * pObj );
static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues );
static void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable );
static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Implements the retiming on the sequential AIG.]
Description [Split the retiming into forward and backward.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose )
{
Vec_Int_t * vSteps;
Vec_Ptr_t * vMoves;
int RetValue;
// forward retiming
vSteps = Abc_NtkUtilRetimingSplit( vLags, 1 );
// translate each set of steps into moves
if ( fVerbose )
printf( "The number of forward steps = %6d.\n", Vec_IntSize(vSteps) );
vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 1 );
if ( fVerbose )
printf( "The number of forward moves = %6d.\n", Vec_PtrSize(vMoves) );
// implement this retiming
Abc_NtkImplementRetimingForward( pNtk, vMoves );
Vec_IntFree( vSteps );
Vec_PtrFree( vMoves );
// backward retiming
vSteps = Abc_NtkUtilRetimingSplit( vLags, 0 );
// translate each set of steps into moves
if ( fVerbose )
printf( "The number of backward steps = %6d.\n", Vec_IntSize(vSteps) );
vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 0 );
if ( fVerbose )
printf( "The number of backward moves = %6d.\n", Vec_PtrSize(vMoves) );
// implement this retiming
RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose );
Vec_IntFree( vSteps );
Vec_PtrFree( vMoves );
return RetValue;
}
/**Function*************************************************************
Synopsis [Implements the given retiming on the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves )
{
Abc_Obj_t * pNode;
int i;
Vec_PtrForEachEntry( vMoves, pNode, i )
Abc_ObjRetimeForward( pNode );
}
/**Function*************************************************************
Synopsis [Retimes node forward by one latch.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeForward( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int Init0, Init1, Init, i;
assert( Abc_ObjFaninNum(pObj) == 2 );
assert( Abc_ObjFaninL0(pObj) >= 1 );
assert( Abc_ObjFaninL1(pObj) >= 1 );
// remove the init values from the fanins
Init0 = Abc_ObjFaninLDeleteFirst( pObj, 0 );
Init1 = Abc_ObjFaninLDeleteFirst( pObj, 1 );
assert( Init0 != ABC_INIT_NONE );
assert( Init1 != ABC_INIT_NONE );
// take into account the complements in the node
if ( Abc_ObjFaninC0(pObj) )
{
if ( Init0 == ABC_INIT_ZERO )
Init0 = ABC_INIT_ONE;
else if ( Init0 == ABC_INIT_ONE )
Init0 = ABC_INIT_ZERO;
}
if ( Abc_ObjFaninC1(pObj) )
{
if ( Init1 == ABC_INIT_ZERO )
Init1 = ABC_INIT_ONE;
else if ( Init1 == ABC_INIT_ONE )
Init1 = ABC_INIT_ZERO;
}
// compute the value at the output of the node
if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO )
Init = ABC_INIT_ZERO;
else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE )
Init = ABC_INIT_ONE;
else
Init = ABC_INIT_DC;
// add the init values to the fanouts
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_ObjFaninLInsertLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout), Init );
}
/**Function*************************************************************
Synopsis [Implements the given retiming on the sequential AIG.]
Description [Returns 0 of initial state computation fails.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose )
{
Abc_RetEdge_t RetEdge;
stmm_table * tTable;
stmm_generator * gen;
Vec_Int_t * vValues;
Abc_Ntk_t * pNtkProb, * pNtkMiter, * pNtkCnf;
Abc_Obj_t * pNode, * pNodeNew;
int * pModel, RetValue, i, clk;
// return if the retiming is trivial
if ( Vec_PtrSize(vMoves) == 0 )
return 1;
// create the network for the initial state computation
// start the table and the array of PO values
pNtkProb = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP );
tTable = stmm_init_table( stmm_numcmp, stmm_numhash );
vValues = Vec_IntAlloc( 100 );
// perform the backward moves and build the network for initial state computation
RetValue = 0;
Vec_PtrForEachEntry( vMoves, pNode, i )
RetValue |= Abc_ObjRetimeBackward( pNode, pNtkProb, tTable, vValues );
// add the PIs corresponding to the white spots
stmm_foreach_item( tTable, gen, (char **)&RetEdge, (char **)&pNodeNew )
Abc_ObjAddFanin( pNodeNew, Abc_NtkCreatePi(pNtkProb) );
// add the PI/PO names
Abc_NtkAddDummyPiNames( pNtkProb );
Abc_NtkAddDummyPoNames( pNtkProb );
// make sure everything is okay with the network structure
if ( !Abc_NtkDoCheck( pNtkProb ) )
{
printf( "Abc_NtkImplementRetimingBackward: The internal network check has failed.\n" );
Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL );
Abc_NtkDelete( pNtkProb );
stmm_free_table( tTable );
Vec_IntFree( vValues );
return 0;
}
// check if conflict is found
if ( RetValue )
{
printf( "Abc_NtkImplementRetimingBackward: A top level conflict is detected. DC latch values are used.\n" );
Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL );
Abc_NtkDelete( pNtkProb );
stmm_free_table( tTable );
Vec_IntFree( vValues );
return 0;
}
// get the miter cone
pNtkMiter = Abc_NtkCreateCone( pNtkProb, pNtkProb->vCos, vValues );
Abc_NtkDelete( pNtkProb );
Vec_IntFree( vValues );
if ( fVerbose )
printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) );
// transform the miter into a logic network for efficient CNF construction
pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 );
Abc_NtkDelete( pNtkMiter );
// solve the miter
clk = clock();
RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 );
if ( fVerbose )
if ( clock() - clk > 500 )
{
PRT( "SAT solving time", clock() - clk );
}
pModel = pNtkCnf->pModel; pNtkCnf->pModel = NULL;
Abc_NtkDelete( pNtkCnf );
// analyze the result
if ( RetValue == -1 || RetValue == 1 )
{
Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL );
if ( RetValue == 1 )
printf( "Abc_NtkImplementRetimingBackward: The problem is unsatisfiable. DC latch values are used.\n" );
else
printf( "Abc_NtkImplementRetimingBackward: The SAT problem timed out. DC latch values are used.\n" );
stmm_free_table( tTable );
return 0;
}
// set the values of the latches
Abc_NtkRetimeSetInitialValues( pNtk, tTable, pModel );
stmm_free_table( tTable );
free( pModel );
return 1;
}
/**Function*************************************************************
Synopsis [Retimes node backward by one latch.]
Description [Constructs the problem for initial state computation.
Returns 1 if the conflict is found.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues )
{
Abc_Obj_t * pFanout;
Abc_InitType_t Init, Value;
Abc_RetEdge_t RetEdge;
Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuffer;
int i, Edge, fMet0, fMet1, fMetN;
// make sure the node can be retimed
assert( Abc_ObjFanoutLMin(pObj) > 0 );
// get the fanout values
fMet0 = fMet1 = fMetN = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
Init = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout) );
if ( Init == ABC_INIT_ZERO )
fMet0 = 1;
else if ( Init == ABC_INIT_ONE )
fMet1 = 1;
else if ( Init == ABC_INIT_NONE )
fMetN = 1;
}
// consider the case when all fanout latchs have don't-care values
// the new values on the fanin edges will be don't-cares
if ( !fMet0 && !fMet1 && !fMetN )
{
// update the fanout edges
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_ObjFaninLDeleteLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout) );
// update the fanin edges
Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable );
Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable );
Abc_ObjFaninLInsertFirst( pObj, 0, ABC_INIT_DC );
Abc_ObjFaninLInsertFirst( pObj, 1, ABC_INIT_DC );
return 0;
}
// the initial values on the fanout edges contain 0, 1, or unknown
// the new values on the fanin edges will be unknown
// add new AND-gate to the network
pNodeNew = Abc_NtkCreateNode( pNtkNew );
pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
// add PO fanouts if any
if ( fMet0 )
{
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
Vec_IntPush( vValues, 0 );
}
if ( fMet1 )
{
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
Vec_IntPush( vValues, 1 );
}
// perform the changes
Abc_ObjForEachFanout( pObj, pFanout, i )
{
Edge = Abc_ObjEdgeNum( pObj, pFanout );
Value = Abc_ObjFaninLDeleteLast( pFanout, Edge );
if ( Value != ABC_INIT_NONE )
continue;
// value is unknown, remove it from the table
RetEdge.iNode = pFanout->Id;
RetEdge.iEdge = Edge;
RetEdge.iLatch = Abc_ObjFaninL( pFanout, Edge ); // after edge is removed
if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) )
assert( 0 );
// create the fanout of the AND gate
Abc_ObjAddFanin( pFanoutNew, pNodeNew );
}
// update the fanin edges
Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable );
Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable );
Abc_ObjFaninLInsertFirst( pObj, 0, ABC_INIT_NONE );
Abc_ObjFaninLInsertFirst( pObj, 1, ABC_INIT_NONE );
// add the buffer
pBuffer = Abc_NtkCreateNode( pNtkNew );
pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
Abc_ObjAddFanin( pNodeNew, pBuffer );
// point to it from the table
RetEdge.iNode = pObj->Id;
RetEdge.iEdge = 0;
RetEdge.iLatch = 0;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(RetEdge), (char *)pBuffer ) )
assert( 0 );
// add the buffer
pBuffer = Abc_NtkCreateNode( pNtkNew );
pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
Abc_ObjAddFanin( pNodeNew, pBuffer );
// point to it from the table
RetEdge.iNode = pObj->Id;
RetEdge.iEdge = 1;
RetEdge.iLatch = 0;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(RetEdge), (char *)pBuffer ) )
assert( 0 );
// report conflict is found
return fMet0 && fMet1;
}
/**Function*************************************************************
Synopsis [Generates the printable edge label with the initial state.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable )
{
Abc_Obj_t * pFanoutNew;
Abc_RetEdge_t RetEdge;
Abc_InitType_t Init;
int nLatches, i;
// get the number of latches on the edge
nLatches = Abc_ObjFaninL( pObj, Edge );
assert( nLatches <= ABC_MAX_EDGE_LATCH );
for ( i = nLatches - 1; i >= 0; i-- )
{
// get the value of this latch
Init = Abc_ObjFaninLGetInitOne( pObj, Edge, i );
if ( Init != ABC_INIT_NONE )
continue;
// get the retiming edge
RetEdge.iNode = pObj->Id;
RetEdge.iEdge = Edge;
RetEdge.iLatch = i;
// remove entry from table and add it with a different key
if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) )
assert( 0 );
RetEdge.iLatch++;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(RetEdge), (char *)pFanoutNew ) )
assert( 0 );
}
}
/**Function*************************************************************
Synopsis [Sets the initial values.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel )
{
Abc_Obj_t * pNode;
stmm_generator * gen;
Abc_RetEdge_t RetEdge;
Abc_InitType_t Init;
int i;
i = 0;
stmm_foreach_item( tTable, gen, (char **)&RetEdge, NULL )
{
pNode = Abc_NtkObj( pNtk, RetEdge.iNode );
Init = pModel? (pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC;
Abc_ObjFaninLSetInitOne( pNode, RetEdge.iEdge, RetEdge.iLatch, Init );
i++;
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,244 +0,0 @@
/**CFile****************************************************************
FileName [abcRetUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Retiming utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcRetUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs forward retiming of the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward )
{
Vec_Ptr_t * vNodes, * vMoves;
Abc_Obj_t * pNode, * pFanout, * pFanin;
int i, k, nLatches;
assert( Abc_NtkIsSeq( pNtk ) );
// assume that all nodes can be retimed
vNodes = Vec_PtrAlloc( 100 );
Abc_AigForEachAnd( pNtk, pNode, i )
{
Vec_PtrPush( vNodes, pNode );
pNode->fMarkA = 1;
}
// process the nodes
vMoves = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) );
// unmark the node as processed
pNode->fMarkA = 0;
// get the number of latches to retime
if ( fForward )
nLatches = Abc_ObjFaninLMin(pNode);
else
nLatches = Abc_ObjFanoutLMin(pNode);
if ( nLatches == 0 )
continue;
assert( nLatches > 0 );
// retime the latches forward
if ( fForward )
Abc_ObjRetimeForwardTry( pNode, nLatches );
else
Abc_ObjRetimeBackwardTry( pNode, nLatches );
// write the moves
for ( k = 0; k < nLatches; k++ )
Vec_PtrPush( vMoves, pNode );
// schedule fanouts for updating
if ( fForward )
{
Abc_ObjForEachFanout( pNode, pFanout, k )
{
if ( Abc_ObjFaninNum(pFanout) != 2 || pFanout->fMarkA )
continue;
pFanout->fMarkA = 1;
Vec_PtrPush( vNodes, pFanout );
}
}
else
{
Abc_ObjForEachFanin( pNode, pFanin, k )
{
if ( Abc_ObjFaninNum(pFanin) != 2 || pFanin->fMarkA )
continue;
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
}
}
}
Vec_PtrFree( vNodes );
// make sure the marks are clean the the retiming is final
Abc_AigForEachAnd( pNtk, pNode, i )
{
assert( pNode->fMarkA == 0 );
if ( fForward )
assert( Abc_ObjFaninLMin(pNode) == 0 );
else
assert( Abc_ObjFanoutLMin(pNode) == 0 );
}
return vMoves;
}
/**Function*************************************************************
Synopsis [Translates retiming steps into retiming moves.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward )
{
Abc_RetStep_t RetStep;
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i, k, iNode, nLatches, Number;
int fChange;
assert( Abc_NtkIsSeq( pNtk ) );
// process the nodes
vMoves = Vec_PtrAlloc( 100 );
while ( Vec_IntSize(vSteps) > 0 )
{
iNode = 0;
fChange = 0;
Vec_IntForEachEntry( vSteps, Number, i )
{
// get the retiming step
RetStep = Abc_Int2RetStep( Number );
// get the node to be retimed
pNode = Abc_NtkObj( pNtk, RetStep.iNode );
assert( RetStep.nLatches > 0 );
// get the number of latches that can be retimed
if ( fForward )
nLatches = Abc_ObjFaninLMin(pNode);
else
nLatches = Abc_ObjFanoutLMin(pNode);
if ( nLatches == 0 )
{
Vec_IntWriteEntry( vSteps, iNode++, Abc_RetStep2Int(RetStep) );
continue;
}
assert( nLatches > 0 );
fChange = 1;
// get the number of latches to be retimed over this node
nLatches = ABC_MIN( nLatches, (int)RetStep.nLatches );
// retime the latches forward
if ( fForward )
Abc_ObjRetimeForwardTry( pNode, nLatches );
else
Abc_ObjRetimeBackwardTry( pNode, nLatches );
// write the moves
for ( k = 0; k < nLatches; k++ )
Vec_PtrPush( vMoves, pNode );
// subtract the retiming performed
RetStep.nLatches -= nLatches;
// store the node if it is not retimed completely
if ( RetStep.nLatches > 0 )
Vec_IntWriteEntry( vSteps, iNode++, Abc_RetStep2Int(RetStep) );
}
// reduce the array
Vec_IntShrink( vSteps, iNode );
if ( !fChange )
{
printf( "Warning: %d strange steps.\n", Vec_IntSize(vSteps) );
/*
Vec_IntForEachEntry( vSteps, Number, i )
{
RetStep = Abc_Int2RetStep( Number );
printf( "%d(%d) ", RetStep.iNode, RetStep.nLatches );
}
printf( "\n" );
*/
break;
}
}
// undo the tentative retiming
if ( fForward )
{
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeBackwardTry( pNode, 1 );
}
else
{
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeForwardTry( pNode, 1 );
}
return vMoves;
}
/**Function*************************************************************
Synopsis [Splits retiming into forward and backward.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward )
{
Vec_Int_t * vNodes;
Abc_RetStep_t RetStep;
int Value, i;
vNodes = Vec_IntAlloc( 100 );
Vec_StrForEachEntry( vLags, Value, i )
{
// assert( Value <= ABC_MAX_EDGE_LATCH );
if ( Value < 0 && fForward )
{
RetStep.iNode = i;
RetStep.nLatches = -Value;
Vec_IntPush( vNodes, Abc_RetStep2Int(RetStep) );
}
else if ( Value > 0 && !fForward )
{
RetStep.iNode = i;
RetStep.nLatches = Value;
Vec_IntPush( vNodes, Abc_RetStep2Int(RetStep) );
}
}
return vNodes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,218 +0,0 @@
/**CFile****************************************************************
FileName [abcSeqMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Manager of sequential AIGs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcSeqMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Abc_SeqLat_t_ Abc_SeqLat_t;
struct Abc_SeqLat_t_
{
Abc_SeqLat_t * pNext; // the next Lat in the ring
Abc_SeqLat_t * pPrev; // the prev Lat in the ring
};
typedef struct Abc_SeqMan_t_ Abc_SeqMan_t;
struct Abc_SeqMan_t_
{
int nSize; // the number of entries in all internal arrays
Vec_Ptr_t * vInits; // the initial states for each edge in the AIG
Extra_MmFixed_t * pMmInits; // memory manager for initial states of the Lates
};
// reading the contents of the lat
static inline Abc_InitType_t Abc_SeqLatInit( Abc_SeqLat_t * pLat ) { return ((unsigned)pLat->pPrev) & 3; }
static inline Abc_SeqLat_t * Abc_SeqLatNext( Abc_SeqLat_t * pLat ) { return pLat->pNext; }
static inline Abc_SeqLat_t * Abc_SeqLatPrev( Abc_SeqLat_t * pLat ) { return (void *)(((unsigned)pLat->pPrev) & (ABC_FULL_MASK << 2)); }
// setting the contents of the lat
static inline void Abc_SeqLatSetInit( Abc_SeqLat_t * pLat, Abc_InitType_t Init ) { pLat->pPrev = (void *)( (3 & Init) | (((unsigned)pLat->pPrev) & (ABC_FULL_MASK << 2)) ); }
static inline void Abc_SeqLatSetNext( Abc_SeqLat_t * pLat, Abc_SeqLat_t * pNext ) { pLat->pNext = pNext; }
static inline void Abc_SeqLatSetPrev( Abc_SeqLat_t * pLat, Abc_SeqLat_t * pPrev ) { Abc_InitType_t Init = Abc_SeqLatInit(pLat); pLat->pPrev = pPrev; Abc_SeqLatSetInit(pLat, Init); }
// accessing initial state datastructure
static inline Vec_Ptr_t * Abc_SeqNodeInits( Abc_Obj_t * pObj ) { return ((Abc_SeqMan_t*)pObj->pNtk->pManFunc)->vInits; }
static inline Abc_SeqLat_t * Abc_SeqNodeReadInit( Abc_Obj_t * pObj, int Edge ) { return Vec_PtrEntry( Abc_SeqNodeInits(pObj), (pObj->Id<<1)+Edge ); }
static inline void Abc_SeqNodeSetInit ( Abc_Obj_t * pObj, int Edge, Abc_SeqLat_t * pInit ) { Vec_PtrWriteEntry( Abc_SeqNodeInits(pObj), (pObj->Id<<1)+Edge, pInit ); }
static inline Abc_SeqLat_t * Abc_SeqNodeCreateLat( Abc_Obj_t * pObj ) { return (Abc_SeqLat_t *)Extra_MmFixedEntryFetch( ((Abc_SeqMan_t*)pObj->pNtk->pManFunc)->pMmInits ); }
static inline void Abc_SeqNodeRecycleLat( Abc_Obj_t * pObj, Abc_SeqLat_t * pLat ) { Extra_MmFixedEntryRecycle( ((Abc_SeqMan_t*)pObj->pNtk->pManFunc)->pMmInits, (char *)pLat ); }
// getting the Lat with the given number
static inline Abc_SeqLat_t * Abc_SeqNodeGetLat( Abc_Obj_t * pObj, int Edge, int iLat )
{
int Counter;
Abc_SeqLat_t * pLat = Abc_SeqNodeReadInit(pObj, Edge);
for ( Counter = 0; Counter != iLat; Counter++ )
pLat = pLat->pNext;
return pLat;
}
// getting the first Lat
static inline Abc_SeqLat_t * Abc_SeqNodeGetLatFirst( Abc_Obj_t * pObj, int Edge )
{
return Abc_SeqNodeReadInit(pObj, Edge);
}
// getting the last Lat
static inline Abc_SeqLat_t * Abc_SeqNodeGetLatLast( Abc_Obj_t * pObj, int Edge )
{
return Abc_SeqLatPrev( Abc_SeqNodeReadInit(pObj, Edge) );
}
// getting the init value of the given Lat on the edge
static inline Abc_InitType_t Abc_SeqNodeGetInitOne( Abc_Obj_t * pObj, int Edge, int iLat )
{
return Abc_SeqLatInit( Abc_SeqNodeGetLat(pObj, Edge, iLat) );
}
// geting the init value of the first Lat on the edge
static inline Abc_InitType_t Abc_SeqNodeGetInitFirst( Abc_Obj_t * pObj, int Edge )
{
return Abc_SeqLatInit( Abc_SeqNodeGetLatFirst(pObj, Edge) );
}
// geting the init value of the last Lat on the edge
static inline Abc_InitType_t Abc_SeqNodeGetInitLast( Abc_Obj_t * pObj, int Edge )
{
return Abc_SeqLatInit( Abc_SeqNodeGetLatLast(pObj, Edge) );
}
// setting the init value of the given Lat on the edge
static inline void Abc_SeqNodeSetInitOne( Abc_Obj_t * pObj, int Edge, int iLat, Abc_InitType_t Init )
{
Abc_SeqLatSetInit( Abc_SeqNodeGetLat(pObj, Edge, iLat), Init );
}
// insert the first Lat on the edge
static inline void Abc_SeqNodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
Abc_SeqLat_t * pLat, * pRing, * pPrev;
pLat = Abc_SeqNodeCreateLat( pObj );
pRing = Abc_SeqNodeReadInit( pObj, Edge );
if ( pRing == NULL )
{
pLat->pNext = pLat->pPrev = pLat;
Abc_SeqNodeSetInit( pObj, Edge, pLat );
}
else
{
Abc_SeqLatSetPrev( pRing, pLat );
Abc_SeqLatSetNext( pLat, pRing );
pPrev = Abc_SeqLatPrev( pRing );
Abc_SeqLatSetPrev( pLat, pPrev );
Abc_SeqLatSetNext( pPrev, pLat );
Abc_SeqNodeSetInit( pObj, Edge, pLat ); // rotate the ring to make pLat the first
}
Abc_SeqLatSetInit( pLat, Init );
}
// insert the last Lat on the edge
static inline void Abc_SeqNodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
Abc_SeqLat_t * pLat, * pRing, * pPrev;
pLat = Abc_SeqNodeCreateLat( pObj );
pRing = Abc_SeqNodeReadInit( pObj, Edge );
if ( pRing == NULL )
{
pLat->pNext = pLat->pPrev = pLat;
Abc_SeqNodeSetInit( pObj, Edge, pLat );
}
else
{
Abc_SeqLatSetPrev( pRing, pLat );
Abc_SeqLatSetNext( pLat, pRing );
pPrev = Abc_SeqLatPrev( pRing );
Abc_SeqLatSetPrev( pLat, pPrev );
Abc_SeqLatSetNext( pPrev, pLat );
}
Abc_SeqLatSetInit( pLat, Init );
}
// delete the first Lat on the edge
static inline Abc_InitType_t Abc_SeqNodeDeleteFirst( Abc_Obj_t * pObj, int Edge )
{
Abc_SeqLat_t * pLat, * pRing, * pPrev, * pNext;
pRing = Abc_SeqNodeReadInit( pObj, Edge );
pLat = pRing; // consider the first latch
if ( pLat->pNext == pLat )
Abc_SeqNodeSetInit( pObj, Edge, NULL );
else
{
pPrev = Abc_SeqLatPrev( pLat );
pNext = Abc_SeqLatNext( pLat );
Abc_SeqLatSetPrev( pNext, pPrev );
Abc_SeqLatSetNext( pPrev, pNext );
Abc_SeqNodeSetInit( pObj, Edge, pNext ); // rotate the ring
}
Abc_SeqNodeRecycleLat( pObj, pLat );
}
// delete the last Lat on the edge
static inline Abc_InitType_t Abc_SeqNodeDeleteLast( Abc_Obj_t * pObj, int Edge )
{
Abc_SeqLat_t * pLat, * pRing, * pPrev, * pNext;
pRing = Abc_SeqNodeReadInit( pObj, Edge );
pLat = Abc_SeqLatPrev( pRing ); // consider the last latch
if ( pLat->pNext == pLat )
Abc_SeqNodeSetInit( pObj, Edge, NULL );
else
{
pPrev = Abc_SeqLatPrev( pLat );
pNext = Abc_SeqLatNext( pLat );
Abc_SeqLatSetPrev( pNext, pPrev );
Abc_SeqLatSetNext( pPrev, pNext );
}
Abc_SeqNodeRecycleLat( pObj, pLat );
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_SeqMan_t * Abc_SeqCreate( int nMaxId )
{
Abc_SeqMan_t * p;
// start the manager
p = ALLOC( Abc_SeqMan_t, 1 );
memset( p, 0, sizeof(Abc_SeqMan_t) );
p->nSize = nMaxId + 1;
// create internal data structures
p->vInits = Vec_PtrStart( 2 * p->nSize );
p->pMmInits = Extra_MmFixedStart( sizeof(Abc_SeqLat_t) );
return p;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,172 +0,0 @@
/**CFile****************************************************************
FileName [abcUtils.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Utilities working sequential AIGs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Counter;
assert( Abc_NtkIsSeq( pNtk ) );
Counter = 0;
Abc_NtkForEachNode( pNtk, pObj, i )
Counter += Abc_ObjFaninLSum( pObj );
Abc_NtkForEachPo( pNtk, pObj, i )
Counter += Abc_ObjFaninLSum( pObj );
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Counter;
assert( Abc_NtkIsSeq( pNtk ) );
Counter = 0;
Abc_NtkForEachPi( pNtk, pObj, i )
Counter += Abc_ObjFanoutLMax( pObj );
Abc_NtkForEachNode( pNtk, pObj, i )
Counter += Abc_ObjFanoutLMax( pObj );
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjLatchGetInitNums( Abc_Obj_t * pObj, int Edge, int * pInits )
{
Abc_InitType_t Init;
int nLatches, i;
nLatches = Abc_ObjFaninL( pObj, Edge );
assert( nLatches <= ABC_MAX_EDGE_LATCH );
for ( i = 0; i < nLatches; i++ )
{
Init = Abc_ObjFaninLGetInitOne( pObj, Edge, i );
pInits[Init]++;
}
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits )
{
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsSeq( pNtk ) );
for ( i = 0; i < 4; i++ )
pInits[i] = 0;
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_ObjLatchGetInitNums( pObj, 0, pInits );
Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( Abc_ObjFaninNum(pObj) > 0 )
Abc_ObjLatchGetInitNums( pObj, 0, pInits );
if ( Abc_ObjFaninNum(pObj) > 1 )
Abc_ObjLatchGetInitNums( pObj, 1, pInits );
}
}
/**Function*************************************************************
Synopsis [Generates the printable edge label with the initial state.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge )
{
static char Buffer[ABC_MAX_EDGE_LATCH + 1];
Abc_InitType_t Init;
int nLatches, i;
nLatches = Abc_ObjFaninL( pObj, Edge );
assert( nLatches <= ABC_MAX_EDGE_LATCH );
for ( i = 0; i < nLatches; i++ )
{
Init = Abc_ObjFaninLGetInitOne( pObj, Edge, i );
if ( Init == ABC_INIT_NONE )
Buffer[i] = '_';
else if ( Init == ABC_INIT_ZERO )
Buffer[i] = '0';
else if ( Init == ABC_INIT_ONE )
Buffer[i] = '1';
else if ( Init == ABC_INIT_DC )
Buffer[i] = 'x';
else assert( 0 );
}
Buffer[nLatches] = 0;
return Buffer;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,355 +0,0 @@
/**CFile****************************************************************
FileName [abcs.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential synthesis package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __ABCS_H__
#define __ABCS_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "abc.h"
#include "cut.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
// the maximum number of latches on the edge
#define ABC_MAX_EDGE_LATCH 16
#define ABC_FULL_MASK 0xFFFFFFFF
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Seq_FpgaMan_t_ Seq_FpgaMan_t;
struct Seq_FpgaMan_t_
{
Abc_Ntk_t * pNtk; // the network to be mapped
Cut_Man_t * pMan; // the cut manager
Vec_Int_t * vArrivals; // the arrival times (L-Values of nodes)
Vec_Ptr_t * vBestCuts; // the best cuts for nodes
Vec_Ptr_t * vMapping; // the nodes used in the mapping
Vec_Ptr_t * vMapCuts; // the info about the cut of each mapped node
Vec_Str_t * vLagsMap; // the lags of the mapped nodes
int fVerbose; // the verbose flag
// runtime stats
int timeCuts; // runtime to compute the cuts
int timeDelay; // runtime to compute the L-values
int timeRet; // runtime to retime the resulting network
int timeNtk; // runtime to create the final network
};
// representation of latch on the edge
typedef struct Abc_RetEdge_t_ Abc_RetEdge_t;
struct Abc_RetEdge_t_ // 1 word
{
unsigned iNode : 24; // the ID of the node
unsigned iEdge : 1; // the edge of the node
unsigned iLatch : 7; // the latch number counting from the node
};
// representation of one retiming step
typedef struct Abc_RetStep_t_ Abc_RetStep_t;
struct Abc_RetStep_t_ // 1 word
{
unsigned iNode : 24; // the ID of the node
unsigned nLatches : 8; // the number of latches to retime
};
static inline int Abc_RetEdge2Int( Abc_RetEdge_t Str ) { return *((int *)&Str); }
static inline Abc_RetEdge_t Abc_Int2RetEdge( int Num ) { return *((Abc_RetEdge_t *)&Num); }
static inline int Abc_RetStep2Int( Abc_RetStep_t Str ) { return *((int *)&Str); }
static inline Abc_RetStep_t Abc_Int2RetStep( int Num ) { return *((Abc_RetStep_t *)&Num); }
// storing arrival times in the nodes
static inline int Abc_NodeReadLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( (pNode)->pNtk->pData, (pNode)->Id ); }
static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( (pNode)->pNtk->pData, (pNode)->Id, (Value) ); }
//static inline int Abc_NodeGetLag( int LValue, int Fi ) { return LValue/Fi - (int)(LValue % Fi == 0); }
static inline int Abc_NodeGetLag( int LValue, int Fi ) { return (LValue + 256*Fi)/Fi - 256 - (int)(LValue % Fi == 0); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
// getting the number of the edge for this fanout
static inline int Abc_ObjEdgeNum( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
{
assert( Abc_NtkIsSeq(pObj->pNtk) );
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
return 0;
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
return 1;
assert( 0 );
return -1;
}
// getting the latch number of the fanout
static inline int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
{
return Abc_ObjFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout) );
}
// setting the latch number of the fanout
static inline void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
{
Abc_ObjSetFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout), nLats );
}
// adding to the latch number of the fanout
static inline void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
{
Abc_ObjAddFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout), nLats );
}
// returns the latch number of the fanout
static inline int Abc_ObjFanoutLMax( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, nLatchCur, nLatchRes;
if ( Abc_ObjFanoutNum(pObj) == 0 )
return 0;
nLatchRes = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
nLatchCur = Abc_ObjFanoutL(pObj, pFanout);
if ( nLatchRes < nLatchCur )
nLatchRes = nLatchCur;
}
assert( nLatchRes >= 0 );
return nLatchRes;
}
// returns the latch number of the fanout
static inline int Abc_ObjFanoutLMin( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, nLatchCur, nLatchRes;
if ( Abc_ObjFanoutNum(pObj) == 0 )
return 0;
nLatchRes = ABC_INFINITY;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
nLatchCur = Abc_ObjFanoutL(pObj, pFanout);
if ( nLatchRes > nLatchCur )
nLatchRes = nLatchCur;
}
assert( nLatchRes < ABC_INFINITY );
return nLatchRes;
}
// returns the sum of latches on the fanout edges
static inline int Abc_ObjFanoutLSum( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, nSum = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
nSum += Abc_ObjFanoutL(pObj, pFanout);
return nSum;
}
// returns the sum of latches on the fanin edges
static inline int Abc_ObjFaninLSum( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanin;
int i, nSum = 0;
Abc_ObjForEachFanin( pObj, pFanin, i )
nSum += Abc_ObjFaninL(pObj, i);
return nSum;
}
// getting the bit-string of init values of the edge
static inline unsigned Abc_ObjFaninLGetInit( Abc_Obj_t * pObj, int Edge )
{
return (unsigned)Vec_IntEntry( pObj->pNtk->vInits, 2 * pObj->Id + Edge );
}
// setting bit-string of init values of the edge
static inline void Abc_ObjFaninLSetInit( Abc_Obj_t * pObj, int Edge, unsigned Init )
{
Vec_IntWriteEntry( pObj->pNtk->vInits, 2 * pObj->Id + Edge, Init );
}
// getting the init value of the given latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLGetInitOne( Abc_Obj_t * pObj, int Edge, int iLatch )
{
return 0x3 & (Abc_ObjFaninLGetInit(pObj, Edge) >> (2*iLatch));
}
// setting the init value of the given latch on the edge
static inline void Abc_ObjFaninLSetInitOne( Abc_Obj_t * pObj, int Edge, int iLatch, Abc_InitType_t Init )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
unsigned EntryNew = (EntryCur & ~(0x3 << (2*iLatch))) | (Init << (2*iLatch));
assert( iLatch < Abc_ObjFaninL(pObj, Edge) );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
}
// geting the init value of the first latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLGetInitFirst( Abc_Obj_t * pObj, int Edge )
{
return 0x3 & Abc_ObjFaninLGetInit( pObj, Edge );
}
// geting the init value of the last latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLGetInitLast( Abc_Obj_t * pObj, int Edge )
{
assert( Abc_ObjFaninL(pObj, Edge) > 0 );
return 0x3 & (Abc_ObjFaninLGetInit(pObj, Edge) >> (2 * (Abc_ObjFaninL(pObj, Edge) - 1)));
}
// insert the first latch on the edge
static inline void Abc_ObjFaninLInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
unsigned EntryNew = ((EntryCur << 2) | Init);
assert( Init >= 0 && Init < 4 );
assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, 1 );
}
// insert the last latch on the edge
static inline void Abc_ObjFaninLInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
unsigned EntryNew = EntryCur | (Init << (2 * Abc_ObjFaninL(pObj, Edge)));
assert( Init >= 0 && Init < 4 );
assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH );
if ( Abc_ObjFaninL(pObj, Edge) >= ABC_MAX_EDGE_LATCH )
printf( "The limit on latched on the edge (%d) is exceeded.\n", ABC_MAX_EDGE_LATCH );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, 1 );
}
// delete the first latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLDeleteFirst( Abc_Obj_t * pObj, int Edge )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
Abc_InitType_t Init = 0x3 & EntryCur;
unsigned EntryNew = EntryCur >> 2;
assert( Abc_ObjFaninL(pObj, Edge) > 0 );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, -1 );
return Init;
}
// delete the last latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLDeleteLast( Abc_Obj_t * pObj, int Edge )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
Abc_InitType_t Init = 0x3 & (EntryCur >> (2 * (Abc_ObjFaninL(pObj, Edge) - 1)));
unsigned EntryNew = EntryCur & ~(((unsigned)0x3) << (2 * (Abc_ObjFaninL(pObj, Edge)-1)));
assert( Abc_ObjFaninL(pObj, Edge) > 0 );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, -1 );
return Init;
}
// retime node forward without initial states
static inline void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches )
{
Abc_Obj_t * pFanout;
int i;
// make sure it is an AND gate
assert( Abc_ObjFaninNum(pObj) == 2 );
// make sure it has enough latches
// assert( Abc_ObjFaninL0(pObj) >= nLatches );
// assert( Abc_ObjFaninL1(pObj) >= nLatches );
// subtract these latches on the fanin side
Abc_ObjAddFaninL0( pObj, -nLatches );
Abc_ObjAddFaninL1( pObj, -nLatches );
// add these latches on the fanout size
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_ObjAddFanoutL( pObj, pFanout, nLatches );
}
// retime node backward without initial states
static inline void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches )
{
Abc_Obj_t * pFanout;
int i;
// make sure it is an AND gate
assert( Abc_ObjFaninNum(pObj) == 2 );
// subtract these latches on the fanout side
Abc_ObjForEachFanout( pObj, pFanout, i )
{
// assert( Abc_ObjFanoutL(pObj, pFanout) >= nLatches );
Abc_ObjAddFanoutL( pObj, pFanout, -nLatches );
}
// add these latches on the fanin size
Abc_ObjAddFaninL0( pObj, nLatches );
Abc_ObjAddFaninL1( pObj, nLatches );
}
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
// iterating through the initial values of the edge
#define Abc_ObjFaninLForEachValue( pObj, Edge, Init, i, Value ) \
for ( i = 0, Init = Abc_ObjFaninLGetInit(pObj, Edge); \
i < Abc_ObjFaninL(pObj, Edge) && ((Value = ((Init >> (2*i)) & 0x3)), 1); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== abcRetCore.c ===========================================================*/
extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fVerbose );
extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose );
extern void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk, int fVerbose );
extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fVerbose );
/*=== abcRetDelay.c ==========================================================*/
extern Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose );
/*=== abcRetImpl.c ===========================================================*/
extern int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose );
extern void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves );
extern int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose );
/*=== abcRetUtil.c ===========================================================*/
extern Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward );
extern Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes, bool fForward );
extern Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward );
/*=== abcSeq.c ===============================================================*/
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );
/*=== abcShare.c =============================================================*/
extern void Abc_NtkSeqShareFanouts( Abc_Ntk_t * pNtk );
/*=== abcUtil.c ==============================================================*/
extern int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk );
extern void Abc_NtkSeqLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits );
extern char * Abc_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

View File

@ -1,9 +0,0 @@
SRC += src/base/abcs/abcFpgaDelay.c \
src/base/abcs/abcFpgaSeq.c \
src/base/abcs/abcRetCore.c \
src/base/abcs/abcRetDelay.c \
src/base/abcs/abcRetImpl.c \
src/base/abcs/abcRetUtil.c \
src/base/abcs/abcSeq.c \
src/base/abcs/abcShare.c \
src/base/abcs/abcUtils.c

View File

@ -42,6 +42,7 @@ static int IoCommandWriteCnf ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteDot ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteGml ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteList ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv );
////////////////////////////////////////////////////////////////////////
@ -78,6 +79,7 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "write_dot", IoCommandWriteDot, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_eqn", IoCommandWriteEqn, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_gml", IoCommandWriteGml, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_list", IoCommandWriteList, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 );
}
@ -1242,6 +1244,71 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int IoCommandWriteList( Abc_Frame_t * pAbc, int argc, char **argv )
{
char * FileName;
int fUseHost;
int c;
fUseHost = 1;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "nh" ) ) != EOF )
{
switch ( c )
{
case 'n':
fUseHost ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pNtkCur == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
if ( !Abc_NtkIsSeq(pAbc->pNtkCur) )
{
fprintf( stdout, "IoCommandWriteList(): Can write adjacency list for sequential AIGs only.\n" );
return 0;
}
if ( argc != util_optind + 1 )
{
goto usage;
}
// get the input file name
FileName = argv[util_optind];
// write the file
Io_WriteList( pAbc->pNtkCur, FileName, fUseHost );
return 0;
usage:
fprintf( pAbc->Err, "usage: write_list [-nh] <file>\n" );
fprintf( pAbc->Err, "\t write network using graph representation formal GML\n" );
fprintf( pAbc->Err, "\t-n : toggle writing host node [default = %s]\n", fUseHost? "yes":"no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
}
/**Function*************************************************************
Synopsis []

View File

@ -85,6 +85,8 @@ extern void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec
extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName );
/*=== abcWriteGml.c ==========================================================*/
extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName );
/*=== abcWriteList.c ==========================================================*/
extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost );
/*=== abcWritePla.c ==========================================================*/
extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName );

View File

@ -79,7 +79,7 @@ Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck )
// prepare the array of nodes
vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds );
Vec_PtrPush( vNodes, Abc_AigConst1(pNtkNew->pManFunc) );
Vec_PtrPush( vNodes, Abc_NtkConst1(pNtkNew) );
// create the PIs
for ( i = 0; i < nInputs; i++ )

View File

@ -19,7 +19,7 @@
***********************************************************************/
#include "io.h"
#include "abcs.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -316,7 +316,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", Abc_ObjFaninC0(pNode)? "dotted" : "bold" );
if ( Abc_ObjFaninL0(pNode) > 0 )
fprintf( pFile, ", label = \"%s\"", Abc_ObjFaninGetInitPrintable(pNode,0) );
fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
@ -331,7 +331,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", Abc_ObjFaninC1(pNode)? "dotted" : "bold" );
if ( Abc_ObjFaninL1(pNode) > 0 )
fprintf( pFile, ", label = \"%s\"", Abc_ObjFaninGetInitPrintable(pNode,1) );
fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}

212
src/base/io/ioWriteList.c Normal file
View File

@ -0,0 +1,212 @@
/**CFile****************************************************************
FileName [ioWriteList.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Procedures to write the graph structure of sequential AIG.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ioWriteList.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "io.h"
/*
-------- Original Message --------
Subject: Re: abc release and retiming
Date: Sun, 13 Nov 2005 20:31:18 -0500 (EST)
From: Luca Carloni <luca@cs.columbia.edu>
To: Alan Mishchenko <alanmi@eecs.berkeley.edu>
Alan,
My graph-representation file format is based on an adjacency list
representation and is indeed quite simple, in fact maybe too simple... I
used it in order to reason on relatively small weighed direct graphs. I
simply list all vertices, one per line and for each vertex "V_source" I
list all vertices that are "sinks" with respect to it, i.e. such that
there is a distinct arc between "V_source" and each of them (in
paranthesis I list the name of the edge and its weight (number of latency
on that path). For instance, if you look at the following graph, you have
that vertex "v_5" is connected to vertex "v_6" through a directed arc
called "v_5_to_v_6" whose latency is equal to 3, i.e. there are three
flip-flops on this arc. Still, notice that I sometime interpret the graph
also as the representation of a LIS where each node corresponds to a
shell encapsulating a sequential core module (i.e. a module which does not
contain any combinational path between its inputs and its outputs). With
this representation an arc of latency 3 is interpreted as a wire where two
relay stations have been inserted in addition to the flip-flop terminating
the output of the core module.
Finally, notice that the name of the arc does not necessarily have to be
"v_5_to_v_6", but it could have been something like "arc_222" or "xyz" as
long as it is a unique name in the graph.
Thanks,
Luca
Example of graph representation
-----------------------------------------------------------------------------
v_5 > v_6 ([v_5_to_v_6] = 3), v_12 ([v_5_to_v_12] = 2).
v_2 > v_4 ([v_2_to_v_4] = 1), v_10_s0 ([v_2_to_v_10_s0] = 6), v_12 ([v_2_to_v_12] = 3).
v_9 > v_10_s0 ([v_9_to_v_10_s0] = 5), v_12 ([v_9_to_v_12] = 2).
v_12 > v_13 ([v_12_to_v_13] = 5).
v_13 > v_14 ([v_13_to_v_14] = 1).
v_6 > v_7 ([v_6_to_v_7] = 2).
v_4 > v_5 ([v_4_to_v_5] = 2).
v_1 > v_2 ([v_1_to_v_2] = 1).
v_7 > v_8 ([v_7_to_v_8] = 2).
t > .
v_14 > t ([v_14_to_t] = 1), v_5 ([v_14_to_v_5] = 1).
v_8 > v_9 ([v_8_to_v_9] = 2).
s > v_1 ([s_to_v_1] = 1).
v_10_s0 > v_10_s1 ([v_10_s0_to_v_10_s1] = 1).
v_10_s1 > v_4 ([v_10_s1__v_4] = 1), v_8 ([v_10_s1__v_8] = 1).
-----------------------------------------------------------------------------
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj );
static void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Writes the adjacency list for a sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
{
FILE * pFile;
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsSeq(pNtk) );
// start the output stream
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteList(): Cannot open the output file \"%s\".\n", pFileName );
return;
}
fprintf( pFile, "# Adjacency list for sequential AIG \"%s\"\n", pNtk->pName );
fprintf( pFile, "# written by ABC on %s\n", Extra_TimeStamp() );
// write the constant node
if ( Abc_ObjFanoutNum( Abc_NtkConst1(pNtk) ) > 0 )
Io_WriteListEdge( pFile, Abc_NtkConst1(pNtk) );
// write the PO edges
Abc_NtkForEachCi( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
// write the internal nodes
Abc_AigForEachAnd( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
// write the host node
if ( fUseHost )
Io_WriteListHost( pFile, pNtk );
else
Abc_NtkForEachCo( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
fprintf( pFile, "\n" );
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Writes the adjacency list for one edge in a sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i;
fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
Abc_ObjForEachFanout( pObj, pFanout, i )
{
fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pFanout), Abc_ObjName(pObj), Abc_ObjName(pFanout), Abc_ObjFanoutL(pObj, pFanout) );
if ( i == Abc_ObjFanoutNum(pObj) - 1 )
fprintf( pFile, "." );
else
fprintf( pFile, "," );
}
fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis [Writes the adjacency list for one edge in a sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i;
Abc_NtkForEachPo( pNtk, pObj, i )
{
fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
fprintf( pFile, " %s ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), "HOST", 0 );
if ( i == Abc_NtkPoNum(pNtk) - 1 )
fprintf( pFile, "." );
else
fprintf( pFile, "," );
}
fprintf( pFile, "\n" );
fprintf( pFile, "%-10s > ", "HOST" );
Abc_NtkForEachPi( pNtk, pObj, i )
{
fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pObj), "HOST", Abc_ObjName(pObj), 0 );
if ( i == Abc_NtkPiNum(pNtk) - 1 )
fprintf( pFile, "." );
else
fprintf( pFile, "," );
}
fprintf( pFile, "\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -15,4 +15,5 @@ SRC += src/base/io/io.c \
src/base/io/ioWriteDot.c \
src/base/io/ioWriteEqn.c \
src/base/io/ioWriteGml.c \
src/base/io/ioWriteList.c \
src/base/io/ioWritePla.c

View File

@ -40,7 +40,7 @@ void open_libs() {
int curr_lib = 0;
#ifdef WIN32
printf("Warning: open_libs WIN32 not implemented.\n");
// printf("Warning: open_libs WIN32 not implemented.\n");
#else
DIR* dirp;
struct dirent* dp;

View File

@ -21,7 +21,7 @@
#include "mainInt.h"
// this line should be included in the library project
//#define _LIB
#define _LIB
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -261,7 +261,7 @@ void Abc_Start()
pAbc = Abc_FrameGetGlobalFrame();
// source the resource file
Abc_UtilsSource( pAbc );
// Abc_UtilsSource( pAbc );
}
/**Function*************************************************************

11
src/base/seq/module.make Normal file
View File

@ -0,0 +1,11 @@
SRC += src/base/seq/seqCreate.c \
src/base/seq/seqFpgaCore.c \
src/base/seq/seqFpgaIter.c \
src/base/seq/seqLatch.c \
src/base/seq/seqMan.c \
src/base/seq/seqMapCore.c \
src/base/seq/seqMapIter.c \
src/base/seq/seqRetCore.c \
src/base/seq/seqRetIter.c \
src/base/seq/seqShare.c \
src/base/seq/seqUtil.c

74
src/base/seq/seq.h Normal file
View File

@ -0,0 +1,74 @@
/**CFile****************************************************************
FileName [seq.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seq.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __SEQ_H__
#define __SEQ_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Abc_Seq_t_ Abc_Seq_t;
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== seqLatch.c ===============================================================*/
extern void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge );
/*=== seqMan.c ===============================================================*/
extern Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk );
extern void Seq_Resize( Abc_Seq_t * p, int nMaxId );
extern void Seq_Delete( Abc_Seq_t * p );
/*=== abcSeq.c ===============================================================*/
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );
/*=== seqShare.c =============================================================*/
extern void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk );
/*=== seqRetCore.c ===========================================================*/
extern void Seq_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fInitial, int fVerbose );
extern void Seq_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose );
extern void Seq_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose );
/*=== seqUtil.c ==============================================================*/
extern char * Seq_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge );
extern void Seq_NtkLatchSetValues( Abc_Ntk_t * pNtk, Abc_InitType_t Init );
extern int Seq_NtkLatchNum( Abc_Ntk_t * pNtk );
extern int Seq_NtkLatchNumMax( Abc_Ntk_t * pNtk );
extern int Seq_NtkLatchNumShared( Abc_Ntk_t * pNtk );
extern void Seq_NtkLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

View File

@ -1,12 +1,12 @@
/**CFile****************************************************************
FileName [abcSeq.c]
FileName [seqCreate.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis [Procedures to derive sequential AIG from combinational AIG with latches.]
Synopsis []
Author [Alan Mishchenko]
@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: seqCreate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
#include "seqInt.h"
/*
A sequential network is similar to AIG in that it contains only
@ -33,29 +33,29 @@
- The attributes contain information about the number of latches
and their initial states.
- The number of latches is stored directly on the edges. The initial
states are stored in a special array associated with the network.
states are stored in the sequential AIG manager.
The AIG of sequential network is static in the sense that the
new AIG nodes are never created.
In the current version of the code, the sequential AIG is static
in the sense that the new AIG nodes are never created.
The retiming (or retiming/mapping) is performed by moving the
latches over the static nodes of the AIG.
The new initial state after forward retiming is computed in a
straight-forward manner. After backward retiming it is computed
by setting up a SAT problem.
The new initial state after backward retiming is computed
by setting up and solving a SAT problem.
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk );
static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pAnd, int Num, int * pnLatches, unsigned * pnInit );
static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, unsigned Init );
static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge, Vec_Int_t * vInitValues );
static void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk );
static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Seq_Lat_t * pRing, int nLatches );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Converts combinational AIG with latches into sequential AIG.]
@ -72,122 +72,101 @@ static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin,
Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj, * pFaninNew;
unsigned Init;
int i, nLatches;
Vec_Int_t * vInitValues;
Abc_InitType_t Init;
int i, k;
// make sure it is an AIG without self-feeding latches
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkCountSelfFeedLatches(pNtk) == 0 );
assert( Abc_NtkIsDfsOrdered(pNtk) );
// start the network
Abc_NtkCleanCopy( pNtk );
pNtkNew = Abc_NtkAlloc( ABC_NTK_SEQ, ABC_FUNC_AIG );
// duplicate the name and the spec
pNtkNew->pName = util_strsav(pNtk->pName);
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
// clone const/PIs/POs
Abc_NtkDupObj(pNtkNew, Abc_AigConst1(pNtk->pManFunc) );
pNtkNew->nNodes -= 1;
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
// Abc_NtkForEachLatch( pNtk, pObj, i )
// Vec_PtrPush( pNtkNew->vObjs, NULL );
// copy the PI/PO names
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pObj) );
// copy the internal nodes, including choices, excluding dangling
vNodes = Abc_AigDfs( pNtk, 0, 0 );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( Abc_ObjFaninNum(pObj) != 2 )
continue;
Abc_NtkDupObj(pNtkNew, pObj);
// assert( pObj->Id == pObj->pCopy->Id );
pObj->pCopy->fPhase = pObj->fPhase; // needed for choices
pObj->pCopy->Level = pObj->Level;
}
// relink the choice nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
Vec_PtrFree( vNodes );
// start the storage for initial states
pNtkNew->vInits = Vec_IntStart( 2 * Abc_NtkObjNumMax(pNtkNew) );
// reconnect the internal nodes
// map the constant nodes
Abc_NtkCleanCopy( pNtk );
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// copy all objects, except the latches and constant
Vec_PtrFill( pNtkNew->vObjs, Abc_NtkObjNumMax(pNtk), NULL );
Vec_PtrWriteEntry( pNtkNew->vObjs, 0, Abc_NtkConst1(pNtk)->pCopy );
Abc_NtkForEachObj( pNtk, pObj, i )
{
// skip the constant and the PIs
if ( Abc_ObjFaninNum(pObj) == 0 )
if ( i == 0 || Abc_ObjIsLatch(pObj) )
continue;
if ( Abc_ObjIsLatch(pObj) )
pObj->pCopy = Abc_ObjAlloc( pNtkNew, pObj->Type );
pObj->pCopy->Id = pObj->Id;
pObj->pCopy->fPhase = pObj->fPhase;
pObj->pCopy->Level = pObj->Level;
Vec_PtrWriteEntry( pNtkNew->vObjs, pObj->pCopy->Id, pObj->pCopy );
pNtkNew->nObjs++;
}
pNtkNew->nNodes = pNtk->nNodes;
pNtkNew->nPis = pNtk->nPis;
pNtkNew->nPos = pNtk->nPos;
// create PI/PO and their names
Abc_NtkForEachPi( pNtk, pObj, i )
{
Vec_PtrPush( pNtkNew->vCis, pObj->pCopy );
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
Vec_PtrPush( pNtkNew->vCos, pObj->pCopy );
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
// relink the choice nodes
Abc_AigForEachAnd( pNtk, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
// start the storage for initial states
Seq_Resize( pNtkNew->pManFunc, Abc_NtkObjNumMax(pNtkNew) );
// reconnect the internal nodes
vInitValues = Vec_IntAlloc( 100 );
Abc_NtkForEachObj( pNtk, pObj, i )
{
// skip constants, PIs, and latches
if ( Abc_ObjFaninNum(pObj) == 0 || Abc_ObjIsLatch(pObj) )
continue;
// process the first fanin
pFaninNew = Abc_NodeAigToSeq( pObj, 0, &nLatches, &Init );
if ( nLatches > ABC_MAX_EDGE_LATCH )
{
printf( "The number of latches on an edge (%d) exceeds the limit (%d).\n", nLatches, ABC_MAX_EDGE_LATCH );
nLatches = ABC_MAX_EDGE_LATCH;
}
Vec_IntClear( vInitValues );
pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 0, vInitValues );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
Abc_ObjAddFaninL0( pObj->pCopy, nLatches );
Vec_IntWriteEntry( pNtkNew->vInits, 2 * pObj->pCopy->Id + 0, Init );
// store the initial values
Vec_IntForEachEntry( vInitValues, Init, k )
Seq_NodeInsertFirst( pObj->pCopy, 0, Init );
// skip single-input nodes
if ( Abc_ObjFaninNum(pObj) == 1 )
continue;
// process the second fanin
pFaninNew = Abc_NodeAigToSeq( pObj, 1, &nLatches, &Init );
if ( nLatches > ABC_MAX_EDGE_LATCH )
{
printf( "The number of latches on an edge (%d) exceeds the limit (%d).\n", nLatches, ABC_MAX_EDGE_LATCH );
nLatches = ABC_MAX_EDGE_LATCH;
}
Vec_IntClear( vInitValues );
pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 1, vInitValues );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
Abc_ObjAddFaninL1( pObj->pCopy, nLatches );
Vec_IntWriteEntry( pNtkNew->vInits, 2 * pObj->pCopy->Id + 1, Init );
// store the initial values
Vec_IntForEachEntry( vInitValues, Init, k )
Seq_NodeInsertFirst( pObj->pCopy, 1, Init );
}
Vec_IntFree( vInitValues );
// set the cutset composed of latch drivers
Vec_PtrFree( pNtkNew->vLats );
pNtkNew->vLats = Abc_NtkAigCutsetCopy( pNtk );
Abc_NtkAigCutsetCopy( pNtk );
// copy EXDC and check correctness
if ( pNtkNew->pExdc )
fprintf( stdout, "Warning: EXDC is dropped when converting to sequential AIG.\n" );
fprintf( stdout, "Warning: EXDC is not copied when converting to sequential AIG.\n" );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkAigToSeq(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Collects the cut set nodes.]
Description [These are internal AND gates that fanins into latches.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pLatch, * pDriver;
int i;
vNodes = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
Abc_NtkIncrementTravId(pNtk);
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
pDriver = Abc_ObjFanin0(pLatch);
if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) )
continue;
Abc_NodeSetTravIdCurrent(pDriver);
Vec_PtrPush( vNodes, pDriver->pCopy );
}
return vNodes;
}
/**Function*************************************************************
Synopsis [Determines the fanin that is transparent for latches.]
@ -199,22 +178,18 @@ Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsigned * pnInit )
Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge, Vec_Int_t * vInitValues )
{
Abc_Obj_t * pFanin, * pFaninNew;
Abc_InitType_t Init;
// get the given fanin of the node
pFanin = Abc_ObjFanin( pObj, Num );
pFanin = Abc_ObjFanin( pObj, Edge );
// if fanin is the internal node, return its copy in the corresponding polarity
if ( !Abc_ObjIsLatch(pFanin) )
{
*pnLatches = 0;
*pnInit = 0;
return Abc_ObjNotCond( pFanin->pCopy, Abc_ObjFaninC(pObj, Num) );
}
return Abc_ObjNotCond( pFanin->pCopy, Abc_ObjFaninC(pObj, Edge) );
// fanin is a latch
// get the new fanins
pFaninNew = Abc_NodeAigToSeq( pFanin, 0, pnLatches, pnInit );
pFaninNew = Abc_NodeAigToSeq( pObjNew, pFanin, 0, vInitValues );
// get the initial state
Init = Abc_LatchInit(pFanin);
// complement the initial state if the inv is retimed over the latch
@ -227,13 +202,37 @@ Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsign
else if ( Init != ABC_INIT_DC )
assert( 0 );
}
// update the latch number and initial state
(*pnLatches)++;
(*pnInit) = ((*pnInit) << 2) | Init;
return Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC(pObj, Num) );
// record the initial state
Vec_IntPush( vInitValues, Init );
return Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC(pObj, Edge) );
}
/**Function*************************************************************
Synopsis [Collects the cut set nodes.]
Description [These are internal AND gates that have latch fanouts.]
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch, * pDriver, * pDriverNew;
int i;
Abc_NtkIncrementTravId(pNtk);
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
pDriver = Abc_ObjFanin0(pLatch);
if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) )
continue;
Abc_NodeSetTravIdCurrent(pDriver);
pDriverNew = pDriver->pCopy;
Vec_PtrPush( pDriverNew->pNtk->vCutSet, pDriverNew );
}
}
/**Function*************************************************************
@ -250,23 +249,12 @@ Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsign
Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pConst1;
int i, nCutNodes;
unsigned Init;
int nLatchMax = 0;
Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
int i;
assert( Abc_NtkIsSeq(pNtk) );
// start the network without latches
nCutNodes = pNtk->vLats->nSize; pNtk->vLats->nSize = 0;
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
pNtk->vLats->nSize = nCutNodes;
// create the constant node
// Abc_NtkDupConst1( pNtk, pNtkNew );
pConst1 = Abc_NtkObj(pNtk,0);
if ( !Abc_ObjIsNode(pConst1) )
pConst1 = NULL;
if ( pConst1 && Abc_ObjFanoutNum(pConst1) > 0 )
pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew );
// duplicate the nodes, create node functions
Abc_NtkForEachNode( pNtk, pObj, i )
@ -291,12 +279,8 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
// skip PIs and the constant
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
if ( nLatchMax < Abc_ObjFaninL0(pObj) )
nLatchMax = Abc_ObjFaninL0(pObj);
// get the initial states of the latches on the fanin edge of this node
Init = Vec_IntEntry( pNtk->vInits, 2 * pObj->Id );
// create the edge
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninL0(pObj), Init );
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Seq_NodeGetRing(pObj,0), Abc_ObjFaninL0(pObj) );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
if ( Abc_ObjFaninNum(pObj) == 1 )
{
@ -305,16 +289,11 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
Abc_ObjSetFaninC( pObj->pCopy, 0 );
continue;
}
if ( nLatchMax < Abc_ObjFaninL0(pObj) )
nLatchMax = Abc_ObjFaninL0(pObj);
// get the initial states of the latches on the fanin edge of this node
Init = Vec_IntEntry( pNtk->vInits, 2 * pObj->Id + 1 );
// create the edge
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Abc_ObjFaninL1(pObj), Init );
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Seq_NodeGetRing(pObj,1), Abc_ObjFaninL1(pObj) );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
// the complemented edges are subsumed by the node function
}
// printf( "The max edge latch num = %d.\n", nLatchMax );
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkNew );
Abc_NtkForEachLatch( pNtkNew, pObjNew, i )
@ -328,7 +307,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
fprintf( stdout, "Abc_NtkSeqToLogicSop(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
@ -341,7 +320,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, unsigned Init )
Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Seq_Lat_t * pRing, int nLatches )
{
Abc_Obj_t * pLatch;
if ( nLatches == 0 )
@ -349,15 +328,13 @@ Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLa
assert( pFanin->pCopy );
return pFanin->pCopy;
}
pFanin = Abc_NodeSeqToLogic( pNtkNew, pFanin, nLatches - 1, Init >> 2 );
pFanin = Abc_NodeSeqToLogic( pNtkNew, pFanin, Seq_LatNext(pRing), nLatches - 1 );
pLatch = Abc_NtkCreateLatch( pNtkNew );
pLatch->pData = (void *)(Init & 3);
pLatch->pData = (void *)Seq_LatInit( pRing );
Abc_ObjAddFanin( pLatch, pFanin );
return pLatch;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

170
src/base/seq/seqFpgaCore.c Normal file
View File

@ -0,0 +1,170 @@
/**CFile****************************************************************
FileName [seqFpgaCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqFpgaCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs FPGA mapping and retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Seq_NtkSeqFpgaRetime( Abc_Ntk_t * pNtk, int fVerbose )
{
Abc_Seq_t * p;
Abc_Ntk_t * pNtkNew;
Abc_Ntk_t * pNtkMap;
int RetValue;
// find the best mapping and retiming (p->vMapping, p->vLags)
Seq_NtkSeqFpgaMapping( pNtk, fVerbose );
// duplicate the nodes contained in multiple cuts
pNtkNew = Seq_NtkSeqFpgaDup( pNtk );
// implement this retiming
p = pNtkNew->pManFunc;
RetValue = Seq_NtkImplementRetiming( pNtkNew, p->vLags, fVerbose );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
// create the final mapped network
pNtkMap = Seq_NtkSeqFpgaMapped( pNtkNew, pNtk );
Abc_NtkDelete( pNtkNew );
return pNtkMap;
}
/**Function*************************************************************
Synopsis [Derives the network by duplicating some of the nodes.]
Description [Information about mapping is given as
(1) array of mapping nodes (p->vMapAnds),
(2) array of best cuts for each node (p->vMapCuts),
(3) array of nodes subsumed by each cut (p->vMapBags),
(4) array of lags of each node in the cut (p->vMapLags).]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk )
{
Abc_Seq_t * p = pNtk->pManFunc;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pLeaf, * pNode, * pDriver, * pDriverNew;
Vec_Ptr_t * vLeaves, * vInside, * vLags;
int i, k, TotalLag;
assert( Abc_NtkIsSeq(pNtk) );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// set the next pointers
Abc_NtkForEachPi( pNtk, pObj, i )
pObj->pNext = pObj->pCopy;
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pNext = NULL;
// start the new sequential AIG manager
Seq_Resize( pNtkNew->pManFunc, 10 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Vec_VecSizeSize(p->vMapBags) );
// create the nodes
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
{
// make sure the leaves are assigned
vLeaves = Vec_VecEntry( p->vMapCuts, i );
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
{
assert( pLeaf->pNext );
pLeaf->pCopy = pLeaf->pNext;
}
// recursively construct the internals
vInside = Vec_VecEntry( p->vMapBags, i );
vLags = Vec_VecEntry( p->vMapLags, i );
Vec_PtrForEachEntry( vInside, pNode, k )
{
Abc_NtkDupObj( pNtkNew, pNode );
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild1Copy(pNode) );
Abc_ObjSetFaninL( pNode->pCopy, 0, Abc_ObjFaninL(pNode, 0) );
Abc_ObjSetFaninL( pNode->pCopy, 1, Abc_ObjFaninL(pNode, 1) );
Seq_NodeDupLats( pNode->pCopy, pNode, 0 );
Seq_NodeDupLats( pNode->pCopy, pNode, 1 );
// set the lag of the new node
TotalLag = Seq_NodeGetLag(pObj) + (char)Vec_PtrEntry(vLags, k);
Seq_NodeSetLag( pNode->pCopy, (char)TotalLag );
}
// set the copy of the last node
pObj->pNext = pObj->pCopy;
}
// set the POs
Abc_NtkForEachPo( pNtk, pObj, i )
{
pDriver = Abc_ObjFanin0(pObj);
pDriverNew = Abc_ObjNotCond(pDriver->pNext, Abc_ObjFaninC0(pObj));
Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
}
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Seq_NtkSeqFpgaDup(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Derives the final mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkMap;
pNtkMap = NULL;
if ( !Abc_NtkCheck( pNtkMap ) )
fprintf( stdout, "Seq_NtkSeqFpgaMapped(): Network check has failed.\n" );
return pNtkMap;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,50 @@
/**CFile****************************************************************
FileName [seqFpgaIter.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqFpgaIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkSeqFpgaMapping( Abc_Ntk_t * pNtk, int fVerbose )
{
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

167
src/base/seq/seqInt.h Normal file
View File

@ -0,0 +1,167 @@
/**CFile****************************************************************
FileName [seqInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __SEQ_INT_H__
#define __SEQ_INT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "abc.h"
#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
#define SEQ_FULL_MASK 0xFFFFFFFF
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
// manager of sequential AIG
struct Abc_Seq_t_
{
Abc_Ntk_t * pNtk; // the network
int nSize; // the number of entries in all internal arrays
Vec_Ptr_t * vInits; // the initial states for each edge in the AIG
Extra_MmFixed_t * pMmInits; // memory manager for latch structures used to remember init states
int fVerbose; // the verbose flag
// the arrival times
Vec_Int_t * vLValues; // the arrival times (L-Values of nodes)
Vec_Ptr_t * vBestCuts; // the best cuts for nodes
Vec_Str_t * vLags; // the lags of the mapped nodes
// representation of the mapping
Vec_Ptr_t * vMapAnds; // nodes visible in the mapping
Vec_Vec_t * vMapCuts; // best cuts for each node
Vec_Vec_t * vMapBags; // nodes subsumed by each cut
Vec_Vec_t * vMapLags; // the internal lags of each node in the bag
// runtime stats
int timeCuts; // runtime to compute the cuts
int timeDelay; // runtime to compute the L-values
int timeRet; // runtime to retime the resulting network
int timeNtk; // runtime to create the final network
};
// data structure to store initial state
typedef struct Seq_Lat_t_ Seq_Lat_t;
struct Seq_Lat_t_
{
Seq_Lat_t * pNext; // the next Lat in the ring
Seq_Lat_t * pPrev; // the prev Lat in the ring
};
// representation of latch on the edge
typedef struct Seq_RetEdge_t_ Seq_RetEdge_t;
struct Seq_RetEdge_t_ // 1 word
{
unsigned iNode : 24; // the ID of the node
unsigned iEdge : 1; // the edge of the node
unsigned iLatch : 7; // the latch number counting from the node
};
// representation of one retiming step
typedef struct Seq_RetStep_t_ Seq_RetStep_t;
struct Seq_RetStep_t_ // 1 word
{
unsigned iNode : 24; // the ID of the node
unsigned nLatches : 8; // the number of latches to retime
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
// transforming retedges into ints and back
static inline int Seq_RetEdge2Int( Seq_RetEdge_t Val ) { return *((int *)&Val); }
static inline Seq_RetEdge_t Seq_Int2RetEdge( int Num ) { return *((Seq_RetEdge_t *)&Num); }
// transforming retsteps into ints and back
static inline int Seq_RetStep2Int( Seq_RetStep_t Val ) { return *((int *)&Val); }
static inline Seq_RetStep_t Seq_Int2RetStep( int Num ) { return *((Seq_RetStep_t *)&Num); }
// storing arrival times in the nodes
static inline Vec_Int_t * Seq_NodeLValues( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vLValues; }
static inline int Seq_NodeGetLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( Seq_NodeLValues(pNode), (pNode)->Id ); }
static inline void Seq_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( Seq_NodeLValues(pNode), (pNode)->Id, (Value) ); }
static inline int Seq_NodeComputeLag( int LValue, int Fi ) { return (LValue + 1024*Fi)/Fi - 1024 - (int)(LValue % Fi == 0); }
// reading the contents of the lat
static inline Abc_InitType_t Seq_LatInit( Seq_Lat_t * pLat ) { return ((unsigned)pLat->pPrev) & 3; }
static inline Seq_Lat_t * Seq_LatNext( Seq_Lat_t * pLat ) { return pLat->pNext; }
static inline Seq_Lat_t * Seq_LatPrev( Seq_Lat_t * pLat ) { return (void *)(((unsigned)pLat->pPrev) & (SEQ_FULL_MASK << 2)); }
// setting the contents of the lat
static inline void Seq_LatSetInit( Seq_Lat_t * pLat, Abc_InitType_t Init ) { pLat->pPrev = (void *)( (3 & Init) | (((unsigned)pLat->pPrev) & (SEQ_FULL_MASK << 2)) ); }
static inline void Seq_LatSetNext( Seq_Lat_t * pLat, Seq_Lat_t * pNext ) { pLat->pNext = pNext; }
static inline void Seq_LatSetPrev( Seq_Lat_t * pLat, Seq_Lat_t * pPrev ) { Abc_InitType_t Init = Seq_LatInit(pLat); pLat->pPrev = pPrev; Seq_LatSetInit(pLat, Init); }
// accessing retiming lags
static inline Vec_Str_t * Seq_NodeLags( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vLags; }
static inline char Seq_NodeGetLag( Abc_Obj_t * pNode ) { return Vec_StrEntry( Seq_NodeLags(pNode), (pNode)->Id ); }
static inline void Seq_NodeSetLag( Abc_Obj_t * pNode, char Value ) { Vec_StrWriteEntry( Seq_NodeLags(pNode), (pNode)->Id, (Value) ); }
// accessing initial states
static inline Vec_Ptr_t * Seq_NodeLats( Abc_Obj_t * pObj ) { return ((Abc_Seq_t*)pObj->pNtk->pManFunc)->vInits; }
static inline Seq_Lat_t * Seq_NodeGetRing( Abc_Obj_t * pObj, int Edge ) { return Vec_PtrEntry( Seq_NodeLats(pObj), (pObj->Id<<1)+Edge ); }
static inline void Seq_NodeSetRing( Abc_Obj_t * pObj, int Edge, Seq_Lat_t * pLat ) { Vec_PtrWriteEntry( Seq_NodeLats(pObj), (pObj->Id<<1)+Edge, pLat ); }
static inline Seq_Lat_t * Seq_NodeCreateLat( Abc_Obj_t * pObj ) { return (Seq_Lat_t *)Extra_MmFixedEntryFetch( ((Abc_Seq_t*)pObj->pNtk->pManFunc)->pMmInits ); }
static inline void Seq_NodeRecycleLat( Abc_Obj_t * pObj, Seq_Lat_t * pLat ) { Extra_MmFixedEntryRecycle( ((Abc_Seq_t*)pObj->pNtk->pManFunc)->pMmInits, (char *)pLat ); }
// getting hold of the structure storing initial states of the latches
static inline Seq_Lat_t * Seq_NodeGetLatFirst( Abc_Obj_t * pObj, int Edge ) { return Seq_NodeGetRing(pObj, Edge); }
static inline Seq_Lat_t * Seq_NodeGetLatLast( Abc_Obj_t * pObj, int Edge ) { return Seq_LatPrev( Seq_NodeGetRing(pObj, Edge) ); }
static inline Seq_Lat_t * Seq_NodeGetLat( Abc_Obj_t * pObj, int Edge, int iLat ) { int c; Seq_Lat_t * pLat = Seq_NodeGetRing(pObj, Edge); for ( c = 0; c != iLat; c++ ) pLat = pLat->pNext; return pLat; }
static inline int Seq_NodeCountLats( Abc_Obj_t * pObj, int Edge ) { int c; Seq_Lat_t * pLat, * pRing = Seq_NodeGetRing(pObj, Edge); if ( pRing == NULL ) return 0; for ( c = 0, pLat = pRing; !c || pLat != pRing; c++ ) pLat = pLat->pNext; return c; }
// getting/setting initial states of the latches
static inline Abc_InitType_t Seq_NodeGetInitOne( Abc_Obj_t * pObj, int Edge, int iLat ) { return Seq_LatInit( Seq_NodeGetLat(pObj, Edge, iLat) ); }
static inline Abc_InitType_t Seq_NodeGetInitFirst( Abc_Obj_t * pObj, int Edge ) { return Seq_LatInit( Seq_NodeGetLatFirst(pObj, Edge) ); }
static inline Abc_InitType_t Seq_NodeGetInitLast( Abc_Obj_t * pObj, int Edge ) { return Seq_LatInit( Seq_NodeGetLatLast(pObj, Edge) ); }
static inline void Seq_NodeSetInitOne( Abc_Obj_t * pObj, int Edge, int iLat, Abc_InitType_t Init ) { Seq_LatSetInit( Seq_NodeGetLat(pObj, Edge, iLat), Init ); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== seqLatch.c ===============================================================*/
extern void Seq_NodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init );
extern void Seq_NodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init );
extern Abc_InitType_t Seq_NodeDeleteFirst( Abc_Obj_t * pObj, int Edge );
extern Abc_InitType_t Seq_NodeDeleteLast( Abc_Obj_t * pObj, int Edge );
/*=== seqFpgaIter.c ============================================================*/
extern void Seq_NtkSeqFpgaMapping( Abc_Ntk_t * pNtk, int fVerbose );
/*=== seqRetIter.c =============================================================*/
extern void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose );
extern int Seq_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose );
/*=== seqUtil.c ================================================================*/
extern int Seq_ObjFanoutLMax( Abc_Obj_t * pObj );
extern int Seq_ObjFanoutLMin( Abc_Obj_t * pObj );
extern int Seq_ObjFanoutLSum( Abc_Obj_t * pObj );
extern int Seq_ObjFaninLSum( Abc_Obj_t * pObj );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

192
src/base/seq/seqLatch.c Normal file
View File

@ -0,0 +1,192 @@
/**CFile****************************************************************
FileName [seqLatch.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis [Manipulation of latch data structures representing initial states.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqLatch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Insert the first Lat on the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
Seq_Lat_t * pLat, * pRing, * pPrev;
pRing = Seq_NodeGetRing( pObj, Edge );
pLat = Seq_NodeCreateLat( pObj );
if ( pRing == NULL )
{
Seq_LatSetPrev( pLat, pLat );
Seq_LatSetNext( pLat, pLat );
Seq_NodeSetRing( pObj, Edge, pLat );
}
else
{
pPrev = Seq_LatPrev( pRing );
Seq_LatSetPrev( pLat, pPrev );
Seq_LatSetNext( pPrev, pLat );
Seq_LatSetPrev( pRing, pLat );
Seq_LatSetNext( pLat, pRing );
Seq_NodeSetRing( pObj, Edge, pLat ); // rotate the ring to make pLat the first
}
Seq_LatSetInit( pLat, Init );
Abc_ObjAddFaninL( pObj, Edge, 1 );
}
/**Function*************************************************************
Synopsis [Insert the last Lat on the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
Seq_Lat_t * pLat, * pRing, * pPrev;
pRing = Seq_NodeGetRing( pObj, Edge );
pLat = Seq_NodeCreateLat( pObj );
if ( pRing == NULL )
{
Seq_LatSetPrev( pLat, pLat );
Seq_LatSetNext( pLat, pLat );
Seq_NodeSetRing( pObj, Edge, pLat );
}
else
{
pPrev = Seq_LatPrev( pRing );
Seq_LatSetPrev( pLat, pPrev );
Seq_LatSetNext( pPrev, pLat );
Seq_LatSetPrev( pRing, pLat );
Seq_LatSetNext( pLat, pRing );
}
Seq_LatSetInit( pLat, Init );
Abc_ObjAddFaninL( pObj, Edge, 1 );
}
/**Function*************************************************************
Synopsis [Delete the first Lat on the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_InitType_t Seq_NodeDeleteFirst( Abc_Obj_t * pObj, int Edge )
{
Abc_InitType_t Init;
Seq_Lat_t * pLat, * pRing, * pPrev, * pNext;
pRing = Seq_NodeGetRing( pObj, Edge );
pLat = pRing; // consider the first latch
if ( pLat->pNext == pLat )
Seq_NodeSetRing( pObj, Edge, NULL );
else
{
pPrev = Seq_LatPrev( pLat );
pNext = Seq_LatNext( pLat );
Seq_LatSetPrev( pNext, pPrev );
Seq_LatSetNext( pPrev, pNext );
Seq_NodeSetRing( pObj, Edge, pNext ); // rotate the ring
}
Init = Seq_LatInit( pLat );
Seq_NodeRecycleLat( pObj, pLat );
Abc_ObjAddFaninL( pObj, Edge, -1 );
return Init;
}
/**Function*************************************************************
Synopsis [Delete the last Lat on the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_InitType_t Seq_NodeDeleteLast( Abc_Obj_t * pObj, int Edge )
{
Abc_InitType_t Init;
Seq_Lat_t * pLat, * pRing, * pPrev, * pNext;
pRing = Seq_NodeGetRing( pObj, Edge );
pLat = Seq_LatPrev( pRing ); // consider the last latch
if ( pLat->pNext == pLat )
Seq_NodeSetRing( pObj, Edge, NULL );
else
{
pPrev = Seq_LatPrev( pLat );
pNext = Seq_LatNext( pLat );
Seq_LatSetPrev( pNext, pPrev );
Seq_LatSetNext( pPrev, pNext );
}
Init = Seq_LatInit( pLat );
Seq_NodeRecycleLat( pObj, pLat );
Abc_ObjAddFaninL( pObj, Edge, -1 );
return Init;
}
/**Function*************************************************************
Synopsis [Insert the last Lat on the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge )
{
Seq_Lat_t * pRing, * pLat;
int i, nLatches;
pRing = Seq_NodeGetRing( pObj, Edge );
if ( pRing == NULL )
return;
nLatches = Seq_NodeCountLats( pObj, Edge );
for ( i = 0, pLat = pRing; i < nLatches; i++, pLat = pLat->pNext )
Seq_NodeInsertLast( pObjNew, Edge, Seq_LatInit(pLat) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

110
src/base/seq/seqMan.c Normal file
View File

@ -0,0 +1,110 @@
/**CFile****************************************************************
FileName [seqMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates sequential AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk )
{
Abc_Seq_t * p;
// start the manager
p = ALLOC( Abc_Seq_t, 1 );
memset( p, 0, sizeof(Abc_Seq_t) );
p->pNtk = pNtk;
p->nSize = 1000;
// create internal data structures
p->vInits = Vec_PtrStart( 2 * p->nSize );
p->pMmInits = Extra_MmFixedStart( sizeof(Seq_Lat_t) );
p->vLValues = Vec_IntStart( p->nSize );
p->vLags = Vec_StrStart( p->nSize );
return p;
}
/**Function*************************************************************
Synopsis [Deallocates sequential AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_Resize( Abc_Seq_t * p, int nMaxId )
{
if ( p->nSize > nMaxId )
return;
p->nSize = nMaxId + 1;
Vec_PtrFill( p->vInits, 2 * p->nSize, NULL );
Vec_IntFill( p->vLValues, p->nSize, 0 );
Vec_StrFill( p->vLags, p->nSize, 0 );
}
/**Function*************************************************************
Synopsis [Deallocates sequential AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_Delete( Abc_Seq_t * p )
{
if ( p->vMapAnds ) Vec_PtrFree( p->vMapAnds ); // the nodes used in the mapping
if ( p->vMapCuts ) Vec_VecFree( p->vMapCuts ); // the cuts used in the mapping
if ( p->vMapBags ) Vec_VecFree( p->vMapBags ); // the nodes included in the cuts used in the mapping
if ( p->vMapLags ) Vec_VecFree( p->vMapLags ); // the lags of the mapped nodes
if ( p->vBestCuts ) Vec_PtrFree( p->vBestCuts ); // the best cuts for nodes
if ( p->vLValues ) Vec_IntFree( p->vLValues ); // the arrival times (L-Values of nodes)
if ( p->vLags ) Vec_StrFree( p->vLags ); // the lags of the mapped nodes
Vec_PtrFree( p->vInits );
Extra_MmFixedStop( p->pMmInits, 0 );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

47
src/base/seq/seqMapCore.c Normal file
View File

@ -0,0 +1,47 @@
/**CFile****************************************************************
FileName [seqMapCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqMapCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

47
src/base/seq/seqMapIter.c Normal file
View File

@ -0,0 +1,47 @@
/**CFile****************************************************************
FileName [seqMapIter.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqMapIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

822
src/base/seq/seqRetCore.c Normal file
View File

@ -0,0 +1,822 @@
/**CFile****************************************************************
FileName [seqRetCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqRetCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*
Retiming can be represented in three equivalent forms:
- as a set of integer lags for each node (array of chars by node ID)
- as a set of node numbers with lag for each, fwd and bwd (two arrays of Seq_RetStep_t_)
- as a set of latch moves over the nodes, fwd and bwd (two arrays of node pointers Abc_Obj_t *)
*/
static void Abc_ObjRetimeForward( Abc_Obj_t * pObj );
static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues );
static void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable );
static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel );
static void Seq_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves );
static int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose );
static void Abc_ObjRetimeForward( Abc_Obj_t * pObj );
static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues );
static void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable );
static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel );
static Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward );
static Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward );
static Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward );
static void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches );
static void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs performs optimal delay retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fInitial, int fVerbose )
{
Abc_Seq_t * p = pNtk->pManFunc;
int RetValue;
if ( !fInitial )
Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC );
// get the retiming lags
Seq_NtkSeqRetimeDelayLags( pNtk, fVerbose );
// implement this retiming
RetValue = Seq_NtkImplementRetiming( pNtk, p->vLags, fVerbose );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
/**Function*************************************************************
Synopsis [Performs most forward retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose )
{
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i;
if ( !fInitial )
Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC );
// get the forward moves
vMoves = Abc_NtkUtilRetimingTry( pNtk, 1 );
// undo the forward moves
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeBackwardTry( pNode, 1 );
// implement this forward retiming
Seq_NtkImplementRetimingForward( pNtk, vMoves );
Vec_PtrFree( vMoves );
}
/**Function*************************************************************
Synopsis [Performs most backward retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose )
{
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i, RetValue;
if ( !fInitial )
Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC );
// get the backward moves
vMoves = Abc_NtkUtilRetimingTry( pNtk, 0 );
// undo the backward moves
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeForwardTry( pNode, 1 );
// implement this backward retiming
RetValue = Seq_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose );
Vec_PtrFree( vMoves );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
/**Function*************************************************************
Synopsis [Implements the retiming on the sequential AIG.]
Description [Split the retiming into forward and backward.]
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose )
{
Vec_Int_t * vSteps;
Vec_Ptr_t * vMoves;
int RetValue;
// forward retiming
vSteps = Abc_NtkUtilRetimingSplit( vLags, 1 );
// translate each set of steps into moves
if ( fVerbose )
printf( "The number of forward steps = %6d.\n", Vec_IntSize(vSteps) );
vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 1 );
if ( fVerbose )
printf( "The number of forward moves = %6d.\n", Vec_PtrSize(vMoves) );
// implement this retiming
Seq_NtkImplementRetimingForward( pNtk, vMoves );
Vec_IntFree( vSteps );
Vec_PtrFree( vMoves );
// backward retiming
vSteps = Abc_NtkUtilRetimingSplit( vLags, 0 );
// translate each set of steps into moves
if ( fVerbose )
printf( "The number of backward steps = %6d.\n", Vec_IntSize(vSteps) );
vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 0 );
if ( fVerbose )
printf( "The number of backward moves = %6d.\n", Vec_PtrSize(vMoves) );
// implement this retiming
RetValue = Seq_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose );
Vec_IntFree( vSteps );
Vec_PtrFree( vMoves );
return RetValue;
}
/**Function*************************************************************
Synopsis [Implements the given retiming on the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves )
{
Abc_Obj_t * pNode;
int i;
Vec_PtrForEachEntry( vMoves, pNode, i )
Abc_ObjRetimeForward( pNode );
}
/**Function*************************************************************
Synopsis [Retimes node forward by one latch.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeForward( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int Init0, Init1, Init, i;
assert( Abc_ObjFaninNum(pObj) == 2 );
assert( Abc_ObjFaninL0(pObj) >= 1 );
assert( Abc_ObjFaninL1(pObj) >= 1 );
// remove the init values from the fanins
Init0 = Seq_NodeDeleteFirst( pObj, 0 );
Init1 = Seq_NodeDeleteFirst( pObj, 1 );
assert( Init0 != ABC_INIT_NONE );
assert( Init1 != ABC_INIT_NONE );
// take into account the complements in the node
if ( Abc_ObjFaninC0(pObj) )
{
if ( Init0 == ABC_INIT_ZERO )
Init0 = ABC_INIT_ONE;
else if ( Init0 == ABC_INIT_ONE )
Init0 = ABC_INIT_ZERO;
}
if ( Abc_ObjFaninC1(pObj) )
{
if ( Init1 == ABC_INIT_ZERO )
Init1 = ABC_INIT_ONE;
else if ( Init1 == ABC_INIT_ONE )
Init1 = ABC_INIT_ZERO;
}
// compute the value at the output of the node
if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO )
Init = ABC_INIT_ZERO;
else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE )
Init = ABC_INIT_ONE;
else
Init = ABC_INIT_DC;
// add the init values to the fanouts
Abc_ObjForEachFanout( pObj, pFanout, i )
Seq_NodeInsertLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout), Init );
}
/**Function*************************************************************
Synopsis [Implements the given retiming on the sequential AIG.]
Description [Returns 0 of initial state computation fails.]
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose )
{
Seq_RetEdge_t RetEdge;
stmm_table * tTable;
stmm_generator * gen;
Vec_Int_t * vValues;
Abc_Ntk_t * pNtkProb, * pNtkMiter, * pNtkCnf;
Abc_Obj_t * pNode, * pNodeNew;
int * pModel, RetValue, i, clk;
// return if the retiming is trivial
if ( Vec_PtrSize(vMoves) == 0 )
return 1;
// create the network for the initial state computation
// start the table and the array of PO values
pNtkProb = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP );
tTable = stmm_init_table( stmm_numcmp, stmm_numhash );
vValues = Vec_IntAlloc( 100 );
// perform the backward moves and build the network for initial state computation
RetValue = 0;
Vec_PtrForEachEntry( vMoves, pNode, i )
RetValue |= Abc_ObjRetimeBackward( pNode, pNtkProb, tTable, vValues );
// add the PIs corresponding to the white spots
stmm_foreach_item( tTable, gen, (char **)&RetEdge, (char **)&pNodeNew )
Abc_ObjAddFanin( pNodeNew, Abc_NtkCreatePi(pNtkProb) );
// add the PI/PO names
Abc_NtkAddDummyPiNames( pNtkProb );
Abc_NtkAddDummyPoNames( pNtkProb );
// make sure everything is okay with the network structure
if ( !Abc_NtkDoCheck( pNtkProb ) )
{
printf( "Seq_NtkImplementRetimingBackward: The internal network check has failed.\n" );
Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL );
Abc_NtkDelete( pNtkProb );
stmm_free_table( tTable );
Vec_IntFree( vValues );
return 0;
}
// check if conflict is found
if ( RetValue )
{
printf( "Seq_NtkImplementRetimingBackward: A top level conflict is detected. DC latch values are used.\n" );
Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL );
Abc_NtkDelete( pNtkProb );
stmm_free_table( tTable );
Vec_IntFree( vValues );
return 0;
}
// get the miter cone
pNtkMiter = Abc_NtkCreateCone( pNtkProb, pNtkProb->vCos, vValues );
Abc_NtkDelete( pNtkProb );
Vec_IntFree( vValues );
if ( fVerbose )
printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) );
// transform the miter into a logic network for efficient CNF construction
pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 );
Abc_NtkDelete( pNtkMiter );
// solve the miter
clk = clock();
RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 );
if ( fVerbose )
if ( clock() - clk > 100 )
{
PRT( "SAT solving time", clock() - clk );
}
pModel = pNtkCnf->pModel; pNtkCnf->pModel = NULL;
Abc_NtkDelete( pNtkCnf );
// analyze the result
if ( RetValue == -1 || RetValue == 1 )
{
Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL );
if ( RetValue == 1 )
printf( "Seq_NtkImplementRetimingBackward: The problem is unsatisfiable. DC latch values are used.\n" );
else
printf( "Seq_NtkImplementRetimingBackward: The SAT problem timed out. DC latch values are used.\n" );
stmm_free_table( tTable );
return 0;
}
// set the values of the latches
Abc_NtkRetimeSetInitialValues( pNtk, tTable, pModel );
stmm_free_table( tTable );
free( pModel );
return 1;
}
/**Function*************************************************************
Synopsis [Retimes node backward by one latch.]
Description [Constructs the problem for initial state computation.
Returns 1 if the conflict is found.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues )
{
Abc_Obj_t * pFanout;
Abc_InitType_t Init, Value;
Seq_RetEdge_t RetEdge;
Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuffer;
int i, Edge, fMet0, fMet1, fMetN;
// make sure the node can be retimed
assert( Seq_ObjFanoutLMin(pObj) > 0 );
// get the fanout values
fMet0 = fMet1 = fMetN = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
Init = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout) );
if ( Init == ABC_INIT_ZERO )
fMet0 = 1;
else if ( Init == ABC_INIT_ONE )
fMet1 = 1;
else if ( Init == ABC_INIT_NONE )
fMetN = 1;
}
// consider the case when all fanout latchs have don't-care values
// the new values on the fanin edges will be don't-cares
if ( !fMet0 && !fMet1 && !fMetN )
{
// update the fanout edges
Abc_ObjForEachFanout( pObj, pFanout, i )
Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout) );
// update the fanin edges
Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable );
Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable );
Seq_NodeInsertFirst( pObj, 0, ABC_INIT_DC );
Seq_NodeInsertFirst( pObj, 1, ABC_INIT_DC );
return 0;
}
// the initial values on the fanout edges contain 0, 1, or unknown
// the new values on the fanin edges will be unknown
// add new AND-gate to the network
pNodeNew = Abc_NtkCreateNode( pNtkNew );
pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
// add PO fanouts if any
if ( fMet0 )
{
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
Vec_IntPush( vValues, 0 );
}
if ( fMet1 )
{
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
Vec_IntPush( vValues, 1 );
}
// perform the changes
Abc_ObjForEachFanout( pObj, pFanout, i )
{
Edge = Abc_ObjFanoutEdgeNum( pObj, pFanout );
Value = Seq_NodeDeleteLast( pFanout, Edge );
if ( Value != ABC_INIT_NONE )
continue;
// value is unknown, remove it from the table
RetEdge.iNode = pFanout->Id;
RetEdge.iEdge = Edge;
RetEdge.iLatch = Abc_ObjFaninL( pFanout, Edge ); // after edge is removed
if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) )
assert( 0 );
// create the fanout of the AND gate
Abc_ObjAddFanin( pFanoutNew, pNodeNew );
}
// update the fanin edges
Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable );
Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable );
Seq_NodeInsertFirst( pObj, 0, ABC_INIT_NONE );
Seq_NodeInsertFirst( pObj, 1, ABC_INIT_NONE );
// add the buffer
pBuffer = Abc_NtkCreateNode( pNtkNew );
pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
Abc_ObjAddFanin( pNodeNew, pBuffer );
// point to it from the table
RetEdge.iNode = pObj->Id;
RetEdge.iEdge = 0;
RetEdge.iLatch = 0;
if ( stmm_insert( tTable, (char *)Seq_RetEdge2Int(RetEdge), (char *)pBuffer ) )
assert( 0 );
// add the buffer
pBuffer = Abc_NtkCreateNode( pNtkNew );
pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
Abc_ObjAddFanin( pNodeNew, pBuffer );
// point to it from the table
RetEdge.iNode = pObj->Id;
RetEdge.iEdge = 1;
RetEdge.iLatch = 0;
if ( stmm_insert( tTable, (char *)Seq_RetEdge2Int(RetEdge), (char *)pBuffer ) )
assert( 0 );
// report conflict is found
return fMet0 && fMet1;
}
/**Function*************************************************************
Synopsis [Generates the printable edge label with the initial state.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable )
{
Abc_Obj_t * pFanoutNew;
Seq_RetEdge_t RetEdge;
Abc_InitType_t Init;
int nLatches, i;
// get the number of latches on the edge
nLatches = Abc_ObjFaninL( pObj, Edge );
for ( i = nLatches - 1; i >= 0; i-- )
{
// get the value of this latch
Init = Seq_NodeGetInitOne( pObj, Edge, i );
if ( Init != ABC_INIT_NONE )
continue;
// get the retiming edge
RetEdge.iNode = pObj->Id;
RetEdge.iEdge = Edge;
RetEdge.iLatch = i;
// remove entry from table and add it with a different key
if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) )
assert( 0 );
RetEdge.iLatch++;
if ( stmm_insert( tTable, (char *)Seq_RetEdge2Int(RetEdge), (char *)pFanoutNew ) )
assert( 0 );
}
}
/**Function*************************************************************
Synopsis [Sets the initial values.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel )
{
Abc_Obj_t * pNode;
stmm_generator * gen;
Seq_RetEdge_t RetEdge;
Abc_InitType_t Init;
int i;
i = 0;
stmm_foreach_item( tTable, gen, (char **)&RetEdge, NULL )
{
pNode = Abc_NtkObj( pNtk, RetEdge.iNode );
Init = pModel? (pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC;
Seq_NodeSetInitOne( pNode, RetEdge.iEdge, RetEdge.iLatch, Init );
i++;
}
}
/**Function*************************************************************
Synopsis [Performs forward retiming of the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward )
{
Vec_Ptr_t * vNodes, * vMoves;
Abc_Obj_t * pNode, * pFanout, * pFanin;
int i, k, nLatches;
assert( Abc_NtkIsSeq( pNtk ) );
// assume that all nodes can be retimed
vNodes = Vec_PtrAlloc( 100 );
Abc_AigForEachAnd( pNtk, pNode, i )
{
Vec_PtrPush( vNodes, pNode );
pNode->fMarkA = 1;
}
// process the nodes
vMoves = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) );
// unmark the node as processed
pNode->fMarkA = 0;
// get the number of latches to retime
if ( fForward )
nLatches = Abc_ObjFaninLMin(pNode);
else
nLatches = Seq_ObjFanoutLMin(pNode);
if ( nLatches == 0 )
continue;
assert( nLatches > 0 );
// retime the latches forward
if ( fForward )
Abc_ObjRetimeForwardTry( pNode, nLatches );
else
Abc_ObjRetimeBackwardTry( pNode, nLatches );
// write the moves
for ( k = 0; k < nLatches; k++ )
Vec_PtrPush( vMoves, pNode );
// schedule fanouts for updating
if ( fForward )
{
Abc_ObjForEachFanout( pNode, pFanout, k )
{
if ( Abc_ObjFaninNum(pFanout) != 2 || pFanout->fMarkA )
continue;
pFanout->fMarkA = 1;
Vec_PtrPush( vNodes, pFanout );
}
}
else
{
Abc_ObjForEachFanin( pNode, pFanin, k )
{
if ( Abc_ObjFaninNum(pFanin) != 2 || pFanin->fMarkA )
continue;
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
}
}
}
Vec_PtrFree( vNodes );
// make sure the marks are clean the the retiming is final
Abc_AigForEachAnd( pNtk, pNode, i )
{
assert( pNode->fMarkA == 0 );
if ( fForward )
assert( Abc_ObjFaninLMin(pNode) == 0 );
else
assert( Seq_ObjFanoutLMin(pNode) == 0 );
}
return vMoves;
}
/**Function*************************************************************
Synopsis [Translates retiming steps into retiming moves.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward )
{
Seq_RetStep_t RetStep;
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i, k, iNode, nLatches, Number;
int fChange;
assert( Abc_NtkIsSeq( pNtk ) );
// process the nodes
vMoves = Vec_PtrAlloc( 100 );
while ( Vec_IntSize(vSteps) > 0 )
{
iNode = 0;
fChange = 0;
Vec_IntForEachEntry( vSteps, Number, i )
{
// get the retiming step
RetStep = Seq_Int2RetStep( Number );
// get the node to be retimed
pNode = Abc_NtkObj( pNtk, RetStep.iNode );
assert( RetStep.nLatches > 0 );
// get the number of latches that can be retimed
if ( fForward )
nLatches = Abc_ObjFaninLMin(pNode);
else
nLatches = Seq_ObjFanoutLMin(pNode);
if ( nLatches == 0 )
{
Vec_IntWriteEntry( vSteps, iNode++, Seq_RetStep2Int(RetStep) );
continue;
}
assert( nLatches > 0 );
fChange = 1;
// get the number of latches to be retimed over this node
nLatches = ABC_MIN( nLatches, (int)RetStep.nLatches );
// retime the latches forward
if ( fForward )
Abc_ObjRetimeForwardTry( pNode, nLatches );
else
Abc_ObjRetimeBackwardTry( pNode, nLatches );
// write the moves
for ( k = 0; k < nLatches; k++ )
Vec_PtrPush( vMoves, pNode );
// subtract the retiming performed
RetStep.nLatches -= nLatches;
// store the node if it is not retimed completely
if ( RetStep.nLatches > 0 )
Vec_IntWriteEntry( vSteps, iNode++, Seq_RetStep2Int(RetStep) );
}
// reduce the array
Vec_IntShrink( vSteps, iNode );
if ( !fChange )
{
printf( "Warning: %d strange steps (a minor bug to be fixed later).\n", Vec_IntSize(vSteps) );
/*
Vec_IntForEachEntry( vSteps, Number, i )
{
RetStep = Seq_Int2RetStep( Number );
printf( "%d(%d) ", RetStep.iNode, RetStep.nLatches );
}
printf( "\n" );
*/
break;
}
}
// undo the tentative retiming
if ( fForward )
{
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeBackwardTry( pNode, 1 );
}
else
{
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeForwardTry( pNode, 1 );
}
return vMoves;
}
/**Function*************************************************************
Synopsis [Splits retiming into forward and backward.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward )
{
Vec_Int_t * vNodes;
Seq_RetStep_t RetStep;
int Value, i;
vNodes = Vec_IntAlloc( 100 );
Vec_StrForEachEntry( vLags, Value, i )
{
if ( Value < 0 && fForward )
{
RetStep.iNode = i;
RetStep.nLatches = -Value;
Vec_IntPush( vNodes, Seq_RetStep2Int(RetStep) );
}
else if ( Value > 0 && !fForward )
{
RetStep.iNode = i;
RetStep.nLatches = Value;
Vec_IntPush( vNodes, Seq_RetStep2Int(RetStep) );
}
}
return vNodes;
}
/**Function*************************************************************
Synopsis [Retime node forward without initial states.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches )
{
Abc_Obj_t * pFanout;
int i;
// make sure it is an AND gate
assert( Abc_ObjFaninNum(pObj) == 2 );
// make sure it has enough latches
// assert( Abc_ObjFaninL0(pObj) >= nLatches );
// assert( Abc_ObjFaninL1(pObj) >= nLatches );
// subtract these latches on the fanin side
Abc_ObjAddFaninL0( pObj, -nLatches );
Abc_ObjAddFaninL1( pObj, -nLatches );
// add these latches on the fanout size
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_ObjAddFanoutL( pObj, pFanout, nLatches );
}
/**Function*************************************************************
Synopsis [Retime node backward without initial states.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches )
{
Abc_Obj_t * pFanout;
int i;
// make sure it is an AND gate
assert( Abc_ObjFaninNum(pObj) == 2 );
// subtract these latches on the fanout side
Abc_ObjForEachFanout( pObj, pFanout, i )
{
// assert( Abc_ObjFanoutL(pObj, pFanout) >= nLatches );
Abc_ObjAddFanoutL( pObj, pFanout, -nLatches );
}
// add these latches on the fanin size
Abc_ObjAddFaninL0( pObj, nLatches );
Abc_ObjAddFaninL1( pObj, nLatches );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

226
src/base/seq/seqRetIter.c Normal file
View File

@ -0,0 +1,226 @@
/**CFile****************************************************************
FileName [seqRetIter.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqRetIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// the internal procedures
static int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
static int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose );
static int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
// node status after updating its arrival time
enum { SEQ_UPDATE_FAIL, SEQ_UPDATE_NO, SEQ_UPDATE_YES };
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Retimes AIG for optimal delay using Pan's algorithm.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose )
{
Abc_Seq_t * p = pNtk->pManFunc;
Abc_Obj_t * pNode;
int i, FiMax, FiBest, RetValue;
assert( Abc_NtkIsSeq( pNtk ) );
// get the upper bound on the clock period
// FiMax = Abc_NtkNodeNum(pNtk);
FiMax = 0;
Abc_AigForEachAnd( pNtk, pNode, i )
if ( FiMax < (int)pNode->Level )
FiMax = pNode->Level;
FiMax += 2;
// make sure this clock period is feasible
assert( Seq_RetimeForPeriod( pNtk, FiMax, fVerbose ) );
// search for the optimal clock period between 0 and nLevelMax
FiBest = Seq_RetimeSearch_rec( pNtk, 0, FiMax, fVerbose );
// recompute the best LValues
RetValue = Seq_RetimeForPeriod( pNtk, FiBest, fVerbose );
assert( RetValue );
// write the retiming lags
Vec_StrFill( p->vLags, p->nSize, 0 );
Abc_AigForEachAnd( pNtk, pNode, i )
Seq_NodeSetLag( pNode, (char)Seq_NodeComputeLag(Seq_NodeGetLValue(pNode), FiBest) );
// print the result
if ( fVerbose )
printf( "The best clock period is %3d.\n", FiBest );
/*
printf( "LValues : " );
Abc_AigForEachAnd( pNtk, pNode, i )
printf( "%d=%d ", i, Seq_NodeGetLValue(pNode) );
printf( "\n" );
printf( "Lags : " );
Abc_AigForEachAnd( pNtk, pNode, i )
if ( Vec_StrEntry(p->vLags,i) != 0 )
printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(p->vLags,i), Seq_NodeGetLValue(pNode), Seq_NodeGetLValue(pNode) - FiBest * Vec_StrEntry(p->vLags,i) );
printf( "\n" );
*/
}
/**Function*************************************************************
Synopsis [Performs binary search for the optimal clock period.]
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose )
{
int Median;
assert( FiMin < FiMax );
if ( FiMin + 1 == FiMax )
return FiMax;
Median = FiMin + (FiMax - FiMin)/2;
if ( Seq_RetimeForPeriod( pNtk, Median, fVerbose ) )
return Seq_RetimeSearch_rec( pNtk, FiMin, Median, fVerbose ); // Median is feasible
else
return Seq_RetimeSearch_rec( pNtk, Median, FiMax, fVerbose ); // Median is infeasible
}
/**Function*************************************************************
Synopsis [Returns 1 if retiming with this clock period is feasible.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
{
Abc_Seq_t * p = pNtk->pManFunc;
Abc_Obj_t * pObj;
int i, c, RetValue, fChange, Counter;
char * pReason = "";
// set l-values of all nodes to be minus infinity
Vec_IntFill( p->vLValues, p->nSize, -ABC_INFINITY );
// set l-values for the constant and PIs
pObj = Abc_NtkObj( pNtk, 0 );
Seq_NodeSetLValue( pObj, 0 );
Abc_NtkForEachPi( pNtk, pObj, i )
Seq_NodeSetLValue( pObj, 0 );
// update all values iteratively
Counter = 0;
for ( c = 0; c < 20; c++ )
{
fChange = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjIsPi(pObj) )
continue;
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
RetValue = Seq_NodeUpdateLValue( pObj, Fi );
Counter++;
if ( RetValue == SEQ_UPDATE_FAIL )
break;
if ( RetValue == SEQ_UPDATE_NO )
continue;
fChange = 1;
}
if ( RetValue == SEQ_UPDATE_FAIL )
break;
if ( fChange == 0 )
break;
}
if ( c == 20 )
{
RetValue = SEQ_UPDATE_FAIL;
pReason = "(timeout)";
}
// report the results
if ( fVerbose )
{
if ( RetValue == SEQ_UPDATE_FAIL )
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason );
else
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter );
}
return RetValue != SEQ_UPDATE_FAIL;
}
/**Function*************************************************************
Synopsis [Computes the l-value of the node.]
Description [The node can be internal or a PO.]
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
{
int lValueNew, lValueOld, lValue0, lValue1;
assert( !Abc_ObjIsPi(pObj) );
assert( Abc_ObjFaninNum(pObj) > 0 );
lValue0 = Seq_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj);
if ( Abc_ObjIsPo(pObj) )
return (lValue0 > Fi)? SEQ_UPDATE_FAIL : SEQ_UPDATE_NO;
if ( Abc_ObjFaninNum(pObj) == 2 )
lValue1 = Seq_NodeGetLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj);
else
lValue1 = -ABC_INFINITY;
lValueNew = 1 + ABC_MAX( lValue0, lValue1 );
lValueOld = Seq_NodeGetLValue(pObj);
// if ( lValueNew == lValueOld )
if ( lValueNew <= lValueOld )
return SEQ_UPDATE_NO;
Seq_NodeSetLValue( pObj, lValueNew );
return SEQ_UPDATE_YES;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,12 +1,12 @@
/**CFile****************************************************************
FileName [abcShare.c]
FileName [seqShare.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Procedures for latch sharing on the fanout edges.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis [Utilities working sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: seqShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -42,7 +42,7 @@ static void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr
SeeAlso []
***********************************************************************/
void Abc_NtkSeqShareFanouts( Abc_Ntk_t * pNtk )
void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;
@ -84,7 +84,7 @@ void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
if ( Abc_ObjFanoutL(pNode, pFanout) == 0 )
continue;
Type = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) );
Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
nLatches[Type]++;
}
// decide what to do
@ -119,7 +119,7 @@ void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
***********************************************************************/
void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
{
Vec_Int_t * vInits = pNode->pNtk->vInits;
Vec_Ptr_t * vInits = Seq_NodeLats( pNode );
Abc_Obj_t * pFanout, * pBuffer;
Abc_InitType_t Type, InitNew;
int i;
@ -130,29 +130,30 @@ void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vN
{
if ( Abc_ObjFanoutL(pNode, pFanout) == 0 )
continue;
Type = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) );
Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
if ( Type == Init )
InitNew = Init;
if ( Type == Init || Type == ABC_INIT_DC )
{
Vec_PtrPush( vNodes, pFanout );
Abc_ObjFaninLDeleteLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) );
Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
}
}
// create the new buffer
pBuffer = Abc_NtkCreateNode( pNode->pNtk );
Abc_ObjAddFanin( pBuffer, pNode );
Abc_ObjSetFaninL( pBuffer, 0, 1 );
// add the initial state
assert( Vec_IntSize(vInits) == 2 * (int)pBuffer->Id );
Vec_IntPush( vInits, InitNew );
Vec_IntPush( vInits, 0 );
// grow storage for initial states
Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 );
for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ )
Vec_PtrPush( vInits, NULL );
Seq_NodeInsertFirst( pBuffer, 0, InitNew );
// redirect the fanouts
Vec_PtrForEachEntry( vNodes, pFanout, i )
Abc_ObjPatchFanin( pFanout, pNode, pBuffer );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

345
src/base/seq/seqUtil.c Normal file
View File

@ -0,0 +1,345 @@
/**CFile****************************************************************
FileName [seqUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: seqUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the maximum latch number on any of the fanouts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_ObjFanoutLMax( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, nLatchCur, nLatchRes;
if ( Abc_ObjFanoutNum(pObj) == 0 )
return 0;
nLatchRes = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
nLatchCur = Abc_ObjFanoutL(pObj, pFanout);
if ( nLatchRes < nLatchCur )
nLatchRes = nLatchCur;
}
assert( nLatchRes >= 0 );
return nLatchRes;
}
/**Function*************************************************************
Synopsis [Returns the minimum latch number on any of the fanouts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_ObjFanoutLMin( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, nLatchCur, nLatchRes;
if ( Abc_ObjFanoutNum(pObj) == 0 )
return 0;
nLatchRes = ABC_INFINITY;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
nLatchCur = Abc_ObjFanoutL(pObj, pFanout);
if ( nLatchRes > nLatchCur )
nLatchRes = nLatchCur;
}
assert( nLatchRes < ABC_INFINITY );
return nLatchRes;
}
/**Function*************************************************************
Synopsis [Returns the sum of latches on the fanout edges.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_ObjFanoutLSum( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, nSum = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
nSum += Abc_ObjFanoutL(pObj, pFanout);
return nSum;
}
/**Function*************************************************************
Synopsis [Returns the sum of latches on the fanin edges.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_ObjFaninLSum( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanin;
int i, nSum = 0;
Abc_ObjForEachFanin( pObj, pFanin, i )
nSum += Abc_ObjFaninL(pObj, i);
return nSum;
}
/**Function*************************************************************
Synopsis [Generates the printable edge label with the initial state.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Seq_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge )
{
static char Buffer[1000];
Abc_InitType_t Init;
int nLatches, i;
nLatches = Abc_ObjFaninL( pObj, Edge );
for ( i = 0; i < nLatches; i++ )
{
Init = Seq_LatInit( Seq_NodeGetLat(pObj, Edge, i) );
if ( Init == ABC_INIT_NONE )
Buffer[i] = '_';
else if ( Init == ABC_INIT_ZERO )
Buffer[i] = '0';
else if ( Init == ABC_INIT_ONE )
Buffer[i] = '1';
else if ( Init == ABC_INIT_DC )
Buffer[i] = 'x';
else assert( 0 );
}
Buffer[nLatches] = 0;
return Buffer;
}
/**Function*************************************************************
Synopsis [Sets the given value to all the latches of the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NodeLatchSetValues( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
Seq_Lat_t * pLat, * pRing;
int c;
pRing = Seq_NodeGetRing(pObj, Edge);
if ( pRing == NULL )
return;
for ( c = 0, pLat = pRing; !c || pLat != pRing; c++, pLat = pLat->pNext )
Seq_LatSetInit( pLat, Init );
}
/**Function*************************************************************
Synopsis [Sets the given value to all the latches of the edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkLatchSetValues( Abc_Ntk_t * pNtk, Abc_InitType_t Init )
{
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsSeq( pNtk ) );
Abc_NtkForEachPo( pNtk, pObj, i )
Seq_NodeLatchSetValues( pObj, 0, Init );
Abc_NtkForEachNode( pNtk, pObj, i )
{
Seq_NodeLatchSetValues( pObj, 0, Init );
Seq_NodeLatchSetValues( pObj, 1, Init );
}
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_NtkLatchNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Counter;
assert( Abc_NtkIsSeq( pNtk ) );
Counter = 0;
Abc_NtkForEachNode( pNtk, pObj, i )
Counter += Seq_ObjFaninLSum( pObj );
Abc_NtkForEachPo( pNtk, pObj, i )
Counter += Seq_ObjFaninLSum( pObj );
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_NtkLatchNumMax( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Max, Cur;
assert( Abc_NtkIsSeq( pNtk ) );
Max = 0;
Abc_AigForEachAnd( pNtk, pObj, i )
{
Cur = Abc_ObjFaninLMax( pObj );
if ( Max < Cur )
Max = Cur;
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
Cur = Abc_ObjFaninL0( pObj );
if ( Max < Cur )
Max = Cur;
}
return Max;
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_NtkLatchNumShared( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Counter;
assert( Abc_NtkIsSeq( pNtk ) );
Counter = 0;
Abc_NtkForEachPi( pNtk, pObj, i )
Counter += Seq_ObjFanoutLMax( pObj );
Abc_NtkForEachNode( pNtk, pObj, i )
Counter += Seq_ObjFanoutLMax( pObj );
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_ObjLatchGetInitNums( Abc_Obj_t * pObj, int Edge, int * pInits )
{
Abc_InitType_t Init;
int nLatches, i;
nLatches = Abc_ObjFaninL( pObj, Edge );
for ( i = 0; i < nLatches; i++ )
{
Init = Seq_NodeGetInitOne( pObj, Edge, i );
pInits[Init]++;
}
}
/**Function*************************************************************
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits )
{
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsSeq( pNtk ) );
for ( i = 0; i < 4; i++ )
pInits[i] = 0;
Abc_NtkForEachPo( pNtk, pObj, i )
Seq_ObjLatchGetInitNums( pObj, 0, pInits );
Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( Abc_ObjFaninNum(pObj) > 0 )
Seq_ObjLatchGetInitNums( pObj, 0, pInits );
if ( Abc_ObjFaninNum(pObj) > 1 )
Seq_ObjLatchGetInitNums( pObj, 1, pInits );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -64,13 +64,10 @@ int Fpga_Mapping( Fpga_Man_t * p )
p->timeMatch = clock() - clk;
// perform area recovery
if ( p->fAreaRecovery )
{
clk = clock();
if ( !Fpga_MappingPostProcess( p ) )
return 0;
p->timeRecover = clock() - clk;
}
clk = clock();
if ( !Fpga_MappingPostProcess( p ) )
return 0;
p->timeRecover = clock() - clk;
//PRT( "Total mapping time", clock() - clkTotal );
// print the AI-graph used for mapping
@ -114,6 +111,9 @@ printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", p->timeMatch );
}
if ( !p->fAreaRecovery )
return 1;
if ( fRecoverAreaFlow )
{
clk = clock();

View File

@ -46,7 +46,7 @@
***********************************************************************/
int Map_Mapping( Map_Man_t * p )
{
int fShowSwitching = 0;
int fShowSwitching = 1;
int fUseAreaFlow = 1;
int fUseExactArea = !p->fSwitching;
int fUseExactAreaWithPhase = !p->fSwitching;
@ -93,7 +93,11 @@ PRT( "Time", p->timeMatch );
//////////////////////////////////////////////////////////////////////
if ( !p->fAreaRecovery )
{
if ( p->fVerbose )
Map_MappingPrintOutputArrivals( p );
return 1;
}
//////////////////////////////////////////////////////////////////////
// perform area recovery using area flow

View File

@ -179,7 +179,7 @@ int Map_SuperLibDeriveFromGenlib( Mio_Library_t * pLib )
return 0;
// write the current library into the file
strcpy( FileNameGenlib, Mio_LibraryReadName(pLib) );
sprintf( FileNameGenlib, "%s_temp", Mio_LibraryReadName(pLib) );
pFile = fopen( FileNameGenlib, "w" );
Mio_WriteLibrary( pFile, pLib, 0 );
fclose( pFile );

View File

@ -81,6 +81,7 @@ extern char * Mio_LibraryReadSopByName ( Mio_Library_t * pLib, char
extern Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib );
extern Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib );
extern Mio_Gate_t * Mio_LibraryReadNand2 ( Mio_Library_t * pLib );
extern Mio_Gate_t * Mio_LibraryReadAnd2 ( Mio_Library_t * pLib );
extern Mio_Gate_t * Mio_LibraryReadBuf ( Mio_Library_t * pLib );
extern Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib );
extern float Mio_LibraryReadDelayInvRise( Mio_Library_t * pLib );

View File

@ -43,9 +43,10 @@ Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib ) { retur
DdManager * Mio_LibraryReadDd ( Mio_Library_t * pLib ) { return pLib->dd; }
Mio_Gate_t * Mio_LibraryReadBuf ( Mio_Library_t * pLib ) { return pLib->pGateBuf; }
Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { return pLib->pGateInv; }
Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; }
Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ) { return pLib->pGate1; }
Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; }
Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ) { return pLib->pGate1; }
Mio_Gate_t * Mio_LibraryReadNand2 ( Mio_Library_t * pLib ) { return pLib->pGateNand2; }
Mio_Gate_t * Mio_LibraryReadAnd2 ( Mio_Library_t * pLib ) { return pLib->pGateAnd2; }
float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockRise : 0.0); }
float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockFall : 0.0); }
float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockMax : 0.0); }

View File

@ -60,6 +60,7 @@ struct Mio_LibraryStruct_t_
Mio_Gate_t * pGateBuf; // the buffer
Mio_Gate_t * pGateInv; // the inverter
Mio_Gate_t * pGateNand2; // the NAND2 gate
Mio_Gate_t * pGateAnd2; // the AND2 gate
st_table * tName2Gate; // the mapping of gate names into their pointer
DdManager * dd; // the nanager storing functions of gates
Extra_MmFlex_t * pMmFlex; // the memory manaqer for SOPs

View File

@ -418,12 +418,14 @@ char *chomp( char *s )
void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
{
Mio_Gate_t * pGate;
DdNode * bFuncBuf, * bFuncInv, * bFuncNand2;
DdNode * bFuncBuf, * bFuncInv, * bFuncNand2, * bFuncAnd2;
bFuncBuf = pLib->dd->vars[0]; Cudd_Ref( bFuncBuf );
bFuncInv = Cudd_Not( pLib->dd->vars[0] ); Cudd_Ref( bFuncInv );
bFuncNand2 = Cudd_bddNand( pLib->dd, pLib->dd->vars[0], pLib->dd->vars[1] ); Cudd_Ref( bFuncNand2 );
bFuncAnd2 = Cudd_bddAnd( pLib->dd, pLib->dd->vars[0], pLib->dd->vars[1] ); Cudd_Ref( bFuncAnd2 );
// get buffer
Mio_LibraryForEachGate( pLib, pGate )
if ( pLib->pGateBuf == NULL && pGate->bFunc == bFuncBuf )
{
@ -435,7 +437,8 @@ void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
printf( "Warnings: GENLIB library reader cannot detect the buffer gate.\n" );
printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
}
// get inverter
Mio_LibraryForEachGate( pLib, pGate )
if ( pLib->pGateInv == NULL && pGate->bFunc == bFuncInv )
{
@ -448,20 +451,28 @@ void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
}
// get the NAND2 and AND2 gates
Mio_LibraryForEachGate( pLib, pGate )
if ( pLib->pGateNand2 == NULL && pGate->bFunc == bFuncNand2 )
{
pLib->pGateNand2 = pGate;
break;
}
if ( pLib->pGateNand2 == NULL )
Mio_LibraryForEachGate( pLib, pGate )
if ( pLib->pGateAnd2 == NULL && pGate->bFunc == bFuncAnd2 )
{
pLib->pGateAnd2 = pGate;
break;
}
if ( pLib->pGateAnd2 == NULL && pLib->pGateNand2 == NULL )
{
printf( "Warnings: GENLIB library reader cannot detect the NAND2 gate.\n" );
printf( "Warnings: GENLIB library reader cannot detect the AND2 or NAND2 gate.\n" );
printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
}
Cudd_RecursiveDeref( pLib->dd, bFuncInv );
Cudd_RecursiveDeref( pLib->dd, bFuncNand2 );
Cudd_RecursiveDeref( pLib->dd, bFuncAnd2 );
}
/**Function*************************************************************

View File

@ -165,9 +165,9 @@ void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int fPrintSops )
Mio_Pin_t * pPin;
fprintf( pFile, "GATE " );
fprintf( pFile, "%12s ", pGate->pName );
fprintf( pFile, "%12s ", pGate->pName );
fprintf( pFile, "%10.2f ", pGate->dArea );
fprintf( pFile, "O=%s;\n", pGate->pForm );
fprintf( pFile, "%s=%s;\n", pGate->pOutName, pGate->pForm );
// print the pins
if ( fPrintSops )
fprintf( pFile, "%s", pGate->pSop? pGate->pSop : "unspecified\n" );

View File

@ -75,7 +75,6 @@ Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams )
{
printf( "The nodes of the network are not DFS ordered.\n" );
// Abc_NtkReassignIds( pNtk );
// Abc_AigRehash( pNtk->pManFunc );
return NULL;
}
// make sure there are no dangling nodes (unless they are choices)

View File

@ -26,7 +26,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define EXTRA_BUFFER_SIZE 1048576 // 1M - size of the data chunk stored in memory
#define EXTRA_BUFFER_SIZE 4*1048576 // 1M - size of the data chunk stored in memory
#define EXTRA_OFFSET_SIZE 4096 // 4K - load new data when less than this is left
#define EXTRA_MINIMUM(a,b) (((a) < (b))? (a) : (b))

View File

@ -95,7 +95,7 @@ struct Dec_Man_t_
////////////////////////////////////////////////////////////////////////
/*=== decAbc.c ========================================================*/
extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Aig_t * pMan, Dec_Graph_t * pGraph );
extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph );
extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpdateLevel, int nGain );
/*=== decFactor.c ========================================================*/

View File

@ -39,14 +39,14 @@
SeeAlso []
***********************************************************************/
Abc_Obj_t * Dec_GraphToNetwork( Abc_Aig_t * pMan, Dec_Graph_t * pGraph )
Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph )
{
Abc_Obj_t * pAnd0, * pAnd1;
Dec_Node_t * pNode;
int i;
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
return Abc_ObjNotCond( Abc_AigConst1(pMan), Dec_GraphIsComplement(pGraph) );
return Abc_ObjNotCond( Abc_NtkConst1(pNtk), Dec_GraphIsComplement(pGraph) );
// check for a literal
if ( Dec_GraphIsVar(pGraph) )
return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
@ -55,7 +55,7 @@ Abc_Obj_t * Dec_GraphToNetwork( Abc_Aig_t * pMan, Dec_Graph_t * pGraph )
{
pAnd0 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
pAnd1 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
pNode->pFunc = Abc_AigAnd( pMan, pAnd0, pAnd1 );
pNode->pFunc = Abc_AigAnd( pNtk->pManFunc, pAnd0, pAnd1 );
}
// complement the result if necessary
return Abc_ObjNotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
@ -119,7 +119,7 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
LevelNew = 1 + ABC_MAX( pNode0->Level, pNode1->Level );
if ( pAnd )
{
if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pMan) )
if ( Abc_ObjRegular(pAnd) == Abc_NtkConst1(pRoot->pNtk) )
LevelNew = 0;
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) )
LevelNew = (int)Abc_ObjRegular(pAnd0)->Level;
@ -155,7 +155,7 @@ void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpda
int nNodesNew, nNodesOld;
nNodesOld = Abc_NtkNodeNum(pNtk);
// create the new structure of nodes
pRootNew = Dec_GraphToNetwork( pNtk->pManFunc, pGraph );
pRootNew = Dec_GraphToNetwork( pNtk, pGraph );
// remove the old nodes
Abc_AigReplace( pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel );
// compare the gains

View File

@ -98,6 +98,7 @@ struct Sim_Man_t_
Abc_Ntk_t * pNtk;
int nInputs;
int nOutputs;
int fLightweight;
// internal simulation information
int nSimBits; // the number of bits in simulation info
int nSimWords; // the number of words in simulation info
@ -172,7 +173,7 @@ struct Sim_Pat_t_
extern Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk, int fVerbose );
extern void Sym_ManStop( Sym_Man_t * p );
extern void Sym_ManPrintStats( Sym_Man_t * p );
extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk );
extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk, int fLightweight );
extern void Sim_ManStop( Sim_Man_t * p );
extern void Sim_ManPrintStats( Sim_Man_t * p );
extern Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p );

View File

@ -31,7 +31,7 @@
/**Function*************************************************************
Synopsis [Starts the simulatin manager.]
Synopsis [Starts the simulation manager.]
Description []
@ -83,7 +83,7 @@ Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk, int fVerbose )
/**Function*************************************************************
Synopsis [Stops the simulatin manager.]
Synopsis [Stops the simulation manager.]
Description []
@ -149,11 +149,9 @@ void Sym_ManPrintStats( Sym_Man_t * p )
}
/**Function*************************************************************
Synopsis [Starts the simulatin manager.]
Synopsis [Starts the simulation manager.]
Description []
@ -162,7 +160,7 @@ void Sym_ManPrintStats( Sym_Man_t * p )
SeeAlso []
***********************************************************************/
Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk )
Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk, int fLightweight )
{
Sim_Man_t * p;
// start the manager
@ -175,24 +173,27 @@ Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk )
p->nSimBits = 2048;
p->nSimWords = SIM_NUM_WORDS(p->nSimBits);
p->vSim0 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 );
p->vSim1 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 );
// support information
p->nSuppBits = Abc_NtkCiNum(pNtk);
p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits);
p->vSuppStr = Sim_ComputeStrSupp( pNtk );
p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 );
// other data
p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) );
p->vFifo = Vec_PtrAlloc( 100 );
p->vDiffs = Vec_IntAlloc( 100 );
// allocate support targets (array of unresolved outputs for each input)
p->vSuppTargs = Vec_VecStart( p->nInputs );
p->fLightweight = fLightweight;
if (!p->fLightweight) {
p->vSim1 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 );
// support information
p->nSuppBits = Abc_NtkCiNum(pNtk);
p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits);
p->vSuppStr = Sim_ComputeStrSupp( pNtk );
p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 );
// other data
p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) );
p->vFifo = Vec_PtrAlloc( 100 );
p->vDiffs = Vec_IntAlloc( 100 );
// allocate support targets (array of unresolved outputs for each input)
p->vSuppTargs = Vec_VecStart( p->nInputs );
}
return p;
}
/**Function*************************************************************
Synopsis [Stops the simulatin manager.]
Synopsis [Stops the simulation manager.]
Description []

View File

@ -53,7 +53,7 @@ Vec_Ptr_t * Sim_SimulateSeqRandom( Abc_Ntk_t * pNtk, int nFrames, int nWords )
assert( Abc_NtkIsStrash(pNtk) );
vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nWords * nFrames, 0 );
// set the constant data
pNode = Abc_AigConst1(pNtk->pManFunc);
pNode = Abc_NtkConst1(pNtk);
Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nWords * nFrames, 1 );
// set the random PI data
Abc_NtkForEachPi( pNtk, pNode, i )
@ -94,7 +94,7 @@ Vec_Ptr_t * Sim_SimulateSeqModel( Abc_Ntk_t * pNtk, int nFrames, int * pModel )
int i, k;
vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nFrames, 0 );
// set the constant data
pNode = Abc_AigConst1(pNtk->pManFunc);
pNode = Abc_NtkConst1(pNtk);
Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nFrames, 1 );
// set the random PI data
Abc_NtkForEachPi( pNtk, pNode, i )

View File

@ -106,7 +106,7 @@ Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk, int fVerbose )
srand( 0xABC );
// start the simulation manager
p = Sim_ManStart( pNtk );
p = Sim_ManStart( pNtk, 0 );
// compute functional support using one round of random simulation
Sim_UtilAssignRandom( p );