Version abc61102

This commit is contained in:
Alan Mishchenko 2006-11-02 08:01:00 -08:00
parent 73bb7932f7
commit faf1265bb8
100 changed files with 13679 additions and 366 deletions

View File

@ -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
View File

@ -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
View File

@ -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"

View File

@ -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 );

View File

@ -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 )

View File

@ -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

View File

@ -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

View File

@ -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 ///

View 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 )

View File

@ -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

View File

@ -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*************************************************************

View File

@ -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 );
}

View File

@ -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

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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;
}

115
src/base/abci/abcBmc.c Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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 );

View File

@ -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 )

View File

@ -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

View File

@ -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;
}
////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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

164
src/base/abci/abcXsim.c Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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

View File

@ -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;

View File

@ -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" );
}

View File

@ -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 );
}

View File

@ -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 ///

View File

@ -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))
////////////////////////////////////////////////////////////////////////

View File

@ -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)

View File

@ -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)

View File

@ -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 ///

View File

@ -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)

View File

@ -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 ) \

View File

@ -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 : "" );

View File

@ -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

8
src/opt/ret/module.make Normal file
View File

@ -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

593
src/opt/ret/retArea.c Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

65
src/opt/ret/retBwd.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

76
src/opt/ret/retCore.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

65
src/opt/ret/retDelay.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

462
src/opt/ret/retFlow.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

65
src/opt/ret/retFwd.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

71
src/opt/ret/retInit.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

68
src/opt/ret/retInt.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

48
src/opt/ret/ret_.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///

View File

@ -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)

BIN
src/temp/aig-alan.tar.gz Normal file

Binary file not shown.

View File

@ -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; }

View File

@ -17,7 +17,7 @@
Revision [$Id: aigBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////

View File

@ -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.]

View File

@ -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 );

321
src/temp/aig_free/aig.h Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

399
src/temp/aig_free/aigDfs.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

162
src/temp/aig_free/aigMan.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

115
src/temp/aig_free/aigMem.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

228
src/temp/aig_free/aigObj.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

373
src/temp/aig_free/aigOper.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 &gt;= 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 ///
////////////////////////////////////////////////////////////////////////

513
src/temp/aig_free/aigUtil.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

375
src/temp/aig_free/cudd2.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

83
src/temp/aig_free/cudd2.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

626
src/temp/aig_free/st.c Normal file
View 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);
}

96
src/temp/aig_free/st.h Normal file
View File

@ -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 */

View File

@ -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 ' '

82
src/temp/aig_free/vec.h Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

667
src/temp/aig_free/vecFlt.h Normal file
View 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

781
src/temp/aig_free/vecInt.h Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

587
src/temp/aig_free/vecPtr.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

510
src/temp/aig_free/vecStr.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

289
src/temp/aig_free/vecVec.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

723
src/temp/esop/esop.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

117
src/temp/esop/esopMan.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

299
src/temp/esop/esopMin.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

277
src/temp/esop/esopUtil.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,3 @@
SRC += src/temp/esop/esopMan.c \
src/temp/esop/esopMin.c \
src/temp/esop/esopUtil.c

View File

@ -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

View File

@ -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;

View File

@ -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 );
}

View File

@ -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

View File

@ -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 );
}

View File

@ -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

View File

@ -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" );
}

View File

@ -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

113
src/temp/player/player.h Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

228
src/temp/player/playerAbc.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

125
src/temp/player/playerMan.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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 ///

View File

@ -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 );