mirror of https://github.com/YosysHQ/abc.git
Version abc61102
This commit is contained in:
parent
73bb7932f7
commit
faf1265bb8
8
Makefile
8
Makefile
|
|
@ -6,18 +6,18 @@ CP := cp
|
|||
|
||||
PROG := abc
|
||||
|
||||
MODULES := src/base/abc src/base/abci src/base/seq src/base/cmd src/base/io src/base/main \
|
||||
MODULES := src/base/abc src/base/abci 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/espresso src/misc/nm src/misc/vec src/misc/hash \
|
||||
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim \
|
||||
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim src/opt/ret \
|
||||
src/sat/asat src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig \
|
||||
src/temp/ivy src/temp/aig src/temp/rwt src/temp/deco src/temp/mem src/temp/ver
|
||||
|
||||
default: $(PROG)
|
||||
|
||||
OPTFLAGS := -DNDEBUG -O3
|
||||
#OPTFLAGS := -g -O
|
||||
#OPTFLAGS := -DNDEBUG -O3
|
||||
OPTFLAGS := -g -O
|
||||
|
||||
CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES))
|
||||
CXXFLAGS += $(CFLAGS)
|
||||
|
|
|
|||
114
abc.dsp
114
abc.dsp
|
|
@ -186,6 +186,10 @@ SOURCE=.\src\base\abci\abcBalance.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abci\abcBmc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abci\abcClpBdd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -332,73 +336,9 @@ SOURCE=.\src\base\abci\abcUnreach.c
|
|||
|
||||
SOURCE=.\src\base\abci\abcVerify.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\seqAigCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\seq\seqAigIter.c
|
||||
# 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\seqMaxMeanCycle.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
|
||||
SOURCE=.\src\base\abci\abcXsim.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "cmd"
|
||||
|
|
@ -1389,6 +1329,42 @@ SOURCE=.\src\opt\sim\simSymStr.c
|
|||
SOURCE=.\src\opt\sim\simUtils.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "ret"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retArea.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retBwd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retDelay.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retFlow.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retFwd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retInit.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\ret\retInt.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "map"
|
||||
|
||||
|
|
@ -2300,14 +2276,6 @@ SOURCE=.\src\temp\aig\aigTable.c
|
|||
|
||||
SOURCE=.\src\temp\aig\aigUtil.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\aig\cudd2.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\aig\cudd2.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# End Group
|
||||
|
|
|
|||
7
abc.rc
7
abc.rc
|
|
@ -1,7 +1,7 @@
|
|||
# global parameters
|
||||
#set check # checks intermediate networks
|
||||
set check # checks intermediate networks
|
||||
#set checkfio # prints warnings when fanins/fanouts are duplicated
|
||||
#set checkread # checks new networks after reading from file
|
||||
set checkread # checks new networks after reading from file
|
||||
set backup # saves backup networks retrived by "undo" and "recall"
|
||||
set savesteps 1 # sets the maximum number of backup networks to save
|
||||
set progressbar # display the progress bar
|
||||
|
|
@ -61,6 +61,7 @@ alias rez restructure -z
|
|||
alias rs resub
|
||||
alias rsz resub -z
|
||||
alias sa set autoexec ps
|
||||
alias scl scleanup
|
||||
alias so source -x
|
||||
alias st strash
|
||||
alias sw sweep
|
||||
|
|
@ -100,7 +101,7 @@ alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l;
|
|||
# temporaries
|
||||
#alias test "rvl th/lib.v; rvv th/t2.v"
|
||||
#alias test "so c/pure_sat/test.c"
|
||||
alias test "r c/14/csat_998.bench; st; ps"
|
||||
#alias test "r c/14/csat_998.bench; st; ps"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -529,6 +529,8 @@ extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj );
|
|||
extern Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
|
||||
extern Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||
extern Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Ptr_t * Abc_NtkDfsSeq( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Ptr_t * Abc_NtkDfsSeqReverse( Abc_Ntk_t * pNtk );
|
||||
extern bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Ptr_t * Abc_NtkSupport( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||
|
|
@ -570,7 +572,8 @@ extern int Abc_NtkLogicToAig( Abc_Ntk_t * pNtk );
|
|||
extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch );
|
||||
extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk );
|
||||
/*=== abcLib.c ==========================================================*/
|
||||
extern Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
|
||||
/*=== abcLib.c ==========================================================*/
|
||||
extern Abc_Lib_t * Abc_LibCreate( char * pName );
|
||||
extern void Abc_LibFree( Abc_Lib_t * pLib );
|
||||
extern Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib );
|
||||
|
|
@ -595,7 +598,7 @@ extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
|
|||
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
|
||||
extern Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
|
||||
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
|
||||
extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj );
|
||||
extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes );
|
||||
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName );
|
||||
extern Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName );
|
||||
extern Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pNode );
|
||||
|
|
@ -604,14 +607,14 @@ extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
|
|||
extern Abc_Obj_t * Abc_NtkFindCi( Abc_Ntk_t * pNtk, char * pName );
|
||||
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
|
||||
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
|
||||
extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
|
||||
extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
|
||||
extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
|
||||
extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
|
||||
extern Abc_Obj_t * Abc_NodeCreateExor( 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_NtkCreateNodeConst0( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
|
||||
extern Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
|
||||
extern bool Abc_NodeIsConst( Abc_Obj_t * pNode );
|
||||
extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode );
|
||||
extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
|
||||
|
|
@ -673,9 +676,11 @@ extern void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, in
|
|||
extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames );
|
||||
extern void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes );
|
||||
extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
|
||||
extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll);
|
||||
extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll );
|
||||
extern void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj );
|
||||
/*=== abcProve.c ==========================================================*/
|
||||
extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams );
|
||||
extern int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars );
|
||||
/*=== abcReconv.c ==========================================================*/
|
||||
extern Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop );
|
||||
extern void Abc_NtkManCutStop( Abc_ManCut_t * p );
|
||||
|
|
@ -751,7 +756,7 @@ extern Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels );
|
|||
/*=== abcSweep.c ==========================================================*/
|
||||
extern int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes );
|
||||
extern int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== abcTiming.c ==========================================================*/
|
||||
extern Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode );
|
||||
extern Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode );
|
||||
|
|
@ -809,6 +814,7 @@ extern Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
|
|||
extern Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Int_t * Abc_NtkGetCiIds( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkReassignIds( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_ObjPointerCompare( void ** pp1, void ** pp2 );
|
||||
/*=== abcVerify.c ==========================================================*/
|
||||
extern int * Abc_NtkVerifyGetCleanModel( Abc_Ntk_t * pNtk, int nFrames );
|
||||
extern int * Abc_NtkVerifySimulatePattern( Abc_Ntk_t * pNtk, int * pModel );
|
||||
|
|
|
|||
|
|
@ -167,13 +167,8 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
|
||||
// check the nodes
|
||||
if ( Abc_NtkHasAig(pNtk) )
|
||||
{
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
Abc_AigCheck( pNtk->pManFunc );
|
||||
else
|
||||
Abc_NtkSeqCheck( pNtk );
|
||||
}
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
Abc_AigCheck( pNtk->pManFunc );
|
||||
else
|
||||
{
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
|
|
@ -240,9 +235,10 @@ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
|
|||
Vec_Int_t * vNameIds;
|
||||
char * pName;
|
||||
int i, NameId;
|
||||
|
||||
/*
|
||||
if ( Abc_NtkIsNetlist(pNtk) )
|
||||
{
|
||||
|
||||
// check that each net has a name
|
||||
Abc_NtkForEachNet( pNtk, pObj, i )
|
||||
{
|
||||
|
|
@ -254,6 +250,7 @@ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
// check that each CI/CO has a name
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
|
|
|
|||
|
|
@ -207,6 +207,118 @@ void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
|||
Vec_PtrPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs DFS for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkDfsSeq_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
// if this node is already visited, skip
|
||||
if ( Abc_NodeIsTravIdCurrent( pNode ) )
|
||||
return;
|
||||
// mark the node as visited
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
// visit the transitive fanin of the node
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
Abc_NtkDfsSeq_rec( pFanin, vNodes );
|
||||
// add the node after the fanins have been added
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of nodes and latches reachable from POs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NtkDfsSeq( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
// set the traversal ID
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
// start the array of nodes
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkDfsSeq_rec( pObj, vNodes );
|
||||
// mark the PIs
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkDfsSeq_rec( pObj, vNodes );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs DFS for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkDfsSeqReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i;
|
||||
// if this node is already visited, skip
|
||||
if ( Abc_NodeIsTravIdCurrent( pNode ) )
|
||||
return;
|
||||
// mark the node as visited
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
// visit the transitive fanin of the node
|
||||
Abc_ObjForEachFanout( pNode, pFanout, i )
|
||||
Abc_NtkDfsSeqReverse_rec( pFanout, vNodes );
|
||||
// add the node after the fanins have been added
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of nodes and latches reachable from POs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NtkDfsSeqReverse( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
// set the traversal ID
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
// start the array of nodes
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkDfsSeqReverse_rec( pObj, vNodes );
|
||||
// mark the logic feeding into POs
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkDfsSeq_rec( pObj, vNodes );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the ordering of nodes is DFS.]
|
||||
|
|
@ -611,9 +723,9 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
|
|||
Abc_Obj_t * pFanin;
|
||||
int fAcyclic, i;
|
||||
assert( !Abc_ObjIsNet(pNode) );
|
||||
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) )
|
||||
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
|
||||
return 1;
|
||||
assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
|
||||
assert( Abc_ObjIsNode(pNode) );
|
||||
// make sure the node is not visited
|
||||
assert( !Abc_NodeIsTravIdPrevious(pNode) );
|
||||
// check if the node is part of the combinational loop
|
||||
|
|
|
|||
|
|
@ -223,8 +223,8 @@ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
|
|||
int nFanoutsOld, i;
|
||||
assert( !Abc_ObjIsComplement(pNodeFrom) );
|
||||
assert( !Abc_ObjIsComplement(pNodeTo) );
|
||||
assert( Abc_ObjIsNode(pNodeFrom) );
|
||||
assert( Abc_ObjIsNode(pNodeTo) );
|
||||
assert( Abc_ObjIsNode(pNodeFrom) || Abc_ObjIsCi(pNodeFrom) );
|
||||
assert( !Abc_ObjIsPo(pNodeTo) );
|
||||
assert( pNodeFrom->pNtk == pNodeTo->pNtk );
|
||||
assert( pNodeFrom != pNodeTo );
|
||||
assert( Abc_ObjFanoutNum(pNodeFrom) > 0 );
|
||||
|
|
@ -255,12 +255,9 @@ void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
|
|||
{
|
||||
assert( !Abc_ObjIsComplement(pNodeOld) );
|
||||
assert( !Abc_ObjIsComplement(pNodeNew) );
|
||||
assert( Abc_ObjIsNode(pNodeOld) );
|
||||
assert( Abc_ObjIsNode(pNodeNew) );
|
||||
assert( pNodeOld->pNtk == pNodeNew->pNtk );
|
||||
assert( pNodeOld != pNodeNew );
|
||||
assert( Abc_ObjFanoutNum(pNodeOld) > 0 );
|
||||
assert( Abc_ObjFanoutNum(pNodeNew) == 0 );
|
||||
// transfer the fanouts to the old node
|
||||
Abc_ObjTransferFanout( pNodeOld, pNodeNew );
|
||||
// remove the old node
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ bool Abc_NtkLatchIsSelfFeed_rec( Abc_Obj_t * pLatch, Abc_Obj_t * pLatchRoot )
|
|||
pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
|
||||
if ( !Abc_ObjIsBi(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
|
||||
return 0;
|
||||
return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch );
|
||||
return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatchRoot );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -120,7 +120,7 @@ int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk )
|
|||
if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) )
|
||||
pConst1 = Abc_AigConst1(pNtk);
|
||||
else
|
||||
pConst1 = Abc_NodeCreateConst1(pNtk);
|
||||
pConst1 = Abc_NtkCreateNodeConst1(pNtk);
|
||||
Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pConst1 );
|
||||
Counter++;
|
||||
}
|
||||
|
|
@ -170,6 +170,28 @@ void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
|
|||
Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Strashes one logic node using its SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vArray;
|
||||
Abc_Obj_t * pLatch;
|
||||
int i;
|
||||
vArray = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
Vec_IntPush( vArray, Abc_LatchIsInit1(pLatch) );
|
||||
return vArray;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -253,9 +253,12 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk, int fDirect )
|
|||
}
|
||||
else if ( Abc_NtkIsSeq(pNtk) )
|
||||
{
|
||||
assert( 0 );
|
||||
/*
|
||||
pNtkTemp = Abc_NtkSeqToLogicSop(pNtk);
|
||||
pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp );
|
||||
Abc_NtkDelete( pNtkTemp );
|
||||
*/
|
||||
}
|
||||
else if ( Abc_NtkIsBddLogic(pNtk) )
|
||||
{
|
||||
|
|
@ -416,7 +419,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
|
|||
// if the constant node is used, duplicate it
|
||||
pObj = Abc_AigConst1(pNtk);
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
pObj->pCopy = Abc_NodeCreateConst1(pNtkNew);
|
||||
pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
// duplicate the nodes and create node functions
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
|
|
@ -505,19 +508,19 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
|
|||
pObj = Abc_AigConst1(pNtk);
|
||||
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
|
||||
{
|
||||
pObj->pCopy = Abc_NodeCreateConst1(pNtkNew);
|
||||
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
|
||||
pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
|
||||
}
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
|
||||
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
|
||||
pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
|
||||
// duplicate the nodes, create node functions, and inverters
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
Abc_NtkDupObj( pNtkNew, pObj, 0 );
|
||||
pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL );
|
||||
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
|
||||
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
|
||||
pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
|
||||
}
|
||||
// connect the objects
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan
|
|||
// start the functionality manager
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
pNtk->pManFunc = Abc_AigAlloc( pNtk );
|
||||
else if ( Abc_NtkIsSeq(pNtk) )
|
||||
pNtk->pManFunc = Seq_Create( pNtk );
|
||||
// else if ( Abc_NtkIsSeq(pNtk) )
|
||||
// pNtk->pManFunc = Seq_Create( pNtk );
|
||||
else if ( Abc_NtkHasSop(pNtk) )
|
||||
pNtk->pManFunc = Extra_MmFlexStart();
|
||||
else if ( Abc_NtkHasBdd(pNtk) )
|
||||
|
|
@ -301,6 +301,7 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
|
|||
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
|
||||
|
|
@ -333,6 +334,7 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
|
|||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
Vec_PtrPush( pNtkNew->vCutSet, pObj->pCopy );
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
// duplicate the nets and nodes (CIs/COs/latches already dupped)
|
||||
|
|
@ -353,6 +355,65 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
|
|||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Attaches the second network at the bottom of the first.]
|
||||
|
||||
Description [Returns the first network. Deletes the second network.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pFanin, * pBuffer;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i, k;
|
||||
assert( pNtkBottom != NULL );
|
||||
if ( pNtkTop == NULL )
|
||||
return pNtkBottom;
|
||||
// make sure the networks are combinational
|
||||
assert( Abc_NtkPiNum(pNtkTop) == Abc_NtkCiNum(pNtkTop) );
|
||||
assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkCiNum(pNtkBottom) );
|
||||
// make sure the POs of the bottom correspond to the PIs of the top
|
||||
assert( Abc_NtkPoNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) );
|
||||
assert( Abc_NtkPiNum(pNtkBottom) < Abc_NtkPiNum(pNtkTop) );
|
||||
// add buffers for the PIs of the top - save results in the POs of the bottom
|
||||
Abc_NtkForEachPi( pNtkTop, pObj, i )
|
||||
{
|
||||
pBuffer = Abc_NtkCreateNodeBuf( pNtkTop, NULL );
|
||||
Abc_ObjTransferFanout( pObj, pBuffer );
|
||||
Abc_NtkPo(pNtkBottom, i)->pCopy = pBuffer;
|
||||
}
|
||||
// remove useless PIs of the top
|
||||
for ( i = Abc_NtkPiNum(pNtkTop) - 1; i >= Abc_NtkPiNum(pNtkBottom); i-- )
|
||||
Abc_NtkDeleteObj( Abc_NtkPi(pNtkTop, i) );
|
||||
assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) );
|
||||
// copy the bottom network
|
||||
Abc_NtkForEachPi( pNtkBottom, pObj, i )
|
||||
Abc_NtkPi(pNtkBottom, i)->pCopy = Abc_NtkPi(pNtkTop, i);
|
||||
// construct all nodes
|
||||
vNodes = Abc_NtkDfs( pNtkBottom, 0 );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
Abc_NtkDupObj(pNtkTop, pObj, 0);
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// connect the POs
|
||||
Abc_NtkForEachPo( pNtkBottom, pObj, i )
|
||||
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
|
||||
// delete old network
|
||||
Abc_NtkDelete( pNtkBottom );
|
||||
// return the network
|
||||
if ( !Abc_NtkCheck( pNtkTop ) )
|
||||
fprintf( stdout, "Abc_NtkAttachBottom(): Network check has failed.\n" );
|
||||
return pNtkTop;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the network composed of one logic cone.]
|
||||
|
|
@ -720,8 +781,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
|
|||
// start the functionality manager
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
Abc_AigFree( pNtk->pManFunc );
|
||||
else if ( Abc_NtkIsSeq(pNtk) )
|
||||
Seq_Delete( pNtk->pManFunc );
|
||||
// else if ( Abc_NtkIsSeq(pNtk) )
|
||||
// Seq_Delete( pNtk->pManFunc );
|
||||
else if ( Abc_NtkHasSop(pNtk) )
|
||||
Extra_MmFlexStop( pNtk->pManFunc, 0 );
|
||||
else if ( Abc_NtkHasBdd(pNtk) )
|
||||
|
|
@ -777,7 +838,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
|
|||
if ( Abc_ObjFaninNum(pNet) > 0 )
|
||||
continue;
|
||||
// add the constant 0 driver
|
||||
pNode = Abc_NodeCreateConst0( pNtk );
|
||||
pNode = Abc_NtkCreateNodeConst0( pNtk );
|
||||
// add the fanout net
|
||||
Abc_ObjAddFanin( pNet, pNode );
|
||||
// add the net to those for which the warning will be printed
|
||||
|
|
|
|||
|
|
@ -129,10 +129,10 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
|
|||
Vec_PtrPush( pNtk->vCos, pObj );
|
||||
break;
|
||||
case ABC_OBJ_BI:
|
||||
Vec_PtrPush( pNtk->vCis, pObj );
|
||||
if ( pNtk->vCis ) Vec_PtrPush( pNtk->vCis, pObj );
|
||||
break;
|
||||
case ABC_OBJ_BO:
|
||||
Vec_PtrPush( pNtk->vCos, pObj );
|
||||
if ( pNtk->vCos ) Vec_PtrPush( pNtk->vCos, pObj );
|
||||
break;
|
||||
case ABC_OBJ_ASSERT:
|
||||
Vec_PtrPush( pNtk->vAsserts, pObj );
|
||||
|
|
@ -146,7 +146,7 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
|
|||
pObj->pData = (void *)ABC_INIT_NONE;
|
||||
case ABC_OBJ_TRI:
|
||||
case ABC_OBJ_BLACKBOX:
|
||||
Vec_PtrPush( pNtk->vBoxes, pObj );
|
||||
if ( pNtk->vBoxes ) Vec_PtrPush( pNtk->vBoxes, pObj );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
@ -171,6 +171,9 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
|
|||
Abc_Ntk_t * pNtk = pObj->pNtk;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i;
|
||||
// remove from the table of names
|
||||
if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
|
||||
Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
|
||||
// delete fanins and fanouts
|
||||
assert( !Abc_ObjIsComplement(pObj) );
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
|
|
@ -186,9 +189,6 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
|
|||
pObj->Id = (1<<26)-1;
|
||||
pNtk->nObjCounts[pObj->Type]--;
|
||||
pNtk->nObjs--;
|
||||
// remove from the table of names
|
||||
if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
|
||||
Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
|
||||
// perform specialized operations depending on the object type
|
||||
switch (pObj->Type)
|
||||
{
|
||||
|
|
@ -210,10 +210,10 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
|
|||
Vec_PtrRemove( pNtk->vCos, pObj );
|
||||
break;
|
||||
case ABC_OBJ_BI:
|
||||
Vec_PtrRemove( pNtk->vCis, pObj );
|
||||
if ( pNtk->vCis ) Vec_PtrRemove( pNtk->vCis, pObj );
|
||||
break;
|
||||
case ABC_OBJ_BO:
|
||||
Vec_PtrRemove( pNtk->vCos, pObj );
|
||||
if ( pNtk->vCos ) Vec_PtrRemove( pNtk->vCos, pObj );
|
||||
break;
|
||||
case ABC_OBJ_ASSERT:
|
||||
Vec_PtrRemove( pNtk->vAsserts, pObj );
|
||||
|
|
@ -230,7 +230,7 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
|
|||
case ABC_OBJ_LATCH:
|
||||
case ABC_OBJ_TRI:
|
||||
case ABC_OBJ_BLACKBOX:
|
||||
Vec_PtrRemove( pNtk->vBoxes, pObj );
|
||||
if ( pNtk->vBoxes ) Vec_PtrRemove( pNtk->vBoxes, pObj );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
@ -251,20 +251,30 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj )
|
||||
void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = pObj->pNtk;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i;
|
||||
assert( !Abc_ObjIsComplement(pObj) );
|
||||
assert( !Abc_ObjIsPi(pObj) );
|
||||
assert( Abc_ObjFanoutNum(pObj) == 0 );
|
||||
// delete fanins and fanouts
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NodeCollectFanins( pObj, vNodes );
|
||||
Abc_NtkDeleteObj( pObj );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
|
||||
Abc_NtkDeleteObj_rec( pObj );
|
||||
if ( fOnlyNodes )
|
||||
{
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
|
||||
Abc_NtkDeleteObj_rec( pObj, fOnlyNodes );
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
if ( !Abc_ObjIsPi(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
|
||||
Abc_NtkDeleteObj_rec( pObj, fOnlyNodes );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
|
|
@ -530,7 +540,7 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
|
||||
|
|
@ -559,7 +569,7 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
|
||||
|
|
@ -588,12 +598,12 @@ Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
|
||||
pNode = Abc_NtkCreateNode( pNtk );
|
||||
Abc_ObjAddFanin( pNode, pFanin );
|
||||
if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin );
|
||||
if ( Abc_NtkHasSop(pNtk) )
|
||||
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" );
|
||||
else if ( Abc_NtkHasBdd(pNtk) )
|
||||
|
|
@ -618,12 +628,12 @@ Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
|
||||
pNode = Abc_NtkCreateNode( pNtk );
|
||||
Abc_ObjAddFanin( pNode, pFanin );
|
||||
pNode = Abc_NtkCreateNode( pNtk );
|
||||
if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin );
|
||||
if ( Abc_NtkHasSop(pNtk) )
|
||||
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" );
|
||||
else if ( Abc_NtkHasBdd(pNtk) )
|
||||
|
|
@ -648,7 +658,7 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
|
|
@ -678,7 +688,7 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
|
|
@ -708,7 +718,7 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
|
|
@ -738,7 +748,7 @@ Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 )
|
||||
Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
assert( Abc_NtkIsLogic(pNtk) );
|
||||
|
|
@ -772,8 +782,7 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t *
|
|||
bool Abc_NodeIsConst( Abc_Obj_t * pNode )
|
||||
{
|
||||
assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) );
|
||||
assert( Abc_ObjIsNode(pNode) );
|
||||
return Abc_ObjFaninNum(pNode) == 0;
|
||||
return Abc_ObjIsNode(pNode) && Abc_ObjFaninNum(pNode) == 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -316,12 +316,18 @@ void Abc_NodeMffsConeSupp( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSu
|
|||
void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode )
|
||||
{
|
||||
Vec_Ptr_t * vCone, * vSupp;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
vCone = Vec_PtrAlloc( 100 );
|
||||
vSupp = Vec_PtrAlloc( 100 );
|
||||
Abc_NodeDeref_rec( pNode );
|
||||
Abc_NodeMffsConeSupp( pNode, vCone, vSupp );
|
||||
Abc_NodeRef_rec( pNode );
|
||||
printf( "Cone = %6d. Supp = %6d. \n", Vec_PtrSize(vCone), Vec_PtrSize(vSupp) );
|
||||
printf( "Node = %6s : Supp = %3d Cone = %3d (",
|
||||
Abc_ObjName(pNode), Vec_PtrSize(vSupp), Vec_PtrSize(vCone) );
|
||||
Vec_PtrForEachEntry( vCone, pObj, i )
|
||||
printf( " %s", Abc_ObjName(pObj) );
|
||||
printf( " )\n" );
|
||||
Vec_PtrFree( vCone );
|
||||
Vec_PtrFree( vSupp );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
|
||||
void Abc_NtkShowAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesShow )
|
||||
{
|
||||
FILE * pFile;
|
||||
Abc_Obj_t * pNode;
|
||||
|
|
@ -96,7 +96,7 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
|
|||
char FileNameDot[200];
|
||||
int i;
|
||||
|
||||
assert( Abc_NtkHasAig(pNtk) );
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// create the file name
|
||||
Abc_ShowGetFileName( pNtk->pName, FileNameDot );
|
||||
// check that the file can be opened
|
||||
|
|
@ -112,7 +112,7 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
|
|||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
// write the DOT file
|
||||
Io_WriteDotAig( pNtk, vNodes, NULL, FileNameDot, 0 );
|
||||
Io_WriteDotAig( pNtk, vNodes, vNodesShow, FileNameDot, 0 );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// visualize the file
|
||||
|
|
|
|||
|
|
@ -81,6 +81,17 @@ void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk )
|
|||
Vec_PtrPush( pNtk->vCos, pObj );
|
||||
Abc_NtkForEachBox( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjIsLatch(pObj) )
|
||||
continue;
|
||||
Abc_ObjForEachFanin( pObj, pTerm, k )
|
||||
Vec_PtrPush( pNtk->vCos, pTerm );
|
||||
Abc_ObjForEachFanout( pObj, pTerm, k )
|
||||
Vec_PtrPush( pNtk->vCis, pTerm );
|
||||
}
|
||||
Abc_NtkForEachBox( pNtk, pObj, i )
|
||||
{
|
||||
if ( !Abc_ObjIsLatch(pObj) )
|
||||
continue;
|
||||
Abc_ObjForEachFanin( pObj, pTerm, k )
|
||||
Vec_PtrPush( pNtk->vCos, pTerm );
|
||||
Abc_ObjForEachFanout( pObj, pTerm, k )
|
||||
|
|
@ -545,11 +556,11 @@ void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fD
|
|||
// add inverters and buffers when necessary
|
||||
if ( Abc_ObjFaninC0(pNodeCo) )
|
||||
{
|
||||
pDriverNew = Abc_NodeCreateInv( pNtk, pDriver );
|
||||
pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
|
||||
Abc_ObjXorFaninC( pNodeCo, 0 );
|
||||
}
|
||||
else
|
||||
pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver );
|
||||
pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
|
||||
}
|
||||
// update the fanin of the PO node
|
||||
Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
|
||||
|
|
@ -925,13 +936,14 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc
|
|||
}
|
||||
else
|
||||
fclose( pFile );
|
||||
|
||||
/*
|
||||
if ( Abc_NtkIsSeq(pNtk) )
|
||||
{
|
||||
pNtk1 = Abc_NtkSeqToLogicSop(pNtk);
|
||||
*pfDelete1 = 1;
|
||||
}
|
||||
else
|
||||
*/
|
||||
pNtk1 = pNtk;
|
||||
pNtk2 = Io_Read( pNtk->pSpec, fCheck );
|
||||
if ( pNtk2 == NULL )
|
||||
|
|
@ -945,12 +957,14 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc
|
|||
fprintf( pErr, "Empty current network.\n" );
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
if ( Abc_NtkIsSeq(pNtk) )
|
||||
{
|
||||
pNtk1 = Abc_NtkSeqToLogicSop(pNtk);
|
||||
*pfDelete1 = 1;
|
||||
}
|
||||
else
|
||||
*/
|
||||
pNtk1 = pNtk;
|
||||
pNtk2 = Io_Read( argv[util_optind], fCheck );
|
||||
if ( pNtk2 == NULL )
|
||||
|
|
@ -1265,6 +1279,26 @@ void Abc_NtkDetectMatching( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the pointers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjPointerCompare( void ** pp1, void ** pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ static int Abc_CommandPrintExdc ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPrintLatch ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPrintMffc ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -90,6 +91,7 @@ static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandEspresso ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandXsim ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandIStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -102,6 +104,7 @@ static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -166,6 +169,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Printing", "print_latch", Abc_CommandPrintLatch, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Abc_CommandPrintFanio, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Printing", "print_mffc", Abc_CommandPrintMffc, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 );
|
||||
|
|
@ -220,6 +224,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Various", "espresso", Abc_CommandEspresso, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "gen", Abc_CommandGen, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "xsim", Abc_CommandXsim, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "istrash", Abc_CommandIStrash, 1 );
|
||||
|
|
@ -232,6 +237,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "New AIG", "iprove", Abc_CommandIProve, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "bmc", Abc_CommandBmc, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
|
||||
|
|
@ -250,15 +256,15 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "FPGA mapping", "ffpga", Abc_CommandFpgaFast, 1 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "pga", Abc_CommandPga, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "scut", Abc_CommandScut, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "scut", Abc_CommandScut, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "scleanup", Abc_CommandSeqCleanup, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
|
||||
|
|
@ -269,8 +275,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
// Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "howard", Abc_CommandHoward, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Sequential", "skew_fwd", Abc_CommandSkewForward, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "howard", Abc_CommandHoward, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "Sequential", "skew_fwd", Abc_CommandSkewForward, 0 );
|
||||
|
||||
// Rwt_Man4ExploreStart();
|
||||
// Map_Var3Print();
|
||||
|
|
@ -618,6 +624,58 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandPrintMffc( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
extern void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// print the nodes
|
||||
Abc_NtkPrintMffc( pOut, pNtk );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: print_mffc [-h]\n" );
|
||||
fprintf( pErr, "\t prints the MFFC of each node in the network\n" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1581,7 +1639,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int fMulti;
|
||||
extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesShow );
|
||||
extern void Abc_NtkShowMulti( Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
|
|
@ -1609,7 +1667,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ( !Abc_NtkHasAig(pNtk) )
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Visualizing networks other than AIGs can be done using command \"show_ntk\".\n" );
|
||||
return 1;
|
||||
|
|
@ -1622,7 +1680,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
if ( !fMulti )
|
||||
Abc_NtkShowAig( pNtk );
|
||||
Abc_NtkShowAig( pNtk, NULL );
|
||||
else
|
||||
Abc_NtkShowMulti( pNtk );
|
||||
return 0;
|
||||
|
|
@ -1683,7 +1741,7 @@ int Abc_CommandShowNtk( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ( Abc_NtkHasAig(pNtk) )
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Visualizing AIG can only be done using command \"show_aig\".\n" );
|
||||
return 1;
|
||||
|
|
@ -4964,6 +5022,88 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int nFrames;
|
||||
int fInputs;
|
||||
int fVerbose;
|
||||
extern void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nFrames = 10;
|
||||
fInputs = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Fivh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'F':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nFrames = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nFrames < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'i':
|
||||
fInputs ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for strashed networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Abc_NtkXValueSimulate( pNtk, nFrames, fInputs, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: xsim [-F num] [-ivh]\n" );
|
||||
fprintf( pErr, "\t performs X-valued simulation of the AIG\n" );
|
||||
fprintf( pErr, "\t-F num : the number of frames to simulate [default = %d]\n", nFrames );
|
||||
fprintf( pErr, "\t-i : toggle X-valued state or X-valued inputs [default = %s]\n", fInputs? "inputs": "state" );
|
||||
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -4978,11 +5118,12 @@ usage:
|
|||
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
Abc_Ntk_t * pNtk;//, * pNtkRes;
|
||||
int c;
|
||||
int nLevels;
|
||||
// extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk );
|
||||
// extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -5064,7 +5205,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
|
||||
// Ivy_TruthEstimateNodesTest();
|
||||
|
||||
/*
|
||||
pNtkRes = Abc_NtkIvy( pNtk );
|
||||
// pNtkRes = Abc_NtkPlayer( pNtk, nLevels, 0 );
|
||||
// pNtkRes = NULL;
|
||||
|
|
@ -5075,7 +5216,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
|
||||
*/
|
||||
Abc_NtkMaxFlowTest( pNtk );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
@ -5100,7 +5242,7 @@ usage:
|
|||
int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp;
|
||||
int c;
|
||||
extern Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk );
|
||||
|
||||
|
|
@ -5132,11 +5274,12 @@ int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for combinatinally strashed AIG networks.\n" );
|
||||
return 1;
|
||||
pNtkTemp = Abc_NtkStrash( pNtk, 0, 1 );
|
||||
pNtkRes = Abc_NtkIvyStrash( pNtkTemp );
|
||||
Abc_NtkDelete( pNtkTemp );
|
||||
}
|
||||
|
||||
pNtkRes = Abc_NtkIvyStrash( pNtk );
|
||||
else
|
||||
pNtkRes = Abc_NtkIvyStrash( pNtk );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
|
|
@ -5741,9 +5884,9 @@ int Abc_CommandHaig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nIters = 3;
|
||||
fUseZeroCost = 1;
|
||||
fVerbose = 0;
|
||||
nIters = 2;
|
||||
fUseZeroCost = 0;
|
||||
fVerbose = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Izvh" ) ) != EOF )
|
||||
{
|
||||
|
|
@ -5869,6 +6012,94 @@ usage:
|
|||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandBmc( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int nFrames;
|
||||
int fInit;
|
||||
int fVerbose;
|
||||
|
||||
extern void Abc_NtkBmc( Abc_Ntk_t * pNtk, int nFrames, int fInit, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nFrames = 5;
|
||||
fInit = 0;
|
||||
fVerbose = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Kivh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nFrames = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nFrames < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'i':
|
||||
fInit ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Abc_NtkIsSeq(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for non-sequential networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
Abc_NtkBmc( pNtk, nFrames, fInit, fVerbose );
|
||||
else
|
||||
{
|
||||
pNtk = Abc_NtkStrash( pNtk, 0, 1 );
|
||||
Abc_NtkBmc( pNtk, nFrames, fInit, fVerbose );
|
||||
Abc_NtkDelete( pNtk );
|
||||
}
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: bmc [-K num] [-ivh]\n" );
|
||||
fprintf( pErr, "\t perform bounded model checking\n" );
|
||||
fprintf( pErr, "\t-K num : number of time frames [default = %d]\n", nFrames );
|
||||
fprintf( pErr, "\t-i : toggle initialization of the first frame [default = %s]\n", fInit? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -7573,48 +7804,38 @@ usage:
|
|||
int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp;
|
||||
Abc_Ntk_t * pNtk, * pNtkTemp;
|
||||
int c, nMaxIters;
|
||||
int fForward;
|
||||
int fBackward;
|
||||
int fInitial;
|
||||
int fVerbose;
|
||||
int Mode;
|
||||
extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fForward = 0;
|
||||
fBackward = 0;
|
||||
Mode = 3;
|
||||
fInitial = 1;
|
||||
fVerbose = 0;
|
||||
fVerbose = 1;
|
||||
nMaxIters = 15;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Ifbivh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Mvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'I':
|
||||
case 'M':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-I\" should be followed by a positive integer.\n" );
|
||||
fprintf( pErr, "Command line switch \"-M\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nMaxIters = atoi(argv[globalUtilOptind]);
|
||||
Mode = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nMaxIters < 0 )
|
||||
if ( Mode < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'f':
|
||||
fForward ^= 1;
|
||||
break;
|
||||
case 'b':
|
||||
fBackward ^= 1;
|
||||
break;
|
||||
case 'i':
|
||||
fInitial ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -7631,61 +7852,56 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 )
|
||||
if ( !Abc_NtkLatchNum(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "The network has no latches. Retiming is not performed.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( Abc_NtkHasAig(pNtk) )
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
// quit if there are choice nodes
|
||||
if ( Abc_NtkGetChoiceNum(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Currently cannot retime networks with choice nodes.\n" );
|
||||
fprintf( pErr, "Retiming with choice nodes is not implemented.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
pNtkRes = Abc_NtkAigToSeq(pNtk);
|
||||
else
|
||||
pNtkRes = Abc_NtkDup(pNtk);
|
||||
// retime the network
|
||||
if ( fForward )
|
||||
Seq_NtkSeqRetimeForward( pNtkRes, fInitial, fVerbose );
|
||||
else if ( fBackward )
|
||||
Seq_NtkSeqRetimeBackward( pNtkRes, fInitial, fVerbose );
|
||||
else
|
||||
Seq_NtkSeqRetimeDelay( pNtkRes, nMaxIters, fInitial, fVerbose );
|
||||
// if the network is an AIG, convert the result into an AIG
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
pNtkRes = Abc_NtkSeqToLogicSop( pNtkTemp = pNtkRes );
|
||||
Abc_NtkDelete( pNtkTemp );
|
||||
pNtkRes = Abc_NtkStrash( pNtkTemp = pNtkRes, 0, 0 );
|
||||
Abc_NtkDelete( pNtkTemp );
|
||||
}
|
||||
pNtk = Abc_NtkAigToLogicSop( pNtkTemp = pNtk );
|
||||
Abc_NtkDelete( pNtkTemp );
|
||||
}
|
||||
else
|
||||
pNtkRes = Seq_NtkRetime( pNtk, nMaxIters, fInitial, fVerbose );
|
||||
// replace the network
|
||||
if ( pNtkRes == NULL )
|
||||
|
||||
// get the network in the SOP form
|
||||
if ( !Abc_NtkLogicToSop(pNtk, 0) )
|
||||
{
|
||||
fprintf( pErr, "Retiming has failed.\n" );
|
||||
printf( "Converting to SOPs has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
|
||||
if ( !Abc_NtkIsLogic(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "The network is not a logic network. Retiming is not performed.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// perform the retiming
|
||||
Abc_NtkRetime( pNtk, Mode, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: retime [-I num] [-fbih]\n" );
|
||||
fprintf( pErr, "\t retimes the current network using Pan's delay-optimal retiming\n" );
|
||||
fprintf( pErr, "\t-I num : max number of iterations of l-value computation [default = %d]\n", nMaxIters );
|
||||
fprintf( pErr, "\t-f : toggle forward retiming (for AIGs) [default = %s]\n", fForward? "yes": "no" );
|
||||
fprintf( pErr, "\t-b : toggle backward retiming (for AIGs) [default = %s]\n", fBackward? "yes": "no" );
|
||||
fprintf( pErr, "\t-i : toggle computation of initial state [default = %s]\n", fInitial? "yes": "no" );
|
||||
fprintf( pErr, "usage: retime [-M num] [-vh]\n" );
|
||||
fprintf( pErr, "\t retimes the current network using one of the algorithms:\n" );
|
||||
fprintf( pErr, "\t 1: most forward retiming\n" );
|
||||
fprintf( pErr, "\t 2: most backward retiming\n" );
|
||||
fprintf( pErr, "\t 3: min-area retiming\n" );
|
||||
fprintf( pErr, "\t 4: min-delay retiming\n" );
|
||||
fprintf( pErr, "\t 5: min-area under min-delay constraint retiming\n" );
|
||||
fprintf( pErr, "\t-M num : the retiming algorithm to use [default = %d]\n", Mode );
|
||||
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
// fprintf( pErr, "\t-I num : max number of iterations of l-value computation [default = %d]\n", nMaxIters );
|
||||
// fprintf( pErr, "\t-f : toggle forward retiming (for AIGs) [default = %s]\n", fForward? "yes": "no" );
|
||||
// fprintf( pErr, "\t-b : toggle backward retiming (for AIGs) [default = %s]\n", fBackward? "yes": "no" );
|
||||
// fprintf( pErr, "\t-i : toggle computation of initial state [default = %s]\n", fInitial? "yes": "no" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -8069,17 +8285,22 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int fVerbose;
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fVerbose = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -8091,18 +8312,23 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsSeq(pNtk) )
|
||||
if ( !Abc_NtkIsLogic(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for sequential AIGs.\n" );
|
||||
fprintf( pErr, "Only works for logic networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
// modify the current network
|
||||
Seq_NtkCleanup( pNtk, 1 );
|
||||
Abc_NtkCleanupSeq( pNtk, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: scleanup [-h]\n" );
|
||||
fprintf( pErr, "usage: scleanup [-vh]\n" );
|
||||
fprintf( pErr, "\t performs sequential cleanup\n" );
|
||||
fprintf( pErr, "\t - removes nodes/latches that do not feed into POs\n" );
|
||||
fprintf( pErr, "\t - removes and shared latches driven by constants\n" );
|
||||
fprintf( pErr, "\t - replaces autonomous logic by free PI variables\n" );
|
||||
fprintf( pErr, "\t (the latter may change sequential behaviour)\n" );
|
||||
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcBmc.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Performs bounded model check.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcBmc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc );
|
||||
|
||||
static void Abc_NtkBmcReport( Ivy_Man_t * pMan, Ivy_Man_t * pFrames, Ivy_Man_t * pFraig, Vec_Ptr_t * vMapping, int nFrames );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkBmc( Abc_Ntk_t * pNtk, int nFrames, int fInit, int fVerbose )
|
||||
{
|
||||
Ivy_FraigParams_t Params, * pParams = &Params;
|
||||
Ivy_Man_t * pMan, * pFrames, * pFraig;
|
||||
Vec_Ptr_t * vMapping;
|
||||
// convert to IVY manager
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0, 0 );
|
||||
// generate timeframes
|
||||
pFrames = Ivy_ManFrames( pMan, Abc_NtkLatchNum(pNtk), nFrames, fInit, &vMapping );
|
||||
// fraig the timeframes
|
||||
Ivy_FraigParamsDefault( pParams );
|
||||
pParams->nBTLimitNode = ABC_INFINITY;
|
||||
pParams->fVerbose = 0;
|
||||
pParams->fProve = 0;
|
||||
pFraig = Ivy_FraigPerform( pFrames, pParams );
|
||||
printf( "Frames have %6d nodes. ", Ivy_ManNodeNum(pFrames) );
|
||||
printf( "Fraig has %6d nodes.\n", Ivy_ManNodeNum(pFraig) );
|
||||
// report the classes
|
||||
// if ( fVerbose )
|
||||
// Abc_NtkBmcReport( pMan, pFrames, pFraig, vMapping, nFrames );
|
||||
// free stuff
|
||||
Vec_PtrFree( vMapping );
|
||||
Ivy_ManStop( pFraig );
|
||||
Ivy_ManStop( pFrames );
|
||||
Ivy_ManStop( pMan );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkBmcReport( Ivy_Man_t * pMan, Ivy_Man_t * pFrames, Ivy_Man_t * pFraig, Vec_Ptr_t * vMapping, int nFrames )
|
||||
{
|
||||
Ivy_Obj_t * pFirst1, * pFirst2, * pFirst3;
|
||||
int i, f, nIdMax, Prev2, Prev3;
|
||||
nIdMax = Ivy_ManObjIdMax(pMan);
|
||||
// check what is the number of nodes in each frame
|
||||
Prev2 = Prev3 = 0;
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
{
|
||||
Ivy_ManForEachNode( pMan, pFirst1, i )
|
||||
{
|
||||
pFirst2 = Ivy_Regular( Vec_PtrEntry(vMapping, f * nIdMax + pFirst1->Id) );
|
||||
if ( Ivy_ObjIsConst1(pFirst2) || pFirst2->Type == 0 )
|
||||
continue;
|
||||
pFirst3 = Ivy_Regular( pFirst2->pEquiv );
|
||||
if ( Ivy_ObjIsConst1(pFirst3) || pFirst3->Type == 0 )
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if ( f )
|
||||
printf( "Frame %3d : Strash = %5d Fraig = %5d\n", f, pFirst2->Id - Prev2, pFirst3->Id - Prev3 );
|
||||
Prev2 = pFirst2->Id;
|
||||
Prev3 = pFirst3->Id;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
|
|||
int i, nNodesDsd;
|
||||
|
||||
// save the CI nodes in the DSD nodes
|
||||
Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NodeCreateConst1(pNtkNew) );
|
||||
Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NtkCreateNodeConst1(pNtkNew) );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
{
|
||||
pNodeDsd = Dsd_ManagerReadInput( pManDsd, i );
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
|
|||
Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
|
||||
// set the constant node
|
||||
// if ( Fpga_NodeReadRefs(Fpga_ManReadConst1(pMan)) > 0 )
|
||||
Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) );
|
||||
Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkCreateNodeConst1(pNtkNew) );
|
||||
// process the nodes in topological order
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ Abc_Ntk_t * Ivy_ManFpgaToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan )
|
|||
// start the new ABC network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_AIG );
|
||||
// transfer the pointers to the basic nodes
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NodeCreateConst1(pNtkNew) );
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkCreateNodeConst1(pNtkNew) );
|
||||
Abc_NtkForEachCi( pNtkNew, pObjAbc, i )
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc );
|
||||
// recursively construct the network
|
||||
|
|
@ -112,7 +112,7 @@ Abc_Ntk_t * Ivy_ManFpgaToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan )
|
|||
if ( Ivy_ObjFaninC0(pObjIvy) ) // complement
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObjAbc) )
|
||||
pObjAbc = Abc_NodeCreateInv( pNtkNew, pObjAbc );
|
||||
pObjAbc = Abc_NtkCreateNodeInv( pNtkNew, pObjAbc );
|
||||
else
|
||||
{
|
||||
// clone the node
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ static inline Abc_Obj_t * Abc_EdgeToNode( Abc_Ntk_t * p, Abc_Edge_t Edge ) {
|
|||
static inline Abc_Obj_t * Abc_ObjFanin0Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ); }
|
||||
static inline Abc_Obj_t * Abc_ObjFanin1Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ); }
|
||||
|
||||
static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs );
|
||||
static Vec_Int_t * Abc_NtkCollectLatchValuesIvy( Abc_Ntk_t * pNtk, int fUseDcs );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -85,7 +85,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
|
|||
if ( fSeq && Abc_NtkCountSelfFeedLatches(pNtk) )
|
||||
{
|
||||
printf( "Warning: The network has %d self-feeding latches. Quitting.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
|
||||
return NULL;
|
||||
// return NULL;
|
||||
}
|
||||
// print warning about choice nodes
|
||||
if ( Abc_NtkGetChoiceNum( pNtk ) )
|
||||
|
|
@ -102,9 +102,9 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
|
|||
if ( fSeq )
|
||||
{
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk, fUseDc );
|
||||
Ivy_ManMakeSeq( pMan, nLatches, pInit );
|
||||
FREE( pInit );
|
||||
Vec_Int_t * vInit = Abc_NtkCollectLatchValuesIvy( pNtk, fUseDc );
|
||||
Ivy_ManMakeSeq( pMan, nLatches, vInit->pArray );
|
||||
Vec_IntFree( vInit );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
return pMan;
|
||||
|
|
@ -191,8 +191,8 @@ Abc_Ntk_t * Abc_NtkIvyHaig( Abc_Ntk_t * pNtk, int nIters, int fUseZeroCost, int
|
|||
return NULL;
|
||||
|
||||
Ivy_ManHaigStart( pMan, fVerbose );
|
||||
Ivy_ManRewriteSeq( pMan, 0, 0 );
|
||||
for ( i = 1; i < nIters; i++ )
|
||||
// Ivy_ManRewriteSeq( pMan, 0, 0 );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
Ivy_ManRewriteSeq( pMan, fUseZeroCost, 0 );
|
||||
Ivy_ManHaigPostprocess( pMan, fVerbose );
|
||||
|
||||
|
|
@ -486,7 +486,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
int fCleanup = 1;
|
||||
// int nNodes;
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk, 0 );
|
||||
Vec_Int_t * vInit = Abc_NtkCollectLatchValuesIvy( pNtk, 0 );
|
||||
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
assert( !Abc_NtkIsSeq(pNtk) );
|
||||
|
|
@ -494,7 +494,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
{
|
||||
if ( !Abc_NtkBddToSop(pNtk, 0) )
|
||||
{
|
||||
FREE( pInit );
|
||||
Vec_IntFree( vInit );
|
||||
printf( "Abc_NtkIvy(): Converting to SOPs has failed.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -513,7 +513,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
pMan = Abc_NtkToAig( pNtk );
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
{
|
||||
FREE( pInit );
|
||||
Vec_IntFree( vInit );
|
||||
printf( "AIG check has failed.\n" );
|
||||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
|
|
@ -975,22 +975,23 @@ Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, cha
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs )
|
||||
Vec_Int_t * Abc_NtkCollectLatchValuesIvy( Abc_Ntk_t * pNtk, int fUseDcs )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int * pArray, i;
|
||||
pArray = ALLOC( int, Abc_NtkLatchNum(pNtk) );
|
||||
Vec_Int_t * vArray;
|
||||
int i;
|
||||
vArray = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
if ( fUseDcs || Abc_LatchIsInitDc(pLatch) )
|
||||
pArray[i] = IVY_INIT_DC;
|
||||
Vec_IntPush( vArray, IVY_INIT_DC );
|
||||
else if ( Abc_LatchIsInit1(pLatch) )
|
||||
pArray[i] = IVY_INIT_1;
|
||||
Vec_IntPush( vArray, IVY_INIT_1 );
|
||||
else if ( Abc_LatchIsInit0(pLatch) )
|
||||
pArray[i] = IVY_INIT_0;
|
||||
Vec_IntPush( vArray, IVY_INIT_0 );
|
||||
else assert( 0 );
|
||||
}
|
||||
return pArray;
|
||||
return vArray;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ int Abc_NtkSuperChoiceLut( Abc_Ntk_t * pNtk, int nLutSize, int nCutSizeMax, int
|
|||
// if there is no delay improvement, skip; otherwise, update level
|
||||
if ( pObjTop->Level >= pObj->Level )
|
||||
{
|
||||
Abc_NtkDeleteObj_rec( pObjTop );
|
||||
Abc_NtkDeleteObj_rec( pObjTop, 1 );
|
||||
continue;
|
||||
}
|
||||
pObj->Level = pObjTop->Level;
|
||||
|
|
@ -570,7 +570,7 @@ Abc_Obj_t * Abc_NodeSuperChoiceLut( Abc_ManScl_t * p, Abc_Obj_t * pObj )
|
|||
{
|
||||
Vec_PtrForEachEntry( p->vLeaves, pFanin, i )
|
||||
if ( Abc_ObjIsNode(pFanin) && Abc_ObjFanoutNum(pFanin) == 0 )
|
||||
Abc_NtkDeleteObj_rec( pFanin );
|
||||
Abc_NtkDeleteObj_rec( pFanin, 1 );
|
||||
return NULL;
|
||||
}
|
||||
// create the topmost node
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int
|
|||
|
||||
// check the case of constant node
|
||||
if ( Map_NodeIsConst(pNodeMap) )
|
||||
return fPhase? Abc_NodeCreateConst1(pNtkNew) : Abc_NodeCreateConst0(pNtkNew);
|
||||
return fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
|
||||
|
||||
// check if the phase is already implemented
|
||||
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
|
||||
|
|
@ -369,7 +369,7 @@ Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
|
|||
* (since the cut only has 4 variables). An interesting question is what
|
||||
* if the first variable (and not the fifth one is the redundant one;
|
||||
* can that happen?) */
|
||||
return Abc_NodeCreateConst0(pNtkNew);
|
||||
return Abc_NtkCreateNodeConst0(pNtkNew);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -503,14 +503,14 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
|
|||
// set the pointers from the mapper to the new nodes
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
{
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
|
||||
}
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
// if ( Abc_NodeIsConst(pNode) )
|
||||
// continue;
|
||||
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
|
||||
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
|
||||
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
|
||||
}
|
||||
|
||||
|
|
@ -630,7 +630,7 @@ Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * p
|
|||
* (since the cut only has 4 variables). An interesting question is what
|
||||
* if the first variable (and not the fifth one is the redundant one;
|
||||
* can that happen?) */
|
||||
return Abc_NodeCreateConst0(pNtkNew);
|
||||
return Abc_NtkCreateNodeConst0(pNtkNew);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew )
|
|||
pNodeNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node );
|
||||
st_free_table( tBdd2Node );
|
||||
if ( Cudd_IsComplement(bFunc) )
|
||||
pNodeNew = Abc_NodeCreateInv( pNtkNew, pNodeNew );
|
||||
pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
|
|
@ -215,18 +215,18 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
|
|||
Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
|
||||
assert( !Cudd_IsComplement(bFunc) );
|
||||
if ( bFunc == b1 )
|
||||
return Abc_NodeCreateConst1(pNtkNew);
|
||||
return Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) )
|
||||
return pNodeNew;
|
||||
// solve for the children nodes
|
||||
pNodeNew0 = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node );
|
||||
if ( Cudd_IsComplement(cuddE(bFunc)) )
|
||||
pNodeNew0 = Abc_NodeCreateInv( pNtkNew, pNodeNew0 );
|
||||
pNodeNew0 = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew0 );
|
||||
pNodeNew1 = Abc_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node );
|
||||
if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) )
|
||||
assert( 0 );
|
||||
// create the MUX node
|
||||
pNodeNew = Abc_NodeCreateMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 );
|
||||
pNodeNew = Abc_NtkCreateNodeMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 );
|
||||
st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
else
|
||||
fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
|
||||
|
||||
if ( !Abc_NtkIsSeq(pNtk) )
|
||||
// if ( !Abc_NtkIsSeq(pNtk) )
|
||||
fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
|
||||
else
|
||||
fprintf( pFile, " lat = %4d(%d,%d)", Seq_NtkLatchNum(pNtk), Seq_NtkLatchNumShared(pNtk), Seq_NtkLatchNumMax(pNtk) );
|
||||
// else
|
||||
// fprintf( pFile, " lat = %4d(%d,%d)", Seq_NtkLatchNum(pNtk), Seq_NtkLatchNumShared(pNtk), Seq_NtkLatchNumMax(pNtk) );
|
||||
|
||||
if ( Abc_NtkIsNetlist(pNtk) )
|
||||
{
|
||||
|
|
@ -228,6 +228,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
int InitNums[4], Init;
|
||||
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
/*
|
||||
if ( Abc_NtkIsSeq(pNtk) )
|
||||
{
|
||||
Seq_NtkLatchGetInitNums( pNtk, InitNums );
|
||||
|
|
@ -236,7 +237,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
Abc_NtkLatchNum(pNtk), InitNums[0], InitNums[1], InitNums[2], InitNums[3] );
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
if ( Abc_NtkLatchNum(pNtk) == 0 )
|
||||
{
|
||||
fprintf( pFile, "The network is combinational.\n" );
|
||||
|
|
@ -381,6 +382,26 @@ void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode )
|
|||
fprintf( pFile, "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the MFFCs of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
extern void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
Abc_NodeMffsConeSuppPrint( pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the factored form of one node.]
|
||||
|
|
@ -833,6 +854,84 @@ void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll ) {
|
|||
fprintf( pFile, "Endpoint Skews : Total |Skew| = %.2f\t Avg |Skew| = %.2f\t Non-Zero Skews = %d\n",
|
||||
sum, avg, nNonZero );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints information about the object.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
fprintf( pFile, "Object %5d : ", pObj->Id );
|
||||
switch ( pObj->Type )
|
||||
{
|
||||
case ABC_OBJ_NONE:
|
||||
fprintf( pFile, "NONE " );
|
||||
break;
|
||||
case ABC_OBJ_CONST1:
|
||||
fprintf( pFile, "Const1 " );
|
||||
break;
|
||||
case ABC_OBJ_PIO:
|
||||
fprintf( pFile, "PIO " );
|
||||
break;
|
||||
case ABC_OBJ_PI:
|
||||
fprintf( pFile, "PI " );
|
||||
break;
|
||||
case ABC_OBJ_PO:
|
||||
fprintf( pFile, "PO " );
|
||||
break;
|
||||
case ABC_OBJ_BI:
|
||||
fprintf( pFile, "BI " );
|
||||
break;
|
||||
case ABC_OBJ_BO:
|
||||
fprintf( pFile, "BO " );
|
||||
break;
|
||||
case ABC_OBJ_ASSERT:
|
||||
fprintf( pFile, "Assert " );
|
||||
break;
|
||||
case ABC_OBJ_NET:
|
||||
fprintf( pFile, "Net " );
|
||||
break;
|
||||
case ABC_OBJ_NODE:
|
||||
fprintf( pFile, "Node " );
|
||||
break;
|
||||
case ABC_OBJ_GATE:
|
||||
fprintf( pFile, "Gate " );
|
||||
break;
|
||||
case ABC_OBJ_LATCH:
|
||||
fprintf( pFile, "Latch " );
|
||||
break;
|
||||
case ABC_OBJ_TRI:
|
||||
fprintf( pFile, "Tristate" );
|
||||
break;
|
||||
case ABC_OBJ_BLACKBOX:
|
||||
fprintf( pFile, "Blackbox" );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
// print the fanins
|
||||
fprintf( pFile, " Fanins ( " );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
fprintf( pFile, "%d ", pFanin->Id );
|
||||
fprintf( pFile, ") " );
|
||||
// print the logic function
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_NtkIsSopLogic(pObj->pNtk) )
|
||||
fprintf( pFile, " %s", pObj->pData );
|
||||
else
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t
|
|||
static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose );
|
||||
static int Abc_NodeDroppingCost( Abc_Obj_t * pNode );
|
||||
|
||||
static int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes );
|
||||
static void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose );
|
||||
static void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 );
|
||||
static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin );
|
||||
|
|
@ -425,7 +426,7 @@ void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv,
|
|||
return;
|
||||
|
||||
// add the invertor
|
||||
pNodeMinInv = Abc_NodeCreateInv( pNtk, pNodeMin );
|
||||
pNodeMinInv = Abc_NtkCreateNodeInv( pNtk, pNodeMin );
|
||||
|
||||
// move the fanouts of the inverted nodes
|
||||
for ( pNode = pListInv; pNode; pNode = pNode->pNext )
|
||||
|
|
@ -583,7 +584,7 @@ int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
|
|||
if ( Abc_ObjFanoutNum(pNode) > 0 )
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
else
|
||||
Abc_NtkDeleteObj_rec( pNode );
|
||||
Abc_NtkDeleteObj_rec( pNode, 1 );
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// sweep a node into its CO fanout if all of this is true:
|
||||
|
|
@ -672,6 +673,263 @@ void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
|
|||
Cudd_RecursiveDeref( dd, bCof1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes all objects whose trav ID is not current.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeRemoveNonCurrentObjects( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int Counter, i;
|
||||
int fVerbose = 0;
|
||||
|
||||
// report on the nodes to be deleted
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "These nodes will be deleted: \n" );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( !Abc_NodeIsTravIdCurrent( pObj ) )
|
||||
{
|
||||
printf( " " );
|
||||
Abc_ObjPrint( stdout, pObj );
|
||||
}
|
||||
}
|
||||
|
||||
// delete the nodes
|
||||
Counter = 0;
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( !Abc_NodeIsTravIdCurrent( pObj ) )
|
||||
{
|
||||
Abc_NtkDeleteObj( pObj );
|
||||
Counter++;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the fanin of this latch is a constant.]
|
||||
|
||||
Description [Returns 0/1 if constant; -1 if not a constant.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkSetTravId_rec( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||||
return;
|
||||
assert( Abc_ObjFaninNum(pObj) == 1 );
|
||||
Abc_NtkSetTravId_rec( Abc_ObjFanin0(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the fanin of this latch is a constant.]
|
||||
|
||||
Description [Returns 0/1 if constant; -1 if not a constant.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkCheckConstant_rec( Abc_Obj_t * pObj )
|
||||
{
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||||
{
|
||||
if ( !Abc_ObjIsNode(pObj) )
|
||||
return -1;
|
||||
if ( Abc_NodeIsConst0(pObj) )
|
||||
return 0;
|
||||
if ( Abc_NodeIsConst1(pObj) )
|
||||
return 1;
|
||||
assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
if ( Abc_ObjIsLatch(pObj) || Abc_ObjFaninNum(pObj) > 1 )
|
||||
return -1;
|
||||
if ( !Abc_ObjIsNode(pObj) || Abc_NodeIsBuf(pObj) )
|
||||
return Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pObj) );
|
||||
if ( Abc_NodeIsInv(pObj) )
|
||||
{
|
||||
int RetValue = Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pObj) );
|
||||
if ( RetValue == 0 )
|
||||
return 1;
|
||||
if ( RetValue == 1 )
|
||||
return 0;
|
||||
return RetValue;
|
||||
}
|
||||
assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes redundant latches.]
|
||||
|
||||
Description [The redundant latches are of two types:
|
||||
- Latches fed by a constant which matches the init value of the latch.
|
||||
- Latches fed by a constant which does not match the init value of the latch
|
||||
can be all replaced by one latch.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkLatchSweep( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pFanin, * pLatch, * pLatchPivot = NULL;
|
||||
int Counter, RetValue, i;
|
||||
Counter = 0;
|
||||
// go through the latches
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
// check if the latch has constant input
|
||||
RetValue = Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pLatch) );
|
||||
if ( RetValue == -1 )
|
||||
continue;
|
||||
// found a latch with constant fanin
|
||||
if ( (RetValue == 1 && Abc_LatchIsInit0(pLatch)) ||
|
||||
(RetValue == 0 && Abc_LatchIsInit1(pLatch)) )
|
||||
{
|
||||
// fanin constant differs from the latch init value
|
||||
if ( pLatchPivot == NULL )
|
||||
{
|
||||
pLatchPivot = pLatch;
|
||||
continue;
|
||||
}
|
||||
if ( Abc_LatchInit(pLatch) != Abc_LatchInit(pLatchPivot) ) // add inverter
|
||||
pFanin = Abc_NtkCreateNodeInv( pNtk, Abc_ObjFanout0(pLatchPivot) );
|
||||
else
|
||||
pFanin = Abc_ObjFanout0(pLatchPivot);
|
||||
}
|
||||
else
|
||||
pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
|
||||
// replace latch
|
||||
Abc_ObjTransferFanout( Abc_ObjFanout0(pLatch), pFanin );
|
||||
// delete the extra nodes
|
||||
Abc_NtkDeleteObj_rec( Abc_ObjFanout0(pLatch), 0 );
|
||||
Counter++;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Replaces autonumnous logic by free inputs.]
|
||||
|
||||
Description [Assumes that non-autonomous logic is marked with
|
||||
the current ID.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkReplaceAutonomousLogic( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode, * pFanin;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i, k, Counter;
|
||||
// collect the nodes that feed into the reachable logic
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
{
|
||||
// skip non-visited fanins
|
||||
if ( !Abc_NodeIsTravIdCurrent(pNode) )
|
||||
continue;
|
||||
// look for non-visited fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, k )
|
||||
{
|
||||
// skip visited fanins
|
||||
if ( Abc_NodeIsTravIdCurrent(pFanin) )
|
||||
continue;
|
||||
// skip constants and latches fed by constants
|
||||
if ( Abc_NtkCheckConstant_rec(pFanin) != -1 ||
|
||||
(Abc_ObjIsBi(pFanin) && Abc_NtkCheckConstant_rec(Abc_ObjFanin0(Abc_ObjFanin0(pFanin))) != -1) )
|
||||
{
|
||||
Abc_NtkSetTravId_rec( pFanin );
|
||||
continue;
|
||||
}
|
||||
assert( !Abc_ObjIsLatch(pFanin) );
|
||||
Vec_PtrPush( vNodes, pFanin );
|
||||
}
|
||||
}
|
||||
Vec_PtrUniqify( vNodes, Abc_ObjPointerCompare );
|
||||
// replace these nodes by the PIs
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
{
|
||||
pFanin = Abc_NtkCreatePi(pNtk);
|
||||
Abc_NodeSetTravIdCurrent( pFanin );
|
||||
Abc_ObjTransferFanout( pNode, pFanin );
|
||||
}
|
||||
Counter = Vec_PtrSize(vNodes);
|
||||
Vec_PtrFree( vNodes );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sequential cleanup.]
|
||||
|
||||
Description [Performs three tasks:
|
||||
- Removes logic that does not feed into POs.
|
||||
- Removes latches driven by constant values equal to the initial state.
|
||||
- Replaces the autonomous components by additional PI variables.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
int Counter;
|
||||
assert( Abc_NtkIsLogic(pNtk) );
|
||||
// mark the nodes reachable from the POs
|
||||
vNodes = Abc_NtkDfsSeq( pNtk );
|
||||
Vec_PtrFree( vNodes );
|
||||
// remove the non-marked nodes
|
||||
Counter = Abc_NodeRemoveNonCurrentObjects( pNtk );
|
||||
if ( fVerbose )
|
||||
printf( "Cleanup removed %4d dangling objects.\n", Counter );
|
||||
// check if some of the latches can be removed
|
||||
Counter = Abc_NtkLatchSweep( pNtk );
|
||||
if ( fVerbose )
|
||||
printf( "Cleanup removed %4d redundant latches.\n", Counter );
|
||||
// detect the autonomous components
|
||||
vNodes = Abc_NtkDfsSeqReverse( pNtk );
|
||||
Vec_PtrFree( vNodes );
|
||||
// replace them by PIs
|
||||
Counter = Abc_NtkReplaceAutonomousLogic( pNtk );
|
||||
if ( fVerbose )
|
||||
printf( "Cleanup added %4d additional PIs.\n", Counter );
|
||||
// remove the non-marked nodes
|
||||
Counter = Abc_NodeRemoveNonCurrentObjects( pNtk );
|
||||
if ( fVerbose )
|
||||
printf( "Cleanup removed %4d autonomous objects.\n", Counter );
|
||||
// check
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
printf( "Abc_NtkCleanupSeq: The network check has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
|
|||
printf( "Networks are NOT EQUIVALENT after framing.\n" );
|
||||
// report the error
|
||||
pFrames->pModel = Abc_NtkVerifyGetCleanModel( pFrames, 1 );
|
||||
Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pFrames->pModel, nFrames );
|
||||
// Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pFrames->pModel, nFrames );
|
||||
FREE( pFrames->pModel );
|
||||
Abc_NtkDelete( pFrames );
|
||||
return;
|
||||
|
|
@ -365,7 +365,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
|
|||
else if ( RetValue == 0 )
|
||||
{
|
||||
printf( "Networks are NOT EQUIVALENT after fraiging.\n" );
|
||||
Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, Fraig_ManReadModel(pMan), nFrames );
|
||||
// Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, Fraig_ManReadModel(pMan), nFrames );
|
||||
}
|
||||
else assert( 0 );
|
||||
// delete the fraig manager
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcXsim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Using X-valued simulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcXsim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define XVS0 1
|
||||
#define XVS1 2
|
||||
#define XVSX 3
|
||||
|
||||
static inline void Abc_ObjSetXsim( Abc_Obj_t * pObj, int Value ) { pObj->pCopy = (void *)Value; }
|
||||
static inline int Abc_ObjGetXsim( Abc_Obj_t * pObj ) { return (int)pObj->pCopy; }
|
||||
static inline int Abc_XsimInv( int Value )
|
||||
{
|
||||
if ( Value == XVS0 )
|
||||
return XVS1;
|
||||
if ( Value == XVS1 )
|
||||
return XVS0;
|
||||
assert( Value == XVSX );
|
||||
return XVSX;
|
||||
}
|
||||
static inline int Abc_XsimAnd( int Value0, int Value1 )
|
||||
{
|
||||
if ( Value0 == XVS0 || Value1 == XVS0 )
|
||||
return XVS0;
|
||||
if ( Value0 == XVSX || Value1 == XVSX )
|
||||
return XVSX;
|
||||
assert( Value0 == XVS1 && Value1 == XVS1 );
|
||||
return XVS1;
|
||||
}
|
||||
static inline int Abc_XsimRand2()
|
||||
{
|
||||
return (rand() & 1) ? XVS1 : XVS0;
|
||||
}
|
||||
static inline int Abc_XsimRand3()
|
||||
{
|
||||
int RetValue;
|
||||
do {
|
||||
RetValue = rand() & 3;
|
||||
} while ( RetValue == 0 );
|
||||
return RetValue;
|
||||
}
|
||||
static inline int Abc_ObjGetXsimFanin0( Abc_Obj_t * pObj )
|
||||
{
|
||||
int RetValue;
|
||||
RetValue = Abc_ObjGetXsim(Abc_ObjFanin0(pObj));
|
||||
return Abc_ObjFaninC0(pObj)? Abc_XsimInv(RetValue) : RetValue;
|
||||
}
|
||||
static inline int Abc_ObjGetXsimFanin1( Abc_Obj_t * pObj )
|
||||
{
|
||||
int RetValue;
|
||||
RetValue = Abc_ObjGetXsim(Abc_ObjFanin1(pObj));
|
||||
return Abc_ObjFaninC1(pObj)? Abc_XsimInv(RetValue) : RetValue;
|
||||
}
|
||||
static inline void Abc_XsimPrint( FILE * pFile, int Value )
|
||||
{
|
||||
if ( Value == XVS0 )
|
||||
{
|
||||
fprintf( pFile, "0" );
|
||||
return;
|
||||
}
|
||||
if ( Value == XVS1 )
|
||||
{
|
||||
fprintf( pFile, "1" );
|
||||
return;
|
||||
}
|
||||
assert( Value == XVSX );
|
||||
fprintf( pFile, "x" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs X-valued simulation of the sequential network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, f;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
srand( 0x12341234 );
|
||||
// start simulation
|
||||
Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 );
|
||||
if ( fInputs )
|
||||
{
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, XVSX );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), XVSX );
|
||||
}
|
||||
// simulate and print the result
|
||||
fprintf( stdout, "Frame : Inputs : Latches : Outputs\n" );
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
{
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, Abc_XsimAnd(Abc_ObjGetXsimFanin0(pObj), Abc_ObjGetXsimFanin1(pObj)) );
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, Abc_ObjGetXsimFanin0(pObj) );
|
||||
// print out
|
||||
fprintf( stdout, "%2d : ", f );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
|
||||
fprintf( stdout, " : " );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_XsimPrint( stdout, Abc_ObjGetXsim(Abc_ObjFanout0(pObj)) );
|
||||
fprintf( stdout, " : " );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
|
||||
fprintf( stdout, "\n" );
|
||||
// assign input values
|
||||
if ( fInputs )
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, XVSX );
|
||||
else
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
|
||||
// transfer the latch values
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) );
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -2,6 +2,7 @@ SRC += src/base/abci/abc.c \
|
|||
src/base/abci/abcAttach.c \
|
||||
src/base/abci/abcAuto.c \
|
||||
src/base/abci/abcBalance.c \
|
||||
src/base/abci/abcBmc.c \
|
||||
src/base/abci/abcClpBdd.c \
|
||||
src/base/abci/abcClpSop.c \
|
||||
src/base/abci/abcCut.c \
|
||||
|
|
@ -37,4 +38,5 @@ SRC += src/base/abci/abc.c \
|
|||
src/base/abci/abcTiming.c \
|
||||
src/base/abci/abcUnate.c \
|
||||
src/base/abci/abcUnreach.c \
|
||||
src/base/abci/abcVerify.c
|
||||
src/base/abci/abcVerify.c \
|
||||
src/base/abci/abcXsim.c
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesI
|
|||
Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 )
|
||||
{
|
||||
Abc_Obj_t * pNet, * pTerm;
|
||||
pTerm = fConst1? Abc_NodeCreateConst1(pNtk) : Abc_NodeCreateConst0(pNtk);
|
||||
pTerm = fConst1? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
|
||||
pNet = Abc_NtkFindNet(pNtk, pName); assert( pNet );
|
||||
Abc_ObjAddFanin( pNet, pTerm );
|
||||
return pTerm;
|
||||
|
|
@ -200,7 +200,7 @@ Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut
|
|||
{
|
||||
Abc_Obj_t * pNet, * pNode;
|
||||
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
|
||||
pNode = Abc_NodeCreateInv(pNtk, pNet);
|
||||
pNode = Abc_NtkCreateNodeInv(pNtk, pNet);
|
||||
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
|
||||
Abc_ObjAddFanin( pNet, pNode );
|
||||
return pNode;
|
||||
|
|
@ -221,7 +221,7 @@ Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut
|
|||
{
|
||||
Abc_Obj_t * pNet, * pNode;
|
||||
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
|
||||
pNode = Abc_NodeCreateBuf(pNtk, pNet);
|
||||
pNode = Abc_NtkCreateNodeBuf(pNtk, pNet);
|
||||
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
|
||||
Abc_ObjAddFanin( pNet, pNode );
|
||||
return pNet;
|
||||
|
|
|
|||
|
|
@ -112,10 +112,13 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
|
|||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "digraph AIG {\n" );
|
||||
fprintf( pFile, "size = \"7.5,10\";\n" );
|
||||
// fprintf( pFile, "size = \"10,8.5\";\n" );
|
||||
// fprintf( pFile, "size = \"14,11\";\n" );
|
||||
// fprintf( pFile, "page = \"8,11\";\n" );
|
||||
// fprintf( pFile, "ranksep = 0.5;\n" );
|
||||
// fprintf( pFile, "nodesep = 0.5;\n" );
|
||||
fprintf( pFile, "center = true;\n" );
|
||||
// fprintf( pFile, "orientation = landscape;\n" );
|
||||
// fprintf( pFile, "orientation = landscape;\n" );
|
||||
// fprintf( pFile, "edge [fontsize = 10];\n" );
|
||||
// fprintf( pFile, "edge [dir = none];\n" );
|
||||
fprintf( pFile, "edge [dir = back];\n" );
|
||||
|
|
@ -320,8 +323,8 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
|
|||
fprintf( pFile, "Node%d%s", Abc_ObjFaninId0(pNode), (Abc_ObjIsLatch(Abc_ObjFanin0(pNode))? "_out":"") );
|
||||
fprintf( pFile, " [" );
|
||||
fprintf( pFile, "style = %s", Abc_ObjFaninC0(pNode)? "dotted" : "bold" );
|
||||
if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL0(pNode) > 0 )
|
||||
fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) );
|
||||
// if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL0(pNode) > 0 )
|
||||
// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) );
|
||||
fprintf( pFile, "]" );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
|
|
@ -335,8 +338,8 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
|
|||
fprintf( pFile, "Node%d%s", Abc_ObjFaninId1(pNode), (Abc_ObjIsLatch(Abc_ObjFanin1(pNode))? "_out":"") );
|
||||
fprintf( pFile, " [" );
|
||||
fprintf( pFile, "style = %s", Abc_ObjFaninC1(pNode)? "dotted" : "bold" );
|
||||
if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL1(pNode) > 0 )
|
||||
fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
|
||||
// if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL1(pNode) > 0 )
|
||||
// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
|
||||
fprintf( pFile, "]" );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -580,7 +580,8 @@ int Seq_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
|
|||
Abc_NtkNodeNum(pNtk), Vec_PtrSize(vNodesPo), Vec_PtrSize(vNodesPi) );
|
||||
if ( Abc_NtkNodeNum(pNtk) > Vec_PtrSize(vNodesPo) )
|
||||
{
|
||||
Counter = Abc_NtkReduceNodes( pNtk, vNodesPo );
|
||||
// Counter = Abc_NtkReduceNodes( pNtk, vNodesPo );
|
||||
Counter = 0;
|
||||
if ( fVerbose )
|
||||
printf( "Cleanup removed %d nodes that are not reachable from the POs.\n", Counter );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ enum Dsd_Type_t_ {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// complementation and testing for pointers for decomposition entries
|
||||
#define Dsd_IsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Dsd_Regular(p) ((Dsd_Node_t *)((unsigned)(p) & ~01))
|
||||
#define Dsd_Not(p) ((Dsd_Node_t *)((long)(p) ^ 01))
|
||||
#define Dsd_NotCond(p,c) ((Dsd_Node_t *)((long)(p) ^ (c)))
|
||||
#define Dsd_IsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Dsd_Regular(p) ((Dsd_Node_t *)((unsigned long)(p) & ~01))
|
||||
#define Dsd_Not(p) ((Dsd_Node_t *)((unsigned long)(p) ^ 01))
|
||||
#define Dsd_NotCond(p,c) ((Dsd_Node_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
|
|
|
|||
|
|
@ -172,8 +172,8 @@ struct _reo_man
|
|||
|
||||
// used to manipulate units
|
||||
#define Unit_Regular(u) ((reo_unit *)((unsigned long)(u) & ~01))
|
||||
#define Unit_Not(u) ((reo_unit *)((long)(u) ^ 01))
|
||||
#define Unit_NotCond(u,c) ((reo_unit *)((long)(u) ^ (c)))
|
||||
#define Unit_Not(u) ((reo_unit *)((unsigned long)(u) ^ 01))
|
||||
#define Unit_NotCond(u,c) ((reo_unit *)((unsigned long)(u) ^ (c)))
|
||||
#define Unit_IsConstant(u) ((int)((u)->lev == REO_CONST_LEVEL))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ typedef struct Fpga_LutLibStruct_t_ Fpga_LutLib_t;
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Fpga_IsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Fpga_Regular(p) ((Fpga_Node_t *)((unsigned)(p) & ~01))
|
||||
#define Fpga_Not(p) ((Fpga_Node_t *)((long)(p) ^ 01))
|
||||
#define Fpga_NotCond(p,c) ((Fpga_Node_t *)((long)(p) ^ (c)))
|
||||
#define Fpga_IsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Fpga_Regular(p) ((Fpga_Node_t *)((unsigned long)(p) & ~01))
|
||||
#define Fpga_Not(p) ((Fpga_Node_t *)((unsigned long)(p) ^ 01))
|
||||
#define Fpga_NotCond(p,c) ((Fpga_Node_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
#define Fpga_Ref(p)
|
||||
#define Fpga_Deref(p)
|
||||
|
|
|
|||
|
|
@ -67,16 +67,16 @@
|
|||
#define FPGA_SEQ_SIGN(p) (1 << (((unsigned)p)%31));
|
||||
|
||||
// internal macros to work with cuts
|
||||
#define Fpga_CutIsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Fpga_CutRegular(p) ((Fpga_Cut_t *)((unsigned)(p) & ~01))
|
||||
#define Fpga_CutNot(p) ((Fpga_Cut_t *)((long)(p) ^ 01))
|
||||
#define Fpga_CutNotCond(p,c) ((Fpga_Cut_t *)((long)(p) ^ (c)))
|
||||
#define Fpga_CutIsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Fpga_CutRegular(p) ((Fpga_Cut_t *)((unsigned long)(p) & ~01))
|
||||
#define Fpga_CutNot(p) ((Fpga_Cut_t *)((unsigned long)(p) ^ 01))
|
||||
#define Fpga_CutNotCond(p,c) ((Fpga_Cut_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
// the cut nodes
|
||||
#define Fpga_SeqIsComplement( p ) (((int)((long) (p) & 01)))
|
||||
#define Fpga_SeqRegular( p ) ((Fpga_Node_t *)((unsigned)(p) & ~015))
|
||||
#define Fpga_SeqIndex( p ) ((((unsigned)(p)) >> 1) & 07)
|
||||
#define Fpga_SeqIndexCreate( p, Ind ) (((unsigned)(p)) | (1 << (((unsigned)(Ind)) & 07)))
|
||||
#define Fpga_SeqIsComplement( p ) (((int)((unsigned long) (p) & 01)))
|
||||
#define Fpga_SeqRegular( p ) ((Fpga_Node_t *)((unsigned long)(p) & ~015))
|
||||
#define Fpga_SeqIndex( p ) ((((unsigned long)(p)) >> 1) & 07)
|
||||
#define Fpga_SeqIndexCreate( p, Ind ) (((unsigned long)(p)) | (1 << (((unsigned)(Ind)) & 07)))
|
||||
|
||||
// internal macros for referencing of nodes
|
||||
#define Fpga_NodeReadRef(p) ((Fpga_Regular(p))->nRefs)
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ struct Map_TimeStruct_t_
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Map_IsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Map_Regular(p) ((Map_Node_t *)((unsigned)(p) & ~01))
|
||||
#define Map_Not(p) ((Map_Node_t *)((long)(p) ^ 01))
|
||||
#define Map_NotCond(p,c) ((Map_Node_t *)((long)(p) ^ (c)))
|
||||
#define Map_IsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Map_Regular(p) ((Map_Node_t *)((unsigned long)(p) & ~01))
|
||||
#define Map_Not(p) ((Map_Node_t *)((unsigned long)(p) ^ 01))
|
||||
#define Map_NotCond(p,c) ((Map_Node_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@
|
|||
#define MAP_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))
|
||||
|
||||
// internal macros to work with cuts
|
||||
#define Map_CutIsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Map_CutRegular(p) ((Map_Cut_t *)((unsigned)(p) & ~01))
|
||||
#define Map_CutNot(p) ((Map_Cut_t *)((long)(p) ^ 01))
|
||||
#define Map_CutNotCond(p,c) ((Map_Cut_t *)((long)(p) ^ (c)))
|
||||
#define Map_CutIsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Map_CutRegular(p) ((Map_Cut_t *)((unsigned long)(p) & ~01))
|
||||
#define Map_CutNot(p) ((Map_Cut_t *)((unsigned long)(p) ^ 01))
|
||||
#define Map_CutNotCond(p,c) ((Map_Cut_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
// internal macros for referencing of nodes
|
||||
#define Map_NodeReadRef(p) ((Map_Regular(p))->nRefs)
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ struct Super2_GateStruct_t_
|
|||
|
||||
|
||||
// manipulation of complemented attributes
|
||||
#define Super2_IsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Super2_Regular(p) ((Super2_Gate_t *)((unsigned)(p) & ~01))
|
||||
#define Super2_Not(p) ((Super2_Gate_t *)((long)(p) ^ 01))
|
||||
#define Super2_NotCond(p,c) ((Super2_Gate_t *)((long)(p) ^ (c)))
|
||||
#define Super2_IsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Super2_Regular(p) ((Super2_Gate_t *)((unsigned long)(p) & ~01))
|
||||
#define Super2_Not(p) ((Super2_Gate_t *)((unsigned long)(p) ^ 01))
|
||||
#define Super2_NotCond(p,c) ((Super2_Gate_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
// iterating through the gates in the library
|
||||
#define Super2_LibForEachGate( Lib, Gate ) \
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, int Type, char * pName, char
|
|||
nEntrySize = sizeof(Nm_Entry_t) + strlen(pName) + (pSuffix?strlen(pSuffix):0) + 1;
|
||||
nEntrySize = (nEntrySize / 4 + ((nEntrySize % 4) > 0)) * 4;
|
||||
pEntry = (Nm_Entry_t *)Extra_MmFlexEntryFetch( p->pMem, nEntrySize );
|
||||
pEntry->pNextI2N = pEntry->pNextN2I = NULL;
|
||||
pEntry->pNextI2N = pEntry->pNextN2I = pEntry->pNameSake = NULL;
|
||||
pEntry->ObjId = ObjId;
|
||||
pEntry->Type = Type;
|
||||
sprintf( pEntry->Name, "%s%s", pName, pSuffix? pSuffix : "" );
|
||||
|
|
|
|||
|
|
@ -574,10 +574,36 @@ static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
|
|||
***********************************************************************/
|
||||
static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
|
||||
{
|
||||
if ( p->nSize < 2 )
|
||||
return;
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
|
||||
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
|
||||
{
|
||||
int i, k;
|
||||
if ( p->nSize < 2 )
|
||||
return;
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
|
||||
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
|
||||
for ( i = k = 1; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] != p->pArray[i-1] )
|
||||
p->pArray[k++] = p->pArray[i];
|
||||
p->nSize = k;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
SRC += src/opt/dec/retArea.c \
|
||||
src/opt/dec/retBwd.c \
|
||||
src/opt/dec/retCore.c \
|
||||
src/opt/dec/retDelay.c \
|
||||
src/opt/dec/retFlow.c \
|
||||
src/opt/dec/retFwd.c \
|
||||
src/opt/dec/retInit.c
|
||||
|
||||
|
|
@ -0,0 +1,593 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retArea.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis [Min-area retiming.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retArea.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Abc_NtkRetimeMinAreaFwd( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
static Abc_Ntk_t * Abc_NtkRetimeMinAreaBwd( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
static void Abc_NtkRetimeMinAreaPrepare( Abc_Ntk_t * pNtk, int fForward );
|
||||
static Vec_Ptr_t * Abc_NtkRetimeMinAreaAddBuffers( Abc_Ntk_t * pNtk );
|
||||
static void Abc_NtkRetimeMinAreaRemoveBuffers( Abc_Ntk_t * pNtk, Vec_Ptr_t * vBuffers );
|
||||
static void Abc_NtkRetimeMinAreaInitValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut );
|
||||
static Abc_Ntk_t * Abc_NtkRetimeMinAreaConstructNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut );
|
||||
static void Abc_NtkRetimeMinAreaUpdateLatches( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward );
|
||||
|
||||
extern Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs min-area retiming.]
|
||||
|
||||
Description [Returns the number of latches reduced.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkTotal = NULL, * pNtkBottom, * pNtkMiter;
|
||||
Vec_Int_t * vValues;
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
// there should not be black boxes
|
||||
assert( Abc_NtkIsSopLogic(pNtk) );
|
||||
assert( Abc_NtkLatchNum(pNtk) == Vec_PtrSize(pNtk->vBoxes) );
|
||||
// reorder CI/CO/latch inputs
|
||||
Abc_NtkOrderCisCos( pNtk );
|
||||
// perform forward retiming
|
||||
vValues = Abc_NtkCollectLatchValues( pNtk );
|
||||
// Abc_NtkRetimeMinAreaFwd( pNtk, fVerbose );
|
||||
pNtkTotal = Abc_NtkRetimeMinAreaBwd( pNtk, fVerbose );
|
||||
|
||||
// while ( Abc_NtkRetimeMinAreaFwd( pNtk, fVerbose ) );
|
||||
// perform backward retiming
|
||||
// while ( pNtkBottom = Abc_NtkRetimeMinAreaBwd( pNtk, fVerbose ) )
|
||||
// pNtkTotal = Abc_NtkAttachBottom( pNtkTotal, pNtkBottom );
|
||||
// compute initial values
|
||||
if ( pNtkTotal )
|
||||
{
|
||||
// convert the target network to AIG
|
||||
Abc_NtkLogicToAig( pNtkTotal );
|
||||
// get the miter
|
||||
pNtkMiter = Abc_NtkCreateTarget( pNtkTotal, pNtkTotal->vCos, vValues );
|
||||
Abc_NtkDelete( pNtkTotal );
|
||||
// get the initial values
|
||||
Abc_NtkRetimeInitialValues( pNtk, pNtkMiter, fVerbose );
|
||||
Abc_NtkDelete( pNtkMiter );
|
||||
}
|
||||
Vec_IntFree( vValues );
|
||||
// fix the COs
|
||||
Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
|
||||
// check for correctness
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
fprintf( stdout, "Abc_NtkRetimeMinArea(): Network check has failed.\n" );
|
||||
// return the number of latches saved
|
||||
return nLatches - Abc_NtkLatchNum(pNtk);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs min-area retiming forward.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeMinAreaFwd( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vBuffers, * vMinCut;
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
// mark current latches and TFO(PIs)
|
||||
Abc_NtkRetimeMinAreaPrepare( pNtk, 1 );
|
||||
// add buffers on edges feeding into the marked nodes
|
||||
vBuffers = Abc_NtkRetimeMinAreaAddBuffers( pNtk );
|
||||
// run the maximum forward flow
|
||||
vMinCut = Abc_NtkMaxFlow( pNtk, 1, fVerbose );
|
||||
assert( Vec_PtrSize(vMinCut) <= Abc_NtkLatchNum(pNtk) );
|
||||
// create new latch boundary if there is improvement
|
||||
if ( Vec_PtrSize(vMinCut) < Abc_NtkLatchNum(pNtk) )
|
||||
{
|
||||
Abc_NtkRetimeMinAreaInitValue( pNtk, vMinCut );
|
||||
Abc_NtkRetimeMinAreaUpdateLatches( pNtk, vMinCut, 1 );
|
||||
}
|
||||
// clean up
|
||||
Abc_NtkRetimeMinAreaRemoveBuffers( pNtk, vBuffers );
|
||||
Vec_PtrFree( vMinCut );
|
||||
Abc_NtkCleanMarkA( pNtk );
|
||||
return nLatches - Abc_NtkLatchNum(pNtk);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs min-area retiming backward.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkRetimeMinAreaBwd( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = NULL;
|
||||
Vec_Ptr_t * vMinCut;
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
// mark current latches and TFI(POs)
|
||||
Abc_NtkRetimeMinAreaPrepare( pNtk, 0 );
|
||||
// run the maximum forward flow
|
||||
vMinCut = Abc_NtkMaxFlow( pNtk, 0, fVerbose );
|
||||
assert( Vec_PtrSize(vMinCut) <= Abc_NtkLatchNum(pNtk) );
|
||||
// create new latch boundary if there is improvement
|
||||
if ( Vec_PtrSize(vMinCut) < Abc_NtkLatchNum(pNtk) )
|
||||
{
|
||||
pNtkNew = Abc_NtkRetimeMinAreaConstructNtk( pNtk, vMinCut );
|
||||
Abc_NtkRetimeMinAreaUpdateLatches( pNtk, vMinCut, 0 );
|
||||
}
|
||||
// clean up
|
||||
Vec_PtrFree( vMinCut );
|
||||
Abc_NtkCleanMarkA( pNtk );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks the cone with MarkA.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMarkCone_rec( Abc_Obj_t * pObj, int fForward )
|
||||
{
|
||||
Abc_Obj_t * pNext;
|
||||
int i;
|
||||
if ( pObj->fMarkA )
|
||||
return;
|
||||
pObj->fMarkA = 1;
|
||||
if ( fForward )
|
||||
{
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
Abc_NtkMarkCone_rec( pNext, fForward );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
Abc_NtkMarkCone_rec( pNext, fForward );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the network for running MaxFlow.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRetimeMinAreaPrepare( Abc_Ntk_t * pNtk, int fForward )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
if ( fForward )
|
||||
{
|
||||
// mark the frontier
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
{
|
||||
pObj->fMarkA = 1;
|
||||
Abc_ObjFanin0(pObj)->fMarkA = 1;
|
||||
}
|
||||
// mark the nodes reachable from the POs
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkMarkCone_rec( pObj, fForward );
|
||||
}
|
||||
else
|
||||
{
|
||||
// mark the frontier
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
{
|
||||
pObj->fMarkA = 1;
|
||||
Abc_ObjFanout0(pObj)->fMarkA = 1;
|
||||
}
|
||||
// mark the nodes reachable from the POs
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkMarkCone_rec( pObj, fForward );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Add extra buffers.]
|
||||
|
||||
Description [This is needed to make sure that forward retiming
|
||||
works correctly. This has to do with the nodes in the TFO cone
|
||||
of the PIs having multiple incoming edges.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NtkRetimeMinAreaAddBuffers( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vFeeds, * vFanouts;
|
||||
Abc_Obj_t * pObj, * pFanin, * pFanout, * pBuffer;
|
||||
int i, k;
|
||||
// collect all nodes that are feeding into the marked nodes
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
vFeeds = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
if ( !pObj->fMarkA )
|
||||
continue;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
if ( !pFanin->fMarkA && !Abc_NodeIsTravIdCurrent(pFanin) )
|
||||
{
|
||||
Abc_NodeSetTravIdCurrent( pFanin );
|
||||
Vec_PtrPush( vFeeds, pFanin );
|
||||
}
|
||||
}
|
||||
// add buffers for each such node
|
||||
vFanouts = Vec_PtrAlloc( 100 );
|
||||
Vec_PtrForEachEntry( vFeeds, pObj, i )
|
||||
{
|
||||
// create and remember the buffers
|
||||
pBuffer = Abc_NtkCreateNodeBuf( pNtk, pObj );
|
||||
Vec_PtrWriteEntry( vFeeds, i, pBuffer );
|
||||
// patch the fanin of each marked fanout to point to the buffer
|
||||
Abc_NodeCollectFanouts( pObj, vFanouts );
|
||||
Vec_PtrForEachEntry( vFanouts, pFanout, k )
|
||||
if ( pFanout->fMarkA )
|
||||
Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
|
||||
}
|
||||
Vec_PtrFree( vFanouts );
|
||||
// mark the new buffers
|
||||
Vec_PtrForEachEntry( vFeeds, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
return vFeeds;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes extra buffers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRetimeMinAreaRemoveBuffers( Abc_Ntk_t * pNtk, Vec_Ptr_t * vBuffers )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Vec_PtrForEachEntry( vBuffers, pObj, i )
|
||||
{
|
||||
Abc_ObjTransferFanout( pObj, Abc_ObjFanin0(pObj) );
|
||||
Abc_NtkDeleteObj( pObj );
|
||||
}
|
||||
Vec_PtrFree( vBuffers );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the results of simulating one node.]
|
||||
|
||||
Description [Assumes that fanins have pCopy set to the input values.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjSopSimulate( Abc_Obj_t * pObj )
|
||||
{
|
||||
char * pCube, * pSop = pObj->pData;
|
||||
int nVars, Value, v, ResOr, ResAnd, ResVar;
|
||||
assert( pSop && !Abc_SopIsExorType(pSop) );
|
||||
// simulate the SOP of the node
|
||||
ResOr = 0;
|
||||
nVars = Abc_SopGetVarNum(pSop);
|
||||
Abc_SopForEachCube( pSop, nVars, pCube )
|
||||
{
|
||||
ResAnd = 1;
|
||||
Abc_CubeForEachVar( pCube, Value, v )
|
||||
{
|
||||
if ( Value == '0' )
|
||||
ResVar = 1 ^ ((int)Abc_ObjFanin(pObj, v)->pCopy);
|
||||
else if ( Value == '1' )
|
||||
ResVar = (int)Abc_ObjFanin(pObj, v)->pCopy;
|
||||
else
|
||||
continue;
|
||||
ResAnd &= ResVar;
|
||||
}
|
||||
ResOr |= ResAnd;
|
||||
}
|
||||
// complement the result if necessary
|
||||
if ( !Abc_SopGetPhase(pSop) )
|
||||
ResOr ^= 1;
|
||||
return ResOr;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute initial values.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeMinAreaInitValue_rec( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
// skip visited nodes
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return (int)pObj->pCopy;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// consider the case of a latch output
|
||||
if ( Abc_ObjIsBi(pObj) )
|
||||
{
|
||||
assert( Abc_ObjIsLatch(Abc_ObjFanin0(pObj)) );
|
||||
pObj->pCopy = (void *)Abc_NtkRetimeMinAreaInitValue_rec( Abc_ObjFanin0(pObj) );
|
||||
return (int)pObj->pCopy;
|
||||
}
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// visit the fanins
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_NtkRetimeMinAreaInitValue_rec( pFanin );
|
||||
// compute the value of the node
|
||||
pObj->pCopy = (void *)Abc_ObjSopSimulate(pObj);
|
||||
return (int)pObj->pCopy;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute initial values.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRetimeMinAreaInitValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// transfer initial values to pCopy and mark the latches
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
{
|
||||
pObj->pCopy = (void *)Abc_LatchIsInit1(pObj);
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
}
|
||||
// propagate initial values
|
||||
Vec_PtrForEachEntry( vMinCut, pObj, i )
|
||||
Abc_NtkRetimeMinAreaInitValue_rec( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs min-area retiming backward.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkRetimeMinAreaConstructNtk_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
// skip visited nodes
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return pObj->pCopy;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// consider the case of a latch output
|
||||
if ( Abc_ObjIsBo(pObj) )
|
||||
return Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, Abc_ObjFanin0(pObj) );
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// visit the fanins
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, pFanin );
|
||||
// compute the value of the node
|
||||
Abc_NtkDupObj( pNtkNew, pObj, 0 );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
|
||||
return pObj->pCopy;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the network from computing initial state.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkRetimeMinAreaConstructNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj, * pObjNew;
|
||||
int i;
|
||||
// create new network
|
||||
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
|
||||
// set mapping of new latches into the PIs of the network
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Vec_PtrForEachEntry( vMinCut, pObj, i )
|
||||
{
|
||||
pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
}
|
||||
// construct the network recursively
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
{
|
||||
pObjNew = Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, Abc_ObjFanin0(pObj) );
|
||||
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObjNew );
|
||||
}
|
||||
// assign dummy node names
|
||||
Abc_NtkAddDummyPiNames( pNtkNew );
|
||||
Abc_NtkAddDummyPoNames( pNtkNew );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Abc_NtkRetimeMinAreaConstructNtk(): Network check has failed.\n" );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the network after backward retiming.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRetimeMinAreaUpdateLatches( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward )
|
||||
{
|
||||
Vec_Ptr_t * vCis, * vCos, * vBoxes, * vBoxesNew, * vFanouts;
|
||||
Abc_Obj_t * pObj, * pLatch, * pLatchIn, * pLatchOut, * pFanout;
|
||||
int i, k;
|
||||
// create new latches
|
||||
Vec_PtrShrink( pNtk->vCis, Abc_NtkCiNum(pNtk) - Abc_NtkLatchNum(pNtk) );
|
||||
Vec_PtrShrink( pNtk->vCos, Abc_NtkCoNum(pNtk) - Abc_NtkLatchNum(pNtk) );
|
||||
vCis = pNtk->vCis; pNtk->vCis = NULL;
|
||||
vCos = pNtk->vCos; pNtk->vCos = NULL;
|
||||
vBoxes = pNtk->vBoxes; pNtk->vBoxes = NULL;
|
||||
// transfer boxes
|
||||
vBoxesNew = Vec_PtrAlloc(100);
|
||||
Vec_PtrForEachEntry( vBoxes, pObj, i )
|
||||
if ( !Abc_ObjIsLatch(pObj) )
|
||||
Vec_PtrPush( vBoxesNew, pObj );
|
||||
// create or reuse latches
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
vFanouts = Vec_PtrAlloc( 100 );
|
||||
Vec_PtrForEachEntry( vMinCut, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObj) && fForward )
|
||||
{
|
||||
pLatchOut = pObj;
|
||||
pLatch = Abc_ObjFanin0(pLatchOut);
|
||||
pLatchIn = Abc_ObjFanin0(pLatch);
|
||||
assert( Abc_ObjIsBi(pLatchOut) && Abc_ObjIsLatch(pLatch) && Abc_ObjIsBo(pLatchIn) );
|
||||
// mark the latch as reused
|
||||
Abc_NodeSetTravIdCurrent( pLatch );
|
||||
}
|
||||
else if ( Abc_ObjIsCo(pObj) && !fForward )
|
||||
{
|
||||
pLatchIn = pObj;
|
||||
pLatch = Abc_ObjFanout0(pLatchIn);
|
||||
pLatchOut = Abc_ObjFanout0(pLatch);
|
||||
assert( Abc_ObjIsBi(pLatchOut) && Abc_ObjIsLatch(pLatch) && Abc_ObjIsBo(pLatchIn) );
|
||||
// mark the latch as reused
|
||||
Abc_NodeSetTravIdCurrent( pLatch );
|
||||
}
|
||||
else
|
||||
{
|
||||
pLatchOut = Abc_NtkCreateBi(pNtk);
|
||||
pLatch = Abc_NtkCreateLatch(pNtk);
|
||||
pLatchIn = Abc_NtkCreateBo(pNtk);
|
||||
Abc_ObjAssignName( pLatchOut, Abc_ObjName(pLatchOut), NULL );
|
||||
Abc_ObjAssignName( pLatchIn, Abc_ObjName(pLatchIn), NULL );
|
||||
// connect
|
||||
Abc_ObjAddFanin( pLatchOut, pLatch );
|
||||
Abc_ObjAddFanin( pLatch, pLatchIn );
|
||||
if ( fForward )
|
||||
{
|
||||
Abc_ObjTransferFanout( pObj, pLatchOut );
|
||||
pLatch->pData = (void *)(pObj->pCopy? ABC_INIT_ONE : ABC_INIT_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
// redirect unmarked edges
|
||||
Abc_NodeCollectFanouts( pObj, vFanouts );
|
||||
Vec_PtrForEachEntry( vFanouts, pFanout, k )
|
||||
if ( !pFanout->fMarkA )
|
||||
Abc_ObjPatchFanin( pFanout, pObj, pLatchOut );
|
||||
}
|
||||
// connect latch to the node
|
||||
Abc_ObjAddFanin( pLatchIn, pObj );
|
||||
}
|
||||
Vec_PtrPush( vCis, pLatchOut );
|
||||
Vec_PtrPush( vBoxesNew, pLatch );
|
||||
Vec_PtrPush( vCos, pLatchIn );
|
||||
}
|
||||
Vec_PtrFree( vFanouts );
|
||||
// remove useless latches
|
||||
Vec_PtrForEachEntry( vBoxes, pObj, i )
|
||||
{
|
||||
if ( !Abc_ObjIsLatch(pObj) )
|
||||
continue;
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
continue;
|
||||
pLatchOut = Abc_ObjFanout0(pObj);
|
||||
pLatch = pObj;
|
||||
pLatchIn = Abc_ObjFanin0(pObj);
|
||||
Abc_ObjTransferFanout( pLatchOut, Abc_ObjFanin0(pLatchIn) );
|
||||
Abc_NtkDeleteObj( pLatchOut );
|
||||
Abc_NtkDeleteObj( pObj );
|
||||
Abc_NtkDeleteObj( pLatchIn );
|
||||
}
|
||||
// set the arrays
|
||||
pNtk->vCis = vCis;
|
||||
pNtk->vCos = vCos;
|
||||
pNtk->vBoxes = vBoxesNew;
|
||||
Vec_PtrFree( vBoxes );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retBwd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis [Most backward retiming.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retBwd.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
printf( "Not implemented.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retCore.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis [The core retiming procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retCore.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implementation of retiming.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose )
|
||||
{
|
||||
int RetValue;
|
||||
assert( Mode > 0 && Mode < 6 );
|
||||
// perform forward retiming
|
||||
switch ( Mode )
|
||||
{
|
||||
case 1: // forward
|
||||
RetValue = Abc_NtkRetimeForward( pNtk, fVerbose );
|
||||
break;
|
||||
case 2: // backward
|
||||
RetValue = Abc_NtkRetimeBackward( pNtk, fVerbose );
|
||||
break;
|
||||
case 3: // min-area
|
||||
RetValue = Abc_NtkRetimeMinArea( pNtk, fVerbose );
|
||||
break;
|
||||
case 4: // min-delay
|
||||
RetValue = Abc_NtkRetimeMinDelay( pNtk, fVerbose );
|
||||
break;
|
||||
case 5: // min-area + min-delay
|
||||
RetValue = Abc_NtkRetimeMinArea( pNtk, fVerbose );
|
||||
RetValue += Abc_NtkRetimeMinDelay( pNtk, fVerbose );
|
||||
break;
|
||||
default:
|
||||
printf( "Unknown retiming option.\n" );
|
||||
break;
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retDelay.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis [Incremental retiming for optimum delay.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retDelay.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
printf( "Not implemented.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,462 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retFlow.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Implementation of maximum flow (min-area retiming).]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retFlow.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Abc_ObjSetPath( Abc_Obj_t * pObj, Abc_Obj_t * pNext ) { pObj->pCopy = pNext; return 1; }
|
||||
static inline Abc_Obj_t * Abc_ObjGetPath( Abc_Obj_t * pObj ) { return pObj->pCopy; }
|
||||
static inline Abc_Obj_t * Abc_ObjGetFanoutPath( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i;
|
||||
assert( Abc_ObjGetPath(pObj) );
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
if ( Abc_ObjGetPath(pFanout) == pObj )
|
||||
return pFanout;
|
||||
return NULL;
|
||||
}
|
||||
static inline Abc_Obj_t * Abc_ObjGetFaninPath( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
assert( Abc_ObjGetPath(pObj) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
if ( Abc_ObjGetPath(pFanin) == pObj )
|
||||
return pFanin;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int Abc_NtkMaxFlowPath( Abc_Ntk_t * pNtk, int * pStart, int fForward );
|
||||
static int Abc_NtkMaxFlowBwdPath_rec( Abc_Obj_t * pObj );
|
||||
static int Abc_NtkMaxFlowFwdPath_rec( Abc_Obj_t * pObj );
|
||||
static Vec_Ptr_t * Abc_NtkMaxFlowMinCut( Abc_Ntk_t * pNtk );
|
||||
static int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward );
|
||||
static void Abc_NtkMaxFlowPrintFlow( Abc_Ntk_t * pNtk, int fForward );
|
||||
static void Abc_NtkMaxFlowPrintCut( Vec_Ptr_t * vMinCut );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Test-bench for the max-flow computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vMinCut;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
|
||||
// forward flow
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
pObj->fMarkA = Abc_ObjFanin0(pObj)->fMarkA = 1;
|
||||
vMinCut = Abc_NtkMaxFlow( pNtk, 1, 1 );
|
||||
Vec_PtrFree( vMinCut );
|
||||
Abc_NtkCleanMarkA( pNtk );
|
||||
|
||||
// backward flow
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
pObj->fMarkA = Abc_ObjFanout0(pObj)->fMarkA = 1;
|
||||
vMinCut = Abc_NtkMaxFlow( pNtk, 0, 1 );
|
||||
Vec_PtrFree( vMinCut );
|
||||
Abc_NtkCleanMarkA( pNtk );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implementation of max-flow/min-cut computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vMinCut;
|
||||
int Flow, RetValue;
|
||||
int clk = clock();
|
||||
int Start = 0;
|
||||
|
||||
// find the max-flow
|
||||
Abc_NtkCleanCopy( pNtk );
|
||||
for ( Flow = 0; Abc_NtkMaxFlowPath( pNtk, &Start, fForward ); Flow++ );
|
||||
// Abc_NtkMaxFlowPrintFlow( pNtk, fForward );
|
||||
|
||||
// find the min-cut with the smallest volume
|
||||
RetValue = Abc_NtkMaxFlowPath( pNtk, NULL, fForward );
|
||||
assert( RetValue == 0 );
|
||||
vMinCut = Abc_NtkMaxFlowMinCut( pNtk );
|
||||
if ( !Abc_NtkMaxFlowVerifyCut(pNtk, vMinCut, fForward) )
|
||||
printf( "Abc_NtkMaxFlow() error! The computed min-cut is not a cut!\n" );
|
||||
|
||||
// report the results
|
||||
printf( "Latches = %6d. %s max-flow = %6d. Min-cut = %6d. ",
|
||||
Abc_NtkLatchNum(pNtk), fForward? "Forward " : "Backward", Flow, Vec_PtrSize(vMinCut) );
|
||||
PRT( "Time", clock() - clk );
|
||||
|
||||
// Abc_NtkMaxFlowPrintCut( vMinCut );
|
||||
return vMinCut;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds and augments one path.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMaxFlowPath( Abc_Ntk_t * pNtk, int * pStart, int fForward )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int i, LatchStart = pStart? *pStart : 0;
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Vec_PtrForEachEntryStart( pNtk->vBoxes, pLatch, i, LatchStart )
|
||||
{
|
||||
if ( !Abc_ObjIsLatch(pLatch) )
|
||||
continue;
|
||||
if ( fForward )
|
||||
{
|
||||
assert( !Abc_ObjFanout0(pLatch)->fMarkA );
|
||||
if ( Abc_NtkMaxFlowFwdPath_rec( Abc_ObjFanout0(pLatch) ) )
|
||||
{
|
||||
if ( pStart ) *pStart = i + 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( !Abc_ObjFanin0(pLatch)->fMarkA );
|
||||
if ( Abc_NtkMaxFlowBwdPath_rec( Abc_ObjFanin0(pLatch) ) )
|
||||
{
|
||||
if ( pStart ) *pStart = i + 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( pStart ) *pStart = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tries to find an augmenting path originating in this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMaxFlowBwdPath_rec( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout, * pFanin;
|
||||
int i;
|
||||
// skip visited nodes
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return 0;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// process node without flow
|
||||
if ( !Abc_ObjGetPath(pObj) )
|
||||
{
|
||||
// start the path if we reached a terminal node
|
||||
if ( pObj->fMarkA )
|
||||
return Abc_ObjSetPath( pObj, (void *)1 );
|
||||
// explore the fanins
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
if ( Abc_NtkMaxFlowBwdPath_rec(pFanin) )
|
||||
return Abc_ObjSetPath( pObj, pFanin );
|
||||
return 0;
|
||||
}
|
||||
// pObj has flow - find the fanout with flow
|
||||
pFanout = Abc_ObjGetFanoutPath( pObj );
|
||||
if ( pFanout == NULL )
|
||||
return 0;
|
||||
// go through the fanins of the fanout with flow
|
||||
Abc_ObjForEachFanin( pFanout, pFanin, i )
|
||||
if ( pFanin != pObj && Abc_NtkMaxFlowBwdPath_rec( pFanin ) )
|
||||
return Abc_ObjSetPath( pFanout, pFanin );
|
||||
// try the fanout
|
||||
if ( Abc_NtkMaxFlowBwdPath_rec( pFanout ) )
|
||||
return Abc_ObjSetPath( pFanout, NULL );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tries to find an augmenting path originating in this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMaxFlowFwdPath_rec( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout, * pFanin;
|
||||
int i;
|
||||
// skip visited nodes
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return 0;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// process node without flow
|
||||
if ( !Abc_ObjGetPath(pObj) )
|
||||
{
|
||||
// start the path if we reached a terminal node
|
||||
if ( pObj->fMarkA )
|
||||
return Abc_ObjSetPath( pObj, (void *)1 );
|
||||
// explore the fanins
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
if ( Abc_NtkMaxFlowFwdPath_rec(pFanout) )
|
||||
return Abc_ObjSetPath( pObj, pFanout );
|
||||
return 0;
|
||||
}
|
||||
// pObj has flow - find the fanout with flow
|
||||
pFanin = Abc_ObjGetFaninPath( pObj );
|
||||
if ( pFanin == NULL )
|
||||
return 0;
|
||||
// go through the fanins of the fanout with flow
|
||||
Abc_ObjForEachFanout( pFanin, pFanout, i )
|
||||
if ( pFanout != pObj && Abc_NtkMaxFlowFwdPath_rec( pFanout ) )
|
||||
return Abc_ObjSetPath( pFanin, pFanout );
|
||||
// try the fanout
|
||||
if ( Abc_NtkMaxFlowFwdPath_rec( pFanin ) )
|
||||
return Abc_ObjSetPath( pFanin, NULL );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find one minumum cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NtkMaxFlowMinCut( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vMinCut;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// collect the cut nodes
|
||||
vMinCut = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
// node without flow is not a cut node
|
||||
if ( !Abc_ObjGetPath(pObj) )
|
||||
continue;
|
||||
// unvisited node is below the cut
|
||||
if ( !Abc_NodeIsTravIdCurrent(pObj) )
|
||||
continue;
|
||||
// add terminal with flow or node whose path is not visited
|
||||
if ( pObj->fMarkA || !Abc_NodeIsTravIdCurrent( Abc_ObjGetPath(pObj) ) )
|
||||
Vec_PtrPush( vMinCut, pObj );
|
||||
}
|
||||
return vMinCut;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies the min-cut is indeed a cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMaxFlowVerifyCut_rec( Abc_Obj_t * pObj, int fForward )
|
||||
{
|
||||
Abc_Obj_t * pNext;
|
||||
int i;
|
||||
// skip visited nodes
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return 1;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// visit the node
|
||||
if ( fForward )
|
||||
{
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
return 0;
|
||||
// explore the fanouts
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
if ( !Abc_NtkMaxFlowVerifyCut_rec(pNext, fForward) )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObj) )
|
||||
return 0;
|
||||
// explore the fanins
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if ( !Abc_NtkMaxFlowVerifyCut_rec(pNext, fForward) )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies the min-cut is indeed a cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// mark the cut with the current traversal ID
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Vec_PtrForEachEntry( vMinCut, pObj, i )
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
// search from the latches for a path to the COs/CIs
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
{
|
||||
if ( fForward )
|
||||
{
|
||||
assert( !Abc_ObjFanout0(pObj)->fMarkA );
|
||||
if ( !Abc_NtkMaxFlowVerifyCut_rec( Abc_ObjFanout0(pObj), fForward ) )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( !Abc_ObjFanin0(pObj)->fMarkA );
|
||||
if ( !Abc_NtkMaxFlowVerifyCut_rec( Abc_ObjFanin0(pObj), fForward ) )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the flows.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMaxFlowPrintFlow( Abc_Ntk_t * pNtk, int fForward )
|
||||
{
|
||||
Abc_Obj_t * pLatch, * pNext, * pPrev;
|
||||
int i;
|
||||
if ( fForward )
|
||||
{
|
||||
Vec_PtrForEachEntry( pNtk->vBoxes, pLatch, i )
|
||||
{
|
||||
assert( !Abc_ObjFanout0(pLatch)->fMarkA );
|
||||
if ( Abc_ObjGetPath(Abc_ObjFanout0(pLatch)) == NULL ) // no flow through this latch
|
||||
continue;
|
||||
printf( "Path = " );
|
||||
for ( pNext = Abc_ObjFanout0(pLatch); pNext != (void *)1; pNext = Abc_ObjGetPath(pNext) )
|
||||
{
|
||||
printf( "%s(%d) ", Abc_ObjName(pNext), pNext->Id );
|
||||
pPrev = pNext;
|
||||
}
|
||||
if ( !Abc_ObjIsPo(pPrev) )
|
||||
printf( "%s(%d) ", Abc_ObjName(Abc_ObjFanout0(pPrev)), Abc_ObjFanout0(pPrev)->Id );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_PtrForEachEntry( pNtk->vBoxes, pLatch, i )
|
||||
{
|
||||
assert( !Abc_ObjFanin0(pLatch)->fMarkA );
|
||||
if ( Abc_ObjGetPath(Abc_ObjFanin0(pLatch)) == NULL ) // no flow through this latch
|
||||
continue;
|
||||
printf( "Path = " );
|
||||
for ( pNext = Abc_ObjFanin0(pLatch); pNext != (void *)1; pNext = Abc_ObjGetPath(pNext) )
|
||||
{
|
||||
printf( "%s(%d) ", Abc_ObjName(pNext), pNext->Id );
|
||||
pPrev = pNext;
|
||||
}
|
||||
if ( !Abc_ObjIsPi(pPrev) )
|
||||
printf( "%s(%d) ", Abc_ObjName(Abc_ObjFanin0(pPrev)), Abc_ObjFanin0(pPrev)->Id );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the min-cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMaxFlowPrintCut( Vec_Ptr_t * vMinCut )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "Min-cut: " );
|
||||
Vec_PtrForEachEntry( vMinCut, pObj, i )
|
||||
printf( "%d ", pObj->Id );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retFwd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis [Most forward retiming.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retFwd.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeForward( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
printf( "Not implemented.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ret_.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: ret_.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes initial values of the new latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int * pModel, RetValue, clk, i;
|
||||
if ( fVerbose )
|
||||
printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) );
|
||||
// solve the miter
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkMiterSat( pNtkMiter, (sint64)500000, (sint64)50000000, 0, 0, NULL, NULL );
|
||||
if ( fVerbose && clock() - clk > 100 )
|
||||
{
|
||||
PRT( "SAT solving time", clock() - clk );
|
||||
}
|
||||
// analyze the result
|
||||
if ( RetValue == 1 )
|
||||
printf( "Abc_NtkRetimeInitialValues(): The problem is unsatisfiable. DC latch values are used.\n" );
|
||||
else if ( RetValue == -1 )
|
||||
printf( "Abc_NtkRetimeInitialValues(): The SAT problem timed out. DC latch values are used.\n" );
|
||||
// set the values of the latches
|
||||
pModel = pNtkMiter->pModel; pNtkMiter->pModel = NULL;
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
pLatch->pData = (void *)(pModel? (pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC);
|
||||
FREE( pModel );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [retInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis [Internal declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: retInt.h,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __RET_INT_H__
|
||||
#define __RET_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== retArea.c ========================================================*/
|
||||
extern int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== retBwd.c ========================================================*/
|
||||
extern int Abc_NtkRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== retCore.c ========================================================*/
|
||||
extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose );
|
||||
/*=== retDelay.c ========================================================*/
|
||||
extern int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== retFlow.c ========================================================*/
|
||||
extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk );
|
||||
extern Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose );
|
||||
/*=== retFwd.c ========================================================*/
|
||||
extern int Abc_NtkRetimeForward( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== retInit.c ========================================================*/
|
||||
extern void Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, int fVerbose );
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ret_.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Retiming package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Oct 31, 2006.]
|
||||
|
||||
Revision [$Id: ret_.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "retInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -106,10 +106,10 @@ struct Rwr_Node_t_ // 24 bytes
|
|||
};
|
||||
|
||||
// manipulation of complemented attributes
|
||||
static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned)p) & 01); }
|
||||
static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) & ~01); }
|
||||
static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) ^ 01); }
|
||||
static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned)(p) ^ (c)); }
|
||||
static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned long)p) & 01); }
|
||||
static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned long)(p) & ~01); }
|
||||
static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned long)(p) ^ 01); }
|
||||
static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned long)(p) ^ (c)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
|
|
|
|||
|
|
@ -104,10 +104,10 @@ struct Prove_ParamsStruct_t_
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// macros working with complemented attributes of the nodes
|
||||
#define Fraig_IsComplement(p) (((int)((long) (p) & 01)))
|
||||
#define Fraig_Regular(p) ((Fraig_Node_t *)((unsigned)(p) & ~01))
|
||||
#define Fraig_Not(p) ((Fraig_Node_t *)((long)(p) ^ 01))
|
||||
#define Fraig_NotCond(p,c) ((Fraig_Node_t *)((long)(p) ^ (c)))
|
||||
#define Fraig_IsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Fraig_Regular(p) ((Fraig_Node_t *)((unsigned long)(p) & ~01))
|
||||
#define Fraig_Not(p) ((Fraig_Node_t *)((unsigned long)(p) ^ 01))
|
||||
#define Fraig_NotCond(p,c) ((Fraig_Node_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
// these are currently not used
|
||||
#define Fraig_Ref(p)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -30,6 +30,11 @@ extern "C" {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "vec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -104,16 +109,20 @@ struct Aig_Man_t_
|
|||
#define AIG_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define AIG_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
#ifndef PRT
|
||||
#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
|
||||
#endif
|
||||
|
||||
static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
|
||||
static inline int Aig_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
|
||||
static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
|
||||
static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
|
||||
static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
|
||||
|
||||
static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned)(p) & ~01); }
|
||||
static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned)(p) ^ 01); }
|
||||
static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned)(p) ^ (c)); }
|
||||
static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned)p) & 01); }
|
||||
static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) & ~01); }
|
||||
static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) ^ 01); }
|
||||
static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned long)(p) ^ (c)); }
|
||||
static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
|
||||
|
||||
static inline Aig_Obj_t * Aig_ManConst0( Aig_Man_t * p ) { return Aig_Not(p->pConst1); }
|
||||
static inline Aig_Obj_t * Aig_ManConst1( Aig_Man_t * p ) { return p->pConst1; }
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
Revision [$Id: aigBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ static Aig_CuddMan_t * s_pCuddMan = NULL;
|
|||
void Cudd2_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd )
|
||||
{
|
||||
int v;
|
||||
assert( s_pCuddMan == NULL );
|
||||
// start the BDD-to-AIG manager when the first BDD manager is allocated
|
||||
if ( s_pCuddMan != NULL )
|
||||
return;
|
||||
s_pCuddMan = ALLOC( Aig_CuddMan_t, 1 );
|
||||
s_pCuddMan->pAig = Aig_ManStart();
|
||||
s_pCuddMan->pTable = st_init_table( st_ptrcmp, st_ptrhash );
|
||||
|
|
@ -125,6 +127,22 @@ static void Cudd2_SetArg( Aig_Obj_t * pNode, void * pResult )
|
|||
st_insert( s_pCuddMan->pTable, (char *)Aig_Regular(pResult), (char *)pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Registers constant 1 node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddOne( void * pCudd, void * pResult )
|
||||
{
|
||||
Cudd2_SetArg( Aig_ManConst1(s_pCuddMan->pAig), pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds elementary variable.]
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// HA: Added for printing messages
|
||||
#ifndef MSG
|
||||
#define MSG(msg) (printf("%s = \n",(msg)));
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -52,6 +57,7 @@ extern "C" {
|
|||
|
||||
extern void Cudd2_Init ( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd );
|
||||
extern void Cudd2_Quit ( void * pCudd );
|
||||
extern void Cudd2_bddOne ( void * pCudd, void * pResult );
|
||||
extern void Cudd2_bddIthVar ( void * pCudd, int iVar, void * pResult );
|
||||
extern void Cudd2_bddAnd ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddOr ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,321 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aig.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aig.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __AIG_H__
|
||||
#define __AIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "vec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Aig_Man_t_ Aig_Man_t;
|
||||
typedef struct Aig_Obj_t_ Aig_Obj_t;
|
||||
typedef int Aig_Edge_t;
|
||||
|
||||
// object types
|
||||
typedef enum {
|
||||
AIG_NONE, // 0: non-existent object
|
||||
AIG_CONST1, // 1: constant 1
|
||||
AIG_PI, // 2: primary input
|
||||
AIG_PO, // 3: primary output
|
||||
AIG_AND, // 4: AND node
|
||||
AIG_EXOR, // 5: EXOR node
|
||||
AIG_VOID // 6: unused object
|
||||
} Aig_Type_t;
|
||||
|
||||
// the AIG node
|
||||
struct Aig_Obj_t_ // 4 words
|
||||
{
|
||||
void * pData; // misc
|
||||
Aig_Obj_t * pFanin0; // fanin
|
||||
Aig_Obj_t * pFanin1; // fanin
|
||||
unsigned long Type : 3; // object type
|
||||
unsigned long fPhase : 1; // value under 000...0 pattern
|
||||
unsigned long fMarkA : 1; // multipurpose mask
|
||||
unsigned long fMarkB : 1; // multipurpose mask
|
||||
unsigned long nRefs : 26; // reference count (level)
|
||||
};
|
||||
|
||||
// the AIG manager
|
||||
struct Aig_Man_t_
|
||||
{
|
||||
// AIG nodes
|
||||
Vec_Ptr_t * vPis; // the array of PIs
|
||||
Vec_Ptr_t * vPos; // the array of POs
|
||||
Aig_Obj_t * pConst1; // the constant 1 node
|
||||
Aig_Obj_t Ghost; // the ghost node
|
||||
// AIG node counters
|
||||
int nObjs[AIG_VOID];// the number of objects by type
|
||||
int nCreated; // the number of created objects
|
||||
int nDeleted; // the number of deleted objects
|
||||
// stuctural hash table
|
||||
Aig_Obj_t ** pTable; // structural hash table
|
||||
int nTableSize; // structural hash table size
|
||||
// various data members
|
||||
void * pData; // the temporary data
|
||||
int nTravIds; // the current traversal ID
|
||||
int fRefCount; // enables reference counting
|
||||
int fCatchExor; // enables EXOR nodes
|
||||
// memory management
|
||||
Vec_Ptr_t * vChunks; // allocated memory pieces
|
||||
Vec_Ptr_t * vPages; // memory pages used by nodes
|
||||
Aig_Obj_t * pListFree; // the list of free nodes
|
||||
// timing statistics
|
||||
int time1;
|
||||
int time2;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AIG_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define AIG_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
#ifndef PRT
|
||||
#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
|
||||
#endif
|
||||
|
||||
static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
|
||||
static inline int Aig_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
|
||||
static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
|
||||
static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
|
||||
static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
|
||||
|
||||
static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) & ~01); }
|
||||
static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) ^ 01); }
|
||||
static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned long)(p) ^ (c)); }
|
||||
static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
|
||||
|
||||
static inline Aig_Obj_t * Aig_ManConst0( Aig_Man_t * p ) { return Aig_Not(p->pConst1); }
|
||||
static inline Aig_Obj_t * Aig_ManConst1( Aig_Man_t * p ) { return p->pConst1; }
|
||||
static inline Aig_Obj_t * Aig_ManGhost( Aig_Man_t * p ) { return &p->Ghost; }
|
||||
static inline Aig_Obj_t * Aig_ManPi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, i); }
|
||||
|
||||
static inline Aig_Edge_t Aig_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
|
||||
static inline int Aig_EdgeId( Aig_Edge_t Edge ) { return Edge >> 1; }
|
||||
static inline int Aig_EdgeIsComplement( Aig_Edge_t Edge ) { return Edge & 1; }
|
||||
static inline Aig_Edge_t Aig_EdgeRegular( Aig_Edge_t Edge ) { return (Edge >> 1) << 1; }
|
||||
static inline Aig_Edge_t Aig_EdgeNot( Aig_Edge_t Edge ) { return Edge ^ 1; }
|
||||
static inline Aig_Edge_t Aig_EdgeNotCond( Aig_Edge_t Edge, int fCond ) { return Edge ^ fCond; }
|
||||
|
||||
static inline int Aig_ManPiNum( Aig_Man_t * p ) { return p->nObjs[AIG_PI]; }
|
||||
static inline int Aig_ManPoNum( Aig_Man_t * p ) { return p->nObjs[AIG_PO]; }
|
||||
static inline int Aig_ManAndNum( Aig_Man_t * p ) { return p->nObjs[AIG_AND]; }
|
||||
static inline int Aig_ManExorNum( Aig_Man_t * p ) { return p->nObjs[AIG_EXOR]; }
|
||||
static inline int Aig_ManNodeNum( Aig_Man_t * p ) { return p->nObjs[AIG_AND]+p->nObjs[AIG_EXOR];}
|
||||
static inline int Aig_ManGetCost( Aig_Man_t * p ) { return p->nObjs[AIG_AND]+3*p->nObjs[AIG_EXOR]; }
|
||||
static inline int Aig_ManObjNum( Aig_Man_t * p ) { return p->nCreated - p->nDeleted; }
|
||||
|
||||
static inline Aig_Type_t Aig_ObjType( Aig_Obj_t * pObj ) { return pObj->Type; }
|
||||
static inline int Aig_ObjIsNone( Aig_Obj_t * pObj ) { return pObj->Type == AIG_NONE; }
|
||||
static inline int Aig_ObjIsConst1( Aig_Obj_t * pObj ) { assert(!Aig_IsComplement(pObj)); return pObj->Type == AIG_CONST1; }
|
||||
static inline int Aig_ObjIsPi( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI; }
|
||||
static inline int Aig_ObjIsPo( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PO; }
|
||||
static inline int Aig_ObjIsAnd( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND; }
|
||||
static inline int Aig_ObjIsExor( Aig_Obj_t * pObj ) { return pObj->Type == AIG_EXOR; }
|
||||
static inline int Aig_ObjIsNode( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND || pObj->Type == AIG_EXOR; }
|
||||
static inline int Aig_ObjIsTerm( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI || pObj->Type == AIG_PO || pObj->Type == AIG_CONST1; }
|
||||
static inline int Aig_ObjIsHash( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND || pObj->Type == AIG_EXOR; }
|
||||
|
||||
static inline int Aig_ObjIsMarkA( Aig_Obj_t * pObj ) { return pObj->fMarkA; }
|
||||
static inline void Aig_ObjSetMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; }
|
||||
static inline void Aig_ObjClearMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 0; }
|
||||
|
||||
static inline void Aig_ObjSetTravId( Aig_Obj_t * pObj, int TravId ) { pObj->pData = (void *)TravId; }
|
||||
static inline void Aig_ObjSetTravIdCurrent( Aig_Man_t * p, Aig_Obj_t * pObj ) { pObj->pData = (void *)p->nTravIds; }
|
||||
static inline void Aig_ObjSetTravIdPrevious( Aig_Man_t * p, Aig_Obj_t * pObj ) { pObj->pData = (void *)(p->nTravIds - 1); }
|
||||
static inline int Aig_ObjIsTravIdCurrent( Aig_Man_t * p, Aig_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds); }
|
||||
static inline int Aig_ObjIsTravIdPrevious( Aig_Man_t * p, Aig_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds - 1); }
|
||||
|
||||
static inline int Aig_ObjTravId( Aig_Obj_t * pObj ) { return (int)pObj->pData; }
|
||||
static inline int Aig_ObjPhase( Aig_Obj_t * pObj ) { return pObj->fPhase; }
|
||||
static inline int Aig_ObjRefs( Aig_Obj_t * pObj ) { return pObj->nRefs; }
|
||||
static inline void Aig_ObjRef( Aig_Obj_t * pObj ) { pObj->nRefs++; }
|
||||
static inline void Aig_ObjDeref( Aig_Obj_t * pObj ) { assert( pObj->nRefs > 0 ); pObj->nRefs--; }
|
||||
static inline void Aig_ObjClearRef( Aig_Obj_t * pObj ) { pObj->nRefs = 0; }
|
||||
static inline int Aig_ObjFaninC0( Aig_Obj_t * pObj ) { return Aig_IsComplement(pObj->pFanin0); }
|
||||
static inline int Aig_ObjFaninC1( Aig_Obj_t * pObj ) { return Aig_IsComplement(pObj->pFanin1); }
|
||||
static inline Aig_Obj_t * Aig_ObjFanin0( Aig_Obj_t * pObj ) { return Aig_Regular(pObj->pFanin0); }
|
||||
static inline Aig_Obj_t * Aig_ObjFanin1( Aig_Obj_t * pObj ) { return Aig_Regular(pObj->pFanin1); }
|
||||
static inline Aig_Obj_t * Aig_ObjChild0( Aig_Obj_t * pObj ) { return pObj->pFanin0; }
|
||||
static inline Aig_Obj_t * Aig_ObjChild1( Aig_Obj_t * pObj ) { return pObj->pFanin1; }
|
||||
static inline Aig_Obj_t * Aig_ObjChild0Copy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj)) : NULL; }
|
||||
static inline Aig_Obj_t * Aig_ObjChild1Copy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj)) : NULL; }
|
||||
static inline int Aig_ObjLevel( Aig_Obj_t * pObj ) { return pObj->nRefs; }
|
||||
static inline int Aig_ObjLevelNew( Aig_Obj_t * pObj ) { return 1 + Aig_ObjIsExor(pObj) + AIG_MAX(Aig_ObjFanin0(pObj)->nRefs, Aig_ObjFanin1(pObj)->nRefs); }
|
||||
static inline void Aig_ObjClean( Aig_Obj_t * pObj ) { memset( pObj, 0, sizeof(Aig_Obj_t) ); }
|
||||
static inline int Aig_ObjWhatFanin( Aig_Obj_t * pObj, Aig_Obj_t * pFanin )
|
||||
{
|
||||
if ( Aig_ObjFanin0(pObj) == pFanin ) return 0;
|
||||
if ( Aig_ObjFanin1(pObj) == pFanin ) return 1;
|
||||
assert(0); return -1;
|
||||
}
|
||||
static inline int Aig_ObjFanoutC( Aig_Obj_t * pObj, Aig_Obj_t * pFanout )
|
||||
{
|
||||
if ( Aig_ObjFanin0(pFanout) == pObj ) return Aig_ObjFaninC0(pObj);
|
||||
if ( Aig_ObjFanin1(pFanout) == pObj ) return Aig_ObjFaninC1(pObj);
|
||||
assert(0); return -1;
|
||||
}
|
||||
|
||||
// create the ghost of the new node
|
||||
static inline Aig_Obj_t * Aig_ObjCreateGhost( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type )
|
||||
{
|
||||
Aig_Obj_t * pGhost;
|
||||
assert( Type != AIG_AND || !Aig_ObjIsConst1(Aig_Regular(p0)) );
|
||||
assert( p1 == NULL || !Aig_ObjIsConst1(Aig_Regular(p1)) );
|
||||
assert( Type == AIG_PI || Aig_Regular(p0) != Aig_Regular(p1) );
|
||||
pGhost = Aig_ManGhost(p);
|
||||
pGhost->Type = Type;
|
||||
pGhost->pFanin0 = p0 < p1? p0 : p1;
|
||||
pGhost->pFanin1 = p0 < p1? p1 : p0;
|
||||
return pGhost;
|
||||
}
|
||||
|
||||
// internal memory manager
|
||||
static inline Aig_Obj_t * Aig_ManFetchMemory( Aig_Man_t * p )
|
||||
{
|
||||
extern void Aig_ManAddMemory( Aig_Man_t * p );
|
||||
Aig_Obj_t * pTemp;
|
||||
if ( p->pListFree == NULL )
|
||||
Aig_ManAddMemory( p );
|
||||
pTemp = p->pListFree;
|
||||
p->pListFree = *((Aig_Obj_t **)pTemp);
|
||||
memset( pTemp, 0, sizeof(Aig_Obj_t) );
|
||||
return pTemp;
|
||||
}
|
||||
static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry )
|
||||
{
|
||||
pEntry->Type = AIG_NONE; // distinquishes dead node from live node
|
||||
*((Aig_Obj_t **)pEntry) = p->pListFree;
|
||||
p->pListFree = pEntry;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterator over the primary inputs
|
||||
#define Aig_ManForEachPi( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPis, pObj, i )
|
||||
// iterator over the primary outputs
|
||||
#define Aig_ManForEachPo( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPos, pObj, i )
|
||||
// iterator over all objects, including those currently not used
|
||||
#define Aig_ManForEachNode( p, pObj, i ) \
|
||||
for ( i = 0; i < p->nTableSize; i++ ) \
|
||||
if ( ((pObj) = p->pTable[i]) == NULL ) {} else
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== aigBalance.c ========================================================*/
|
||||
extern Aig_Man_t * Aig_ManBalance( Aig_Man_t * p, int fUpdateLevel );
|
||||
extern Aig_Obj_t * Aig_NodeBalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel );
|
||||
/*=== aigCheck.c ========================================================*/
|
||||
extern int Aig_ManCheck( Aig_Man_t * p );
|
||||
/*=== aigDfs.c ==========================================================*/
|
||||
extern Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p );
|
||||
extern Vec_Ptr_t * Aig_ManDfsNode( Aig_Man_t * p, Aig_Obj_t * pNode );
|
||||
extern int Aig_ManCountLevels( Aig_Man_t * p );
|
||||
extern void Aig_ManCreateRefs( Aig_Man_t * p );
|
||||
extern int Aig_DagSize( Aig_Obj_t * pObj );
|
||||
extern void Aig_ConeUnmark_rec( Aig_Obj_t * pObj );
|
||||
extern Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pObj, int nVars );
|
||||
extern Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t * pFunc, int iVar );
|
||||
/*=== aigMan.c ==========================================================*/
|
||||
extern Aig_Man_t * Aig_ManStart();
|
||||
extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p );
|
||||
extern void Aig_ManStop( Aig_Man_t * p );
|
||||
extern int Aig_ManCleanup( Aig_Man_t * p );
|
||||
extern void Aig_ManPrintStats( Aig_Man_t * p );
|
||||
/*=== aigMem.c ==========================================================*/
|
||||
extern void Aig_ManStartMemory( Aig_Man_t * p );
|
||||
extern void Aig_ManStopMemory( Aig_Man_t * p );
|
||||
/*=== aigObj.c ==========================================================*/
|
||||
extern Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p );
|
||||
extern Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver );
|
||||
extern Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost );
|
||||
extern void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 );
|
||||
extern void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
extern void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
extern void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
/*=== aigOper.c =========================================================*/
|
||||
extern Aig_Obj_t * Aig_IthVar( Aig_Man_t * p, int i );
|
||||
extern Aig_Obj_t * Aig_Oper( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type );
|
||||
extern Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 );
|
||||
extern Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 );
|
||||
extern Aig_Obj_t * Aig_Exor( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 );
|
||||
extern Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 );
|
||||
extern Aig_Obj_t * Aig_Maj( Aig_Man_t * p, Aig_Obj_t * pA, Aig_Obj_t * pB, Aig_Obj_t * pC );
|
||||
extern Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs );
|
||||
extern Aig_Obj_t * Aig_CreateAnd( Aig_Man_t * p, int nVars );
|
||||
extern Aig_Obj_t * Aig_CreateOr( Aig_Man_t * p, int nVars );
|
||||
extern Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars );
|
||||
/*=== aigTable.c ========================================================*/
|
||||
extern Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost );
|
||||
extern void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
extern void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
extern int Aig_TableCountEntries( Aig_Man_t * p );
|
||||
extern void Aig_TableProfile( Aig_Man_t * p );
|
||||
/*=== aigUtil.c =========================================================*/
|
||||
extern void Aig_ManIncrementTravId( Aig_Man_t * p );
|
||||
extern void Aig_ManCleanData( Aig_Man_t * p );
|
||||
extern void Aig_ObjCollectMulti( Aig_Obj_t * pFunc, Vec_Ptr_t * vSuper );
|
||||
extern int Aig_ObjIsMuxType( Aig_Obj_t * pObj );
|
||||
extern int Aig_ObjRecognizeExor( Aig_Obj_t * pObj, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 );
|
||||
extern Aig_Obj_t * Aig_ObjRecognizeMux( Aig_Obj_t * pObj, Aig_Obj_t ** ppObjT, Aig_Obj_t ** ppObjE );
|
||||
extern void Aig_ObjPrintVerilog( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, int Level );
|
||||
extern void Aig_ObjPrintVerbose( Aig_Obj_t * pObj, int fHaig );
|
||||
extern void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig );
|
||||
extern void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,391 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigBalance.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Algebraic AIG balancing.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Aig_Obj_t * Aig_NodeBalance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
|
||||
static Vec_Ptr_t * Aig_NodeBalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
|
||||
static int Aig_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
|
||||
static void Aig_NodeBalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
|
||||
static void Aig_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs algebraic balancing of the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManBalance( Aig_Man_t * p, int fUpdateLevel )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjNew;
|
||||
Vec_Vec_t * vStore;
|
||||
int i;
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart();
|
||||
pNew->fRefCount = 0;
|
||||
// map the PI nodes
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
// balance the AIG
|
||||
vStore = Vec_VecAlloc( 50 );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pObjNew = Aig_NodeBalance_rec( pNew, Aig_ObjFanin0(pObj), vStore, 0, fUpdateLevel );
|
||||
Aig_ObjCreatePo( pNew, Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) ) );
|
||||
}
|
||||
Vec_VecFree( vStore );
|
||||
// remove dangling nodes
|
||||
// Aig_ManCreateRefs( pNew );
|
||||
// if ( i = Aig_ManCleanup( pNew ) )
|
||||
// printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
|
||||
// check the resulting AIG
|
||||
if ( !Aig_ManCheck(pNew) )
|
||||
printf( "Aig_ManBalance(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the new node constructed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_NodeBalance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
|
||||
{
|
||||
Aig_Obj_t * pObjNew;
|
||||
Vec_Ptr_t * vSuper;
|
||||
int i;
|
||||
assert( !Aig_IsComplement(pObjOld) );
|
||||
// return if the result is known
|
||||
if ( pObjOld->pData )
|
||||
return pObjOld->pData;
|
||||
assert( Aig_ObjIsNode(pObjOld) );
|
||||
// get the implication supergate
|
||||
vSuper = Aig_NodeBalanceCone( pObjOld, vStore, Level );
|
||||
// check if supergate contains two nodes in the opposite polarity
|
||||
if ( vSuper->nSize == 0 )
|
||||
return pObjOld->pData = Aig_ManConst0(pNew);
|
||||
if ( Vec_PtrSize(vSuper) < 2 )
|
||||
printf( "BUG!\n" );
|
||||
// for each old node, derive the new well-balanced node
|
||||
for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
|
||||
{
|
||||
pObjNew = Aig_NodeBalance_rec( pNew, Aig_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
|
||||
vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement(vSuper->pArray[i]) );
|
||||
}
|
||||
// build the supergate
|
||||
pObjNew = Aig_NodeBalanceBuildSuper( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel );
|
||||
// make sure the balanced node is not assigned
|
||||
// assert( pObjOld->Level >= Aig_Regular(pObjNew)->Level );
|
||||
assert( pObjOld->pData == NULL );
|
||||
return pObjOld->pData = pObjNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the nodes of the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_NodeBalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
|
||||
{
|
||||
int RetValue1, RetValue2, i;
|
||||
// check if the node is visited
|
||||
if ( Aig_Regular(pObj)->fMarkB )
|
||||
{
|
||||
// check if the node occurs in the same polarity
|
||||
for ( i = 0; i < vSuper->nSize; i++ )
|
||||
if ( vSuper->pArray[i] == pObj )
|
||||
return 1;
|
||||
// check if the node is present in the opposite polarity
|
||||
for ( i = 0; i < vSuper->nSize; i++ )
|
||||
if ( vSuper->pArray[i] == Aig_Not(pObj) )
|
||||
return -1;
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
// if the new node is complemented or a PI, another gate begins
|
||||
if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1) )
|
||||
{
|
||||
Vec_PtrPush( vSuper, pObj );
|
||||
Aig_Regular(pObj)->fMarkB = 1;
|
||||
return 0;
|
||||
}
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
// go through the branches
|
||||
RetValue1 = Aig_NodeBalanceCone_rec( pRoot, Aig_ObjChild0(pObj), vSuper );
|
||||
RetValue2 = Aig_NodeBalanceCone_rec( pRoot, Aig_ObjChild1(pObj), vSuper );
|
||||
if ( RetValue1 == -1 || RetValue2 == -1 )
|
||||
return -1;
|
||||
// return 1 if at least one branch has a duplicate
|
||||
return RetValue1 || RetValue2;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the nodes of the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Aig_NodeBalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
int RetValue, i;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
// extend the storage
|
||||
if ( Vec_VecSize( vStore ) <= Level )
|
||||
Vec_VecPush( vStore, Level, 0 );
|
||||
// get the temporary array of nodes
|
||||
vNodes = Vec_VecEntry( vStore, Level );
|
||||
Vec_PtrClear( vNodes );
|
||||
// collect the nodes in the implication supergate
|
||||
RetValue = Aig_NodeBalanceCone_rec( pObj, pObj, vNodes );
|
||||
assert( vNodes->nSize > 1 );
|
||||
// unmark the visited nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Aig_Regular(pObj)->fMarkB = 0;
|
||||
// if we found the node and its complement in the same implication supergate,
|
||||
// return empty set of nodes (meaning that we should use constant-0 node)
|
||||
if ( RetValue == -1 )
|
||||
vNodes->nSize = 0;
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_NodeCompareLevelsDecrease( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 )
|
||||
{
|
||||
int Diff = Aig_ObjLevel(Aig_Regular(*pp1)) - Aig_ObjLevel(Aig_Regular(*pp2));
|
||||
if ( Diff > 0 )
|
||||
return -1;
|
||||
if ( Diff < 0 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Builds implication supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_NodeBalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel )
|
||||
{
|
||||
Aig_Obj_t * pObj1, * pObj2;
|
||||
int LeftBound;
|
||||
assert( vSuper->nSize > 1 );
|
||||
// sort the new nodes by level in the decreasing order
|
||||
Vec_PtrSort( vSuper, Aig_NodeCompareLevelsDecrease );
|
||||
// balance the nodes
|
||||
while ( vSuper->nSize > 1 )
|
||||
{
|
||||
// find the left bound on the node to be paired
|
||||
LeftBound = (!fUpdateLevel)? 0 : Aig_NodeBalanceFindLeft( vSuper );
|
||||
// find the node that can be shared (if no such node, randomize choice)
|
||||
Aig_NodeBalancePermute( p, vSuper, LeftBound, Type == AIG_EXOR );
|
||||
// pull out the last two nodes
|
||||
pObj1 = Vec_PtrPop(vSuper);
|
||||
pObj2 = Vec_PtrPop(vSuper);
|
||||
Aig_NodeBalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type) );
|
||||
}
|
||||
return Vec_PtrEntry(vSuper, 0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds the left bound on the next candidate to be paired.]
|
||||
|
||||
Description [The nodes in the array are in the decreasing order of levels.
|
||||
The last node in the array has the smallest level. By default it would be paired
|
||||
with the next node on the left. However, it may be possible to pair it with some
|
||||
other node on the left, in such a way that the new node is shared. This procedure
|
||||
finds the index of the left-most node, which can be paired with the last node.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
|
||||
{
|
||||
Aig_Obj_t * pObjRight, * pObjLeft;
|
||||
int Current;
|
||||
// if two or less nodes, pair with the first
|
||||
if ( Vec_PtrSize(vSuper) < 3 )
|
||||
return 0;
|
||||
// set the pointer to the one before the last
|
||||
Current = Vec_PtrSize(vSuper) - 2;
|
||||
pObjRight = Vec_PtrEntry( vSuper, Current );
|
||||
// go through the nodes to the left of this one
|
||||
for ( Current--; Current >= 0; Current-- )
|
||||
{
|
||||
// get the next node on the left
|
||||
pObjLeft = Vec_PtrEntry( vSuper, Current );
|
||||
// if the level of this node is different, quit the loop
|
||||
if ( Aig_ObjLevel(Aig_Regular(pObjLeft)) != Aig_ObjLevel(Aig_Regular(pObjRight)) )
|
||||
break;
|
||||
}
|
||||
Current++;
|
||||
// get the node, for which the equality holds
|
||||
pObjLeft = Vec_PtrEntry( vSuper, Current );
|
||||
assert( Aig_ObjLevel(Aig_Regular(pObjLeft)) == Aig_ObjLevel(Aig_Regular(pObjRight)) );
|
||||
return Current;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Moves closer to the end the node that is best for sharing.]
|
||||
|
||||
Description [If there is no node with sharing, randomly chooses one of
|
||||
the legal nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_NodeBalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
|
||||
{
|
||||
Aig_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
|
||||
int RightBound, i;
|
||||
// get the right bound
|
||||
RightBound = Vec_PtrSize(vSuper) - 2;
|
||||
assert( LeftBound <= RightBound );
|
||||
if ( LeftBound == RightBound )
|
||||
return;
|
||||
// get the two last nodes
|
||||
pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
|
||||
pObj2 = Vec_PtrEntry( vSuper, RightBound );
|
||||
if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 )
|
||||
return;
|
||||
// find the first node that can be shared
|
||||
for ( i = RightBound; i >= LeftBound; i-- )
|
||||
{
|
||||
pObj3 = Vec_PtrEntry( vSuper, i );
|
||||
if ( Aig_Regular(pObj3) == p->pConst1 )
|
||||
{
|
||||
Vec_PtrWriteEntry( vSuper, i, pObj2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
|
||||
return;
|
||||
}
|
||||
pGhost = Aig_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_EXOR : AIG_AND );
|
||||
if ( Aig_TableLookup( p, pGhost ) )
|
||||
{
|
||||
if ( pObj3 == pObj2 )
|
||||
return;
|
||||
Vec_PtrWriteEntry( vSuper, i, pObj2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// we did not find the node to share, randomize choice
|
||||
{
|
||||
int Choice = rand() % (RightBound - LeftBound + 1);
|
||||
pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
|
||||
if ( pObj3 == pObj2 )
|
||||
return;
|
||||
Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts a new node in the order by levels.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pObj1, * pObj2;
|
||||
int i;
|
||||
if ( Vec_PtrPushUnique(vStore, pObj) )
|
||||
return;
|
||||
// find the p of the node
|
||||
for ( i = vStore->nSize-1; i > 0; i-- )
|
||||
{
|
||||
pObj1 = vStore->pArray[i ];
|
||||
pObj2 = vStore->pArray[i-1];
|
||||
if ( Aig_ObjLevel(Aig_Regular(pObj1)) <= Aig_ObjLevel(Aig_Regular(pObj2)) )
|
||||
break;
|
||||
vStore->pArray[i ] = pObj2;
|
||||
vStore->pArray[i-1] = pObj1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigCheck.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [AIG checking procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigCheck.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the consistency of the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManCheck( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pObj2;
|
||||
int i;
|
||||
// check primary inputs
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
if ( Aig_ObjFanin0(pObj) || Aig_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The PI node \"%p\" has fanins.\n", pObj );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// check primary outputs
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjFanin0(pObj) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The PO node \"%p\" has NULL fanin.\n", pObj );
|
||||
return 0;
|
||||
}
|
||||
if ( Aig_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The PO node \"%p\" has second fanin.\n", pObj );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// check internal nodes
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjFanin0(pObj) || !Aig_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The AIG has internal node \"%p\" with a NULL fanin.\n", pObj );
|
||||
return 0;
|
||||
}
|
||||
if ( Aig_ObjFanin0(pObj) >= Aig_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The AIG has node \"%p\" with a wrong ordering of fanins.\n", pObj );
|
||||
return 0;
|
||||
}
|
||||
pObj2 = Aig_TableLookup( p, pObj );
|
||||
if ( pObj2 != pObj )
|
||||
{
|
||||
printf( "Aig_ManCheck: Node \"%p\" is not in the structural hashing table.\n", pObj );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// count the total number of nodes
|
||||
if ( Aig_ManObjNum(p) != 1 + Aig_ManPiNum(p) + Aig_ManPoNum(p) + Aig_ManAndNum(p) + Aig_ManExorNum(p) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The number of created nodes is wrong.\n" );
|
||||
return 0;
|
||||
}
|
||||
// count the number of nodes in the table
|
||||
if ( Aig_TableCountEntries(p) != Aig_ManAndNum(p) + Aig_ManExorNum(p) )
|
||||
{
|
||||
printf( "Aig_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
|
||||
return 0;
|
||||
}
|
||||
// if ( !Aig_ManIsAcyclic(p) )
|
||||
// return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,399 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigDfs.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [DFS traversal procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects internal nodes in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManDfs_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
Aig_ManDfs_rec( Aig_ObjFanin0(pObj), vNodes );
|
||||
Aig_ManDfs_rec( Aig_ObjFanin1(pObj), vNodes );
|
||||
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjSetMarkA(pObj);
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects internal nodes in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
vNodes = Vec_PtrAlloc( Aig_ManNodeNum(p) );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
Aig_ManDfs_rec( pObj, vNodes );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
Aig_ObjClearMarkA(pObj);
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects internal nodes in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Aig_ManDfsNode( Aig_Man_t * p, Aig_Obj_t * pNode )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
assert( !Aig_IsComplement(pNode) );
|
||||
vNodes = Vec_PtrAlloc( 16 );
|
||||
Aig_ManDfs_rec( pNode, vNodes );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Aig_ObjClearMarkA(pObj);
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the max number of levels in the manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManCountLevels( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, LevelsMax, Level0, Level1;
|
||||
// initialize the levels
|
||||
Aig_ManConst1(p)->pData = NULL;
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
// compute levels in a DFS order
|
||||
vNodes = Aig_ManDfs( p );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
Level0 = (int)Aig_ObjFanin0(pObj)->pData;
|
||||
Level1 = (int)Aig_ObjFanin1(pObj)->pData;
|
||||
pObj->pData = (void *)(1 + Aig_ObjIsExor(pObj) + AIG_MAX(Level0, Level1));
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// get levels of the POs
|
||||
LevelsMax = 0;
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
LevelsMax = AIG_MAX( LevelsMax, (int)Aig_ObjFanin0(pObj)->pData );
|
||||
return LevelsMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates correct reference counters at each node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManCreateRefs( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
if ( p->fRefCount )
|
||||
return;
|
||||
p->fRefCount = 1;
|
||||
// clear refs
|
||||
Aig_ObjClearRef( Aig_ManConst1(p) );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
Aig_ObjClearRef( pObj );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
Aig_ObjClearRef( pObj );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Aig_ObjClearRef( pObj );
|
||||
// set refs
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
Aig_ObjRef( Aig_ObjFanin0(pObj) );
|
||||
Aig_ObjRef( Aig_ObjFanin1(pObj) );
|
||||
}
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Aig_ObjRef( Aig_ObjFanin0(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of AIG nodes rooted at this cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ConeMark_rec( Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
Aig_ConeMark_rec( Aig_ObjFanin0(pObj) );
|
||||
Aig_ConeMark_rec( Aig_ObjFanin1(pObj) );
|
||||
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjSetMarkA( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of AIG nodes rooted at this cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ConeCleanAndMark_rec( Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
Aig_ConeCleanAndMark_rec( Aig_ObjFanin0(pObj) );
|
||||
Aig_ConeCleanAndMark_rec( Aig_ObjFanin1(pObj) );
|
||||
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjSetMarkA( pObj );
|
||||
pObj->pData = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of AIG nodes rooted at this cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ConeCountAndMark_rec( Aig_Obj_t * pObj )
|
||||
{
|
||||
int Counter;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
|
||||
return 0;
|
||||
Counter = 1 + Aig_ConeCountAndMark_rec( Aig_ObjFanin0(pObj) ) +
|
||||
Aig_ConeCountAndMark_rec( Aig_ObjFanin1(pObj) );
|
||||
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjSetMarkA( pObj );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of AIG nodes rooted at this cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ConeUnmark_rec( Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) || !Aig_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
Aig_ConeUnmark_rec( Aig_ObjFanin0(pObj) );
|
||||
Aig_ConeUnmark_rec( Aig_ObjFanin1(pObj) );
|
||||
assert( Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjClearMarkA( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of AIG nodes rooted at this cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_DagSize( Aig_Obj_t * pObj )
|
||||
{
|
||||
int Counter;
|
||||
Counter = Aig_ConeCountAndMark_rec( Aig_Regular(pObj) );
|
||||
Aig_ConeUnmark_rec( Aig_Regular(pObj) );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the AIG from one manager into another.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_Transfer_rec( Aig_Man_t * pDest, Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
Aig_Transfer_rec( pDest, Aig_ObjFanin0(pObj) );
|
||||
Aig_Transfer_rec( pDest, Aig_ObjFanin1(pObj) );
|
||||
pObj->pData = Aig_And( pDest, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjSetMarkA( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the AIG from one manager into another.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pRoot, int nVars )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
// solve simple cases
|
||||
if ( pSour == pDest )
|
||||
return pRoot;
|
||||
if ( Aig_ObjIsConst1( Aig_Regular(pRoot) ) )
|
||||
return Aig_NotCond( Aig_ManConst1(pDest), Aig_IsComplement(pRoot) );
|
||||
// set the PI mapping
|
||||
Aig_ManForEachPi( pSour, pObj, i )
|
||||
{
|
||||
if ( i == nVars )
|
||||
break;
|
||||
pObj->pData = Aig_IthVar(pDest, i);
|
||||
}
|
||||
// transfer and set markings
|
||||
Aig_Transfer_rec( pDest, Aig_Regular(pRoot) );
|
||||
// clear the markings
|
||||
Aig_ConeUnmark_rec( Aig_Regular(pRoot) );
|
||||
return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_Compose_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFunc, Aig_Obj_t * pVar )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( Aig_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) )
|
||||
{
|
||||
pObj->pData = pObj == pVar ? pFunc : pObj;
|
||||
return;
|
||||
}
|
||||
Aig_Compose_rec( p, Aig_ObjFanin0(pObj), pFunc, pVar );
|
||||
Aig_Compose_rec( p, Aig_ObjFanin1(pObj), pFunc, pVar );
|
||||
pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
|
||||
Aig_ObjSetMarkA( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t * pFunc, int iVar )
|
||||
{
|
||||
// quit if the PI variable is not defined
|
||||
if ( iVar >= Aig_ManPiNum(p) )
|
||||
{
|
||||
printf( "Aig_Compose(): The PI variable %d is not defined.\n", iVar );
|
||||
return NULL;
|
||||
}
|
||||
// recursively perform composition
|
||||
Aig_Compose_rec( p, Aig_Regular(pRoot), pFunc, Aig_ManPi(p, iVar) );
|
||||
// clear the markings
|
||||
Aig_ConeUnmark_rec( Aig_Regular(pRoot) );
|
||||
return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [AIG manager.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aig_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManStart()
|
||||
{
|
||||
Aig_Man_t * p;
|
||||
// start the manager
|
||||
p = ALLOC( Aig_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Aig_Man_t) );
|
||||
// perform initializations
|
||||
p->nTravIds = 1;
|
||||
p->fRefCount = 1;
|
||||
p->fCatchExor = 0;
|
||||
// allocate arrays for nodes
|
||||
p->vPis = Vec_PtrAlloc( 100 );
|
||||
p->vPos = Vec_PtrAlloc( 100 );
|
||||
// prepare the internal memory manager
|
||||
Aig_ManStartMemory( p );
|
||||
// create the constant node
|
||||
p->pConst1 = Aig_ManFetchMemory( p );
|
||||
p->pConst1->Type = AIG_CONST1;
|
||||
p->pConst1->fPhase = 1;
|
||||
p->nCreated = 1;
|
||||
// start the table
|
||||
p->nTableSize = 10007;
|
||||
p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize );
|
||||
memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManStop( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
// make sure the nodes have clean marks
|
||||
pObj = Aig_ManConst1(p);
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
// print time
|
||||
if ( p->time1 ) { PRT( "time1", p->time1 ); }
|
||||
if ( p->time2 ) { PRT( "time2", p->time2 ); }
|
||||
// Aig_TableProfile( p );
|
||||
if ( p->vChunks ) Aig_ManStopMemory( p );
|
||||
if ( p->vPis ) Vec_PtrFree( p->vPis );
|
||||
if ( p->vPos ) Vec_PtrFree( p->vPos );
|
||||
free( p->pTable );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ManCleanup( Aig_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pNode;
|
||||
int i, nNodesOld;
|
||||
assert( p->fRefCount );
|
||||
nNodesOld = Aig_ManNodeNum(p);
|
||||
// collect roots of dangling nodes
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Aig_ManForEachNode( p, pNode, i )
|
||||
if ( Aig_ObjRefs(pNode) == 0 )
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
// recursively remove dangling nodes
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
Aig_ObjDelete_rec( p, pNode );
|
||||
Vec_PtrFree( vNodes );
|
||||
return nNodesOld - Aig_ManNodeNum(p);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManPrintStats( Aig_Man_t * p )
|
||||
{
|
||||
printf( "PI/PO = %d/%d. ", Aig_ManPiNum(p), Aig_ManPoNum(p) );
|
||||
printf( "A = %7d. ", Aig_ManAndNum(p) );
|
||||
printf( "X = %5d. ", Aig_ManExorNum(p) );
|
||||
printf( "Cre = %7d. ", p->nCreated );
|
||||
printf( "Del = %7d. ", p->nDeleted );
|
||||
printf( "Lev = %3d. ", Aig_ManCountLevels(p) );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigMem.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Memory management for the AIG nodes.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigMem.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// memory management
|
||||
#define IVY_PAGE_SIZE 12 // page size containing 2^IVY_PAGE_SIZE nodes
|
||||
#define IVY_PAGE_MASK 4095 // page bitmask (2^IVY_PAGE_SIZE)-1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the internal memory manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManStartMemory( Aig_Man_t * p )
|
||||
{
|
||||
p->vChunks = Vec_PtrAlloc( 128 );
|
||||
p->vPages = Vec_PtrAlloc( 128 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the internal memory manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManStopMemory( Aig_Man_t * p )
|
||||
{
|
||||
void * pMemory;
|
||||
int i;
|
||||
Vec_PtrForEachEntry( p->vChunks, pMemory, i )
|
||||
free( pMemory );
|
||||
Vec_PtrFree( p->vChunks );
|
||||
Vec_PtrFree( p->vPages );
|
||||
p->pListFree = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates additional memory for the nodes.]
|
||||
|
||||
Description [Allocates IVY_PAGE_SIZE nodes. Aligns memory by 32 bytes.
|
||||
Records the pointer to the AIG manager in the -1 entry.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManAddMemory( Aig_Man_t * p )
|
||||
{
|
||||
char * pMemory;
|
||||
int i, nBytes;
|
||||
assert( sizeof(Aig_Obj_t) <= 64 );
|
||||
assert( p->pListFree == NULL );
|
||||
// assert( (Aig_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
|
||||
// allocate new memory page
|
||||
nBytes = sizeof(Aig_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
|
||||
pMemory = ALLOC( char, nBytes );
|
||||
Vec_PtrPush( p->vChunks, pMemory );
|
||||
// align memory at the 32-byte boundary
|
||||
pMemory = pMemory + 64 - (((int)pMemory) & 63);
|
||||
// remember the manager in the first entry
|
||||
Vec_PtrPush( p->vPages, pMemory );
|
||||
// break the memory down into nodes
|
||||
p->pListFree = (Aig_Obj_t *)pMemory;
|
||||
for ( i = 1; i <= IVY_PAGE_MASK; i++ )
|
||||
{
|
||||
*((char **)pMemory) = pMemory + sizeof(Aig_Obj_t);
|
||||
pMemory += sizeof(Aig_Obj_t);
|
||||
}
|
||||
*((char **)pMemory) = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigObj.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Adding/removing objects.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigObj.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates primary input.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
pObj = Aig_ManFetchMemory( p );
|
||||
pObj->Type = AIG_PI;
|
||||
Vec_PtrPush( p->vPis, pObj );
|
||||
p->nObjs[AIG_PI]++;
|
||||
p->nCreated++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates primary output with the given driver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
pObj = Aig_ManFetchMemory( p );
|
||||
pObj->Type = AIG_PO;
|
||||
Vec_PtrPush( p->vPos, pObj );
|
||||
// add connections
|
||||
pObj->pFanin0 = pDriver;
|
||||
if ( p->fRefCount )
|
||||
Aig_ObjRef( Aig_Regular(pDriver) );
|
||||
else
|
||||
pObj->nRefs = Aig_ObjLevel( Aig_Regular(pDriver) );
|
||||
// update node counters of the manager
|
||||
p->nObjs[AIG_PO]++;
|
||||
p->nCreated++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the new node assuming it does not exist.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
assert( !Aig_IsComplement(pGhost) );
|
||||
assert( Aig_ObjIsNode(pGhost) );
|
||||
assert( pGhost == &p->Ghost );
|
||||
// get memory for the new object
|
||||
pObj = Aig_ManFetchMemory( p );
|
||||
pObj->Type = pGhost->Type;
|
||||
// add connections
|
||||
Aig_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
|
||||
// update node counters of the manager
|
||||
p->nObjs[Aig_ObjType(pObj)]++;
|
||||
p->nCreated++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Connect the object to the fanin.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
// add the first fanin
|
||||
pObj->pFanin0 = pFan0;
|
||||
pObj->pFanin1 = pFan1;
|
||||
// increment references of the fanins and add their fanouts
|
||||
if ( p->fRefCount )
|
||||
{
|
||||
if ( pFan0 != NULL )
|
||||
Aig_ObjRef( Aig_ObjFanin0(pObj) );
|
||||
if ( pFan1 != NULL )
|
||||
Aig_ObjRef( Aig_ObjFanin1(pObj) );
|
||||
}
|
||||
else
|
||||
pObj->nRefs = Aig_ObjLevelNew( pObj );
|
||||
// add the node to the structural hash table
|
||||
Aig_TableInsert( p, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Connect the object to the fanin.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
// remove connections
|
||||
if ( pObj->pFanin0 != NULL )
|
||||
Aig_ObjDeref(Aig_ObjFanin0(pObj));
|
||||
if ( pObj->pFanin1 != NULL )
|
||||
Aig_ObjDeref(Aig_ObjFanin1(pObj));
|
||||
// remove the node from the structural hash table
|
||||
Aig_TableDelete( p, pObj );
|
||||
// add the first fanin
|
||||
pObj->pFanin0 = NULL;
|
||||
pObj->pFanin1 = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deletes the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( !Aig_ObjIsTerm(pObj) );
|
||||
assert( Aig_ObjRefs(pObj) == 0 );
|
||||
// update node counters of the manager
|
||||
p->nObjs[pObj->Type]--;
|
||||
p->nDeleted++;
|
||||
// remove connections
|
||||
Aig_ObjDisconnect( p, pObj );
|
||||
// remove PIs/POs from the arrays
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
Vec_PtrRemove( p->vPis, pObj );
|
||||
// free the node
|
||||
Aig_ManRecycleMemory( p, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deletes the MFFC of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pFanin0, * pFanin1;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) )
|
||||
return;
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
pFanin0 = Aig_ObjFanin0(pObj);
|
||||
pFanin1 = Aig_ObjFanin1(pObj);
|
||||
Aig_ObjDelete( p, pObj );
|
||||
if ( pFanin0 && !Aig_ObjIsNone(pFanin0) && Aig_ObjRefs(pFanin0) == 0 )
|
||||
Aig_ObjDelete_rec( p, pFanin0 );
|
||||
if ( pFanin1 && !Aig_ObjIsNone(pFanin1) && Aig_ObjRefs(pFanin1) == 0 )
|
||||
Aig_ObjDelete_rec( p, pFanin1 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,373 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigOper.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [AIG operations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigOper.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// procedure to detect an EXOR gate
|
||||
static inline int Aig_ObjIsExorType( Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 )
|
||||
{
|
||||
if ( !Aig_IsComplement(p0) || !Aig_IsComplement(p1) )
|
||||
return 0;
|
||||
p0 = Aig_Regular(p0);
|
||||
p1 = Aig_Regular(p1);
|
||||
if ( !Aig_ObjIsAnd(p0) || !Aig_ObjIsAnd(p1) )
|
||||
return 0;
|
||||
if ( Aig_ObjFanin0(p0) != Aig_ObjFanin0(p1) || Aig_ObjFanin1(p0) != Aig_ObjFanin1(p1) )
|
||||
return 0;
|
||||
if ( Aig_ObjFaninC0(p0) == Aig_ObjFaninC0(p1) || Aig_ObjFaninC1(p0) == Aig_ObjFaninC1(p1) )
|
||||
return 0;
|
||||
*ppFan0 = Aig_ObjChild0(p0);
|
||||
*ppFan1 = Aig_ObjChild1(p0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns i-th elementary variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_IthVar( Aig_Man_t * p, int i )
|
||||
{
|
||||
int v;
|
||||
for ( v = Aig_ManPiNum(p); v <= i; v++ )
|
||||
Aig_ObjCreatePi( p );
|
||||
assert( i < Vec_PtrSize(p->vPis) );
|
||||
return Aig_ManPi( p, i );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Perform one operation.]
|
||||
|
||||
Description [The argument nodes can be complemented.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Oper( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type )
|
||||
{
|
||||
if ( Type == AIG_AND )
|
||||
return Aig_And( p, p0, p1 );
|
||||
if ( Type == AIG_EXOR )
|
||||
return Aig_Exor( p, p0, p1 );
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs canonicization step.]
|
||||
|
||||
Description [The argument nodes can be complemented.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
|
||||
{
|
||||
Aig_Obj_t * pGhost, * pResult;
|
||||
// Aig_Obj_t * pFan0, * pFan1;
|
||||
// check trivial cases
|
||||
if ( p0 == p1 )
|
||||
return p0;
|
||||
if ( p0 == Aig_Not(p1) )
|
||||
return Aig_Not(p->pConst1);
|
||||
if ( Aig_Regular(p0) == p->pConst1 )
|
||||
return p0 == p->pConst1 ? p1 : Aig_Not(p->pConst1);
|
||||
if ( Aig_Regular(p1) == p->pConst1 )
|
||||
return p1 == p->pConst1 ? p0 : Aig_Not(p->pConst1);
|
||||
// check if it can be an EXOR gate
|
||||
// if ( Aig_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
|
||||
// return Aig_Exor( p, pFan0, pFan1 );
|
||||
// check the table
|
||||
pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_AND );
|
||||
if ( pResult = Aig_TableLookup( p, pGhost ) )
|
||||
return pResult;
|
||||
return Aig_ObjCreate( p, pGhost );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs canonicization step.]
|
||||
|
||||
Description [The argument nodes can be complemented.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Exor( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
|
||||
{
|
||||
/*
|
||||
Aig_Obj_t * pGhost, * pResult;
|
||||
// check trivial cases
|
||||
if ( p0 == p1 )
|
||||
return Aig_Not(p->pConst1);
|
||||
if ( p0 == Aig_Not(p1) )
|
||||
return p->pConst1;
|
||||
if ( Aig_Regular(p0) == p->pConst1 )
|
||||
return Aig_NotCond( p1, p0 == p->pConst1 );
|
||||
if ( Aig_Regular(p1) == p->pConst1 )
|
||||
return Aig_NotCond( p0, p1 == p->pConst1 );
|
||||
// check the table
|
||||
pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_EXOR );
|
||||
if ( pResult = Aig_TableLookup( p, pGhost ) )
|
||||
return pResult;
|
||||
return Aig_ObjCreate( p, pGhost );
|
||||
*/
|
||||
return Aig_Or( p, Aig_And(p, p0, Aig_Not(p1)), Aig_And(p, Aig_Not(p0), p1) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements Boolean OR.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
|
||||
{
|
||||
return Aig_Not( Aig_And( p, Aig_Not(p0), Aig_Not(p1) ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements ITE operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 )
|
||||
{
|
||||
/*
|
||||
Aig_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
|
||||
int Count0, Count1;
|
||||
// consider trivial cases
|
||||
if ( p0 == Aig_Not(p1) )
|
||||
return Aig_Exor( p, pC, p0 );
|
||||
// other cases can be added
|
||||
// implement the first MUX (F = C * x1 + C' * x0)
|
||||
|
||||
// check for constants here!!!
|
||||
|
||||
pTempA1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, p1, AIG_AND) );
|
||||
pTempA2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), p0, AIG_AND) );
|
||||
if ( pTempA1 && pTempA2 )
|
||||
{
|
||||
pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempA1), Aig_Not(pTempA2), AIG_AND) );
|
||||
if ( pTemp ) return Aig_Not(pTemp);
|
||||
}
|
||||
Count0 = (pTempA1 != NULL) + (pTempA2 != NULL);
|
||||
// implement the second MUX (F' = C * x1' + C' * x0')
|
||||
pTempB1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, Aig_Not(p1), AIG_AND) );
|
||||
pTempB2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), Aig_Not(p0), AIG_AND) );
|
||||
if ( pTempB1 && pTempB2 )
|
||||
{
|
||||
pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempB1), Aig_Not(pTempB2), AIG_AND) );
|
||||
if ( pTemp ) return pTemp;
|
||||
}
|
||||
Count1 = (pTempB1 != NULL) + (pTempB2 != NULL);
|
||||
// compare and decide which one to implement
|
||||
if ( Count0 >= Count1 )
|
||||
{
|
||||
pTempA1 = pTempA1? pTempA1 : Aig_And(p, pC, p1);
|
||||
pTempA2 = pTempA2? pTempA2 : Aig_And(p, Aig_Not(pC), p0);
|
||||
return Aig_Or( p, pTempA1, pTempA2 );
|
||||
}
|
||||
pTempB1 = pTempB1? pTempB1 : Aig_And(p, pC, Aig_Not(p1));
|
||||
pTempB2 = pTempB2? pTempB2 : Aig_And(p, Aig_Not(pC), Aig_Not(p0));
|
||||
return Aig_Not( Aig_Or( p, pTempB1, pTempB2 ) );
|
||||
*/
|
||||
return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements ITE operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Maj( Aig_Man_t * p, Aig_Obj_t * pA, Aig_Obj_t * pB, Aig_Obj_t * pC )
|
||||
{
|
||||
return Aig_Or( p, Aig_Or(p, Aig_And(p, pA, pB), Aig_And(p, pA, pC)), Aig_And(p, pB, pC) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the well-balanced tree of gates.]
|
||||
|
||||
Description [Disregards levels and possible logic sharing.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Multi_rec( Aig_Man_t * p, Aig_Obj_t ** ppObjs, int nObjs, Aig_Type_t Type )
|
||||
{
|
||||
Aig_Obj_t * pObj1, * pObj2;
|
||||
if ( nObjs == 1 )
|
||||
return ppObjs[0];
|
||||
pObj1 = Aig_Multi_rec( p, ppObjs, nObjs/2, Type );
|
||||
pObj2 = Aig_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type );
|
||||
return Aig_Oper( p, pObj1, pObj2, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Old code.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Multi( Aig_Man_t * p, Aig_Obj_t ** pArgs, int nArgs, Aig_Type_t Type )
|
||||
{
|
||||
assert( Type == AIG_AND || Type == AIG_EXOR );
|
||||
assert( nArgs > 0 );
|
||||
return Aig_Multi_rec( p, pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs )
|
||||
{
|
||||
int i;
|
||||
assert( vPairs->nSize > 0 );
|
||||
assert( vPairs->nSize % 2 == 0 );
|
||||
// go through the cubes of the node's SOP
|
||||
for ( i = 0; i < vPairs->nSize; i += 2 )
|
||||
vPairs->pArray[i/2] = Aig_Not( Aig_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) );
|
||||
vPairs->nSize = vPairs->nSize/2;
|
||||
return Aig_Not( Aig_Multi_rec( p, (Aig_Obj_t **)vPairs->pArray, vPairs->nSize, AIG_AND ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates AND function with nVars inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_CreateAnd( Aig_Man_t * p, int nVars )
|
||||
{
|
||||
Aig_Obj_t * pFunc;
|
||||
int i;
|
||||
pFunc = Aig_ManConst1( p );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pFunc = Aig_And( p, pFunc, Aig_IthVar(p, i) );
|
||||
return pFunc;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates AND function with nVars inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_CreateOr( Aig_Man_t * p, int nVars )
|
||||
{
|
||||
Aig_Obj_t * pFunc;
|
||||
int i;
|
||||
pFunc = Aig_ManConst0( p );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pFunc = Aig_Or( p, pFunc, Aig_IthVar(p, i) );
|
||||
return pFunc;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates AND function with nVars inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars )
|
||||
{
|
||||
Aig_Obj_t * pFunc;
|
||||
int i;
|
||||
pFunc = Aig_ManConst0( p );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pFunc = Aig_Exor( p, pFunc, Aig_IthVar(p, i) );
|
||||
return pFunc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigTable.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Structural hashing table.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006. ]
|
||||
|
||||
Revision [$Id: aigTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// hashing the node
|
||||
static unsigned long Aig_Hash( Aig_Obj_t * pObj, int TableSize )
|
||||
{
|
||||
unsigned long Key = Aig_ObjIsExor(pObj) * 1699;
|
||||
Key ^= (long)Aig_ObjFanin0(pObj) * 7937;
|
||||
Key ^= (long)Aig_ObjFanin1(pObj) * 2971;
|
||||
Key ^= Aig_ObjFaninC0(pObj) * 911;
|
||||
Key ^= Aig_ObjFaninC1(pObj) * 353;
|
||||
return Key % TableSize;
|
||||
}
|
||||
|
||||
// returns the place where this node is stored (or should be stored)
|
||||
static Aig_Obj_t ** Aig_TableFind( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int i;
|
||||
assert( Aig_ObjChild0(pObj) && Aig_ObjChild1(pObj) );
|
||||
assert( Aig_ObjChild0(pObj) < Aig_ObjChild1(pObj) );
|
||||
for ( i = Aig_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
if ( p->pTable[i] == pObj )
|
||||
break;
|
||||
return p->pTable + i;
|
||||
}
|
||||
|
||||
static void Aig_TableResize( Aig_Man_t * p );
|
||||
static unsigned int Cudd_PrimeAig( unsigned int p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if node with the given attributes is in the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost )
|
||||
{
|
||||
int i;
|
||||
assert( !Aig_IsComplement(pGhost) );
|
||||
assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) );
|
||||
assert( Aig_ObjChild0(pGhost) < Aig_ObjChild1(pGhost) );
|
||||
if ( p->fRefCount && (!Aig_ObjRefs(Aig_ObjFanin0(pGhost)) || !Aig_ObjRefs(Aig_ObjFanin1(pGhost))) )
|
||||
return NULL;
|
||||
for ( i = Aig_Hash(pGhost, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
{
|
||||
if ( Aig_ObjChild0(p->pTable[i]) == Aig_ObjChild0(pGhost) &&
|
||||
Aig_ObjChild1(p->pTable[i]) == Aig_ObjChild1(pGhost) &&
|
||||
Aig_ObjType(p->pTable[i]) == Aig_ObjType(pGhost) )
|
||||
return p->pTable[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the new node to the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t ** ppPlace;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( Aig_TableLookup(p, pObj) == NULL );
|
||||
if ( p->nTableSize < 2 * Aig_ManNodeNum(p) )
|
||||
Aig_TableResize( p );
|
||||
ppPlace = Aig_TableFind( p, pObj );
|
||||
assert( *ppPlace == NULL );
|
||||
*ppPlace = pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deletes the node from the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pEntry, ** ppPlace;
|
||||
int i;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
ppPlace = Aig_TableFind( p, pObj );
|
||||
assert( *ppPlace == pObj ); // node should be in the table
|
||||
*ppPlace = NULL;
|
||||
// rehash the adjacent entries
|
||||
i = ppPlace - p->pTable;
|
||||
for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
{
|
||||
pEntry = p->pTable[i];
|
||||
p->pTable[i] = 0;
|
||||
Aig_TableInsert( p, pEntry );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Count the number of nodes in the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_TableCountEntries( Aig_Man_t * p )
|
||||
{
|
||||
int i, Counter = 0;
|
||||
for ( i = 0; i < p->nTableSize; i++ )
|
||||
Counter += (p->pTable[i] != NULL);
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the table.]
|
||||
|
||||
Description [Typically this procedure should not be called.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_TableResize( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t ** pTableOld, ** ppPlace;
|
||||
int nTableSizeOld, Counter, nEntries, e, clk;
|
||||
clk = clock();
|
||||
// save the old table
|
||||
pTableOld = p->pTable;
|
||||
nTableSizeOld = p->nTableSize;
|
||||
// get the new table
|
||||
p->nTableSize = Cudd_PrimeAig( 5 * Aig_ManNodeNum(p) );
|
||||
p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize );
|
||||
memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize );
|
||||
// rehash the entries from the old table
|
||||
Counter = 0;
|
||||
for ( e = 0; e < nTableSizeOld; e++ )
|
||||
{
|
||||
if ( pTableOld[e] == 0 )
|
||||
continue;
|
||||
Counter++;
|
||||
// get the place where this entry goes in the table table
|
||||
ppPlace = Aig_TableFind( p, pTableOld[e] );
|
||||
assert( *ppPlace == NULL ); // should not be in the table
|
||||
*ppPlace = pTableOld[e];
|
||||
}
|
||||
nEntries = Aig_ManNodeNum(p);
|
||||
// assert( Counter == nEntries );
|
||||
// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
|
||||
// PRT( "Time", clock() - clk );
|
||||
// replace the table and the parameters
|
||||
free( pTableOld );
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis [Profiles the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
void Aig_TableProfile( Aig_Man_t * p )
|
||||
{
|
||||
int i, Counter = 0;
|
||||
for ( i = 0; i < p->nTableSize; i++ )
|
||||
{
|
||||
if ( p->pTable[i] )
|
||||
Counter++;
|
||||
else if ( Counter )
|
||||
{
|
||||
printf( "%d ", Counter );
|
||||
Counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis [Returns the next prime >= p.]
|
||||
|
||||
Description [Copied from CUDD, for stand-aloneness.]
|
||||
|
||||
SideEffects [None]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
unsigned int Cudd_PrimeAig( unsigned int p)
|
||||
{
|
||||
int i,pn;
|
||||
|
||||
p--;
|
||||
do {
|
||||
p++;
|
||||
if (p&1) {
|
||||
pn = 1;
|
||||
i = 3;
|
||||
while ((unsigned) (i * i) <= p) {
|
||||
if (p % i == 0) {
|
||||
pn = 0;
|
||||
break;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
} else {
|
||||
pn = 0;
|
||||
}
|
||||
} while (!pn);
|
||||
return(p);
|
||||
|
||||
} /* end of Cudd_Prime */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,513 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigUtil.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Various procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: aigUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
|
||||
int Extra_Base10Log( unsigned Num )
|
||||
{
|
||||
int Res;
|
||||
assert( Num >= 0 );
|
||||
if ( Num == 0 ) return 0;
|
||||
if ( Num == 1 ) return 1;
|
||||
for ( Res = 0, Num--; Num; Num /= 10, Res++ );
|
||||
return Res;
|
||||
} /* end of Extra_Base2Log */
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Increments the current traversal ID of the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManIncrementTravId( Aig_Man_t * p )
|
||||
{
|
||||
if ( p->nTravIds >= (1<<30)-1 )
|
||||
Aig_ManCleanData( p );
|
||||
p->nTravIds++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManCleanData( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
p->nTravIds = 1;
|
||||
Aig_ManConst1(p)->pData = NULL;
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Detects multi-input gate rooted at this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjCollectMulti_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
|
||||
{
|
||||
if ( pRoot != pObj && (Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) || Aig_ObjType(pRoot) != Aig_ObjType(pObj)) )
|
||||
{
|
||||
Vec_PtrPushUnique(vSuper, pObj);
|
||||
return;
|
||||
}
|
||||
Aig_ObjCollectMulti_rec( pRoot, Aig_ObjChild0(pObj), vSuper );
|
||||
Aig_ObjCollectMulti_rec( pRoot, Aig_ObjChild1(pObj), vSuper );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Detects multi-input gate rooted at this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjCollectMulti( Aig_Obj_t * pRoot, Vec_Ptr_t * vSuper )
|
||||
{
|
||||
assert( !Aig_IsComplement(pRoot) );
|
||||
Vec_PtrClear( vSuper );
|
||||
Aig_ObjCollectMulti_rec( pRoot, pRoot, vSuper );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ObjIsMuxType( Aig_Obj_t * pNode )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1;
|
||||
// check that the node is regular
|
||||
assert( !Aig_IsComplement(pNode) );
|
||||
// if the node is not AND, this is not MUX
|
||||
if ( !Aig_ObjIsAnd(pNode) )
|
||||
return 0;
|
||||
// if the children are not complemented, this is not MUX
|
||||
if ( !Aig_ObjFaninC0(pNode) || !Aig_ObjFaninC1(pNode) )
|
||||
return 0;
|
||||
// get children
|
||||
pNode0 = Aig_ObjFanin0(pNode);
|
||||
pNode1 = Aig_ObjFanin1(pNode);
|
||||
// if the children are not ANDs, this is not MUX
|
||||
if ( !Aig_ObjIsAnd(pNode0) || !Aig_ObjIsAnd(pNode1) )
|
||||
return 0;
|
||||
// otherwise the node is MUX iff it has a pair of equal grandchildren
|
||||
return (Aig_ObjFanin0(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC0(pNode1))) ||
|
||||
(Aig_ObjFanin0(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC1(pNode1))) ||
|
||||
(Aig_ObjFanin1(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC0(pNode1))) ||
|
||||
(Aig_ObjFanin1(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC1(pNode1)));
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recognizes what nodes are inputs of the EXOR.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_ObjRecognizeExor( Aig_Obj_t * pObj, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 )
|
||||
{
|
||||
Aig_Obj_t * p0, * p1;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( !Aig_ObjIsNode(pObj) )
|
||||
return 0;
|
||||
if ( Aig_ObjIsExor(pObj) )
|
||||
{
|
||||
*ppFan0 = Aig_ObjChild0(pObj);
|
||||
*ppFan1 = Aig_ObjChild1(pObj);
|
||||
return 1;
|
||||
}
|
||||
assert( Aig_ObjIsAnd(pObj) );
|
||||
p0 = Aig_ObjChild0(pObj);
|
||||
p1 = Aig_ObjChild1(pObj);
|
||||
if ( !Aig_IsComplement(p0) || !Aig_IsComplement(p1) )
|
||||
return 0;
|
||||
p0 = Aig_Regular(p0);
|
||||
p1 = Aig_Regular(p1);
|
||||
if ( !Aig_ObjIsAnd(p0) || !Aig_ObjIsAnd(p1) )
|
||||
return 0;
|
||||
if ( Aig_ObjFanin0(p0) != Aig_ObjFanin0(p1) || Aig_ObjFanin1(p0) != Aig_ObjFanin1(p1) )
|
||||
return 0;
|
||||
if ( Aig_ObjFaninC0(p0) == Aig_ObjFaninC0(p1) || Aig_ObjFaninC1(p0) == Aig_ObjFaninC1(p1) )
|
||||
return 0;
|
||||
*ppFan0 = Aig_ObjChild0(p0);
|
||||
*ppFan1 = Aig_ObjChild1(p0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
|
||||
|
||||
Description [If the node is a MUX, returns the control variable C.
|
||||
Assigns nodes T and E to be the then and else variables of the MUX.
|
||||
Node C is never complemented. Nodes T and E can be complemented.
|
||||
This function also recognizes EXOR/NEXOR gates as MUXes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Aig_ObjRecognizeMux( Aig_Obj_t * pNode, Aig_Obj_t ** ppNodeT, Aig_Obj_t ** ppNodeE )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1;
|
||||
assert( !Aig_IsComplement(pNode) );
|
||||
assert( Aig_ObjIsMuxType(pNode) );
|
||||
// get children
|
||||
pNode0 = Aig_ObjFanin0(pNode);
|
||||
pNode1 = Aig_ObjFanin1(pNode);
|
||||
|
||||
// find the control variable
|
||||
if ( Aig_ObjFanin1(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC1(pNode1)) )
|
||||
{
|
||||
// if ( Fraig_IsComplement(pNode1->p2) )
|
||||
if ( Aig_ObjFaninC1(pNode0) )
|
||||
{ // pNode2->p2 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
|
||||
return Aig_ObjChild1(pNode1);//pNode2->p2;
|
||||
}
|
||||
else
|
||||
{ // pNode1->p2 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
|
||||
return Aig_ObjChild1(pNode0);//pNode1->p2;
|
||||
}
|
||||
}
|
||||
else if ( Aig_ObjFanin0(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC0(pNode1)) )
|
||||
{
|
||||
// if ( Fraig_IsComplement(pNode1->p1) )
|
||||
if ( Aig_ObjFaninC0(pNode0) )
|
||||
{ // pNode2->p1 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
|
||||
return Aig_ObjChild0(pNode1);//pNode2->p1;
|
||||
}
|
||||
else
|
||||
{ // pNode1->p1 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
|
||||
return Aig_ObjChild0(pNode0);//pNode1->p1;
|
||||
}
|
||||
}
|
||||
else if ( Aig_ObjFanin0(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC1(pNode1)) )
|
||||
{
|
||||
// if ( Fraig_IsComplement(pNode1->p1) )
|
||||
if ( Aig_ObjFaninC0(pNode0) )
|
||||
{ // pNode2->p2 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
|
||||
return Aig_ObjChild1(pNode1);//pNode2->p2;
|
||||
}
|
||||
else
|
||||
{ // pNode1->p1 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
|
||||
return Aig_ObjChild0(pNode0);//pNode1->p1;
|
||||
}
|
||||
}
|
||||
else if ( Aig_ObjFanin1(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC0(pNode1)) )
|
||||
{
|
||||
// if ( Fraig_IsComplement(pNode1->p2) )
|
||||
if ( Aig_ObjFaninC1(pNode0) )
|
||||
{ // pNode2->p1 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
|
||||
return Aig_ObjChild0(pNode1);//pNode2->p1;
|
||||
}
|
||||
else
|
||||
{ // pNode1->p2 is positive phase of C
|
||||
*ppNodeT = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
|
||||
*ppNodeE = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
|
||||
return Aig_ObjChild1(pNode0);//pNode1->p2;
|
||||
}
|
||||
}
|
||||
assert( 0 ); // this is not MUX
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints Verilog formula for the AIG rooted at this node.]
|
||||
|
||||
Description [The formula is in terms of PIs, which should have
|
||||
their names assigned in pObj->pData fields.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjPrintVerilog( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, int Level )
|
||||
{
|
||||
Vec_Ptr_t * vSuper;
|
||||
Aig_Obj_t * pFanin, * pFanin0, * pFanin1, * pFaninC;
|
||||
int fCompl, i;
|
||||
// store the complemented attribute
|
||||
fCompl = Aig_IsComplement(pObj);
|
||||
pObj = Aig_Regular(pObj);
|
||||
// constant case
|
||||
if ( Aig_ObjIsConst1(pObj) )
|
||||
{
|
||||
fprintf( pFile, "%d", !fCompl );
|
||||
return;
|
||||
}
|
||||
// PI case
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
{
|
||||
fprintf( pFile, "%s%s", fCompl? "~" : "", pObj->pData );
|
||||
return;
|
||||
}
|
||||
// EXOR case
|
||||
if ( Aig_ObjIsExor(pObj) )
|
||||
{
|
||||
Vec_VecExpand( vLevels, Level );
|
||||
vSuper = Vec_VecEntry( vLevels, Level );
|
||||
Aig_ObjCollectMulti( pObj, vSuper );
|
||||
fprintf( pFile, "%s", (Level==0? "" : "(") );
|
||||
Vec_PtrForEachEntry( vSuper, pFanin, i )
|
||||
{
|
||||
Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin, (fCompl && i==0)), vLevels, Level+1 );
|
||||
if ( i < Vec_PtrSize(vSuper) - 1 )
|
||||
fprintf( pFile, " ^ " );
|
||||
}
|
||||
fprintf( pFile, "%s", (Level==0? "" : ")") );
|
||||
return;
|
||||
}
|
||||
// MUX case
|
||||
if ( Aig_ObjIsMuxType(pObj) )
|
||||
{
|
||||
if ( Aig_ObjRecognizeExor( pObj, &pFanin0, &pFanin1 ) )
|
||||
{
|
||||
fprintf( pFile, "%s", (Level==0? "" : "(") );
|
||||
Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin0, fCompl), vLevels, Level+1 );
|
||||
fprintf( pFile, " ^ " );
|
||||
Aig_ObjPrintVerilog( pFile, pFanin1, vLevels, Level+1 );
|
||||
fprintf( pFile, "%s", (Level==0? "" : ")") );
|
||||
}
|
||||
else
|
||||
{
|
||||
pFaninC = Aig_ObjRecognizeMux( pObj, &pFanin1, &pFanin0 );
|
||||
fprintf( pFile, "%s", (Level==0? "" : "(") );
|
||||
Aig_ObjPrintVerilog( pFile, pFaninC, vLevels, Level+1 );
|
||||
fprintf( pFile, " ? " );
|
||||
Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin1, fCompl), vLevels, Level+1 );
|
||||
fprintf( pFile, " : " );
|
||||
Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin0, fCompl), vLevels, Level+1 );
|
||||
fprintf( pFile, "%s", (Level==0? "" : ")") );
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AND case
|
||||
Vec_VecExpand( vLevels, Level );
|
||||
vSuper = Vec_VecEntry(vLevels, Level);
|
||||
Aig_ObjCollectMulti( pObj, vSuper );
|
||||
fprintf( pFile, "%s", (Level==0? "" : "(") );
|
||||
Vec_PtrForEachEntry( vSuper, pFanin, i )
|
||||
{
|
||||
Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin, fCompl), vLevels, Level+1 );
|
||||
if ( i < Vec_PtrSize(vSuper) - 1 )
|
||||
fprintf( pFile, " %s ", fCompl? "|" : "&" );
|
||||
}
|
||||
fprintf( pFile, "%s", (Level==0? "" : ")") );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints node in HAIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ObjPrintVerbose( Aig_Obj_t * pObj, int fHaig )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
printf( "Node %p : ", pObj );
|
||||
if ( Aig_ObjIsConst1(pObj) )
|
||||
printf( "constant 1" );
|
||||
else if ( Aig_ObjIsPi(pObj) )
|
||||
printf( "PI" );
|
||||
else
|
||||
printf( "AND( %p%s, %p%s )",
|
||||
Aig_ObjFanin0(pObj), (Aig_ObjFaninC0(pObj)? "\'" : " "),
|
||||
Aig_ObjFanin1(pObj), (Aig_ObjFaninC1(pObj)? "\'" : " ") );
|
||||
printf( " (refs = %3d)", Aig_ObjRefs(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints node in HAIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "PIs: " );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
printf( " %p", pObj );
|
||||
printf( "\n" );
|
||||
vNodes = Aig_ManDfs( p );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Aig_ObjPrintVerbose( pObj, fHaig ), printf( "\n" );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the AIG into the BLIF file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj, * pConst1 = NULL;
|
||||
int i, nDigits, Counter = 0;
|
||||
if ( Aig_ManPoNum(p) == 0 )
|
||||
{
|
||||
printf( "Aig_ManDumpBlif(): AIG manager does not have POs.\n" );
|
||||
return;
|
||||
}
|
||||
// collect nodes in the DFS order
|
||||
vNodes = Aig_ManDfs( p );
|
||||
// assign IDs to objects
|
||||
Aig_ManConst1(p)->pData = (void *)Counter++;
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = (void *)Counter++;
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
pObj->pData = (void *)Counter++;
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
pObj->pData = (void *)Counter++;
|
||||
nDigits = Extra_Base10Log( Counter );
|
||||
// write the file
|
||||
pFile = fopen( pFileName, "w" );
|
||||
fprintf( pFile, "# BLIF file written by procedure Aig_ManDumpBlif() in ABC\n" );
|
||||
fprintf( pFile, "# http://www.eecs.berkeley.edu/~alanmi/abc/\n" );
|
||||
fprintf( pFile, ".model test\n" );
|
||||
// write PIs
|
||||
fprintf( pFile, ".inputs" );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
|
||||
fprintf( pFile, "\n" );
|
||||
// write POs
|
||||
fprintf( pFile, ".outputs" );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
|
||||
fprintf( pFile, "\n" );
|
||||
// write nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
fprintf( pFile, ".names n%0*d n%0*d n%0*d\n",
|
||||
nDigits, (int)Aig_ObjFanin0(pObj)->pData,
|
||||
nDigits, (int)Aig_ObjFanin1(pObj)->pData,
|
||||
nDigits, (int)pObj->pData );
|
||||
fprintf( pFile, "%d%d 1\n", !Aig_ObjFaninC0(pObj), !Aig_ObjFaninC1(pObj) );
|
||||
}
|
||||
// write POs
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, ".names n%0*d n%0*d\n",
|
||||
nDigits, (int)Aig_ObjFanin0(pObj)->pData,
|
||||
nDigits, (int)pObj->pData );
|
||||
fprintf( pFile, "%d 1\n", !Aig_ObjFaninC0(pObj) );
|
||||
if ( Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) )
|
||||
pConst1 = Aig_ManConst1(p);
|
||||
}
|
||||
if ( pConst1 )
|
||||
fprintf( pFile, ".names n%0*d\n 1\n", nDigits, (int)pConst1->pData );
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
fclose( pFile );
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cudd2.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Recording AIGs for the BDD operations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - October 3, 2006.]
|
||||
|
||||
Revision [$Id: cudd2.c,v 1.00 2006/10/03 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
#include "st.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Aig_CuddMan_t_ Aig_CuddMan_t;
|
||||
struct Aig_CuddMan_t_
|
||||
{
|
||||
Aig_Man_t * pAig; // internal AIG package
|
||||
st_table * pTable; // hash table mapping BDD nodes into AIG nodes
|
||||
};
|
||||
|
||||
// static Cudd AIG manager used in this experiment
|
||||
static Aig_CuddMan_t * s_pCuddMan = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start AIG recording.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd )
|
||||
{
|
||||
int v;
|
||||
assert( s_pCuddMan == NULL );
|
||||
s_pCuddMan = ALLOC( Aig_CuddMan_t, 1 );
|
||||
s_pCuddMan->pAig = Aig_ManStart();
|
||||
s_pCuddMan->pTable = st_init_table( st_ptrcmp, st_ptrhash );
|
||||
for ( v = 0; v < (int)numVars; v++ )
|
||||
Aig_ObjCreatePi( s_pCuddMan->pAig );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops AIG recording.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_Quit( void * pCudd )
|
||||
{
|
||||
assert( s_pCuddMan != NULL );
|
||||
Aig_ManDumpBlif( s_pCuddMan->pAig, "aig_temp.blif" );
|
||||
Aig_ManStop( s_pCuddMan->pAig );
|
||||
st_free_table( s_pCuddMan->pTable );
|
||||
free( s_pCuddMan );
|
||||
s_pCuddMan = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fetches AIG node corresponding to the BDD node from the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static Aig_Obj_t * Cudd2_GetArg( void * pArg )
|
||||
{
|
||||
Aig_Obj_t * pNode;
|
||||
assert( s_pCuddMan != NULL );
|
||||
if ( !st_lookup( s_pCuddMan->pTable, (char *)Aig_Regular(pArg), (char **)&pNode ) )
|
||||
{
|
||||
printf( "Cudd2_GetArg(): An argument BDD is not in the hash table.\n" );
|
||||
return NULL;
|
||||
}
|
||||
return Aig_NotCond( pNode, Aig_IsComplement(pArg) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the AIG node corresponding to the BDD node into the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static void Cudd2_SetArg( Aig_Obj_t * pNode, void * pResult )
|
||||
{
|
||||
assert( s_pCuddMan != NULL );
|
||||
if ( st_is_member( s_pCuddMan->pTable, (char *)Aig_Regular(pResult) ) )
|
||||
return;
|
||||
pNode = Aig_NotCond( pNode, Aig_IsComplement(pResult) );
|
||||
st_insert( s_pCuddMan->pTable, (char *)Aig_Regular(pResult), (char *)pNode );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates equivalent of BDD.ONE and BDD.ReadZero.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
void Cudd2_bddOne( void * pCudd, void * pResult )
|
||||
{
|
||||
Cudd2_SetArg( Aig_ManConst1(s_pCuddMan->pAig), pResult );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds elementary variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddIthVar( void * pCudd, int iVar, void * pResult )
|
||||
{
|
||||
int v;
|
||||
assert( s_pCuddMan != NULL );
|
||||
for ( v = Aig_ManPiNum(s_pCuddMan->pAig); v <= iVar; v++ )
|
||||
Aig_ObjCreatePi( s_pCuddMan->pAig );
|
||||
Cudd2_SetArg( Aig_ManPi(s_pCuddMan->pAig, iVar), pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddAnd( void * pCudd, void * pArg0, void * pArg1, void * pResult )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1, * pNode;
|
||||
pNode0 = Cudd2_GetArg( pArg0 );
|
||||
pNode1 = Cudd2_GetArg( pArg1 );
|
||||
pNode = Aig_And( s_pCuddMan->pAig, pNode0, pNode1 );
|
||||
Cudd2_SetArg( pNode, pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddOr( void * pCudd, void * pArg0, void * pArg1, void * pResult )
|
||||
{
|
||||
Cudd2_bddAnd( pCudd, Aig_Not(pArg0), Aig_Not(pArg1), Aig_Not(pResult) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddNand( void * pCudd, void * pArg0, void * pArg1, void * pResult )
|
||||
{
|
||||
Cudd2_bddAnd( pCudd, pArg0, pArg1, Aig_Not(pResult) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddNor( void * pCudd, void * pArg0, void * pArg1, void * pResult )
|
||||
{
|
||||
Cudd2_bddAnd( pCudd, Aig_Not(pArg0), Aig_Not(pArg1), pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddXor( void * pCudd, void * pArg0, void * pArg1, void * pResult )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1, * pNode;
|
||||
pNode0 = Cudd2_GetArg( pArg0 );
|
||||
pNode1 = Cudd2_GetArg( pArg1 );
|
||||
pNode = Aig_Exor( s_pCuddMan->pAig, pNode0, pNode1 );
|
||||
Cudd2_SetArg( pNode, pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddXnor( void * pCudd, void * pArg0, void * pArg1, void * pResult )
|
||||
{
|
||||
Cudd2_bddXor( pCudd, pArg0, pArg1, Aig_Not(pResult) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddIte( void * pCudd, void * pArg0, void * pArg1, void * pArg2, void * pResult )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1, * pNode2, * pNode;
|
||||
pNode0 = Cudd2_GetArg( pArg0 );
|
||||
pNode1 = Cudd2_GetArg( pArg1 );
|
||||
pNode2 = Cudd2_GetArg( pArg2 );
|
||||
pNode = Aig_Mux( s_pCuddMan->pAig, pNode0, pNode1, pNode2 );
|
||||
Cudd2_SetArg( pNode, pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs BDD operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddCompose( void * pCudd, void * pArg0, void * pArg1, int v, void * pResult )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1, * pNode;
|
||||
pNode0 = Cudd2_GetArg( pArg0 );
|
||||
pNode1 = Cudd2_GetArg( pArg1 );
|
||||
pNode = Aig_Compose( s_pCuddMan->pAig, pNode0, pNode1, v );
|
||||
Cudd2_SetArg( pNode, pResult );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Should be called after each containment check.]
|
||||
|
||||
Description [Result should be 1 if Cudd2_bddLeq returned 1.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddLeq( void * pCudd, void * pArg0, void * pArg1, int Result )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1, * pNode;
|
||||
pNode0 = Cudd2_GetArg( pArg0 );
|
||||
pNode1 = Cudd2_GetArg( pArg1 );
|
||||
pNode = Aig_And( s_pCuddMan->pAig, pNode0, Aig_Not(pNode1) );
|
||||
Aig_ObjCreatePo( s_pCuddMan->pAig, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Should be called after each equality check.]
|
||||
|
||||
Description [Result should be 1 if they are equal.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_bddEqual( void * pCudd, void * pArg0, void * pArg1, int Result )
|
||||
{
|
||||
Aig_Obj_t * pNode0, * pNode1, * pNode;
|
||||
pNode0 = Cudd2_GetArg( pArg0 );
|
||||
pNode1 = Cudd2_GetArg( pArg1 );
|
||||
pNode = Aig_Exor( s_pCuddMan->pAig, pNode0, pNode1 );
|
||||
Aig_ObjCreatePo( s_pCuddMan->pAig, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Should be called each time a BDD node is dereferenced.]
|
||||
|
||||
Description [Removes mapping of a BDD node into an AIG node when the BDD
|
||||
node is dereferenced.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cudd2_RecursiveDeref( void * pCudd, void * pArg )
|
||||
{
|
||||
assert( s_pCuddMan != NULL );
|
||||
assert( st_is_member(s_pCuddMan->pTable, (char *)Aig_Regular(pArg)) );
|
||||
st_delete( s_pCuddMan->pTable, (char *)Aig_Regular(pArg), NULL );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cudd2.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic And-Inverter Graph package.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - October 3, 2006.]
|
||||
|
||||
Revision [$Id: cudd2.h,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __CUDD2_H__
|
||||
#define __CUDD2_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// HA: Added for printing messages
|
||||
#ifndef MSG
|
||||
#define MSG(msg) (printf("%s = \n",(msg)));
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern void Cudd2_Init ( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd );
|
||||
extern void Cudd2_Quit ( void * pCudd );
|
||||
extern void Cudd2_bddOne ( void * pCudd, void * pResult );
|
||||
|
||||
extern void Cudd2_bddIthVar ( void * pCudd, int iVar, void * pResult );
|
||||
extern void Cudd2_bddAnd ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddOr ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddNand ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddNor ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddXor ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddXnor ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
|
||||
extern void Cudd2_bddIte ( void * pCudd, void * pArg0, void * pArg1, void * pArg2, void * pResult );
|
||||
extern void Cudd2_bddCompose( void * pCudd, void * pArg0, void * pArg1, int v, void * pResult );
|
||||
extern void Cudd2_bddLeq ( void * pCudd, void * pArg0, void * pArg1, int Result );
|
||||
extern void Cudd2_bddEqual ( void * pCudd, void * pArg0, void * pArg1, int Result );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* Revision Control Information
|
||||
*
|
||||
* /projects/hsis/CVS/utilities/st/st.c,v
|
||||
* serdar
|
||||
* 1.1
|
||||
* 1993/07/29 01:00:13
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
//#include "extra.h"
|
||||
#include "st.h"
|
||||
|
||||
#ifndef ABS
|
||||
# define ABS(a) ((a) < 0 ? -(a) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef ALLOC
|
||||
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
|
||||
#endif
|
||||
|
||||
#ifndef FREE
|
||||
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
|
||||
#endif
|
||||
|
||||
#ifndef REALLOC
|
||||
#define REALLOC(type, obj, num) \
|
||||
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
|
||||
((type *) malloc(sizeof(type) * (num))))
|
||||
#endif
|
||||
|
||||
#define ST_NUMCMP(x,y) ((x) != (y))
|
||||
#define ST_NUMHASH(x,size) (ABS((long)x)%(size))
|
||||
#define ST_PTRHASH(x,size) ((int)((unsigned long)(x)>>2)%size)
|
||||
#define EQUAL(func, x, y) \
|
||||
((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\
|
||||
(ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))
|
||||
|
||||
|
||||
#define do_hash(key, table)\
|
||||
((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\
|
||||
(table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\
|
||||
(*table->hash)((key), (table)->num_bins))
|
||||
|
||||
static int rehash();
|
||||
int st_numhash(), st_ptrhash(), st_numcmp(), st_ptrcmp();
|
||||
|
||||
st_table *
|
||||
st_init_table_with_params(compare, hash, size, density, grow_factor,
|
||||
reorder_flag)
|
||||
int (*compare)();
|
||||
int (*hash)();
|
||||
int size;
|
||||
int density;
|
||||
double grow_factor;
|
||||
int reorder_flag;
|
||||
{
|
||||
int i;
|
||||
st_table *new;
|
||||
|
||||
new = ALLOC(st_table, 1);
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->compare = compare;
|
||||
new->hash = hash;
|
||||
new->num_entries = 0;
|
||||
new->max_density = density;
|
||||
new->grow_factor = grow_factor;
|
||||
new->reorder_flag = reorder_flag;
|
||||
if (size <= 0) {
|
||||
size = 1;
|
||||
}
|
||||
new->num_bins = size;
|
||||
new->bins = ALLOC(st_table_entry *, size);
|
||||
if (new->bins == NULL) {
|
||||
FREE(new);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < size; i++) {
|
||||
new->bins[i] = 0;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
st_table *
|
||||
st_init_table(compare, hash)
|
||||
int (*compare)();
|
||||
int (*hash)();
|
||||
{
|
||||
return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
|
||||
ST_DEFAULT_MAX_DENSITY,
|
||||
ST_DEFAULT_GROW_FACTOR,
|
||||
ST_DEFAULT_REORDER_FLAG);
|
||||
}
|
||||
|
||||
void
|
||||
st_free_table(table)
|
||||
st_table *table;
|
||||
{
|
||||
register st_table_entry *ptr, *next;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < table->num_bins ; i++) {
|
||||
ptr = table->bins[i];
|
||||
while (ptr != NULL) {
|
||||
next = ptr->next;
|
||||
FREE(ptr);
|
||||
ptr = next;
|
||||
}
|
||||
}
|
||||
FREE(table->bins);
|
||||
FREE(table);
|
||||
}
|
||||
|
||||
#define PTR_NOT_EQUAL(table, ptr, user_key)\
|
||||
(ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key))
|
||||
|
||||
#define FIND_ENTRY(table, hash_val, key, ptr, last) \
|
||||
(last) = &(table)->bins[hash_val];\
|
||||
(ptr) = *(last);\
|
||||
while (PTR_NOT_EQUAL((table), (ptr), (key))) {\
|
||||
(last) = &(ptr)->next; (ptr) = *(last);\
|
||||
}\
|
||||
if ((ptr) != NULL && (table)->reorder_flag) {\
|
||||
*(last) = (ptr)->next;\
|
||||
(ptr)->next = (table)->bins[hash_val];\
|
||||
(table)->bins[hash_val] = (ptr);\
|
||||
}
|
||||
|
||||
int
|
||||
st_lookup(table, key, value)
|
||||
st_table *table;
|
||||
register char *key;
|
||||
char **value;
|
||||
{
|
||||
int hash_val;
|
||||
register st_table_entry *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr, last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
if (value != NULL) {
|
||||
*value = ptr->record;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
st_lookup_int(table, key, value)
|
||||
st_table *table;
|
||||
register char *key;
|
||||
int *value;
|
||||
{
|
||||
int hash_val;
|
||||
register st_table_entry *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr, last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
if (value != 0) {
|
||||
*value = (long) ptr->record;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* This macro does not check if memory allocation fails. Use at you own risk */
|
||||
#define ADD_DIRECT(table, key, value, hash_val, new)\
|
||||
{\
|
||||
if (table->num_entries/table->num_bins >= table->max_density) {\
|
||||
rehash(table);\
|
||||
hash_val = do_hash(key,table);\
|
||||
}\
|
||||
\
|
||||
new = ALLOC(st_table_entry, 1);\
|
||||
\
|
||||
new->key = key;\
|
||||
new->record = value;\
|
||||
new->next = table->bins[hash_val];\
|
||||
table->bins[hash_val] = new;\
|
||||
table->num_entries++;\
|
||||
}
|
||||
|
||||
int
|
||||
st_insert(table, key, value)
|
||||
register st_table *table;
|
||||
register char *key;
|
||||
char *value;
|
||||
{
|
||||
int hash_val;
|
||||
st_table_entry *new;
|
||||
register st_table_entry *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr, last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
if (table->num_entries/table->num_bins >= table->max_density) {
|
||||
if (rehash(table) == ST_OUT_OF_MEM) {
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
hash_val = do_hash(key, table);
|
||||
}
|
||||
new = ALLOC(st_table_entry, 1);
|
||||
if (new == NULL) {
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
new->key = key;
|
||||
new->record = value;
|
||||
new->next = table->bins[hash_val];
|
||||
table->bins[hash_val] = new;
|
||||
table->num_entries++;
|
||||
return 0;
|
||||
} else {
|
||||
ptr->record = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
st_add_direct(table, key, value)
|
||||
st_table *table;
|
||||
char *key;
|
||||
char *value;
|
||||
{
|
||||
int hash_val;
|
||||
st_table_entry *new;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
if (table->num_entries / table->num_bins >= table->max_density) {
|
||||
if (rehash(table) == ST_OUT_OF_MEM) {
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
hash_val = do_hash(key, table);
|
||||
new = ALLOC(st_table_entry, 1);
|
||||
if (new == NULL) {
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
new->key = key;
|
||||
new->record = value;
|
||||
new->next = table->bins[hash_val];
|
||||
table->bins[hash_val] = new;
|
||||
table->num_entries++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
st_find_or_add(table, key, slot)
|
||||
st_table *table;
|
||||
char *key;
|
||||
char ***slot;
|
||||
{
|
||||
int hash_val;
|
||||
st_table_entry *new, *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr, last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
if (table->num_entries / table->num_bins >= table->max_density) {
|
||||
if (rehash(table) == ST_OUT_OF_MEM) {
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
hash_val = do_hash(key, table);
|
||||
}
|
||||
new = ALLOC(st_table_entry, 1);
|
||||
if (new == NULL) {
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
new->key = key;
|
||||
new->record = (char *) 0;
|
||||
new->next = table->bins[hash_val];
|
||||
table->bins[hash_val] = new;
|
||||
table->num_entries++;
|
||||
if (slot != NULL) *slot = &new->record;
|
||||
return 0;
|
||||
} else {
|
||||
if (slot != NULL) *slot = &ptr->record;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
st_find(table, key, slot)
|
||||
st_table *table;
|
||||
char *key;
|
||||
char ***slot;
|
||||
{
|
||||
int hash_val;
|
||||
st_table_entry *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr, last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
if (slot != NULL) {
|
||||
*slot = &ptr->record;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
rehash(table)
|
||||
register st_table *table;
|
||||
{
|
||||
register st_table_entry *ptr, *next, **old_bins;
|
||||
int i, old_num_bins, hash_val, old_num_entries;
|
||||
|
||||
/* save old values */
|
||||
old_bins = table->bins;
|
||||
old_num_bins = table->num_bins;
|
||||
old_num_entries = table->num_entries;
|
||||
|
||||
/* rehash */
|
||||
table->num_bins = (int)(table->grow_factor * old_num_bins);
|
||||
if (table->num_bins % 2 == 0) {
|
||||
table->num_bins += 1;
|
||||
}
|
||||
table->num_entries = 0;
|
||||
table->bins = ALLOC(st_table_entry *, table->num_bins);
|
||||
if (table->bins == NULL) {
|
||||
table->bins = old_bins;
|
||||
table->num_bins = old_num_bins;
|
||||
table->num_entries = old_num_entries;
|
||||
return ST_OUT_OF_MEM;
|
||||
}
|
||||
/* initialize */
|
||||
for (i = 0; i < table->num_bins; i++) {
|
||||
table->bins[i] = 0;
|
||||
}
|
||||
|
||||
/* copy data over */
|
||||
for (i = 0; i < old_num_bins; i++) {
|
||||
ptr = old_bins[i];
|
||||
while (ptr != NULL) {
|
||||
next = ptr->next;
|
||||
hash_val = do_hash(ptr->key, table);
|
||||
ptr->next = table->bins[hash_val];
|
||||
table->bins[hash_val] = ptr;
|
||||
table->num_entries++;
|
||||
ptr = next;
|
||||
}
|
||||
}
|
||||
FREE(old_bins);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
st_table *
|
||||
st_copy(old_table)
|
||||
st_table *old_table;
|
||||
{
|
||||
st_table *new_table;
|
||||
st_table_entry *ptr, *newptr, *next, *new;
|
||||
int i, j, num_bins = old_table->num_bins;
|
||||
|
||||
new_table = ALLOC(st_table, 1);
|
||||
if (new_table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*new_table = *old_table;
|
||||
new_table->bins = ALLOC(st_table_entry *, num_bins);
|
||||
if (new_table->bins == NULL) {
|
||||
FREE(new_table);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < num_bins ; i++) {
|
||||
new_table->bins[i] = NULL;
|
||||
ptr = old_table->bins[i];
|
||||
while (ptr != NULL) {
|
||||
new = ALLOC(st_table_entry, 1);
|
||||
if (new == NULL) {
|
||||
for (j = 0; j <= i; j++) {
|
||||
newptr = new_table->bins[j];
|
||||
while (newptr != NULL) {
|
||||
next = newptr->next;
|
||||
FREE(newptr);
|
||||
newptr = next;
|
||||
}
|
||||
}
|
||||
FREE(new_table->bins);
|
||||
FREE(new_table);
|
||||
return NULL;
|
||||
}
|
||||
*new = *ptr;
|
||||
new->next = new_table->bins[i];
|
||||
new_table->bins[i] = new;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
return new_table;
|
||||
}
|
||||
|
||||
int
|
||||
st_delete(table, keyp, value)
|
||||
register st_table *table;
|
||||
register char **keyp;
|
||||
char **value;
|
||||
{
|
||||
int hash_val;
|
||||
char *key = *keyp;
|
||||
register st_table_entry *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr ,last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*last = ptr->next;
|
||||
if (value != NULL) *value = ptr->record;
|
||||
*keyp = ptr->key;
|
||||
FREE(ptr);
|
||||
table->num_entries--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
st_delete_int(table, keyp, value)
|
||||
register st_table *table;
|
||||
register long *keyp;
|
||||
char **value;
|
||||
{
|
||||
int hash_val;
|
||||
char *key = (char *) *keyp;
|
||||
register st_table_entry *ptr, **last;
|
||||
|
||||
hash_val = do_hash(key, table);
|
||||
|
||||
FIND_ENTRY(table, hash_val, key, ptr ,last);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*last = ptr->next;
|
||||
if (value != NULL) *value = ptr->record;
|
||||
*keyp = (long) ptr->key;
|
||||
FREE(ptr);
|
||||
table->num_entries--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
st_foreach(table, func, arg)
|
||||
st_table *table;
|
||||
enum st_retval (*func)();
|
||||
char *arg;
|
||||
{
|
||||
st_table_entry *ptr, **last;
|
||||
enum st_retval retval;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < table->num_bins; i++) {
|
||||
last = &table->bins[i]; ptr = *last;
|
||||
while (ptr != NULL) {
|
||||
retval = (*func)(ptr->key, ptr->record, arg);
|
||||
switch (retval) {
|
||||
case ST_CONTINUE:
|
||||
last = &ptr->next; ptr = *last;
|
||||
break;
|
||||
case ST_STOP:
|
||||
return 0;
|
||||
case ST_DELETE:
|
||||
*last = ptr->next;
|
||||
table->num_entries--; /* cstevens@ic */
|
||||
FREE(ptr);
|
||||
ptr = *last;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
st_strhash(string, modulus)
|
||||
register char *string;
|
||||
int modulus;
|
||||
{
|
||||
register int val = 0;
|
||||
register int c;
|
||||
|
||||
while ((c = *string++) != '\0') {
|
||||
val = val*997 + c;
|
||||
}
|
||||
|
||||
return ((val < 0) ? -val : val)%modulus;
|
||||
}
|
||||
|
||||
int
|
||||
st_numhash(x, size)
|
||||
char *x;
|
||||
int size;
|
||||
{
|
||||
return ST_NUMHASH(x, size);
|
||||
}
|
||||
|
||||
int
|
||||
st_ptrhash(x, size)
|
||||
char *x;
|
||||
int size;
|
||||
{
|
||||
return ST_PTRHASH(x, size);
|
||||
}
|
||||
|
||||
int
|
||||
st_numcmp(x, y)
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
return ST_NUMCMP(x, y);
|
||||
}
|
||||
|
||||
int
|
||||
st_ptrcmp(x, y)
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
return ST_NUMCMP(x, y);
|
||||
}
|
||||
|
||||
st_generator *
|
||||
st_init_gen(table)
|
||||
st_table *table;
|
||||
{
|
||||
st_generator *gen;
|
||||
|
||||
gen = ALLOC(st_generator, 1);
|
||||
if (gen == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
gen->table = table;
|
||||
gen->entry = NULL;
|
||||
gen->index = 0;
|
||||
return gen;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
st_gen(gen, key_p, value_p)
|
||||
st_generator *gen;
|
||||
char **key_p;
|
||||
char **value_p;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (gen->entry == NULL) {
|
||||
/* try to find next entry */
|
||||
for(i = gen->index; i < gen->table->num_bins; i++) {
|
||||
if (gen->table->bins[i] != NULL) {
|
||||
gen->index = i+1;
|
||||
gen->entry = gen->table->bins[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gen->entry == NULL) {
|
||||
return 0; /* that's all folks ! */
|
||||
}
|
||||
}
|
||||
*key_p = gen->entry->key;
|
||||
if (value_p != 0) {
|
||||
*value_p = gen->entry->record;
|
||||
}
|
||||
gen->entry = gen->entry->next;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
st_gen_int(gen, key_p, value_p)
|
||||
st_generator *gen;
|
||||
char **key_p;
|
||||
long *value_p;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (gen->entry == NULL) {
|
||||
/* try to find next entry */
|
||||
for(i = gen->index; i < gen->table->num_bins; i++) {
|
||||
if (gen->table->bins[i] != NULL) {
|
||||
gen->index = i+1;
|
||||
gen->entry = gen->table->bins[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gen->entry == NULL) {
|
||||
return 0; /* that's all folks ! */
|
||||
}
|
||||
}
|
||||
*key_p = gen->entry->key;
|
||||
if (value_p != 0) {
|
||||
*value_p = (long) gen->entry->record;
|
||||
}
|
||||
gen->entry = gen->entry->next;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
st_free_gen(gen)
|
||||
st_generator *gen;
|
||||
{
|
||||
FREE(gen);
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Revision Control Information
|
||||
*
|
||||
* /projects/hsis/CVS/utilities/st/st.h,v
|
||||
* serdar
|
||||
* 1.1
|
||||
* 1993/07/29 01:00:21
|
||||
*
|
||||
*/
|
||||
/* LINTLIBRARY */
|
||||
|
||||
/* /projects/hsis/CVS/utilities/st/st.h,v 1.1 1993/07/29 01:00:21 serdar Exp */
|
||||
|
||||
#ifndef ST_INCLUDED
|
||||
#define ST_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct st_table_entry st_table_entry;
|
||||
struct st_table_entry {
|
||||
char *key;
|
||||
char *record;
|
||||
st_table_entry *next;
|
||||
};
|
||||
|
||||
typedef struct st_table st_table;
|
||||
struct st_table {
|
||||
int (*compare)();
|
||||
int (*hash)();
|
||||
int num_bins;
|
||||
int num_entries;
|
||||
int max_density;
|
||||
int reorder_flag;
|
||||
double grow_factor;
|
||||
st_table_entry **bins;
|
||||
};
|
||||
|
||||
typedef struct st_generator st_generator;
|
||||
struct st_generator {
|
||||
st_table *table;
|
||||
st_table_entry *entry;
|
||||
int index;
|
||||
};
|
||||
|
||||
#define st_is_member(table,key) st_lookup(table,key,(char **) 0)
|
||||
#define st_count(table) ((table)->num_entries)
|
||||
|
||||
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
|
||||
|
||||
typedef enum st_retval (*ST_PFSR)();
|
||||
typedef int (*ST_PFI)();
|
||||
|
||||
extern st_table *st_init_table_with_params (ST_PFI, ST_PFI, int, int, double, int);
|
||||
extern st_table *st_init_table (ST_PFI, ST_PFI);
|
||||
extern void st_free_table (st_table *);
|
||||
extern int st_lookup (st_table *, char *, char **);
|
||||
extern int st_lookup_int (st_table *, char *, int *);
|
||||
extern int st_insert (st_table *, char *, char *);
|
||||
extern int st_add_direct (st_table *, char *, char *);
|
||||
extern int st_find_or_add (st_table *, char *, char ***);
|
||||
extern int st_find (st_table *, char *, char ***);
|
||||
extern st_table *st_copy (st_table *);
|
||||
extern int st_delete (st_table *, char **, char **);
|
||||
extern int st_delete_int (st_table *, long *, char **);
|
||||
extern int st_foreach (st_table *, ST_PFSR, char *);
|
||||
extern int st_strhash (char *, int);
|
||||
extern int st_numhash (char *, int);
|
||||
extern int st_ptrhash (char *, int);
|
||||
extern int st_numcmp (char *, char *);
|
||||
extern int st_ptrcmp (char *, char *);
|
||||
extern st_generator *st_init_gen (st_table *);
|
||||
extern int st_gen (st_generator *, char **, char **);
|
||||
extern int st_gen_int (st_generator *, char **, long *);
|
||||
extern void st_free_gen (st_generator *);
|
||||
|
||||
|
||||
#define ST_DEFAULT_MAX_DENSITY 5
|
||||
#define ST_DEFAULT_INIT_TABLE_SIZE 11
|
||||
#define ST_DEFAULT_GROW_FACTOR 2.0
|
||||
#define ST_DEFAULT_REORDER_FLAG 0
|
||||
|
||||
#define st_foreach_item(table, gen, key, value) \
|
||||
for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);)
|
||||
|
||||
#define st_foreach_item_int(table, gen, key, value) \
|
||||
for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);)
|
||||
|
||||
#define ST_OUT_OF_MEM -10000
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ST_INCLUDED */
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
INCPATHS = -I$(ROOT)/aig-alan
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
PURE_C_SRCS += \
|
||||
${addprefix $(ROOT)/aig-alan/, \
|
||||
aigBalance.c \
|
||||
aigCheck.c \
|
||||
aigDfs.c \
|
||||
aigMan.c \
|
||||
aigMem.c \
|
||||
aigObj.c \
|
||||
aigOper.c \
|
||||
aigTable.c \
|
||||
aigUtil.c \
|
||||
cudd2.c \
|
||||
st.c \
|
||||
}
|
||||
|
||||
C_SRCS += $(PURE_C_SRCS)
|
||||
|
||||
|
||||
PURE_C_OBJS += \
|
||||
${addprefix $(ROOT)/obj/aig-alan/, \
|
||||
aigBalance.o \
|
||||
aigCheck.o \
|
||||
aigDfs.o \
|
||||
aigMan.o \
|
||||
aigMem.o \
|
||||
aigObj.o \
|
||||
aigOper.o \
|
||||
aigTable.o \
|
||||
aigUtil.o \
|
||||
cudd2.o \
|
||||
st.o \
|
||||
}
|
||||
|
||||
OBJS += $(PURE_C_OBJS)
|
||||
|
||||
PURE_C_DEPS += \
|
||||
${addprefix $(ROOT)/obj/aig-alan, \
|
||||
aigBalance.d \
|
||||
aigCheck.d \
|
||||
aigDfs.d \
|
||||
aigMan.d \
|
||||
aigMem.d \
|
||||
aigObj.d \
|
||||
aigOper.d \
|
||||
aigTable.d \
|
||||
aigUtil.d \
|
||||
cudd2.d \
|
||||
st.d \
|
||||
}
|
||||
|
||||
DEPS += $(PURE_C_DEPS)
|
||||
|
||||
|
||||
OCAML_OBJS +=
|
||||
|
||||
|
||||
DEPEND_SRCS +=
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
$(ROOT)/obj/aig-alan/%.o: $(ROOT)/aig-alan/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: GCC C Compiler: $(CC)'
|
||||
@echo $(CC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $<
|
||||
@$(CC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $< && \
|
||||
echo -n $(@:%.o=%.d) $(dir $@) > $(@:%.o=%.d) && \
|
||||
$(CC) -MM -MG -P -w $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 $< >> $(@:%.o=%.d)
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
$(ROOT)/obj/aig-alan/%.o: $(ROOT)/aig-alan/%.cpp
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: G++ C Compiler: $(GPCC)'
|
||||
@echo $(GPPCC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $<
|
||||
@$(GPPCC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $< && \
|
||||
echo -n $(@:%.o=%.d) $(dir $@) > $(@:%.o=%.d) && \
|
||||
$(GPPCC) -MM -MG -P -w $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 $< >> $(@:%.o=%.d)
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_H__
|
||||
#define __VEC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#ifndef ALLOC
|
||||
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
|
||||
#endif
|
||||
|
||||
#ifndef FREE
|
||||
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
|
||||
#endif
|
||||
|
||||
#ifndef REALLOC
|
||||
#define REALLOC(type, obj, num) \
|
||||
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
|
||||
((type *) malloc(sizeof(type) * (num))))
|
||||
#endif
|
||||
|
||||
|
||||
#include "vecInt.h"
|
||||
#include "vecFlt.h"
|
||||
#include "vecStr.h"
|
||||
#include "vecPtr.h"
|
||||
#include "vecVec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,667 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecFlt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of floats.]
|
||||
|
||||
Author [Aaron P. Hurst]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_FLT_H__
|
||||
#define __VEC_FLT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Flt_t_ Vec_Flt_t;
|
||||
struct Vec_Flt_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
float * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_FltForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_FltForEachEntryStart( vVec, Entry, i, Start ) \
|
||||
for ( i = Start; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_FltForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_FltForEachEntryReverse( vVec, pEntry, i ) \
|
||||
for ( i = Vec_FltSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_FltEntry(vVec, i)), 1); i-- )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Flt_t * Vec_FltAlloc( int nCap )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = ALLOC( Vec_Flt_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Flt_t * Vec_FltStart( int nSize )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = Vec_FltAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(float) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from a float array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Flt_t * Vec_FltAllocArray( float * pArray, int nSize )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = ALLOC( Vec_Flt_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from a float array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Flt_t * Vec_FltAllocArrayCopy( float * pArray, int nSize )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = ALLOC( Vec_Flt_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( float, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(float) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the float array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Flt_t * Vec_FltDup( Vec_Flt_t * pVec )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = ALLOC( Vec_Flt_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(float) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Flt_t * Vec_FltDupArray( Vec_Flt_t * pVec )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = ALLOC( Vec_Flt_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltFree( Vec_Flt_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float * Vec_FltReleaseArray( Vec_Flt_t * p )
|
||||
{
|
||||
float * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float * Vec_FltArray( Vec_Flt_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_FltSize( Vec_Flt_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float Vec_FltEntry( Vec_Flt_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltWriteEntry( Vec_Flt_t * p, int i, float Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltAddToEntry( Vec_Flt_t * p, int i, float Addition )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] += Addition;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float Vec_FltEntryLast( Vec_Flt_t * p )
|
||||
{
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltGrow( Vec_Flt_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( float, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltFill( Vec_Flt_t * p, int nSize, float Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_FltGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_FltGrow( p, nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltShrink( Vec_Flt_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltClear( Vec_Flt_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltPush( Vec_Flt_t * p, float Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_FltGrow( p, 16 );
|
||||
else
|
||||
Vec_FltGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
// HA: Commented as proposed by Alan M.
|
||||
// static inline void Vec_FltPushMem( Extra_MmStep_t * pMemMan, Vec_Flt_t * p, float Entry )
|
||||
// {
|
||||
// if ( p->nSize == p->nCap )
|
||||
// {
|
||||
// float * pArray;
|
||||
// int i;
|
||||
|
||||
// if ( p->nSize == 0 )
|
||||
// p->nCap = 1;
|
||||
// pArray = (float *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
|
||||
// // pArray = ALLOC( float, p->nCap * 2 );
|
||||
// if ( p->pArray )
|
||||
// {
|
||||
// for ( i = 0; i < p->nSize; i++ )
|
||||
// pArray[i] = p->pArray[i];
|
||||
// Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
|
||||
// // free( p->pArray );
|
||||
// }
|
||||
// p->nCap *= 2;
|
||||
// p->pArray = pArray;
|
||||
// }
|
||||
// p->pArray[p->nSize++] = Entry;
|
||||
// }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltPushOrder( Vec_Flt_t * p, float Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_FltGrow( p, 16 );
|
||||
else
|
||||
Vec_FltGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
if ( p->pArray[i] > Entry )
|
||||
p->pArray[i+1] = p->pArray[i];
|
||||
else
|
||||
break;
|
||||
p->pArray[i+1] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_FltPushUnique( Vec_Flt_t * p, float Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_FltPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float Vec_FltPop( Vec_Flt_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_FltFind( Vec_Flt_t * p, float Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_FltRemove( Vec_Flt_t * p, float Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
if ( i == p->nSize )
|
||||
return 0;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two floats.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_FltSortCompare1( float * pp1, float * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two floats.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_FltSortCompare2( float * pp1, float * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_FltSort( Vec_Flt_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(float),
|
||||
(int (*)(const void *, const void *)) Vec_FltSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(float),
|
||||
(int (*)(const void *, const void *)) Vec_FltSortCompare1 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,781 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of integers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_INT_H__
|
||||
#define __VEC_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//HA: Commented as advised by Alan
|
||||
//#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Int_t_ Vec_Int_t;
|
||||
struct Vec_Int_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
int * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_IntForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryStart( vVec, Entry, i, Start ) \
|
||||
for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \
|
||||
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAlloc( int nCap )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntStart( int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = Vec_IntAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(int) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( int, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(int) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFree( Vec_Int_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntReleaseArray( Vec_Int_t * p )
|
||||
{
|
||||
int * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntArray( Vec_Int_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSize( Vec_Int_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntEntry( Vec_Int_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] += Addition;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntEntryLast( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( int, p->pArray, nCapMin );
|
||||
assert( p->pArray );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntClear( Vec_Int_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize - 1; i >= 1; i-- )
|
||||
p->pArray[i] = p->pArray[i-1];
|
||||
p->pArray[0] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
// HA: Commented as advised by Alan M.
|
||||
// static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry )
|
||||
// {
|
||||
// if ( p->nSize == p->nCap )
|
||||
// {
|
||||
// int * pArray;
|
||||
// int i;
|
||||
|
||||
// if ( p->nSize == 0 )
|
||||
// p->nCap = 1;
|
||||
// if ( pMemMan )
|
||||
// pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
|
||||
// else
|
||||
// pArray = ALLOC( int, p->nCap * 2 );
|
||||
// if ( p->pArray )
|
||||
// {
|
||||
// for ( i = 0; i < p->nSize; i++ )
|
||||
// pArray[i] = p->pArray[i];
|
||||
// if ( pMemMan )
|
||||
// Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
|
||||
// else
|
||||
// free( p->pArray );
|
||||
// }
|
||||
// p->nCap *= 2;
|
||||
// p->pArray = pArray;
|
||||
// }
|
||||
// p->pArray[p->nSize++] = Entry;
|
||||
//}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry while preserving the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
if ( p->pArray[i] > Entry )
|
||||
p->pArray[i+1] = p->pArray[i];
|
||||
else
|
||||
break;
|
||||
p->pArray[i+1] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry while preserving the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_IntPushOrder( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_IntPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the pointer to the next nWords entries in the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned * Vec_IntFetch( Vec_Int_t * p, int nWords )
|
||||
{
|
||||
p->nSize += nWords;
|
||||
if ( p->nSize > p->nCap )
|
||||
{
|
||||
// Vec_IntGrow( p, 2 * p->nSize );
|
||||
return NULL;
|
||||
}
|
||||
return ((unsigned *)p->pArray) + p->nSize - nWords;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPop( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
if ( i == p->nSize )
|
||||
return 0;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare1( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare2( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSort( Vec_Int_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare1 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSortUnsigned( Vec_Int_t * p )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,587 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecPtr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of generic pointers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_PTR_H__
|
||||
#define __VEC_PTR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Ptr_t_ Vec_Ptr_t;
|
||||
struct Vec_Ptr_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through entries
|
||||
#define Vec_PtrForEachEntry( vVec, pEntry, i ) \
|
||||
for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
|
||||
for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
|
||||
for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
|
||||
for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrStart( int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = Vec_PtrAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(void *) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( void *, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(void *) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFree( Vec_Ptr_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p )
|
||||
{
|
||||
void ** pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrArray( Vec_Ptr_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrSize( Vec_Ptr_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray + i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( void *, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
if ( p->nSize < 2 * nSize )
|
||||
Vec_PtrGrow( p, 2 * nSize );
|
||||
else
|
||||
Vec_PtrGrow( p, p->nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrClear( Vec_Ptr_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_PtrGrow( p, 16 );
|
||||
else
|
||||
Vec_PtrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_PtrPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrPop( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
// delete assuming that it is closer to the end
|
||||
for ( i = p->nSize - 1; i >= 0; i-- )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i >= 0 );
|
||||
/*
|
||||
// delete assuming that it is closer to the beginning
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i < p->nSize );
|
||||
*/
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Moves the first nItems to the end.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
|
||||
{
|
||||
assert( nItems < p->nSize );
|
||||
Vec_PtrGrow( p, nItems + p->nSize );
|
||||
memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
|
||||
memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
|
||||
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecStr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of characters.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_STR_H__
|
||||
#define __VEC_STR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Str_t_ Vec_Str_t;
|
||||
struct Vec_Str_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
char * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_StrForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAlloc( int nCap )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrStart( int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = Vec_StrAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( char, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFree( Vec_Str_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrReleaseArray( Vec_Str_t * p )
|
||||
{
|
||||
char * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrArray( Vec_Str_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSize( Vec_Str_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntry( Vec_Str_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntryLast( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );
|
||||
p->nCap = 2 * nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_StrGrow( p, nSize );
|
||||
p->nSize = nSize;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrClear( Vec_Str_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_StrGrow( p, 16 );
|
||||
else
|
||||
Vec_StrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Appends the string to the char vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrAppend( Vec_Str_t * p, char * pString )
|
||||
{
|
||||
int i, nLength = strlen(pString);
|
||||
Vec_StrGrow( p, p->nSize + nLength );
|
||||
for ( i = 0; i < nLength; i++ )
|
||||
p->pArray[p->nSize + i] = pString[i];
|
||||
p->nSize += nLength;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrPop( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare1( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecVec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable vector of resizable vectors.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_VEC_H__
|
||||
#define __VEC_VEC_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Vec_t_ Vec_Vec_t;
|
||||
struct Vec_Vec_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through levels
|
||||
#define Vec_VecForEachLevel( vGlob, vVec, i ) \
|
||||
for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
|
||||
for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
|
||||
// iteratores through entries
|
||||
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
|
||||
for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; i <= LevelStop; i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
p = ALLOC( Vec_Vec_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecStart( int nSize )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
int i;
|
||||
p = Vec_VecAlloc( nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = nSize;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= Level + 1 )
|
||||
return;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i <= Level; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSize( Vec_Vec_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecFree( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrFree( vVec );
|
||||
Vec_PtrFree( (Vec_Ptr_t *)p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector of vectors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSizeSize( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i, Counter = 0;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Counter += vVec->nSize;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecClear( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrClear( vVec );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i < Level + 1; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
Vec_VecPush( p, Level, Entry );
|
||||
else
|
||||
Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,723 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [esop.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Internal declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: esop.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __ESOP_H__
|
||||
#define __ESOP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "vec.h"
|
||||
#include "mem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Esop_Man_t_ Esop_Man_t;
|
||||
typedef struct Esop_Cube_t_ Esop_Cube_t;
|
||||
typedef struct Mem_Fixed_t_ Mem_Fixed_t;
|
||||
|
||||
struct Esop_Man_t_
|
||||
{
|
||||
int nVars; // the number of vars
|
||||
int nWords; // the number of words
|
||||
Mem_Fixed_t * pMemMan1; // memory manager for cubes
|
||||
Mem_Fixed_t * pMemMan2; // memory manager for cubes
|
||||
Mem_Fixed_t * pMemMan4; // memory manager for cubes
|
||||
Mem_Fixed_t * pMemMan8; // memory manager for cubes
|
||||
// temporary cubes
|
||||
Esop_Cube_t * pOne0; // tautology cube
|
||||
Esop_Cube_t * pOne1; // tautology cube
|
||||
Esop_Cube_t * pTriv0; // trivial cube
|
||||
Esop_Cube_t * pTriv1; // trivial cube
|
||||
Esop_Cube_t * pTemp; // cube for computing the distance
|
||||
Esop_Cube_t * pBubble; // cube used as a separator
|
||||
// temporary storage for the new cover
|
||||
int nCubes; // the number of cubes
|
||||
Esop_Cube_t ** ppStore; // storage for cubes by number of literals
|
||||
};
|
||||
|
||||
struct Esop_Cube_t_
|
||||
{
|
||||
Esop_Cube_t * pNext; // the pointer to the next cube in the cover
|
||||
unsigned nVars : 10; // the number of variables
|
||||
unsigned nWords : 12; // the number of machine words
|
||||
unsigned nLits : 10; // the number of literals in the cube
|
||||
unsigned uData[1]; // the bit-data for the cube
|
||||
};
|
||||
|
||||
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
|
||||
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
|
||||
#define REALLOC(type, obj, num) \
|
||||
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
|
||||
((type *) malloc(sizeof(type) * (num))))
|
||||
|
||||
// iterators through the entries in the linked lists of cubes
|
||||
#define Esop_CoverForEachCube( pCover, pCube ) \
|
||||
for ( pCube = pCover; \
|
||||
pCube; \
|
||||
pCube = pCube->pNext )
|
||||
#define Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \
|
||||
for ( pCube = pCover, \
|
||||
pCube2 = pCube? pCube->pNext: NULL; \
|
||||
pCube; \
|
||||
pCube = pCube2, \
|
||||
pCube2 = pCube? pCube->pNext: NULL )
|
||||
#define Esop_CoverForEachCubePrev( pCover, pCube, ppPrev ) \
|
||||
for ( pCube = pCover, \
|
||||
ppPrev = &(pCover); \
|
||||
pCube; \
|
||||
ppPrev = &pCube->pNext, \
|
||||
pCube = pCube->pNext )
|
||||
|
||||
|
||||
// macros to get hold of bits and values in the cubes
|
||||
static inline int Esop_CubeHasBit( Esop_Cube_t * p, int i ) { return (p->uData[i >> 5] & (1<<(i & 31))) > 0; }
|
||||
static inline void Esop_CubeSetBit( Esop_Cube_t * p, int i ) { p->uData[i >> 5] |= (1<<(i & 31)); }
|
||||
static inline void Esop_CubeXorBit( Esop_Cube_t * p, int i ) { p->uData[i >> 5] ^= (1<<(i & 31)); }
|
||||
static inline int Esop_CubeGetVar( Esop_Cube_t * p, int Var ) { return 3 & (p->uData[(Var<<1)>>5] >> ((Var<<1) & 31)); }
|
||||
static inline void Esop_CubeXorVar( Esop_Cube_t * p, int Var, int Value ) { p->uData[(Var<<1)>>5] ^= (Value<<((Var<<1) & 31)); }
|
||||
static inline int Esop_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
|
||||
|
||||
/*=== esopMem.c ===========================================================*/
|
||||
extern Mem_Fixed_t * Mem_FixedStart( int nEntrySize );
|
||||
extern void Mem_FixedStop( Mem_Fixed_t * p, int fVerbose );
|
||||
extern char * Mem_FixedEntryFetch( Mem_Fixed_t * p );
|
||||
extern void Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry );
|
||||
extern void Mem_FixedRestart( Mem_Fixed_t * p );
|
||||
extern int Mem_FixedReadMemUsage( Mem_Fixed_t * p );
|
||||
/*=== esopMin.c ===========================================================*/
|
||||
extern void Esop_EsopMinimize( Esop_Man_t * p );
|
||||
extern void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube );
|
||||
/*=== esopMan.c ===========================================================*/
|
||||
extern Esop_Man_t * Esop_ManAlloc( int nVars );
|
||||
extern void Esop_ManClean( Esop_Man_t * p, int nSupp );
|
||||
extern void Esop_ManFree( Esop_Man_t * p );
|
||||
/*=== esopUtil.c ===========================================================*/
|
||||
extern void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube );
|
||||
extern void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover );
|
||||
extern void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p );
|
||||
extern void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop );
|
||||
extern void Esop_CoverCheck( Esop_Man_t * p );
|
||||
extern int Esop_CubeCheck( Esop_Cube_t * pCube );
|
||||
extern Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize );
|
||||
extern void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover );
|
||||
extern int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Esop_Cube_t * Esop_CubeAlloc( Esop_Man_t * p )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
if ( p->nWords <= 1 )
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan1 );
|
||||
else if ( p->nWords <= 2 )
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan2 );
|
||||
else if ( p->nWords <= 4 )
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan4 );
|
||||
else if ( p->nWords <= 8 )
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan8 );
|
||||
pCube->pNext = NULL;
|
||||
pCube->nVars = p->nVars;
|
||||
pCube->nWords = p->nWords;
|
||||
pCube->nLits = 0;
|
||||
memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cube representing elementary var.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Esop_Cube_t * Esop_CubeAllocVar( Esop_Man_t * p, int iVar, int fCompl )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
pCube = Esop_CubeAlloc( p );
|
||||
Esop_CubeXorBit( pCube, iVar*2+fCompl );
|
||||
pCube->nLits = 1;
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Esop_Cube_t * Esop_CubeDup( Esop_Man_t * p, Esop_Cube_t * pCopy )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
pCube = Esop_CubeAlloc( p );
|
||||
memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords );
|
||||
pCube->nLits = pCopy->nLits;
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CubeRecycle( Esop_Man_t * p, Esop_Cube_t * pCube )
|
||||
{
|
||||
if ( pCube->nWords <= 1 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );
|
||||
else if ( pCube->nWords <= 2 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );
|
||||
else if ( pCube->nWords <= 4 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );
|
||||
else if ( pCube->nWords <= 8 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the cube cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CoverRecycle( Esop_Man_t * p, Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube, * pCube2;
|
||||
if ( pCover == NULL )
|
||||
return;
|
||||
if ( pCover->nWords <= 1 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );
|
||||
else if ( pCover->nWords <= 2 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );
|
||||
else if ( pCover->nWords <= 4 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );
|
||||
else if ( pCover->nWords <= 8 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the cube cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Esop_Cube_t * Esop_CoverDup( Esop_Man_t * p, Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube, * pCubeNew;
|
||||
Esop_Cube_t * pCoverNew = NULL, ** ppTail = &pCoverNew;
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pCubeNew = Esop_CubeDup( p, pCube );
|
||||
*ppTail = pCubeNew;
|
||||
ppTail = &pCubeNew->pNext;
|
||||
}
|
||||
*ppTail = NULL;
|
||||
return pCoverNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of cubes in the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CubeCountLits( Esop_Cube_t * pCube )
|
||||
{
|
||||
unsigned uData;
|
||||
int Count = 0, i, w;
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
uData = pCube->uData[w] ^ (pCube->uData[w] >> 1);
|
||||
for ( i = 0; i < 32; i += 2 )
|
||||
if ( uData & (1 << i) )
|
||||
Count++;
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of cubes in the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CubeGetLits( Esop_Cube_t * pCube, Vec_Int_t * vLits )
|
||||
{
|
||||
unsigned uData;
|
||||
int i, w;
|
||||
Vec_IntClear( vLits );
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
uData = pCube->uData[w] ^ (pCube->uData[w] >> 1);
|
||||
for ( i = 0; i < 32; i += 2 )
|
||||
if ( uData & (1 << i) )
|
||||
Vec_IntPush( vLits, w*16 + i/2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of cubes in the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CoverCountCubes( Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
int Count = 0;
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
Count++;
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are disjoint.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CubesDisjoint( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
|
||||
{
|
||||
unsigned uData;
|
||||
int i;
|
||||
assert( pCube0->nVars == pCube1->nVars );
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
{
|
||||
uData = pCube0->uData[i] & pCube1->uData[i];
|
||||
uData = (uData | (uData >> 1)) & 0x55555555;
|
||||
if ( uData != 0x55555555 )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the disjoint variables of the two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CoverGetDisjVars( Esop_Cube_t * pThis, Esop_Cube_t * pCube, Vec_Int_t * vVars )
|
||||
{
|
||||
unsigned uData;
|
||||
int i, w;
|
||||
Vec_IntClear( vVars );
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
uData = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555;
|
||||
uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1));
|
||||
if ( uData == 0 )
|
||||
continue;
|
||||
for ( i = 0; i < 32; i += 2 )
|
||||
if ( uData & (1 << i) )
|
||||
Vec_IntPush( vVars, w*16 + i/2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are disjoint.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CubesDistOne( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, Esop_Cube_t * pTemp )
|
||||
{
|
||||
unsigned uData;
|
||||
int i, fFound = 0;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
{
|
||||
uData = pCube0->uData[i] ^ pCube1->uData[i];
|
||||
if ( uData == 0 )
|
||||
{
|
||||
if ( pTemp ) pTemp->uData[i] = 0;
|
||||
continue;
|
||||
}
|
||||
if ( fFound )
|
||||
return 0;
|
||||
uData = (uData | (uData >> 1)) & 0x55555555;
|
||||
if ( (uData & (uData-1)) > 0 ) // more than one 1
|
||||
return 0;
|
||||
if ( pTemp ) pTemp->uData[i] = uData | (uData << 1);
|
||||
fFound = 1;
|
||||
}
|
||||
if ( fFound == 0 )
|
||||
{
|
||||
printf( "\n" );
|
||||
Esop_CubeWrite( stdout, pCube0 );
|
||||
Esop_CubeWrite( stdout, pCube1 );
|
||||
printf( "Error: Esop_CubesDistOne() looks at two equal cubes!\n" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are disjoint.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CubesDistTwo( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, int * pVar0, int * pVar1 )
|
||||
{
|
||||
unsigned uData;//, uData2;
|
||||
int i, k, Var0 = -1, Var1 = -1;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
{
|
||||
uData = pCube0->uData[i] ^ pCube1->uData[i];
|
||||
if ( uData == 0 )
|
||||
continue;
|
||||
if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s
|
||||
return 0;
|
||||
uData = (uData | (uData >> 1)) & 0x55555555;
|
||||
if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 )
|
||||
return 0;
|
||||
for ( k = 0; k < 32; k += 2 )
|
||||
if ( uData & (1 << k) )
|
||||
{
|
||||
if ( Var0 == -1 )
|
||||
Var0 = 16 * i + k/2;
|
||||
else if ( Var1 == -1 )
|
||||
Var1 = 16 * i + k/2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
if ( Var0 >= 0 )
|
||||
{
|
||||
uData &= 0xFFFF;
|
||||
uData2 = (uData >> 16);
|
||||
if ( uData && uData2 )
|
||||
return 0;
|
||||
if ( uData )
|
||||
{
|
||||
}
|
||||
uData }= uData2;
|
||||
uData &= 0x
|
||||
}
|
||||
*/
|
||||
}
|
||||
if ( Var0 >= 0 && Var1 >= 0 )
|
||||
{
|
||||
*pVar0 = Var0;
|
||||
*pVar1 = Var1;
|
||||
return 1;
|
||||
}
|
||||
if ( Var0 == -1 || Var1 == -1 )
|
||||
{
|
||||
printf( "\n" );
|
||||
Esop_CubeWrite( stdout, pCube0 );
|
||||
Esop_CubeWrite( stdout, pCube1 );
|
||||
printf( "Error: Esop_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the produce of two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Esop_Cube_t * Esop_CubesProduct( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
int i;
|
||||
assert( pCube0->nVars == pCube1->nVars );
|
||||
pCube = Esop_CubeAlloc( p );
|
||||
for ( i = 0; i < p->nWords; i++ )
|
||||
pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i];
|
||||
pCube->nLits = Esop_CubeCountLits( pCube );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the produce of two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Esop_Cube_t * Esop_CubesXor( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
int i;
|
||||
assert( pCube0->nVars == pCube1->nVars );
|
||||
pCube = Esop_CubeAlloc( p );
|
||||
for ( i = 0; i < p->nWords; i++ )
|
||||
pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i];
|
||||
pCube->nLits = Esop_CubeCountLits( pCube );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the produce of two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CubesAreEqual( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
if ( pCube0->uData[i] != pCube1->uData[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if pCube1 is contained in pCube0, bitwise.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CubeIsContained( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the cube into the result of merging.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CubesTransform( Esop_Cube_t * pCube, Esop_Cube_t * pDist, Esop_Cube_t * pMask )
|
||||
{
|
||||
int w;
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
pCube->uData[w] = pCube->uData[w] ^ pDist->uData[w];
|
||||
pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the cube into the result of distance-1 merging.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CubesTransformOr( Esop_Cube_t * pCube, Esop_Cube_t * pDist )
|
||||
{
|
||||
int w;
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
pCube->uData[w] |= pDist->uData[w];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the cover in the increasing number of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Esop_CoverExpandRemoveEqual( Esop_Man_t * p, Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube, * pCube2, * pThis;
|
||||
if ( pCover == NULL )
|
||||
{
|
||||
Esop_ManClean( p, p->nVars );
|
||||
return;
|
||||
}
|
||||
Esop_ManClean( p, pCover->nVars );
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
{
|
||||
// go through the linked list
|
||||
Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
|
||||
if ( Esop_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
Esop_CubeRecycle( p, pCube );
|
||||
break;
|
||||
}
|
||||
if ( pThis != NULL )
|
||||
continue;
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the given cube is contained in one of the cubes of the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Esop_CoverContainsCube( Esop_Man_t * p, Esop_Cube_t * pCube )
|
||||
{
|
||||
Esop_Cube_t * pThis;
|
||||
int i;
|
||||
/*
|
||||
// this cube cannot be equal to any cube
|
||||
Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
|
||||
{
|
||||
if ( Esop_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
Esop_CubeWrite( stdout, pCube );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
*/
|
||||
// try to find a containing cube
|
||||
for ( i = 0; i <= (int)pCube->nLits; i++ )
|
||||
Esop_CoverForEachCube( p->ppStore[i], pThis )
|
||||
{
|
||||
// skip the bubble
|
||||
if ( pThis != p->pBubble && Esop_CubeIsContained( pThis, pCube ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [esopMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [SOP manipulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: esopMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "esop.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the minimization manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Esop_Man_t * Esop_ManAlloc( int nVars )
|
||||
{
|
||||
Esop_Man_t * pMan;
|
||||
// start the manager
|
||||
pMan = ALLOC( Esop_Man_t, 1 );
|
||||
memset( pMan, 0, sizeof(Esop_Man_t) );
|
||||
pMan->nVars = nVars;
|
||||
pMan->nWords = Esop_BitWordNum( nVars * 2 );
|
||||
pMan->pMemMan1 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) );
|
||||
pMan->pMemMan2 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) );
|
||||
pMan->pMemMan4 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) );
|
||||
pMan->pMemMan8 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) );
|
||||
// allocate storage for the temporary cover
|
||||
pMan->ppStore = ALLOC( Esop_Cube_t *, pMan->nVars + 1 );
|
||||
// create tautology cubes
|
||||
Esop_ManClean( pMan, nVars );
|
||||
pMan->pOne0 = Esop_CubeAlloc( pMan );
|
||||
pMan->pOne1 = Esop_CubeAlloc( pMan );
|
||||
pMan->pTemp = Esop_CubeAlloc( pMan );
|
||||
pMan->pBubble = Esop_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0;
|
||||
// create trivial cubes
|
||||
Esop_ManClean( pMan, 1 );
|
||||
pMan->pTriv0 = Esop_CubeAllocVar( pMan, 0, 0 );
|
||||
pMan->pTriv1 = Esop_CubeAllocVar( pMan, 0, 0 );
|
||||
Esop_ManClean( pMan, nVars );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans the minimization manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_ManClean( Esop_Man_t * p, int nSupp )
|
||||
{
|
||||
// set the size of the cube manager
|
||||
p->nVars = nSupp;
|
||||
p->nWords = Esop_BitWordNum(2*nSupp);
|
||||
// clean the storage
|
||||
memset( p->ppStore, 0, sizeof(Esop_Cube_t *) * (nSupp + 1) );
|
||||
p->nCubes = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the minimization manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_ManFree( Esop_Man_t * p )
|
||||
{
|
||||
Mem_FixedStop ( p->pMemMan1, 0 );
|
||||
Mem_FixedStop ( p->pMemMan2, 0 );
|
||||
Mem_FixedStop ( p->pMemMan4, 0 );
|
||||
Mem_FixedStop ( p->pMemMan8, 0 );
|
||||
free( p->ppStore );
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [esopMin.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [ESOP manipulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: esopMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "esop.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Esop_EsopRewrite( Esop_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [ESOP minimization procedure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_EsopMinimize( Esop_Man_t * p )
|
||||
{
|
||||
int nCubesInit, nCubesOld, nIter;
|
||||
if ( p->nCubes < 3 )
|
||||
return;
|
||||
nIter = 0;
|
||||
nCubesInit = p->nCubes;
|
||||
do {
|
||||
nCubesOld = p->nCubes;
|
||||
Esop_EsopRewrite( p );
|
||||
nIter++;
|
||||
}
|
||||
while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
|
||||
|
||||
// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs one round of rewriting using distance 2 cubes.]
|
||||
|
||||
Description [The weakness of this procedure is that it tries each cube
|
||||
with only one distance-2 cube. If this pair does not lead to improvement
|
||||
the cube is inserted into the cover anyhow, and we try another pair.
|
||||
A possible improvement would be to try this cube with all distance-2
|
||||
cubes, until an improvement is found, or until all such cubes are tried.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_EsopRewrite( Esop_Man_t * p )
|
||||
{
|
||||
Esop_Cube_t * pCube, ** ppPrev;
|
||||
Esop_Cube_t * pThis, ** ppPrevT;
|
||||
int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld;
|
||||
int nPairs = 0;
|
||||
|
||||
// insert the bubble before the first cube
|
||||
p->pBubble->pNext = p->ppStore[0];
|
||||
p->ppStore[0] = p->pBubble;
|
||||
p->pBubble->nLits = 0;
|
||||
|
||||
// go through the cubes
|
||||
while ( 1 )
|
||||
{
|
||||
// get the index of the bubble
|
||||
Index = p->pBubble->nLits;
|
||||
|
||||
// find the bubble
|
||||
Esop_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
|
||||
if ( pCube == p->pBubble )
|
||||
break;
|
||||
assert( pCube == p->pBubble );
|
||||
|
||||
// remove the bubble, get the next cube after the bubble
|
||||
*ppPrev = p->pBubble->pNext;
|
||||
pCube = p->pBubble->pNext;
|
||||
if ( pCube == NULL )
|
||||
for ( Index++; Index <= p->nVars; Index++ )
|
||||
if ( p->ppStore[Index] )
|
||||
{
|
||||
ppPrev = &(p->ppStore[Index]);
|
||||
pCube = p->ppStore[Index];
|
||||
break;
|
||||
}
|
||||
// stop if there is no more cubes
|
||||
if ( pCube == NULL )
|
||||
break;
|
||||
|
||||
// find the first dist2 cube
|
||||
Esop_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
|
||||
if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
if ( pThis == NULL && Index < p->nVars )
|
||||
Esop_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
|
||||
if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
if ( pThis == NULL && Index < p->nVars - 1 )
|
||||
Esop_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT )
|
||||
if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
// continue if there is no dist2 cube
|
||||
if ( pThis == NULL )
|
||||
{
|
||||
// insert the bubble after the cube
|
||||
p->pBubble->pNext = pCube->pNext;
|
||||
pCube->pNext = p->pBubble;
|
||||
p->pBubble->nLits = pCube->nLits;
|
||||
continue;
|
||||
}
|
||||
nPairs++;
|
||||
|
||||
// remove the cubes, insert the bubble instead of pCube
|
||||
*ppPrevT = pThis->pNext;
|
||||
*ppPrev = p->pBubble;
|
||||
p->pBubble->pNext = pCube->pNext;
|
||||
p->pBubble->nLits = pCube->nLits;
|
||||
p->nCubes -= 2;
|
||||
|
||||
// Exorlink-2:
|
||||
// A{v00} B{v01} + A{v10} B{v11} =
|
||||
// A{v00+v10} B{v01} + A{v10} B{v01+v11} =
|
||||
// A{v00} B{v01+v11} + A{v00+v10} B{v11}
|
||||
|
||||
// save the dist2 parameters
|
||||
v00 = Esop_CubeGetVar( pCube, Var0 );
|
||||
v01 = Esop_CubeGetVar( pCube, Var1 );
|
||||
v10 = Esop_CubeGetVar( pThis, Var0 );
|
||||
v11 = Esop_CubeGetVar( pThis, Var1 );
|
||||
//printf( "\n" );
|
||||
//Esop_CubeWrite( stdout, pCube );
|
||||
//Esop_CubeWrite( stdout, pThis );
|
||||
|
||||
// derive the first pair of resulting cubes
|
||||
Esop_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits -= (v00 != 3);
|
||||
pCube->nLits += ((v00 ^ v10) != 3);
|
||||
Esop_CubeXorVar( pThis, Var1, v01 );
|
||||
pThis->nLits -= (v11 != 3);
|
||||
pThis->nLits += ((v01 ^ v11) != 3);
|
||||
|
||||
// add the cubes
|
||||
nCubesOld = p->nCubes;
|
||||
Esop_EsopAddCube( p, pCube );
|
||||
Esop_EsopAddCube( p, pThis );
|
||||
// check if the cubes were absorbed
|
||||
if ( p->nCubes < nCubesOld + 2 )
|
||||
continue;
|
||||
|
||||
// pull out both cubes
|
||||
assert( pThis == p->ppStore[pThis->nLits] );
|
||||
p->ppStore[pThis->nLits] = pThis->pNext;
|
||||
assert( pCube == p->ppStore[pCube->nLits] );
|
||||
p->ppStore[pCube->nLits] = pCube->pNext;
|
||||
p->nCubes -= 2;
|
||||
|
||||
// derive the second pair of resulting cubes
|
||||
Esop_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits -= ((v00 ^ v10) != 3);
|
||||
pCube->nLits += (v00 != 3);
|
||||
Esop_CubeXorVar( pCube, Var1, v11 );
|
||||
pCube->nLits -= (v01 != 3);
|
||||
pCube->nLits += ((v01 ^ v11) != 3);
|
||||
|
||||
Esop_CubeXorVar( pThis, Var0, v00 );
|
||||
pThis->nLits -= (v10 != 3);
|
||||
pThis->nLits += ((v00 ^ v10) != 3);
|
||||
Esop_CubeXorVar( pThis, Var1, v01 );
|
||||
pThis->nLits -= ((v01 ^ v11) != 3);
|
||||
pThis->nLits += (v11 != 3);
|
||||
|
||||
// add them anyhow
|
||||
Esop_EsopAddCube( p, pCube );
|
||||
Esop_EsopAddCube( p, pThis );
|
||||
}
|
||||
// printf( "Pairs = %d ", nPairs );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the cube to storage.]
|
||||
|
||||
Description [Returns 0 if the cube is added or removed. Returns 1
|
||||
if the cube is glued with some other cube and has to be added again.
|
||||
Do not forget to clean the storage!]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Esop_EsopAddCubeInt( Esop_Man_t * p, Esop_Cube_t * pCube )
|
||||
{
|
||||
Esop_Cube_t * pThis, ** ppPrev;
|
||||
// try to find the identical cube
|
||||
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
|
||||
{
|
||||
if ( Esop_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Esop_CubeRecycle( p, pCube );
|
||||
Esop_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// find a distance-1 cube if it exists
|
||||
if ( pCube->nLits < pCube->nVars )
|
||||
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
|
||||
{
|
||||
if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Esop_CubesTransform( pCube, pThis, p->pTemp );
|
||||
pCube->nLits++;
|
||||
Esop_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
|
||||
{
|
||||
if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Esop_CubesTransform( pCube, pThis, p->pTemp );
|
||||
pCube->nLits--;
|
||||
Esop_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ( pCube->nLits > 0 )
|
||||
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
|
||||
{
|
||||
if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Esop_CubesTransform( pCube, pThis, p->pTemp );
|
||||
Esop_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// add the cube
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the cube to storage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube )
|
||||
{
|
||||
assert( pCube != p->pBubble );
|
||||
assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
|
||||
while ( Esop_EsopAddCubeInt( p, pCube ) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [esopUtil.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Utilities.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: esopUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "esop.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube )
|
||||
{
|
||||
int i;
|
||||
assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
|
||||
for ( i = 0; i < (int)pCube->nVars; i++ )
|
||||
if ( Esop_CubeHasBit(pCube, i*2) )
|
||||
{
|
||||
if ( Esop_CubeHasBit(pCube, i*2+1) )
|
||||
fprintf( pFile, "-" );
|
||||
else
|
||||
fprintf( pFile, "0" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Esop_CubeHasBit(pCube, i*2+1) )
|
||||
fprintf( pFile, "1" );
|
||||
else
|
||||
fprintf( pFile, "?" );
|
||||
}
|
||||
fprintf( pFile, " 1\n" );
|
||||
// fprintf( pFile, " %d\n", pCube->nLits );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
Esop_CubeWrite( pFile, pCube );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
int i;
|
||||
for ( i = 0; i <= p->nVars; i++ )
|
||||
{
|
||||
Esop_CoverForEachCube( p->ppStore[i], pCube )
|
||||
{
|
||||
printf( "%2d : ", i );
|
||||
if ( pCube == p->pBubble )
|
||||
{
|
||||
printf( "Bubble\n" );
|
||||
continue;
|
||||
}
|
||||
Esop_CubeWrite( pFile, pCube );
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop )
|
||||
{
|
||||
char Buffer[1000];
|
||||
Esop_Cube_t * pCube;
|
||||
FILE * pFile;
|
||||
int i;
|
||||
sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" );
|
||||
for ( i = strlen(Buffer) - 1; i >= 0; i-- )
|
||||
if ( Buffer[i] == '<' || Buffer[i] == '>' )
|
||||
Buffer[i] = '_';
|
||||
pFile = fopen( Buffer, "w" );
|
||||
fprintf( pFile, "# %s cover for output %s generated by ABC\n", fEsop? "ESOP":"SOP", pName );
|
||||
fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
|
||||
fprintf( pFile, ".o %d\n", 1 );
|
||||
fprintf( pFile, ".p %d\n", Esop_CoverCountCubes(pCover) );
|
||||
if ( fEsop ) fprintf( pFile, ".type esop\n" );
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
Esop_CubeWrite( pFile, pCube );
|
||||
fprintf( pFile, ".e\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_CoverCheck( Esop_Man_t * p )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
int i;
|
||||
for ( i = 0; i <= p->nVars; i++ )
|
||||
Esop_CoverForEachCube( p->ppStore[i], pCube )
|
||||
assert( i == (int)pCube->nLits );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Esop_CubeCheck( Esop_Cube_t * pCube )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCube->nVars; i++ )
|
||||
if ( Esop_CubeGetVar( pCube, i ) == 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the cover from the sorted structure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize )
|
||||
{
|
||||
Esop_Cube_t * pCov = NULL, ** ppTail = &pCov;
|
||||
Esop_Cube_t * pCube, * pCube2;
|
||||
int i;
|
||||
for ( i = 0; i <= nSuppSize; i++ )
|
||||
{
|
||||
Esop_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
|
||||
{
|
||||
assert( i == (int)pCube->nLits );
|
||||
*ppTail = pCube;
|
||||
ppTail = &pCube->pNext;
|
||||
assert( pCube->uData[0] ); // not a bubble
|
||||
}
|
||||
}
|
||||
*ppTail = NULL;
|
||||
return pCov;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the cover in the increasing number of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube, * pCube2;
|
||||
Esop_ManClean( p, p->nVars );
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
{
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the cover in the increasing number of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover )
|
||||
{
|
||||
Esop_Cube_t * pCube;
|
||||
int i, Counter;
|
||||
if ( pCover == NULL )
|
||||
return 0;
|
||||
// clean the cube
|
||||
for ( i = 0; i < (int)pCover->nWords; i++ )
|
||||
p->pTemp->uData[i] = ~((unsigned)0);
|
||||
// add the bit data
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
for ( i = 0; i < (int)pCover->nWords; i++ )
|
||||
p->pTemp->uData[i] &= pCube->uData[i];
|
||||
// count the vars
|
||||
Counter = 0;
|
||||
for ( i = 0; i < (int)pCover->nVars; i++ )
|
||||
Counter += ( Esop_CubeGetVar(p->pTemp, i) != 3 );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC += src/temp/esop/esopMan.c \
|
||||
src/temp/esop/esopMin.c \
|
||||
src/temp/esop/esopUtil.c
|
||||
|
|
@ -183,10 +183,10 @@ static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i
|
|||
static inline void Ivy_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
|
||||
static inline void Ivy_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
|
||||
|
||||
static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) & ~01); }
|
||||
static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) ^ 01); }
|
||||
static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned)(p) ^ (c)); }
|
||||
static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned)p) & 01); }
|
||||
static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned long)(p) & ~01); }
|
||||
static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned long)(p) ^ 01); }
|
||||
static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned long)(p) ^ (c)); }
|
||||
static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
|
||||
|
||||
static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pConst1); }
|
||||
static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pConst1; }
|
||||
|
|
@ -471,6 +471,7 @@ extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t *
|
|||
extern Ivy_Man_t * Ivy_ManStart();
|
||||
extern Ivy_Man_t * Ivy_ManStartFrom( Ivy_Man_t * p );
|
||||
extern Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p );
|
||||
extern Ivy_Man_t * Ivy_ManFrames( Ivy_Man_t * pMan, int nLatches, int nFrames, int fInit, Vec_Ptr_t ** pvMapping );
|
||||
extern void Ivy_ManStop( Ivy_Man_t * p );
|
||||
extern int Ivy_ManCleanup( Ivy_Man_t * p );
|
||||
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel );
|
||||
|
|
@ -538,7 +539,7 @@ extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj,
|
|||
extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj );
|
||||
extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObjT, Ivy_Obj_t ** ppObjE );
|
||||
extern Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ObjPrintVerbose( Ivy_Obj_t * pObj, int fHaig );
|
||||
extern void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig );
|
||||
extern void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig );
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -1807,7 +1807,7 @@ void Ivy_FraigMiterProve( Ivy_FraigMan_t * p )
|
|||
***********************************************************************/
|
||||
void Ivy_FraigSweep( Ivy_FraigMan_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
Ivy_Obj_t * pObj;//, * pTemp;
|
||||
int i, k = 0;
|
||||
p->nClassesZero = p->lClasses.pHead? (Ivy_ObjIsConst1(p->lClasses.pHead) ? Ivy_FraigCountClassNodes(p->lClasses.pHead) : 0) : 0;
|
||||
p->nClassesBeg = p->lClasses.nItems;
|
||||
|
|
@ -1817,6 +1817,9 @@ p->nClassesBeg = p->lClasses.nItems;
|
|||
{
|
||||
Extra_ProgressBarUpdate( p->pProgress, k++, NULL );
|
||||
pObj->pEquiv = Ivy_FraigAnd( p, pObj );
|
||||
assert( pObj->pEquiv != NULL );
|
||||
// pTemp = Ivy_Regular(pObj->pEquiv);
|
||||
// assert( Ivy_Regular(pObj->pEquiv)->Type );
|
||||
}
|
||||
Extra_ProgressBarStop( p->pProgress );
|
||||
p->nClassesEnd = p->lClasses.nItems;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static inline Ivy_Obj_t * Ivy_HaigObjRepr( Ivy_Obj_t * pObj )
|
|||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// if the node has no equivalent or has fanout, it is representative
|
||||
// if the node has no equivalent node or has fanout, it is representative
|
||||
if ( pObj->pEquiv == NULL || Ivy_ObjRefs(pObj) > 0 )
|
||||
return pObj;
|
||||
// the node belongs to a class and is not a representative
|
||||
|
|
@ -110,6 +110,14 @@ void Ivy_ManHaigStart( Ivy_Man_t * p, int fVerbose )
|
|||
Vec_IntPush( vLatches, pObj->Id );
|
||||
}
|
||||
p->pHaig->pData = vLatches;
|
||||
/*
|
||||
{
|
||||
int x;
|
||||
Ivy_ManShow( p, 0, NULL );
|
||||
Ivy_ManShow( p->pHaig, 1, NULL );
|
||||
x = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -257,7 +265,7 @@ void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pO
|
|||
return;
|
||||
// if the second node belongs to a class, do not merge classes (for the time being)
|
||||
if ( Ivy_ObjRefs(pObjOldHaigR) == 0 || pObjNewHaigR->pEquiv != NULL ||
|
||||
Ivy_ObjRefs(pObjNewHaigR) > 0 || Ivy_ObjIsInTfi_rec(pObjNewHaigR, pObjOldHaigR, 10) )
|
||||
Ivy_ObjRefs(pObjNewHaigR) > 0 ) //|| Ivy_ObjIsInTfi_rec(pObjNewHaigR, pObjOldHaigR, 10) )
|
||||
{
|
||||
/*
|
||||
if ( pObjNewHaigR->pEquiv != NULL )
|
||||
|
|
@ -363,8 +371,8 @@ void Ivy_ManHaigPostprocess( Ivy_Man_t * p, int fVerbose )
|
|||
else
|
||||
printf( "HAIG contains a cycle\n" );
|
||||
|
||||
if ( fVerbose )
|
||||
Ivy_ManHaigSimulate( p );
|
||||
// if ( fVerbose )
|
||||
// Ivy_ManHaigSimulate( p );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ Ivy_Man_t * Ivy_ManStart()
|
|||
p = ALLOC( Ivy_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Ivy_Man_t) );
|
||||
// perform initializations
|
||||
p->Ghost.Id = -1;
|
||||
p->nTravIds = 1;
|
||||
p->fCatchExor = 1;
|
||||
p->Ghost.Id = -1;
|
||||
p->nTravIds = 1;
|
||||
p->fCatchExor = 1;
|
||||
// allocate arrays for nodes
|
||||
p->vPis = Vec_PtrAlloc( 100 );
|
||||
p->vPos = Vec_PtrAlloc( 100 );
|
||||
|
|
@ -155,6 +155,72 @@ Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManFrames( Ivy_Man_t * pMan, int nLatches, int nFrames, int fInit, Vec_Ptr_t ** pvMapping )
|
||||
{
|
||||
Vec_Ptr_t * vMapping;
|
||||
Ivy_Man_t * pNew;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, f, nPis, nPos, nIdMax;
|
||||
assert( Ivy_ManLatchNum(pMan) == 0 );
|
||||
assert( nFrames > 0 );
|
||||
// prepare the mapping
|
||||
nPis = Ivy_ManPiNum(pMan) - nLatches;
|
||||
nPos = Ivy_ManPoNum(pMan) - nLatches;
|
||||
nIdMax = Ivy_ManObjIdMax(pMan);
|
||||
// create the new manager
|
||||
pNew = Ivy_ManStart();
|
||||
// set the starting values of latch inputs
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
Ivy_ManPo(pMan, nPos+i)->pEquiv = fInit? Ivy_Not(Ivy_ManConst1(pNew)) : Ivy_ObjCreatePi(pNew);
|
||||
// add timeframes
|
||||
vMapping = Vec_PtrStart( nIdMax * nFrames + 1 );
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
{
|
||||
// create PIs
|
||||
Ivy_ManConst1(pMan)->pEquiv = Ivy_ManConst1(pNew);
|
||||
for ( i = 0; i < nPis; i++ )
|
||||
Ivy_ManPi(pMan, i)->pEquiv = Ivy_ObjCreatePi(pNew);
|
||||
// transfer values to latch outputs
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
Ivy_ManPi(pMan, nPis+i)->pEquiv = Ivy_ManPo(pMan, nPos+i)->pEquiv;
|
||||
// perform strashing
|
||||
Ivy_ManForEachNode( pMan, pObj, i )
|
||||
pObj->pEquiv = Ivy_And( pNew, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
|
||||
// create POs
|
||||
for ( i = 0; i < nPos; i++ )
|
||||
Ivy_ManPo(pMan, i)->pEquiv = Ivy_ObjCreatePo( pNew, Ivy_ObjChild0Equiv(Ivy_ManPo(pMan, i)) );
|
||||
// set the results of latch inputs
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
Ivy_ManPo(pMan, nPos+i)->pEquiv = Ivy_ObjChild0Equiv(Ivy_ManPo(pMan, nPos+i));
|
||||
// save the pointers in this frame
|
||||
Ivy_ManForEachObj( pMan, pObj, i )
|
||||
Vec_PtrWriteEntry( vMapping, f * nIdMax + i, pObj->pEquiv );
|
||||
}
|
||||
// connect latches
|
||||
if ( !fInit )
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
Ivy_ObjCreatePo( pNew, Ivy_ManPo(pMan, nPos+i)->pEquiv );
|
||||
// remove dangling nodes
|
||||
Ivy_ManCleanup(pNew);
|
||||
*pvMapping = vMapping;
|
||||
// check the resulting network
|
||||
if ( !Ivy_ManCheck(pNew) )
|
||||
printf( "Ivy_ManFrames(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the AIG manager.]
|
||||
|
|
@ -291,6 +357,46 @@ int Ivy_ManCleanupSeq( Ivy_Man_t * p )
|
|||
return RetValue;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if latches form self-loop.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManLatchIsSelfFeed_rec( Ivy_Obj_t * pLatch, Ivy_Obj_t * pLatchRoot )
|
||||
{
|
||||
if ( !Ivy_ObjIsLatch(pLatch) && !Ivy_ObjIsBuf(pLatch) )
|
||||
return 0;
|
||||
if ( pLatch == pLatchRoot )
|
||||
return 1;
|
||||
return Ivy_ManLatchIsSelfFeed_rec( Ivy_ObjFanin0(pLatch), pLatchRoot );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if latches form self-loop.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManLatchIsSelfFeed( Ivy_Obj_t * pLatch )
|
||||
{
|
||||
if ( !Ivy_ObjIsLatch(pLatch) )
|
||||
return 0;
|
||||
return Ivy_ManLatchIsSelfFeed_rec( Ivy_ObjFanin0(pLatch), pLatch );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
|
@ -305,23 +411,30 @@ int Ivy_ManCleanupSeq( Ivy_Man_t * p )
|
|||
int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel )
|
||||
{
|
||||
Ivy_Obj_t * pNode;
|
||||
int LimitFactor = 20;
|
||||
int LimitFactor = 100;
|
||||
int NodeBeg = Ivy_ManNodeNum(p);
|
||||
int nSteps;
|
||||
for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ )
|
||||
{
|
||||
pNode = Vec_PtrEntryLast(p->vBufs);
|
||||
while ( Ivy_ObjIsBuf(pNode) )
|
||||
pNode = Ivy_ObjReadFirstFanout( p, pNode );
|
||||
// check if this buffer should remain
|
||||
if ( Ivy_ManLatchIsSelfFeed(pNode) )
|
||||
{
|
||||
Vec_PtrPop(p->vBufs);
|
||||
continue;
|
||||
}
|
||||
//printf( "Propagating buffer %d with input %d and output %d\n", Ivy_ObjFaninId0(pNode), Ivy_ObjFaninId0(Ivy_ObjFanin0(pNode)), pNode->Id );
|
||||
//printf( "Latch num %d\n", Ivy_ManLatchNum(p) );
|
||||
Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel );
|
||||
if ( nSteps > Ivy_ManNodeNum(p) * LimitFactor )
|
||||
if ( nSteps > NodeBeg * LimitFactor )
|
||||
{
|
||||
printf( "This circuit cannot be forward retimed completely. Structural hashing is not finished after %d forward latch moves.\n", Ivy_ManNodeNum(p) * LimitFactor );
|
||||
printf( "This circuit cannot be forward retimed completely. Structural hashing is not finished after %d forward latch moves.\n", NodeBeg * LimitFactor );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// printf( "Number of steps = %d\n", nSteps );
|
||||
printf( "Number of steps = %d. Nodes beg = %d. Nodes end = %d.\n", nSteps, NodeBeg, Ivy_ManNodeNum(p) );
|
||||
return nSteps;
|
||||
}
|
||||
|
||||
|
|
@ -416,6 +529,8 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
|
|||
*/
|
||||
// perform hashing by propagating the buffers
|
||||
Ivy_ManPropagateBuffers( p, 0 );
|
||||
if ( Ivy_ManBufNum(p) )
|
||||
printf( "The number of remaining buffers is %d.\n", Ivy_ManBufNum(p) );
|
||||
// fix the levels
|
||||
Ivy_ManResetLevels( p );
|
||||
// check the resulting network
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
|
|||
p->nCreated++;
|
||||
|
||||
// printf( "Adding %sAIG node: ", p->pHaig==NULL? "H":" " );
|
||||
// Ivy_ObjPrintVerbose( pObj, p->pHaig==NULL );
|
||||
// Ivy_ObjPrintVerbose( p, pObj, p->pHaig==NULL );
|
||||
// printf( "\n" );
|
||||
|
||||
// if HAIG is defined, create a corresponding node
|
||||
|
|
@ -234,7 +234,7 @@ void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew
|
|||
if ( p->fFanout )
|
||||
Ivy_ObjAddFanout( p, Ivy_Regular(pFaninNew), pObj );
|
||||
// get rid of old fanin
|
||||
if ( !Ivy_ObjIsPi(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 )
|
||||
if ( !Ivy_ObjIsPi(pFaninOld) && !Ivy_ObjIsConst1(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pFaninOld, 1 );
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +333,8 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
|
|||
assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) );
|
||||
// the object cannot be the same
|
||||
assert( pObjOld != Ivy_Regular(pObjNew) );
|
||||
//printf( "Replacing %d by %d.\n", Ivy_Regular(pObjOld)->Id, Ivy_Regular(pObjNew)->Id );
|
||||
|
||||
// if HAIG is defined, create the choice node
|
||||
if ( p->pHaig )
|
||||
{
|
||||
|
|
@ -410,8 +412,8 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
|
|||
if ( p->pHaig )
|
||||
{
|
||||
int x;
|
||||
Ivy_ManShow( p, 0 );
|
||||
Ivy_ManShow( p->pHaig, 1 );
|
||||
Ivy_ManShow( p, 0, NULL );
|
||||
Ivy_ManShow( p->pHaig, 1, NULL );
|
||||
x = 0;
|
||||
}
|
||||
*/
|
||||
|
|
@ -458,6 +460,11 @@ void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel
|
|||
pResult = Ivy_Latch( p, pFanReal0, Ivy_ObjInit(pNode) );
|
||||
else
|
||||
assert( 0 );
|
||||
|
||||
//printf( "===== Replacing %d by %d.\n", pNode->Id, pResult->Id );
|
||||
//Ivy_ObjPrintVerbose( p, pNode, 0 ); printf( "\n" );
|
||||
//Ivy_ObjPrintVerbose( p, pResult, 0 ); printf( "\n" );
|
||||
|
||||
// perform the replacement
|
||||
Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,12 +242,14 @@ p->timeRes += clock() - clk;
|
|||
|
||||
if ( GainBest == -1 )
|
||||
return -1;
|
||||
|
||||
/*
|
||||
{
|
||||
Ivy_Cut_t * pCut = p->pCut;
|
||||
printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) );
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
|
||||
printf( " }\n" );
|
||||
}
|
||||
*/
|
||||
|
||||
// copy the leaves
|
||||
|
|
|
|||
|
|
@ -623,9 +623,10 @@ Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjPrintVerbose( Ivy_Obj_t * pObj, int fHaig )
|
||||
void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig )
|
||||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
int fShowFanouts = 0;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
printf( "Node %5d : ", Ivy_ObjId(pObj) );
|
||||
if ( Ivy_ObjIsConst1(pObj) )
|
||||
|
|
@ -635,14 +636,40 @@ void Ivy_ObjPrintVerbose( Ivy_Obj_t * pObj, int fHaig )
|
|||
else if ( Ivy_ObjIsPo(pObj) )
|
||||
printf( "PO" );
|
||||
else if ( Ivy_ObjIsLatch(pObj) )
|
||||
printf( "latch %d%s", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
|
||||
printf( "latch (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
|
||||
else if ( Ivy_ObjIsBuf(pObj) )
|
||||
printf( "buffer %d%s", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
|
||||
printf( "buffer (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
|
||||
else
|
||||
printf( "AND( %5d%s, %5d%s )",
|
||||
Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " "),
|
||||
Ivy_ObjFanin1(pObj)->Id, (Ivy_ObjFaninC1(pObj)? "\'" : " ") );
|
||||
printf( " (refs = %3d)", Ivy_ObjRefs(pObj) );
|
||||
if ( fShowFanouts )
|
||||
{
|
||||
Vec_Ptr_t * vFanouts;
|
||||
Ivy_Obj_t * pFanout;
|
||||
int i;
|
||||
vFanouts = Vec_PtrAlloc( 10 );
|
||||
printf( "\nFanouts:\n" );
|
||||
Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i )
|
||||
{
|
||||
printf( " " );
|
||||
printf( "Node %5d : ", Ivy_ObjId(pFanout) );
|
||||
if ( Ivy_ObjIsPo(pFanout) )
|
||||
printf( "PO" );
|
||||
else if ( Ivy_ObjIsLatch(pFanout) )
|
||||
printf( "latch (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") );
|
||||
else if ( Ivy_ObjIsBuf(pFanout) )
|
||||
printf( "buffer (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") );
|
||||
else
|
||||
printf( "AND( %5d%s, %5d%s )",
|
||||
Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " "),
|
||||
Ivy_ObjFanin1(pFanout)->Id, (Ivy_ObjFaninC1(pFanout)? "\'" : " ") );
|
||||
printf( "\n" );
|
||||
}
|
||||
Vec_PtrFree( vFanouts );
|
||||
return;
|
||||
}
|
||||
if ( !fHaig )
|
||||
{
|
||||
if ( pObj->pEquiv == NULL )
|
||||
|
|
@ -700,7 +727,7 @@ void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig )
|
|||
printf( "\n" );
|
||||
vNodes = Ivy_ManDfsSeq( p, NULL );
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
|
||||
Ivy_ObjPrintVerbose( pObj, fHaig ), printf( "\n" );
|
||||
Ivy_ObjPrintVerbose( p, pObj, fHaig ), printf( "\n" );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
SRC += src/temp/player/playerToAbc.c \
|
||||
src/temp/player/playerCore.c \
|
||||
src/temp/player/playerMan.c \
|
||||
src/temp/player/playerUtil.c
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [player.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLA decomposition package.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: player.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __XYZ_H__
|
||||
#define __XYZ_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ivy.h"
|
||||
#include "esop.h"
|
||||
#include "vec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Pla_Man_t_ Pla_Man_t;
|
||||
typedef struct Pla_Obj_t_ Pla_Obj_t;
|
||||
|
||||
// storage for node information
|
||||
struct Pla_Obj_t_
|
||||
{
|
||||
unsigned fFixed : 1; // fixed node
|
||||
unsigned Depth : 31; // the depth in terms of LUTs/PLAs
|
||||
int nRefs; // the number of references
|
||||
Vec_Int_t vSupp[2]; // supports in two frames
|
||||
Esop_Cube_t * pCover[2]; // esops in two frames
|
||||
};
|
||||
|
||||
// storage for additional information
|
||||
struct Pla_Man_t_
|
||||
{
|
||||
// general characteristics
|
||||
int nLutMax; // the number of vars
|
||||
int nPlaMax; // the number of vars
|
||||
int nCubesMax; // the limit on the number of cubes in the intermediate covers
|
||||
Ivy_Man_t * pManAig; // the AIG manager
|
||||
Pla_Obj_t * pPlaStrs; // memory for structures
|
||||
Esop_Man_t * pManMin; // the cube manager
|
||||
// arrays to map local variables
|
||||
Vec_Int_t * vComTo0; // mapping of common variables into first fanin
|
||||
Vec_Int_t * vComTo1; // mapping of common variables into second fanin
|
||||
Vec_Int_t * vPairs0; // the first var in each pair of common vars
|
||||
Vec_Int_t * vPairs1; // the second var in each pair of common vars
|
||||
Vec_Int_t * vTriv0; // trival support of the first node
|
||||
Vec_Int_t * vTriv1; // trival support of the second node
|
||||
// statistics
|
||||
int nNodes; // the number of nodes processed
|
||||
int nNodesLut; // the number of nodes processed
|
||||
int nNodesPla; // the number of nodes processed
|
||||
int nNodesBoth; // the number of nodes processed
|
||||
int nNodesDeref; // the number of nodes processed
|
||||
};
|
||||
|
||||
#define PLAYER_FANIN_LIMIT 128
|
||||
|
||||
#define PLA_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define PLA_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
#define PLA_EMPTY ((Esop_Cube_t *)1)
|
||||
|
||||
static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (Pla_Man_t *)p->pData; }
|
||||
static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return ((Pla_Man_t *)p->pData)->pPlaStrs + pObj->Id; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== playerToAbc.c ==============================================================*/
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose );
|
||||
/*=== playerCore.c =============================================================*/
|
||||
extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
|
||||
/*=== playerMan.c ==============================================================*/
|
||||
extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax );
|
||||
extern void Pla_ManFree( Pla_Man_t * p );
|
||||
extern void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr );
|
||||
/*=== playerUtil.c =============================================================*/
|
||||
extern int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp );
|
||||
extern Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit );
|
||||
extern Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit );
|
||||
extern void Pla_ManComputeStats( Ivy_Man_t * pAig, Vec_Int_t * vNodes );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerAbc.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLAyer decomposition package.]
|
||||
|
||||
Synopsis [Bridge between ABC and PLAyer.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 20, 2006.]
|
||||
|
||||
Revision [$Id: playerAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p );
|
||||
static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to PLAyer for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose )
|
||||
{
|
||||
int fUseRewriting = 1;
|
||||
Ivy_Man_t * pMan, * pManExt;
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
return NULL;
|
||||
// convert to the new AIG manager
|
||||
pMan = Ivy_ManFromAbc( pNtk );
|
||||
// check the correctness of conversion
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" );
|
||||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
}
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
if ( fUseRewriting )
|
||||
{
|
||||
// simplify
|
||||
pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
|
||||
Ivy_ManStop( pManExt );
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
// perform decomposition/mapping into PLAs/LUTs
|
||||
pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
|
||||
Ivy_ManStop( pMan );
|
||||
pMan = pManExt;
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkAig = Ivy_ManToAbc( pNtk, pMan );
|
||||
Ivy_ManStop( pMan );
|
||||
// chech the resulting network
|
||||
if ( !Abc_NtkCheck( pNtkAig ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkAig );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.]
|
||||
|
||||
Description [Assumes DFS ordering of nodes in the AIG of ABC.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Ivy_Man_t * pMan;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// create the manager
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), Abc_NtkNodeNum(pNtk) + 10 );
|
||||
// create the PIs
|
||||
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i);
|
||||
// perform the conversion of the internal nodes
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_And( (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) );
|
||||
// create the POs
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Ivy_ObjConnect( Ivy_ManPo(pMan, i), (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) );
|
||||
Ivy_ManCleanup( pMan );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts AIG manager after PLA/LUT mapping into a logic ABC network.]
|
||||
|
||||
Description [The AIG manager contains nodes with extended functionality.
|
||||
Node types are in pObj->Type. Node fanins are in pObj->vFanins. Functions
|
||||
of LUT nodes are in pMan->vTruths.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Vec_Int_t * vIvyNodes, * vIvyFanins, * vTruths = pMan->vTruths;
|
||||
Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
|
||||
Ivy_Obj_t * pIvyNode, * pIvyFanin;
|
||||
int pCompls[PLAYER_FANIN_LIMIT];
|
||||
int i, k, Fanin, nFanins;
|
||||
// start the new ABC network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtkOld, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
// transfer the pointers to the basic nodes
|
||||
Ivy_ManCleanTravId(pMan);
|
||||
Ivy_ManConst1(pMan)->TravId = Abc_AigConst1(pNtkNew)->Id;
|
||||
Abc_NtkForEachCi( pNtkNew, pObjNew, i )
|
||||
Ivy_ManPi(pMan, i)->TravId = pObjNew->Id;
|
||||
// construct the logic network isomorphic to logic network in the AIG manager
|
||||
vIvyNodes = Ivy_ManDfsExt( pMan );
|
||||
Ivy_ManForEachNodeVec( pMan, vIvyNodes, pIvyNode, i )
|
||||
{
|
||||
// get fanins of the old node
|
||||
vIvyFanins = Ivy_ObjGetFanins( pIvyNode );
|
||||
nFanins = Vec_IntSize(vIvyFanins);
|
||||
// create the new node
|
||||
pObjNew = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntForEachEntry( vIvyFanins, Fanin, k )
|
||||
{
|
||||
pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_EdgeId(Fanin) );
|
||||
pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
|
||||
Abc_ObjAddFanin( pObjNew, pFaninNew );
|
||||
pCompls[k] = Ivy_EdgeIsComplement(Fanin);
|
||||
assert( Ivy_ObjIsAndMulti(pIvyNode) || nFanins == 1 || pCompls[k] == 0 ); // EXOR/LUT cannot have complemented fanins
|
||||
}
|
||||
assert( k <= PLAYER_FANIN_LIMIT );
|
||||
// create logic function of the node
|
||||
if ( Ivy_ObjIsAndMulti(pIvyNode) )
|
||||
pObjNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, nFanins, pCompls );
|
||||
else if ( Ivy_ObjIsExorMulti(pIvyNode) )
|
||||
pObjNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nFanins );
|
||||
else if ( Ivy_ObjIsLut(pIvyNode) )
|
||||
pObjNew->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, nFanins, Ivy_ObjGetTruth(pIvyNode) );
|
||||
else assert( 0 );
|
||||
assert( Abc_SopGetVarNum(pObjNew->pData) == nFanins );
|
||||
pIvyNode->TravId = pObjNew->Id;
|
||||
}
|
||||
//Pla_ManComputeStats( pMan, vIvyNodes );
|
||||
Vec_IntFree( vIvyNodes );
|
||||
// connect the PO nodes
|
||||
Abc_NtkForEachCo( pNtkOld, pObj, i )
|
||||
{
|
||||
// get the old fanin of the PO node
|
||||
vIvyFanins = Ivy_ObjGetFanins( Ivy_ManPo(pMan, i) );
|
||||
Fanin = Vec_IntEntry( vIvyFanins, 0 );
|
||||
pIvyFanin = Ivy_ManObj( pMan, Ivy_EdgeId(Fanin) );
|
||||
// get the new ABC node corresponding to the old fanin
|
||||
pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
|
||||
if ( Ivy_EdgeIsComplement(Fanin) ) // complement
|
||||
{
|
||||
// pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew);
|
||||
if ( Abc_ObjIsCi(pFaninNew) )
|
||||
pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew);
|
||||
else
|
||||
{
|
||||
// clone the node
|
||||
pObjNew = Abc_NtkCloneObj( pFaninNew );
|
||||
// set complemented functions
|
||||
pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pFaninNew->pData );
|
||||
Abc_SopComplement(pObjNew->pData);
|
||||
// return the new node
|
||||
pFaninNew = pObjNew;
|
||||
}
|
||||
assert( Abc_SopGetVarNum(pFaninNew->pData) == Abc_ObjFaninNum(pFaninNew) );
|
||||
}
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
}
|
||||
// remove dangling nodes
|
||||
Abc_NtkForEachNode(pNtkNew, pObj, i)
|
||||
if ( Abc_ObjFanoutNum(pObj) == 0 )
|
||||
Abc_NtkDeleteObj(pObj);
|
||||
// fix CIs feeding directly into COs
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerBuild.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLA decomposition package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: playerBuild.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld );
|
||||
static Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
|
||||
static Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 );
|
||||
static int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the AIG manager (IVY) for the network after mapping.]
|
||||
|
||||
Description [Uses extended node types (multi-input AND, multi-input EXOR, LUT).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld )
|
||||
{
|
||||
Ivy_Man_t * pNew;
|
||||
Ivy_Obj_t * pObjOld, * pObjNew;
|
||||
int i;
|
||||
// start the new manager
|
||||
pNew = Ivy_ManStart( Ivy_ManPiNum(pOld), Ivy_ManPoNum(pOld), 2*Ivy_ManNodeNum(pOld) + 10 );
|
||||
pNew->fExtended = 1;
|
||||
// transfer the const/PI numbers
|
||||
Ivy_ManCleanTravId(pOld);
|
||||
Ivy_ManConst1(pOld)->TravId = Ivy_ManConst1(pNew)->Id;
|
||||
Ivy_ManForEachPi( pOld, pObjOld, i )
|
||||
pObjOld->TravId = Ivy_ManPi(pNew, i)->Id;
|
||||
// recursively construct the network
|
||||
Ivy_ManForEachPo( pOld, pObjOld, i )
|
||||
{
|
||||
pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) );
|
||||
Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 );
|
||||
Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_EdgeCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) );
|
||||
}
|
||||
// compute the LUT functions
|
||||
Pla_ManToAigLutFuncs( pNew, pOld );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively construct the new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )
|
||||
{
|
||||
Pla_Man_t * p = Ivy_ObjMan(pObjOld)->pData;
|
||||
Vec_Int_t * vSupp;
|
||||
Esop_Cube_t * pCover, * pCube;
|
||||
Ivy_Obj_t * pFaninOld, * pFaninNew, * pObjNew;
|
||||
Pla_Obj_t * pStr;
|
||||
int Entry, nCubes, ObjNewId, i;
|
||||
// skip the node if it is a constant or already processed
|
||||
if ( Ivy_ObjIsConst1(pObjOld) || pObjOld->TravId )
|
||||
return Ivy_ManObj( pNew, pObjOld->TravId );
|
||||
assert( Ivy_ObjIsAnd(pObjOld) || Ivy_ObjIsExor(pObjOld) );
|
||||
// get the support and the cover
|
||||
pStr = Ivy_ObjPlaStr( pNew, pObjOld );
|
||||
if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax )
|
||||
{
|
||||
vSupp = &pStr->vSupp[0];
|
||||
pCover = PLA_EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
vSupp = &pStr->vSupp[1];
|
||||
pCover = pStr->pCover[1];
|
||||
assert( pCover != PLA_EMPTY );
|
||||
}
|
||||
// process the fanins
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
Pla_ManToAig_rec( pNew, Ivy_ObjObj(pObjOld, Entry) );
|
||||
// consider the case of a LUT
|
||||
if ( pCover == PLA_EMPTY )
|
||||
{
|
||||
pObjNew = Ivy_ObjCreateExt( pNew, IVY_LUT );
|
||||
Ivy_ObjStartFanins( pObjNew, p->nLutMax );
|
||||
// remember new object ID in case it changes
|
||||
ObjNewId = pObjNew->Id;
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFaninOld = Ivy_ObjObj( pObjOld, Entry );
|
||||
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninOld->TravId, 0) );
|
||||
}
|
||||
// get the new object
|
||||
pObjNew = Ivy_ManObj(pNew, ObjNewId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for each cube, construct the node
|
||||
nCubes = Esop_CoverCountCubes( pCover );
|
||||
if ( nCubes == 0 )
|
||||
pObjNew = Ivy_ManToAigConst( pNew, 0 );
|
||||
else if ( nCubes == 1 )
|
||||
pObjNew = Ivy_ManToAigCube( pNew, pObjOld, pCover, vSupp );
|
||||
else
|
||||
{
|
||||
pObjNew = Ivy_ObjCreateExt( pNew, IVY_EXORM );
|
||||
Ivy_ObjStartFanins( pObjNew, p->nLutMax );
|
||||
// remember new object ID in case it changes
|
||||
ObjNewId = pObjNew->Id;
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp );
|
||||
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninNew->Id, 0) );
|
||||
}
|
||||
// get the new object
|
||||
pObjNew = Ivy_ManObj(pNew, ObjNewId);
|
||||
}
|
||||
}
|
||||
pObjOld->TravId = pObjNew->Id;
|
||||
pObjNew->TravId = pObjOld->Id;
|
||||
return pObjNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns constant 1 node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 )
|
||||
{
|
||||
Ivy_Obj_t * pObjNew;
|
||||
pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );
|
||||
Ivy_ObjStartFanins( pObjNew, 1 );
|
||||
Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate(0, !fConst1) );
|
||||
return pObjNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t * pCube, Vec_Int_t * vSupp )
|
||||
{
|
||||
Ivy_Obj_t * pObjNew, * pFaninOld;
|
||||
int i, Value;
|
||||
// if tautology cube, create constant 1 node
|
||||
if ( pCube->nLits == 0 )
|
||||
return Ivy_ManToAigConst( pNew, 1 );
|
||||
// create AND node
|
||||
pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );
|
||||
Ivy_ObjStartFanins( pObjNew, pCube->nLits );
|
||||
// add fanins
|
||||
for ( i = 0; i < (int)pCube->nVars; i++ )
|
||||
{
|
||||
Value = Esop_CubeGetVar( pCube, i );
|
||||
assert( Value != 0 );
|
||||
if ( Value == 3 )
|
||||
continue;
|
||||
pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) );
|
||||
Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate( pFaninOld->TravId, Value==1 ) );
|
||||
}
|
||||
assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits );
|
||||
return pObjNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively construct the new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )
|
||||
{
|
||||
Vec_Int_t * vSupp, * vFanins, * vNodes, * vTemp;
|
||||
Ivy_Obj_t * pObjOld, * pObjNew;
|
||||
unsigned * pComputed, * pTruth;
|
||||
int i, k, Counter = 0;
|
||||
// create mapping from the LUT nodes into truth table indices
|
||||
assert( pNew->vTruths == NULL );
|
||||
vNodes = Vec_IntAlloc( 100 );
|
||||
vTemp = Vec_IntAlloc( 100 );
|
||||
pNew->vTruths = Vec_IntStart( Ivy_ManObjIdNext(pNew) );
|
||||
Ivy_ManForEachObj( pNew, pObjNew, i )
|
||||
{
|
||||
if ( Ivy_ObjIsLut(pObjNew) )
|
||||
Vec_IntWriteEntry( pNew->vTruths, i, 8 * Counter++ );
|
||||
else
|
||||
Vec_IntWriteEntry( pNew->vTruths, i, -1 );
|
||||
}
|
||||
// allocate memory
|
||||
pNew->pMemory = ALLOC( unsigned, 8 * Counter );
|
||||
memset( pNew->pMemory, 0, sizeof(unsigned) * 8 * Counter );
|
||||
// derive truth tables
|
||||
Ivy_ManForEachObj( pNew, pObjNew, i )
|
||||
{
|
||||
if ( !Ivy_ObjIsLut(pObjNew) )
|
||||
continue;
|
||||
pObjOld = Ivy_ManObj( pOld, pObjNew->TravId );
|
||||
vSupp = Ivy_ObjPlaStr(pNew, pObjOld)->vSupp;
|
||||
assert( Vec_IntSize(vSupp) <= 8 );
|
||||
pTruth = Ivy_ObjGetTruth( pObjNew );
|
||||
pComputed = Ivy_ManCutTruth( pNew, pObjOld, vSupp, vNodes, vTemp );
|
||||
// check if the truth table is constant 0
|
||||
for ( k = 0; k < 8; k++ )
|
||||
if ( pComputed[k] )
|
||||
break;
|
||||
if ( k == 8 )
|
||||
{
|
||||
// create inverter
|
||||
for ( k = 0; k < 8; k++ )
|
||||
pComputed[k] = 0x55555555;
|
||||
// point it to the constant 1 node
|
||||
vFanins = Ivy_ObjGetFanins( pObjNew );
|
||||
Vec_IntClear( vFanins );
|
||||
Vec_IntPush( vFanins, Ivy_EdgeCreate(0, 1) );
|
||||
}
|
||||
memcpy( pTruth, pComputed, sizeof(unsigned) * 8 );
|
||||
// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" );
|
||||
}
|
||||
Vec_IntFree( vTemp );
|
||||
Vec_IntFree( vNodes );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,376 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerCore.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLA decomposition package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: playerCore.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Pla_ManDecomposeInt( Pla_Man_t * p );
|
||||
static int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj );
|
||||
static void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
|
||||
Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose )
|
||||
{
|
||||
Pla_Man_t * p;
|
||||
p = Pla_ManAlloc( pAig, nLutMax, nPlaMax );
|
||||
if ( !Pla_ManDecomposeInt( p ) )
|
||||
{
|
||||
printf( "Decomposition/mapping failed.\n" );
|
||||
Pla_ManFree( p );
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManDecomposeInt( Pla_Man_t * p )
|
||||
{
|
||||
Ivy_Man_t * pAig = p->pManAig;
|
||||
Ivy_Obj_t * pObj;
|
||||
Pla_Obj_t * pStr;
|
||||
int i;
|
||||
|
||||
// prepare the PI structures
|
||||
Ivy_ManForEachPi( pAig, pObj, i )
|
||||
{
|
||||
pStr = Ivy_ObjPlaStr( pAig, pObj );
|
||||
pStr->fFixed = 1;
|
||||
pStr->Depth = 0;
|
||||
pStr->nRefs = (unsigned)pObj->nRefs;
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
pStr->pCover[1] = PLA_EMPTY;
|
||||
}
|
||||
|
||||
// assuming DFS ordering of nodes in the manager
|
||||
Ivy_ManForEachNode( pAig, pObj, i )
|
||||
if ( !Pla_ManDecomposeNode(p, pObj) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Records decomposition statistics for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Pla_ManCountDecNodes( Pla_Man_t * p, Pla_Obj_t * pStr )
|
||||
{
|
||||
if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax && pStr->pCover[1] != PLA_EMPTY )
|
||||
p->nNodesBoth++;
|
||||
else if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax )
|
||||
p->nNodesLut++;
|
||||
else if ( pStr->pCover[1] != PLA_EMPTY )
|
||||
p->nNodesPla++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs decomposition/mapping for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Pla_Obj_t * pStr, * pStr0, * pStr1;
|
||||
Vec_Int_t * vSuppA, * vSuppB, * vSupp0, * vSupp1;
|
||||
Esop_Cube_t * pCovA, * pCovB;
|
||||
int nSuppSize1, nSuppSize2;
|
||||
|
||||
assert( pObj->nRefs > 0 );
|
||||
p->nNodes++;
|
||||
|
||||
// get the structures
|
||||
pStr = Ivy_ObjPlaStr( p->pManAig, pObj );
|
||||
pStr0 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin0( pObj ) );
|
||||
pStr1 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin1( pObj ) );
|
||||
vSupp0 = &pStr->vSupp[0];
|
||||
vSupp1 = &pStr->vSupp[1];
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
pStr->pCover[1] = PLA_EMPTY;
|
||||
|
||||
// process level 1
|
||||
Pla_NodeGetSuppsAndCovers( p, pObj, 1, &vSuppA, &vSuppB, &pCovA, &pCovB );
|
||||
nSuppSize1 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 );
|
||||
if ( nSuppSize1 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
else if ( Ivy_ObjIsAnd(pObj) )
|
||||
pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 );
|
||||
else
|
||||
pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 );
|
||||
|
||||
// process level 2
|
||||
if ( PLA_MAX(pStr0->Depth, pStr1->Depth) > 1 )
|
||||
{
|
||||
Pla_NodeGetSuppsAndCovers( p, pObj, 2, &vSuppA, &vSuppB, &pCovA, &pCovB );
|
||||
nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp1 );
|
||||
if ( nSuppSize2 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
|
||||
pStr->pCover[1] = PLA_EMPTY;
|
||||
else if ( Ivy_ObjIsAnd(pObj) )
|
||||
pStr->pCover[1] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 );
|
||||
else
|
||||
pStr->pCover[1] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 );
|
||||
}
|
||||
|
||||
// determine the level of this node
|
||||
pStr->nRefs = (unsigned)pObj->nRefs;
|
||||
pStr->Depth = PLA_MAX( pStr0->Depth, pStr1->Depth );
|
||||
pStr->Depth = pStr->Depth? pStr->Depth : 1;
|
||||
if ( nSuppSize1 > p->nLutMax && pStr->pCover[1] == PLA_EMPTY )
|
||||
{
|
||||
pStr->Depth++;
|
||||
// free second level
|
||||
if ( pStr->pCover[1] != PLA_EMPTY )
|
||||
Esop_CoverRecycle( p->pManMin, pStr->pCover[1] );
|
||||
vSupp1->nCap = 0;
|
||||
vSupp1->nSize = 0;
|
||||
FREE( vSupp1->pArray );
|
||||
pStr->pCover[1] = PLA_EMPTY;
|
||||
// move first to second
|
||||
pStr->vSupp[1] = pStr->vSupp[0];
|
||||
pStr->pCover[1] = pStr->pCover[0];
|
||||
vSupp0->nCap = 0;
|
||||
vSupp0->nSize = 0;
|
||||
vSupp0->pArray = NULL;
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
// get zero level
|
||||
Pla_NodeGetSuppsAndCovers( p, pObj, 0, &vSuppA, &vSuppB, &pCovA, &pCovB );
|
||||
nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 );
|
||||
assert( nSuppSize2 == 2 );
|
||||
if ( pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
else if ( Ivy_ObjIsAnd(pObj) )
|
||||
pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 );
|
||||
else
|
||||
pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 );
|
||||
// count stats
|
||||
if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 );
|
||||
if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 );
|
||||
// mark the nodes
|
||||
pStr0->fFixed = 1;
|
||||
pStr1->fFixed = 1;
|
||||
}
|
||||
else if ( pStr0->Depth < pStr1->Depth )
|
||||
{
|
||||
if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 );
|
||||
pStr0->fFixed = 1;
|
||||
}
|
||||
else // if ( pStr0->Depth > pStr1->Depth )
|
||||
{
|
||||
if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 );
|
||||
pStr1->fFixed = 1;
|
||||
}
|
||||
assert( pStr->Depth );
|
||||
|
||||
// free some of the covers to save memory
|
||||
assert( pStr0->nRefs > 0 );
|
||||
assert( pStr1->nRefs > 0 );
|
||||
pStr0->nRefs--;
|
||||
pStr1->nRefs--;
|
||||
|
||||
if ( pStr0->nRefs == 0 && !pStr0->fFixed )
|
||||
Pla_ManFreeStr( p, pStr0 ), p->nNodesDeref++;
|
||||
if ( pStr1->nRefs == 0 && !pStr1->fFixed )
|
||||
Pla_ManFreeStr( p, pStr1 ), p->nNodesDeref++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns pointers to the support arrays on the given level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
|
||||
Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB )
|
||||
{
|
||||
Ivy_Obj_t * pFan0, * pFan1;
|
||||
Pla_Obj_t * pStr, * pStr0, * pStr1;
|
||||
Esop_Cube_t * pCovA, * pCovB;
|
||||
int fCompl0, fCompl1;
|
||||
assert( Level >= 0 && Level <= 2 );
|
||||
// get the complemented attributes
|
||||
fCompl0 = Ivy_ObjFaninC0( pObj );
|
||||
fCompl1 = Ivy_ObjFaninC1( pObj );
|
||||
// get the fanins
|
||||
pFan0 = Ivy_ObjFanin0( pObj );
|
||||
pFan1 = Ivy_ObjFanin1( pObj );
|
||||
// get the structures
|
||||
pStr = Ivy_ObjPlaStr( p->pManAig, pObj );
|
||||
pStr0 = Ivy_ObjPlaStr( p->pManAig, pFan0 );
|
||||
pStr1 = Ivy_ObjPlaStr( p->pManAig, pFan1 );
|
||||
// make sure the fanins are processed
|
||||
assert( Ivy_ObjIsPi(pFan0) || pStr0->Depth > 0 );
|
||||
assert( Ivy_ObjIsPi(pFan1) || pStr1->Depth > 0 );
|
||||
// prepare the return values depending on the level
|
||||
Vec_IntWriteEntry( p->vTriv0, 0, pFan0->Id );
|
||||
Vec_IntWriteEntry( p->vTriv1, 0, pFan1->Id );
|
||||
*pvSuppA = p->vTriv0;
|
||||
*pvSuppB = p->vTriv1;
|
||||
pCovA = p->pManMin->pTriv0;
|
||||
pCovB = p->pManMin->pTriv1;
|
||||
if ( Level == 1 )
|
||||
{
|
||||
if ( pStr0->Depth == pStr1->Depth )
|
||||
{
|
||||
if ( pStr0->Depth > 0 )
|
||||
{
|
||||
*pvSuppA = &pStr0->vSupp[0];
|
||||
*pvSuppB = &pStr1->vSupp[0];
|
||||
pCovA = pStr0->pCover[0];
|
||||
pCovB = pStr1->pCover[0];
|
||||
}
|
||||
}
|
||||
else if ( pStr0->Depth < pStr1->Depth )
|
||||
{
|
||||
*pvSuppB = &pStr1->vSupp[0];
|
||||
pCovB = pStr1->pCover[0];
|
||||
}
|
||||
else // if ( pStr0->Depth > pStr1->Depth )
|
||||
{
|
||||
*pvSuppA = &pStr0->vSupp[0];
|
||||
pCovA = pStr0->pCover[0];
|
||||
}
|
||||
}
|
||||
else if ( Level == 2 )
|
||||
{
|
||||
if ( pStr0->Depth == pStr1->Depth )
|
||||
{
|
||||
*pvSuppA = &pStr0->vSupp[1];
|
||||
*pvSuppB = &pStr1->vSupp[1];
|
||||
pCovA = pStr0->pCover[1];
|
||||
pCovB = pStr1->pCover[1];
|
||||
}
|
||||
else if ( pStr0->Depth + 1 == pStr1->Depth )
|
||||
{
|
||||
*pvSuppA = &pStr0->vSupp[0];
|
||||
*pvSuppB = &pStr1->vSupp[1];
|
||||
pCovA = pStr0->pCover[0];
|
||||
pCovB = pStr1->pCover[1];
|
||||
}
|
||||
else if ( pStr0->Depth == pStr1->Depth + 1 )
|
||||
{
|
||||
*pvSuppA = &pStr0->vSupp[1];
|
||||
*pvSuppB = &pStr1->vSupp[0];
|
||||
pCovA = pStr0->pCover[1];
|
||||
pCovB = pStr1->pCover[0];
|
||||
}
|
||||
else if ( pStr0->Depth < pStr1->Depth )
|
||||
{
|
||||
*pvSuppB = &pStr1->vSupp[1];
|
||||
pCovB = pStr1->pCover[1];
|
||||
}
|
||||
else // if ( pStr0->Depth > pStr1->Depth )
|
||||
{
|
||||
*pvSuppA = &pStr0->vSupp[1];
|
||||
pCovA = pStr0->pCover[1];
|
||||
}
|
||||
}
|
||||
// complement the first if needed
|
||||
if ( pCovA == PLA_EMPTY || !fCompl0 )
|
||||
*pvCovA = pCovA;
|
||||
else if ( pCovA && pCovA->nLits == 0 ) // topmost one is the tautology cube
|
||||
*pvCovA = pCovA->pNext;
|
||||
else
|
||||
*pvCovA = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCovA;
|
||||
// complement the second if needed
|
||||
if ( pCovB == PLA_EMPTY || !fCompl1 )
|
||||
*pvCovB = pCovB;
|
||||
else if ( pCovB && pCovB->nLits == 0 ) // topmost one is the tautology cube
|
||||
*pvCovB = pCovB->pNext;
|
||||
else
|
||||
*pvCovB = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCovB;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if ( pObj->Id == 1371 )
|
||||
{
|
||||
int k;
|
||||
printf( "Zero : " );
|
||||
for ( k = 0; k < vSuppA->nSize; k++ )
|
||||
printf( "%d ", vSuppA->pArray[k] );
|
||||
printf( "\n" );
|
||||
printf( "One : " );
|
||||
for ( k = 0; k < vSuppB->nSize; k++ )
|
||||
printf( "%d ", vSuppB->pArray[k] );
|
||||
printf( "\n" );
|
||||
printf( "Node : " );
|
||||
for ( k = 0; k < vSupp0->nSize; k++ )
|
||||
printf( "%d ", vSupp0->pArray[k] );
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
Esop_CoverWrite( stdout, pCovA );
|
||||
printf( "\n" );
|
||||
Esop_CoverWrite( stdout, pCovB );
|
||||
printf( "\n" );
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLA decomposition package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: playerMan.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates the PLA/LUT mapping manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * pAig, int nLutMax, int nPlaMax )
|
||||
{
|
||||
Pla_Man_t * pMan;
|
||||
assert( !(nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128) );
|
||||
// start the manager
|
||||
pMan = ALLOC( Pla_Man_t, 1 );
|
||||
memset( pMan, 0, sizeof(Pla_Man_t) );
|
||||
pMan->nLutMax = nLutMax;
|
||||
pMan->nPlaMax = nPlaMax;
|
||||
pMan->nCubesMax = 2 * nPlaMax; // higher limit, later reduced
|
||||
pMan->pManAig = pAig;
|
||||
// set up the temporaries
|
||||
pMan->vComTo0 = Vec_IntAlloc( 2 * nPlaMax );
|
||||
pMan->vComTo1 = Vec_IntAlloc( 2 * nPlaMax );
|
||||
pMan->vPairs0 = Vec_IntAlloc( nPlaMax );
|
||||
pMan->vPairs1 = Vec_IntAlloc( nPlaMax );
|
||||
pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
|
||||
pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
|
||||
// allocate memory for object structures
|
||||
pMan->pPlaStrs = ALLOC( Pla_Obj_t, Ivy_ManObjIdMax(pAig)+1 );
|
||||
memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * (Ivy_ManObjIdMax(pAig)+1) );
|
||||
// create the cube manager
|
||||
pMan->pManMin = Esop_ManAlloc( nPlaMax );
|
||||
// save the resulting manager
|
||||
assert( pAig->pData == NULL );
|
||||
pAig->pData = pMan;
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the PLA/LUT mapping manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManFree( Pla_Man_t * p )
|
||||
{
|
||||
Pla_Obj_t * pStr;
|
||||
int i;
|
||||
Esop_ManFree( p->pManMin );
|
||||
Vec_IntFree( p->vTriv0 );
|
||||
Vec_IntFree( p->vTriv1 );
|
||||
Vec_IntFree( p->vComTo0 );
|
||||
Vec_IntFree( p->vComTo1 );
|
||||
Vec_IntFree( p->vPairs0 );
|
||||
Vec_IntFree( p->vPairs1 );
|
||||
for ( i = 0, pStr = p->pPlaStrs; i <= Ivy_ManObjIdMax(p->pManAig); i++, pStr++ )
|
||||
FREE( pStr->vSupp[0].pArray ), FREE( pStr->vSupp[1].pArray );
|
||||
free( p->pPlaStrs );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans the PLA/LUT structure of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr )
|
||||
{
|
||||
if ( pStr->pCover[0] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[0] );
|
||||
if ( pStr->pCover[1] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[1] );
|
||||
if ( pStr->vSupp[0].pArray ) free( pStr->vSupp[0].pArray );
|
||||
if ( pStr->vSupp[1].pArray ) free( pStr->vSupp[1].pArray );
|
||||
memset( pStr, 0, sizeof(Pla_Obj_t) );
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
pStr->pCover[1] = PLA_EMPTY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,523 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerToAbc.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLAyer decomposition package.]
|
||||
|
||||
Synopsis [Bridge between ABC and PLAyer.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 20, 2006.]
|
||||
|
||||
Revision [$Id: playerToAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p );
|
||||
static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode );
|
||||
static Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
|
||||
static Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
|
||||
static Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
|
||||
static int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose );
|
||||
|
||||
static inline void Abc_ObjSetIvy2Abc( Ivy_Man_t * p, int IvyId, Abc_Obj_t * pObjAbc ) { assert(Vec_PtrEntry(p->pCopy, IvyId) == NULL); assert(!Abc_ObjIsComplement(pObjAbc)); Vec_PtrWriteEntry( p->pCopy, IvyId, pObjAbc ); }
|
||||
static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) { return Vec_PtrEntry( p->pCopy, IvyId ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Applies PLA/LUT mapping to the ABC network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose )
|
||||
{
|
||||
Pla_Man_t * p;
|
||||
Ivy_Man_t * pMan, * pManExt;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
return NULL;
|
||||
// convert to the new AIG manager
|
||||
pMan = Ivy_ManFromAbc( pNtk );
|
||||
// check the correctness of conversion
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" );
|
||||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
}
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
if ( fRewriting )
|
||||
{
|
||||
// simplify
|
||||
pMan = Ivy_ManResyn0( pManExt = pMan, 1, 0 );
|
||||
Ivy_ManStop( pManExt );
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
if ( fSynthesis )
|
||||
{
|
||||
// simplify
|
||||
pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
|
||||
Ivy_ManStop( pManExt );
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
// perform decomposition
|
||||
if ( fFastMode )
|
||||
{
|
||||
// perform mapping into LUTs
|
||||
Ivy_FastMapPerform( pMan, nLutMax, 1, fVerbose );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkNew = Ivy_ManToAbc( pNtk, pMan, NULL, fFastMode );
|
||||
// pNtkNew = NULL;
|
||||
Ivy_FastMapStop( pMan );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( nLutMax >= 2 && nLutMax <= 8 );
|
||||
// perform decomposition/mapping into PLAs/LUTs
|
||||
p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkNew = Ivy_ManToAbc( pNtk, pMan, p, fFastMode );
|
||||
Pla_ManFree( p );
|
||||
}
|
||||
Ivy_ManStop( pMan );
|
||||
// chech the resulting network
|
||||
if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
// Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.]
|
||||
|
||||
Description [Assumes DFS ordering of nodes in the AIG of ABC.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Ivy_Man_t * pMan;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// create the manager
|
||||
pMan = Ivy_ManStart();
|
||||
// create the PIs
|
||||
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan);
|
||||
// perform the conversion of the internal nodes
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_And( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) );
|
||||
// create the POs
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Ivy_ObjCreatePo( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) );
|
||||
Ivy_ManCleanup( pMan );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the ABC network after mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObjAbc, * pObj;
|
||||
Ivy_Obj_t * pObjIvy;
|
||||
Vec_Int_t * vNodes, * vTemp;
|
||||
int i;
|
||||
// start mapping from Ivy into Abc
|
||||
pMan->pCopy = Vec_PtrStart( Ivy_ManObjIdMax(pMan) + 1 );
|
||||
// start the new ABC network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
// transfer the pointers to the basic nodes
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkCreateNodeConst1(pNtkNew) );
|
||||
Abc_NtkForEachCi( pNtkNew, pObjAbc, i )
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc );
|
||||
// recursively construct the network
|
||||
vNodes = Vec_IntAlloc( 100 );
|
||||
vTemp = Vec_IntAlloc( 100 );
|
||||
Ivy_ManForEachPo( pMan, pObjIvy, i )
|
||||
{
|
||||
// get the new ABC node corresponding to the old fanin of the PO in IVY
|
||||
if ( fFastMode )
|
||||
pObjAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
|
||||
else
|
||||
pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
|
||||
// consider the case of complemented fanin of the PO
|
||||
if ( Ivy_ObjFaninC0(pObjIvy) ) // complement
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObjAbc) )
|
||||
pObjAbc = Abc_NtkCreateNodeInv( pNtkNew, pObjAbc );
|
||||
else
|
||||
{
|
||||
// clone the node
|
||||
pObj = Abc_NtkCloneObj( pObjAbc );
|
||||
// set complemented functions
|
||||
pObj->pData = Abc_SopRegister( pNtkNew->pManFunc, pObjAbc->pData );
|
||||
Abc_SopComplement(pObj->pData);
|
||||
// return the new node
|
||||
pObjAbc = pObj;
|
||||
}
|
||||
assert( Abc_SopGetVarNum(pObjAbc->pData) == Abc_ObjFaninNum(pObjAbc) );
|
||||
}
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), pObjAbc );
|
||||
}
|
||||
Vec_IntFree( vTemp );
|
||||
Vec_IntFree( vNodes );
|
||||
Vec_PtrFree( pMan->pCopy );
|
||||
pMan->pCopy = NULL;
|
||||
// remove dangling nodes
|
||||
// Abc_NtkForEachNode( pNtkNew, pObjAbc, i )
|
||||
// if ( Abc_ObjFanoutNum(pObjAbc) == 0 )
|
||||
// Abc_NtkDeleteObj(pObjAbc);
|
||||
Abc_NtkCleanup( pNtkNew, 0 );
|
||||
// fix CIs feeding directly into COs
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively construct the new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp )
|
||||
{
|
||||
Vec_Int_t * vSupp;
|
||||
Esop_Cube_t * pCover, * pCube;
|
||||
Abc_Obj_t * pObjAbc, * pFaninAbc;
|
||||
Pla_Obj_t * pStr;
|
||||
int Entry, nCubes, i;
|
||||
unsigned * puTruth;
|
||||
// skip the node if it is a constant or already processed
|
||||
pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id );
|
||||
if ( pObjAbc )
|
||||
return pObjAbc;
|
||||
assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) );
|
||||
// get the support and the cover
|
||||
pStr = Ivy_ObjPlaStr( pMan, pObjIvy );
|
||||
if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax )
|
||||
{
|
||||
vSupp = &pStr->vSupp[0];
|
||||
pCover = PLA_EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
vSupp = &pStr->vSupp[1];
|
||||
pCover = pStr->pCover[1];
|
||||
assert( pCover != PLA_EMPTY );
|
||||
}
|
||||
// create new node and its fanins
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ManObj(pMan, Entry), vNodes, vTemp );
|
||||
// consider the case of a LUT
|
||||
if ( pCover == PLA_EMPTY )
|
||||
{
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
Abc_ObjAddFanin( pObjAbc, Abc_ObjGetIvy2Abc(pMan, Entry) );
|
||||
// check if the truth table is constant 0
|
||||
puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
|
||||
// if the function is constant 0, create constant 0 node
|
||||
if ( Extra_TruthIsConst0(puTruth, 8) )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew );
|
||||
}
|
||||
else if ( Extra_TruthIsConst1(puTruth, 8) )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NtkCreateNodeConst1( pNtkNew );
|
||||
}
|
||||
else
|
||||
{
|
||||
int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes, 1 );
|
||||
if ( vNodes->nSize == -1 )
|
||||
printf( "Ivy_ManToAbc_rec(): Internal error.\n" );
|
||||
pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes );
|
||||
if ( fCompl ) Abc_SopComplement(pObjAbc->pData);
|
||||
// printf( "Cover contains %d cubes.\n", Vec_IntSize(vNodes) );
|
||||
// pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// for each cube, construct the node
|
||||
nCubes = Esop_CoverCountCubes( pCover );
|
||||
if ( nCubes == 0 )
|
||||
pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew );
|
||||
else if ( nCubes == 1 )
|
||||
pObjAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCover, vSupp );
|
||||
else
|
||||
{
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pFaninAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCube, vSupp );
|
||||
Abc_ObjAddFanin( pObjAbc, pFaninAbc );
|
||||
}
|
||||
pObjAbc->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc) );
|
||||
}
|
||||
}
|
||||
Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc );
|
||||
return pObjAbc;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp )
|
||||
{
|
||||
int pCompls[PLAYER_FANIN_LIMIT];
|
||||
Abc_Obj_t * pObjAbc, * pFaninAbc;
|
||||
int i, k, Value;
|
||||
// if tautology cube, create constant 1 node
|
||||
if ( pCube->nLits == 0 )
|
||||
return Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
// create AND node
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( i = k = 0; i < (int)pCube->nVars; i++ )
|
||||
{
|
||||
Value = Esop_CubeGetVar( pCube, i );
|
||||
assert( Value != 0 );
|
||||
if ( Value == 3 )
|
||||
continue;
|
||||
pFaninAbc = Abc_ObjGetIvy2Abc( pMan, Vec_IntEntry(vSupp, i) );
|
||||
pFaninAbc = Abc_ObjNotCond( pFaninAbc, Value==1 );
|
||||
Abc_ObjAddFanin( pObjAbc, Abc_ObjRegular(pFaninAbc) );
|
||||
pCompls[k++] = Abc_ObjIsComplement(pFaninAbc);
|
||||
}
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc), pCompls );
|
||||
assert( Abc_ObjFaninNum(pObjAbc) == (int)pCube->nLits );
|
||||
return pObjAbc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively construct the new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp )
|
||||
{
|
||||
Vec_Int_t Supp, * vSupp = &Supp;
|
||||
Abc_Obj_t * pObjAbc, * pFaninAbc;
|
||||
int i, Entry;
|
||||
unsigned * puTruth;
|
||||
// skip the node if it is a constant or already processed
|
||||
pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id );
|
||||
if ( pObjAbc )
|
||||
return pObjAbc;
|
||||
assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) );
|
||||
// get the support of K-LUT
|
||||
Ivy_FastMapReadSupp( pMan, pObjIvy, vSupp );
|
||||
// create new ABC node and its fanins
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFaninAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ManObj(pMan, Entry), vNodes, vTemp );
|
||||
Abc_ObjAddFanin( pObjAbc, pFaninAbc );
|
||||
}
|
||||
// check if the truth table is constant 0
|
||||
puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
|
||||
// if the function is constant 0, create constant 0 node
|
||||
if ( Extra_TruthIsConst0(puTruth, 8) )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew );
|
||||
}
|
||||
else if ( Extra_TruthIsConst1(puTruth, 8) )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NtkCreateNodeConst1( pNtkNew );
|
||||
}
|
||||
else
|
||||
{
|
||||
int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes, 1 );
|
||||
if ( vNodes->nSize == -1 )
|
||||
printf( "Ivy_ManToAbcFast_rec(): Internal error.\n" );
|
||||
pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes );
|
||||
if ( fCompl ) Abc_SopComplement(pObjAbc->pData);
|
||||
}
|
||||
Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc );
|
||||
return pObjAbc;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes cost of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Abc_NodePlayerCost( int nFanins )
|
||||
{
|
||||
if ( nFanins <= 4 )
|
||||
return 1;
|
||||
if ( nFanins <= 6 )
|
||||
return 2;
|
||||
if ( nFanins <= 8 )
|
||||
return 4;
|
||||
if ( nFanins <= 16 )
|
||||
return 8;
|
||||
if ( nFanins <= 32 )
|
||||
return 16;
|
||||
if ( nFanins <= 64 )
|
||||
return 32;
|
||||
if ( nFanins <= 128 )
|
||||
return 64;
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the number of ranks needed for one level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Abc_NtkPlayerCostOneLevel( int nCost, int RankCost )
|
||||
{
|
||||
return (nCost / RankCost) + ((nCost % RankCost) > 0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cost function for the network (number of ranks).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int * pLevelCosts, * pLevelCostsR;
|
||||
int Cost, CostTotal, CostTotalR, nRanksTotal, nRanksTotalR;
|
||||
int nFanins, nLevels, LevelR, i;
|
||||
// compute the reverse levels
|
||||
Abc_NtkStartReverseLevels( pNtk );
|
||||
// compute the costs for each level
|
||||
nLevels = Abc_NtkGetLevelNum( pNtk );
|
||||
pLevelCosts = ALLOC( int, nLevels + 1 );
|
||||
pLevelCostsR = ALLOC( int, nLevels + 1 );
|
||||
memset( pLevelCosts, 0, sizeof(int) * (nLevels + 1) );
|
||||
memset( pLevelCostsR, 0, sizeof(int) * (nLevels + 1) );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
nFanins = Abc_ObjFaninNum(pObj);
|
||||
if ( nFanins == 0 )
|
||||
continue;
|
||||
Cost = Abc_NodePlayerCost( nFanins );
|
||||
LevelR = Vec_IntEntry( pNtk->vLevelsR, pObj->Id );
|
||||
pLevelCosts[ pObj->Level ] += Cost;
|
||||
pLevelCostsR[ LevelR ] += Cost;
|
||||
}
|
||||
// compute the total cost
|
||||
CostTotal = CostTotalR = nRanksTotal = nRanksTotalR = 0;
|
||||
for ( i = 0; i <= nLevels; i++ )
|
||||
{
|
||||
CostTotal += pLevelCosts[i];
|
||||
CostTotalR += pLevelCostsR[i];
|
||||
nRanksTotal += Abc_NtkPlayerCostOneLevel( pLevelCosts[i], RankCost );
|
||||
nRanksTotalR += Abc_NtkPlayerCostOneLevel( pLevelCostsR[i], RankCost );
|
||||
}
|
||||
assert( CostTotal == CostTotalR );
|
||||
// print out statistics
|
||||
if ( fVerbose )
|
||||
{
|
||||
for ( i = 1; i <= nLevels; i++ )
|
||||
{
|
||||
printf( "Level %2d : Cost = %7d. Ranks = %6.3f. Cost = %7d. Ranks = %6.3f.\n", i,
|
||||
pLevelCosts[i], ((double)pLevelCosts[i])/RankCost,
|
||||
pLevelCostsR[nLevels+1-i], ((double)pLevelCostsR[nLevels+1-i])/RankCost );
|
||||
}
|
||||
printf( "TOTAL : Cost = %7d. Ranks = %6d. RanksR = %5d. RanksBest = %5d.\n",
|
||||
CostTotal, nRanksTotal, nRanksTotalR, nLevels );
|
||||
}
|
||||
free( pLevelCosts );
|
||||
free( pLevelCostsR );
|
||||
return nRanksTotal;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerUtil.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLA decomposition package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: playerUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Merges two supports.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp )
|
||||
{
|
||||
int k0, k1;
|
||||
|
||||
assert( vSupp0->nSize && vSupp1->nSize );
|
||||
|
||||
Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 );
|
||||
Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 );
|
||||
Vec_IntClear( p->vPairs0 );
|
||||
Vec_IntClear( p->vPairs1 );
|
||||
|
||||
vSupp->nSize = 0;
|
||||
vSupp->nCap = vSupp0->nSize + vSupp1->nSize;
|
||||
vSupp->pArray = ALLOC( int, vSupp->nCap );
|
||||
|
||||
for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; )
|
||||
{
|
||||
if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
|
||||
Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
|
||||
Vec_IntPush( p->vPairs0, k0 );
|
||||
Vec_IntPush( p->vPairs1, k1 );
|
||||
Vec_IntPush( vSupp, vSupp0->pArray[k0] );
|
||||
k0++; k1++;
|
||||
}
|
||||
else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
|
||||
Vec_IntPush( vSupp, vSupp0->pArray[k0] );
|
||||
k0++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
|
||||
Vec_IntPush( vSupp, vSupp1->pArray[k1] );
|
||||
k1++;
|
||||
}
|
||||
}
|
||||
for ( ; k0 < vSupp0->nSize; k0++ )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
|
||||
Vec_IntPush( vSupp, vSupp0->pArray[k0] );
|
||||
}
|
||||
for ( ; k1 < vSupp1->nSize; k1++ )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
|
||||
Vec_IntPush( vSupp, vSupp1->pArray[k1] );
|
||||
}
|
||||
/*
|
||||
printf( "Zero : " );
|
||||
for ( k = 0; k < vSupp0->nSize; k++ )
|
||||
printf( "%d ", vSupp0->pArray[k] );
|
||||
printf( "\n" );
|
||||
|
||||
printf( "One : " );
|
||||
for ( k = 0; k < vSupp1->nSize; k++ )
|
||||
printf( "%d ", vSupp1->pArray[k] );
|
||||
printf( "\n" );
|
||||
|
||||
printf( "Sum : " );
|
||||
for ( k = 0; k < vSupp->nSize; k++ )
|
||||
printf( "%d ", vSupp->pArray[k] );
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
*/
|
||||
return Vec_IntSize(vSupp);
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the produce of two covers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit )
|
||||
{
|
||||
Esop_Cube_t * pCube, * pCube0, * pCube1;
|
||||
Esop_Cube_t * pCover;
|
||||
int i, Val0, Val1;
|
||||
assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY );
|
||||
|
||||
// clean storage
|
||||
assert( nSupp <= p->nPlaMax );
|
||||
Esop_ManClean( p->pManMin, nSupp );
|
||||
// go through the cube pairs
|
||||
Esop_CoverForEachCube( pCover0, pCube0 )
|
||||
Esop_CoverForEachCube( pCover1, pCube1 )
|
||||
{
|
||||
// go through the support variables of the cubes
|
||||
for ( i = 0; i < p->vPairs0->nSize; i++ )
|
||||
{
|
||||
Val0 = Esop_CubeGetVar( pCube0, p->vPairs0->pArray[i] );
|
||||
Val1 = Esop_CubeGetVar( pCube1, p->vPairs1->pArray[i] );
|
||||
if ( (Val0 & Val1) == 0 )
|
||||
break;
|
||||
}
|
||||
// check disjointness
|
||||
if ( i < p->vPairs0->nSize )
|
||||
continue;
|
||||
|
||||
if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax )
|
||||
{
|
||||
pCover = Esop_CoverCollect( p->pManMin, nSupp );
|
||||
//Esop_CoverWriteFile( pCover, "large", 1 );
|
||||
Esop_CoverRecycle( p->pManMin, pCover );
|
||||
return PLA_EMPTY;
|
||||
}
|
||||
|
||||
// create the product cube
|
||||
pCube = Esop_CubeAlloc( p->pManMin );
|
||||
|
||||
// add the literals
|
||||
pCube->nLits = 0;
|
||||
for ( i = 0; i < nSupp; i++ )
|
||||
{
|
||||
if ( p->vComTo0->pArray[i] == -1 )
|
||||
Val0 = 3;
|
||||
else
|
||||
Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
|
||||
|
||||
if ( p->vComTo1->pArray[i] == -1 )
|
||||
Val1 = 3;
|
||||
else
|
||||
Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
|
||||
|
||||
if ( (Val0 & Val1) == 3 )
|
||||
continue;
|
||||
|
||||
Esop_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 );
|
||||
pCube->nLits++;
|
||||
}
|
||||
// add the cube to storage
|
||||
Esop_EsopAddCube( p->pManMin, pCube );
|
||||
}
|
||||
|
||||
// minimize the cover
|
||||
Esop_EsopMinimize( p->pManMin );
|
||||
pCover = Esop_CoverCollect( p->pManMin, nSupp );
|
||||
|
||||
// quit if the cover is too large
|
||||
if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax )
|
||||
{
|
||||
Esop_CoverRecycle( p->pManMin, pCover );
|
||||
return PLA_EMPTY;
|
||||
}
|
||||
// if ( pCover && pCover->nWords > 4 )
|
||||
// printf( "%d", pCover->nWords );
|
||||
// else
|
||||
// printf( "." );
|
||||
return pCover;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the EXOR of two covers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit )
|
||||
{
|
||||
Esop_Cube_t * pCube, * pCube0, * pCube1;
|
||||
Esop_Cube_t * pCover;
|
||||
int i, Val0, Val1;
|
||||
assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY );
|
||||
|
||||
// clean storage
|
||||
assert( nSupp <= p->nPlaMax );
|
||||
Esop_ManClean( p->pManMin, nSupp );
|
||||
Esop_CoverForEachCube( pCover0, pCube0 )
|
||||
{
|
||||
// create the cube
|
||||
pCube = Esop_CubeAlloc( p->pManMin );
|
||||
pCube->nLits = 0;
|
||||
for ( i = 0; i < p->vComTo0->nSize; i++ )
|
||||
{
|
||||
if ( p->vComTo0->pArray[i] == -1 )
|
||||
continue;
|
||||
Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
|
||||
if ( Val0 == 3 )
|
||||
continue;
|
||||
Esop_CubeXorVar( pCube, i, Val0 ^ 3 );
|
||||
pCube->nLits++;
|
||||
}
|
||||
if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax )
|
||||
{
|
||||
pCover = Esop_CoverCollect( p->pManMin, nSupp );
|
||||
Esop_CoverRecycle( p->pManMin, pCover );
|
||||
return PLA_EMPTY;
|
||||
}
|
||||
// add the cube to storage
|
||||
Esop_EsopAddCube( p->pManMin, pCube );
|
||||
}
|
||||
Esop_CoverForEachCube( pCover1, pCube1 )
|
||||
{
|
||||
// create the cube
|
||||
pCube = Esop_CubeAlloc( p->pManMin );
|
||||
pCube->nLits = 0;
|
||||
for ( i = 0; i < p->vComTo1->nSize; i++ )
|
||||
{
|
||||
if ( p->vComTo1->pArray[i] == -1 )
|
||||
continue;
|
||||
Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
|
||||
if ( Val1 == 3 )
|
||||
continue;
|
||||
Esop_CubeXorVar( pCube, i, Val1 ^ 3 );
|
||||
pCube->nLits++;
|
||||
}
|
||||
if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax )
|
||||
{
|
||||
pCover = Esop_CoverCollect( p->pManMin, nSupp );
|
||||
Esop_CoverRecycle( p->pManMin, pCover );
|
||||
return PLA_EMPTY;
|
||||
}
|
||||
// add the cube to storage
|
||||
Esop_EsopAddCube( p->pManMin, pCube );
|
||||
}
|
||||
|
||||
// minimize the cover
|
||||
Esop_EsopMinimize( p->pManMin );
|
||||
pCover = Esop_CoverCollect( p->pManMin, nSupp );
|
||||
|
||||
// quit if the cover is too large
|
||||
if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax )
|
||||
{
|
||||
Esop_CoverRecycle( p->pManMin, pCover );
|
||||
return PLA_EMPTY;
|
||||
}
|
||||
return pCover;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area/delay of the mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )
|
||||
{
|
||||
Ivy_Obj_t * pObj, * pFanin;
|
||||
Vec_Int_t * vFanins;
|
||||
int Area, Delay, Fanin, nFanins, i, k;
|
||||
|
||||
Delay = Area = 0;
|
||||
// compute levels and area
|
||||
Ivy_ManForEachPi( p, pObj, i )
|
||||
pObj->Level = 0;
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
|
||||
{
|
||||
// compute level of the node
|
||||
pObj->Level = 0;
|
||||
vFanins = Ivy_ObjGetFanins( pObj );
|
||||
Vec_IntForEachEntry( vFanins, Fanin, k )
|
||||
{
|
||||
pFanin = Ivy_ManObj(p, Ivy_EdgeId(Fanin));
|
||||
pObj->Level = IVY_MAX( pObj->Level, pFanin->Level );
|
||||
}
|
||||
pObj->Level += 1;
|
||||
// compute area of the node
|
||||
nFanins = Ivy_ObjFaninNum( pObj );
|
||||
if ( nFanins <= 4 )
|
||||
Area += 1;
|
||||
else if ( nFanins <= 6 )
|
||||
Area += 2;
|
||||
else if ( nFanins <= 8 )
|
||||
Area += 4;
|
||||
else if ( nFanins <= 16 )
|
||||
Area += 8;
|
||||
else if ( nFanins <= 32 )
|
||||
Area += 16;
|
||||
else if ( nFanins <= 64 )
|
||||
Area += 32;
|
||||
else if ( nFanins <= 128 )
|
||||
Area += 64;
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
Fanin = Ivy_ObjReadFanin(pObj, 0);
|
||||
pFanin = Ivy_ManObj( p, Ivy_EdgeId(Fanin) );
|
||||
pObj->Level = pFanin->Level;
|
||||
Delay = IVY_MAX( Delay, (int)pObj->Level );
|
||||
}
|
||||
printf( "Area = %d. Delay = %d.\n", Area, Delay );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -111,10 +111,10 @@ struct Rwt_Node_t_ // 24 bytes
|
|||
};
|
||||
|
||||
// manipulation of complemented attributes
|
||||
static inline int Rwt_IsComplement( Rwt_Node_t * p ) { return (int)(((unsigned)p) & 01); }
|
||||
static inline Rwt_Node_t * Rwt_Regular( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned)(p) & ~01); }
|
||||
static inline Rwt_Node_t * Rwt_Not( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned)(p) ^ 01); }
|
||||
static inline Rwt_Node_t * Rwt_NotCond( Rwt_Node_t * p, int c ) { return (Rwt_Node_t *)((unsigned)(p) ^ (c)); }
|
||||
static inline int Rwt_IsComplement( Rwt_Node_t * p ) { return (int)(((unsigned long)p) & 01); }
|
||||
static inline Rwt_Node_t * Rwt_Regular( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned long)(p) & ~01); }
|
||||
static inline Rwt_Node_t * Rwt_Not( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned long)(p) ^ 01); }
|
||||
static inline Rwt_Node_t * Rwt_NotCond( Rwt_Node_t * p, int c ) { return (Rwt_Node_t *)((unsigned long)(p) ^ (c)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
|
|
|
|||
|
|
@ -387,13 +387,13 @@ int Ver_ParseModule( Ver_Man_t * pMan )
|
|||
if ( Abc_ObjFanoutNum(pNet) == 0 )
|
||||
Abc_NtkDeleteObj(pNet);
|
||||
else
|
||||
Abc_ObjAddFanin( pNet, Abc_NodeCreateConst0(pNtk) );
|
||||
Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst0(pNtk) );
|
||||
// check if constant 1 net is used
|
||||
pNet = Abc_NtkFindOrCreateNet( pNtk, "1'b1" );
|
||||
if ( Abc_ObjFanoutNum(pNet) == 0 )
|
||||
Abc_NtkDeleteObj(pNet);
|
||||
else
|
||||
Abc_ObjAddFanin( pNet, Abc_NodeCreateConst1(pNtk) );
|
||||
Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst1(pNtk) );
|
||||
|
||||
// fix the dangling nets
|
||||
Abc_NtkFinalizeRead( pNtk );
|
||||
|
|
|
|||
Loading…
Reference in New Issue