mirror of https://github.com/YosysHQ/abc.git
Version abc51114
This commit is contained in:
parent
e2619aa120
commit
85f42d0ebd
2
Makefile
2
Makefile
|
|
@ -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
112
abc.dsp
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
1
abc.rc
1
abc.rc
|
|
@ -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
1236
abclib.plg
File diff suppressed because it is too large
Load Diff
|
|
@ -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.
|
||||
|
||||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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] );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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 []
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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++ )
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 ========================================================*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 []
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Reference in New Issue