mirror of https://github.com/YosysHQ/abc.git
Version abc60701
This commit is contained in:
parent
3814121784
commit
616bb095f1
66
abc.dsp
66
abc.dsp
|
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\aig" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\temp\ivy" /I "src\temp\esop" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\aig" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\temp\ivy" /I "src\temp\esop" /I "src\temp\rwt" /I "src\temp\deco" /I "src\temp\mem" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
@ -50,7 +50,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"_TEST/abc.exe"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /machine:I386 /out:"_TEST/abc.exe"
|
||||
|
||||
!ELSEIF "$(CFG)" == "abc - Win32 Debug"
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\aig" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\temp\ivy" /I "src\temp\esop" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\aig" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\temp\ivy" /I "src\temp\esop" /I "src\temp\rwt" /I "src\temp\deco" /I "src\temp\mem" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
|
||||
# SUBTRACT CPP /X
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
|
|
@ -2114,6 +2114,10 @@ SOURCE=.\src\temp\ivy\ivyMulti.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyMulti8.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyObj.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2122,10 +2126,22 @@ SOURCE=.\src\temp\ivy\ivyOper.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyResyn.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyRewrite.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyRwrAlg.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyRwrPre.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivySeq.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2182,10 +2198,6 @@ SOURCE=.\src\temp\esop\esopMan.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\esop\esopMem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\esop\esopMin.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2237,6 +2249,46 @@ SOURCE=.\src\temp\xyz\xyzMinUtil.c
|
|||
SOURCE=.\src\temp\xyz\xyzTest.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "rwt"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\rwt\rwt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\rwt\rwtDec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\rwt\rwtMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\rwt\rwtUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "deco"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\deco\deco.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "mem"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\mem\mem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\mem\mem.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
|
|
|||
|
|
@ -4647,9 +4647,11 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// Ivy_TruthTest();
|
||||
|
||||
|
||||
pNtkRes = Abc_NtkIvy( pNtk );
|
||||
Ivy_TruthEstimateNodesTest();
|
||||
|
||||
// pNtkRes = Abc_NtkIvy( pNtk );
|
||||
// pNtkRes = Abc_NtkPlayer( pNtk, nLevels, 0 );
|
||||
// pNtkRes = NULL;
|
||||
pNtkRes = NULL;
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
|||
Vec_PtrFree( vNodes );
|
||||
Vec_IntFree( vChoices );
|
||||
PRT( "Total", clock() - clk );
|
||||
//Abc_NtkPrintCuts_( p, pNtk, 0 );
|
||||
//Abc_NtkPrintCuts( p, pNtk, 0 );
|
||||
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
|
||||
|
||||
// temporary printout of stats
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ extern char * Mio_GateReadSop( void * pGate );
|
|||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Ivy_Man_t * pMan;
|
||||
Ivy_Man_t * pMan, * pTemp = NULL;
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
int fCleanup = 1;
|
||||
int nNodes;
|
||||
|
|
@ -74,7 +74,6 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
|
||||
// convert to the AIG manager
|
||||
pMan = Abc_NtkToAig( pNtk );
|
||||
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
{
|
||||
printf( "AIG check has failed.\n" );
|
||||
|
|
@ -82,13 +81,29 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Ivy_MffcTest( pMan );
|
||||
Ivy_ManPrintStats( pMan );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// pMan = Ivy_ManBalance( pTemp = pMan, 1 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
|
||||
// Ivy_ManSeqRewrite( pMan, 0, 0 );
|
||||
// Ivy_ManTestCutsAlg( pMan );
|
||||
Ivy_ManTestCutsBool( pMan );
|
||||
Ivy_ManPrintStats( pMan );
|
||||
// Ivy_ManTestCutsBool( pMan );
|
||||
// Ivy_ManRewriteAlg( pMan, 1, 1 );
|
||||
|
||||
// pMan = Ivy_ManResyn( pTemp = pMan, 1 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
|
||||
// Ivy_ManTestCutsAll( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
// Ivy_ManRewritePre( pMan, 1, 0, 0 );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRequiredLevels( pMan );
|
||||
|
||||
// convert from the AIG manager
|
||||
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
|
||||
|
|
@ -191,9 +206,9 @@ Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld )
|
|||
// create the manager
|
||||
assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkHasAig(pNtkOld) );
|
||||
if ( Abc_NtkHasSop(pNtkOld) )
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), 3 * Abc_NtkGetLitNum(pNtkOld) + 10 );
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), Abc_NtkGetLitNum(pNtkOld) + 1000 );
|
||||
else
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), 3 * Abc_NtkNodeNum(pNtkOld) + 10 );
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), Abc_NtkNodeNum(pNtkOld) + 1000 );
|
||||
// create the PIs
|
||||
Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
|
||||
Abc_NtkForEachCi( pNtkOld, pObj, i )
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
// print the statistic into a file
|
||||
{
|
||||
FILE * pTable;
|
||||
|
|
@ -146,6 +146,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// print the statistic into a file
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "stdio.h"
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "stdio.h"
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
#include "vec.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "stdio.h"
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
|
|||
***********************************************************************/
|
||||
static inline int Vec_IntEntryLast( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
|
|||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
|
|||
***********************************************************************/
|
||||
static inline char Vec_StrEntryLast( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ struct Vec_Vec_t_
|
|||
#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 ///
|
||||
|
|
|
|||
|
|
@ -102,6 +102,36 @@ static inline void Cut_CutFilter( Cut_Man_t * p, Cut_Cut_t * pList )
|
|||
*ppListR = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks equality of one cut.]
|
||||
|
||||
Description [Returns 1 if the cut is removed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Cut_CutFilterOneEqual( Cut_Man_t * p, Cut_List_t * pSuperList, Cut_Cut_t * pCut )
|
||||
{
|
||||
Cut_Cut_t * pTemp;
|
||||
Cut_ListForEachCut( pSuperList->pHead[pCut->nLeaves], pTemp )
|
||||
{
|
||||
// skip the non-contained cuts
|
||||
if ( pCut->uSign != pTemp->uSign )
|
||||
continue;
|
||||
// check containment seriously
|
||||
if ( Cut_CutCheckDominance( pTemp, pCut ) )
|
||||
{
|
||||
p->nCutsFilter++;
|
||||
Cut_CutRecycle( p, pCut );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks containment for one cut.]
|
||||
|
|
@ -266,6 +296,7 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
|
|||
if ( p->pParams->fFilter )
|
||||
{
|
||||
if ( Cut_CutFilterOne(p, pSuperList, pCut) )
|
||||
// if ( Cut_CutFilterOneEqual(p, pSuperList, pCut) )
|
||||
return 0;
|
||||
if ( p->pParams->fSeq )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest );
|
||||
static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -64,6 +65,7 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int
|
|||
p->nNodesConsidered++;
|
||||
// get the required times
|
||||
Required = fUpdateLevel? Abc_NodeReadRequiredLevel(pNode) : ABC_INFINITY;
|
||||
|
||||
// get the node's cuts
|
||||
clk = clock();
|
||||
pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
|
||||
|
|
@ -77,6 +79,9 @@ clk = clock();
|
|||
// consider only 4-input cuts
|
||||
if ( pCut->nLeaves < 4 )
|
||||
continue;
|
||||
// if ( pNode->Id == 82 )
|
||||
// Cut_CutPrint( pCut, 0 ), printf( "\n" );
|
||||
|
||||
// get the fanin permutation
|
||||
uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
|
||||
pPerm = p->pPerms4[ p->pPerms[uTruth] ];
|
||||
|
|
@ -144,6 +149,27 @@ p->timeRes += clock() - clk;
|
|||
return -1;
|
||||
|
||||
// printf( "%d", nNodesSaveCur - GainBest );
|
||||
/*
|
||||
if ( GainBest > 0 )
|
||||
{
|
||||
if ( Rwr_CutIsBoolean( pNode, p->vFanins ) )
|
||||
printf( "b" );
|
||||
else
|
||||
{
|
||||
printf( "Node %d : ", pNode->Id );
|
||||
Vec_PtrForEachEntry( p->vFanins, pFanin, i )
|
||||
printf( "%d ", Abc_ObjRegular(pFanin)->Id );
|
||||
printf( "a" );
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ( GainBest > 0 )
|
||||
if ( p->fCompl )
|
||||
printf( "c" );
|
||||
else
|
||||
printf( "." );
|
||||
*/
|
||||
|
||||
// copy the leaves
|
||||
Vec_PtrForEachEntry( p->vFanins, pFanin, i )
|
||||
|
|
@ -221,6 +247,65 @@ Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCu
|
|||
return pGraphBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the type of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_CutIsBoolean_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, int fMarkA )
|
||||
{
|
||||
if ( Vec_PtrFind(vLeaves, pObj) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pObj)) >= 0 )
|
||||
{
|
||||
if ( fMarkA )
|
||||
pObj->fMarkA = 1;
|
||||
else
|
||||
pObj->fMarkB = 1;
|
||||
return;
|
||||
}
|
||||
assert( !Abc_ObjIsCi(pObj) );
|
||||
Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, fMarkA );
|
||||
Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, fMarkA );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the type of the cut.]
|
||||
|
||||
Description [Returns 1(0) if the cut is Boolean (algebraic).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
Abc_Obj_t * pTemp;
|
||||
int i, RetValue;
|
||||
Vec_PtrForEachEntry( vLeaves, pTemp, i )
|
||||
{
|
||||
pTemp = Abc_ObjRegular(pTemp);
|
||||
assert( !pTemp->fMarkA && !pTemp->fMarkB );
|
||||
}
|
||||
Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, 1 );
|
||||
Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, 0 );
|
||||
RetValue = 0;
|
||||
Vec_PtrForEachEntry( vLeaves, pTemp, i )
|
||||
{
|
||||
pTemp = Abc_ObjRegular(pTemp);
|
||||
RetValue |= pTemp->fMarkA && pTemp->fMarkB;
|
||||
pTemp->fMarkA = pTemp->fMarkB = 0;
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,699 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [deco.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [A simple decomposition tree/node data structure and its APIs.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: deco.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __DEC_H__
|
||||
#define __DEC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Dec_Edge_t_ Dec_Edge_t;
|
||||
struct Dec_Edge_t_
|
||||
{
|
||||
unsigned fCompl : 1; // the complemented bit
|
||||
unsigned Node : 30; // the decomposition node pointed by the edge
|
||||
};
|
||||
|
||||
typedef struct Dec_Node_t_ Dec_Node_t;
|
||||
struct Dec_Node_t_
|
||||
{
|
||||
Dec_Edge_t eEdge0; // the left child of the node
|
||||
Dec_Edge_t eEdge1; // the right child of the node
|
||||
// other info
|
||||
void * pFunc; // the function of the node (BDD or AIG)
|
||||
unsigned Level : 16; // the level of this node in the global AIG
|
||||
// printing info
|
||||
unsigned fNodeOr : 1; // marks the original OR node
|
||||
unsigned fCompl0 : 1; // marks the original complemented edge
|
||||
unsigned fCompl1 : 1; // marks the original complemented edge
|
||||
};
|
||||
|
||||
typedef struct Dec_Graph_t_ Dec_Graph_t;
|
||||
struct Dec_Graph_t_
|
||||
{
|
||||
int fConst; // marks the constant 1 graph
|
||||
int nLeaves; // the number of leaves
|
||||
int nSize; // the number of nodes (including the leaves)
|
||||
int nCap; // the number of allocated nodes
|
||||
Dec_Node_t * pNodes; // the array of leaves and internal nodes
|
||||
Dec_Edge_t eRoot; // the pointer to the topmost node
|
||||
};
|
||||
|
||||
typedef struct Dec_Man_t_ Dec_Man_t;
|
||||
struct Dec_Man_t_
|
||||
{
|
||||
void * pMvcMem; // memory manager for MVC cover (used for factoring)
|
||||
Vec_Int_t * vCubes; // storage for cubes
|
||||
Vec_Int_t * vLits; // storage for literals
|
||||
// precomputation information about 4-variable functions
|
||||
unsigned short * puCanons; // canonical forms
|
||||
char * pPhases; // canonical phases
|
||||
char * pPerms; // canonical permutations
|
||||
unsigned char * pMap; // mapping of functions into class numbers
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// interator throught the leaves
|
||||
#define Dec_GraphForEachLeaf( pGraph, pLeaf, i ) \
|
||||
for ( i = 0; (i < (pGraph)->nLeaves) && (((pLeaf) = Dec_GraphNode(pGraph, i)), 1); i++ )
|
||||
// interator throught the internal nodes
|
||||
#define Dec_GraphForEachNode( pGraph, pAnd, i ) \
|
||||
for ( i = (pGraph)->nLeaves; (i < (pGraph)->nSize) && (((pAnd) = Dec_GraphNode(pGraph, i)), 1); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an edge pointing to the node in the given polarity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_EdgeCreate( int Node, int fCompl )
|
||||
{
|
||||
Dec_Edge_t eEdge = { fCompl, Node };
|
||||
return eEdge;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the edge into unsigned integer.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Dec_EdgeToInt( Dec_Edge_t eEdge )
|
||||
{
|
||||
return (eEdge.Node << 1) | eEdge.fCompl;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts unsigned integer into the edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_IntToEdge( unsigned Edge )
|
||||
{
|
||||
return Dec_EdgeCreate( Edge >> 1, Edge & 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the edge into unsigned integer.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Dec_EdgeToInt_( Dec_Edge_t eEdge )
|
||||
{
|
||||
return *(unsigned *)&eEdge;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts unsigned integer into the edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_IntToEdge_( unsigned Edge )
|
||||
{
|
||||
return *(Dec_Edge_t *)&Edge;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a graph with the given number of leaves.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Graph_t * Dec_GraphCreate( int nLeaves )
|
||||
{
|
||||
Dec_Graph_t * pGraph;
|
||||
pGraph = ALLOC( Dec_Graph_t, 1 );
|
||||
memset( pGraph, 0, sizeof(Dec_Graph_t) );
|
||||
pGraph->nLeaves = nLeaves;
|
||||
pGraph->nSize = nLeaves;
|
||||
pGraph->nCap = 2 * nLeaves + 50;
|
||||
pGraph->pNodes = ALLOC( Dec_Node_t, pGraph->nCap );
|
||||
memset( pGraph->pNodes, 0, sizeof(Dec_Node_t) * pGraph->nSize );
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates constant 0 graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Graph_t * Dec_GraphCreateConst0()
|
||||
{
|
||||
Dec_Graph_t * pGraph;
|
||||
pGraph = ALLOC( Dec_Graph_t, 1 );
|
||||
memset( pGraph, 0, sizeof(Dec_Graph_t) );
|
||||
pGraph->fConst = 1;
|
||||
pGraph->eRoot.fCompl = 1;
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates constant 1 graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Graph_t * Dec_GraphCreateConst1()
|
||||
{
|
||||
Dec_Graph_t * pGraph;
|
||||
pGraph = ALLOC( Dec_Graph_t, 1 );
|
||||
memset( pGraph, 0, sizeof(Dec_Graph_t) );
|
||||
pGraph->fConst = 1;
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the literal graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Graph_t * Dec_GraphCreateLeaf( int iLeaf, int nLeaves, int fCompl )
|
||||
{
|
||||
Dec_Graph_t * pGraph;
|
||||
assert( 0 <= iLeaf && iLeaf < nLeaves );
|
||||
pGraph = Dec_GraphCreate( nLeaves );
|
||||
pGraph->eRoot.Node = iLeaf;
|
||||
pGraph->eRoot.fCompl = fCompl;
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a graph with the given number of leaves.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Dec_GraphFree( Dec_Graph_t * pGraph )
|
||||
{
|
||||
FREE( pGraph->pNodes );
|
||||
free( pGraph );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the graph is a constant.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphIsConst( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->fConst;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the graph is constant 0.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphIsConst0( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->fConst && pGraph->eRoot.fCompl;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the graph is constant 1.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphIsConst1( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->fConst && !pGraph->eRoot.fCompl;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the graph is complemented.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphIsComplement( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->eRoot.fCompl;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the graph is complemented.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Dec_GraphComplement( Dec_Graph_t * pGraph )
|
||||
{
|
||||
pGraph->eRoot.fCompl ^= 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of leaves.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphLeaveNum( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->nLeaves;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of internal nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphNodeNum( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->nSize - pGraph->nLeaves;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the pointer to the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Node_t * Dec_GraphNode( Dec_Graph_t * pGraph, int i )
|
||||
{
|
||||
return pGraph->pNodes + i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the pointer to the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Node_t * Dec_GraphNodeLast( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->pNodes + pGraph->nSize - 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of the given node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphNodeInt( Dec_Graph_t * pGraph, Dec_Node_t * pNode )
|
||||
{
|
||||
return pNode - pGraph->pNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the graph represents elementary variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphIsVar( Dec_Graph_t * pGraph )
|
||||
{
|
||||
return pGraph->eRoot.Node < (unsigned)pGraph->nLeaves;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the graph represents elementary variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphNodeIsVar( Dec_Graph_t * pGraph, Dec_Node_t * pNode )
|
||||
{
|
||||
return Dec_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the elementary variable elementary variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Node_t * Dec_GraphVar( Dec_Graph_t * pGraph )
|
||||
{
|
||||
assert( Dec_GraphIsVar( pGraph ) );
|
||||
return Dec_GraphNode( pGraph, pGraph->eRoot.Node );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of the elementary variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Dec_GraphVarInt( Dec_Graph_t * pGraph )
|
||||
{
|
||||
assert( Dec_GraphIsVar( pGraph ) );
|
||||
return Dec_GraphNodeInt( pGraph, Dec_GraphVar(pGraph) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the root of the graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Dec_GraphSetRoot( Dec_Graph_t * pGraph, Dec_Edge_t eRoot )
|
||||
{
|
||||
pGraph->eRoot = eRoot;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Appends a new node to the graph.]
|
||||
|
||||
Description [This procedure is meant for internal use.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Node_t * Dec_GraphAppendNode( Dec_Graph_t * pGraph )
|
||||
{
|
||||
Dec_Node_t * pNode;
|
||||
if ( pGraph->nSize == pGraph->nCap )
|
||||
{
|
||||
pGraph->pNodes = REALLOC( Dec_Node_t, pGraph->pNodes, 2 * pGraph->nCap );
|
||||
pGraph->nCap = 2 * pGraph->nCap;
|
||||
}
|
||||
pNode = pGraph->pNodes + pGraph->nSize++;
|
||||
memset( pNode, 0, sizeof(Dec_Node_t) );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an AND node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_GraphAddNodeAnd( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 )
|
||||
{
|
||||
Dec_Node_t * pNode;
|
||||
// get the new node
|
||||
pNode = Dec_GraphAppendNode( pGraph );
|
||||
// set the inputs and other info
|
||||
pNode->eEdge0 = eEdge0;
|
||||
pNode->eEdge1 = eEdge1;
|
||||
pNode->fCompl0 = eEdge0.fCompl;
|
||||
pNode->fCompl1 = eEdge1.fCompl;
|
||||
return Dec_EdgeCreate( pGraph->nSize - 1, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an OR node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_GraphAddNodeOr( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 )
|
||||
{
|
||||
Dec_Node_t * pNode;
|
||||
// get the new node
|
||||
pNode = Dec_GraphAppendNode( pGraph );
|
||||
// set the inputs and other info
|
||||
pNode->eEdge0 = eEdge0;
|
||||
pNode->eEdge1 = eEdge1;
|
||||
pNode->fCompl0 = eEdge0.fCompl;
|
||||
pNode->fCompl1 = eEdge1.fCompl;
|
||||
// make adjustments for the OR gate
|
||||
pNode->fNodeOr = 1;
|
||||
pNode->eEdge0.fCompl = !pNode->eEdge0.fCompl;
|
||||
pNode->eEdge1.fCompl = !pNode->eEdge1.fCompl;
|
||||
return Dec_EdgeCreate( pGraph->nSize - 1, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an XOR node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_GraphAddNodeXor( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1, int Type )
|
||||
{
|
||||
Dec_Edge_t eNode0, eNode1, eNode;
|
||||
if ( Type == 0 )
|
||||
{
|
||||
// derive the first AND
|
||||
eEdge0.fCompl ^= 1;
|
||||
eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
eEdge0.fCompl ^= 1;
|
||||
// derive the second AND
|
||||
eEdge1.fCompl ^= 1;
|
||||
eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
// derive the final OR
|
||||
eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// derive the first AND
|
||||
eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
// derive the second AND
|
||||
eEdge0.fCompl ^= 1;
|
||||
eEdge1.fCompl ^= 1;
|
||||
eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
// derive the final OR
|
||||
eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
eNode.fCompl ^= 1;
|
||||
}
|
||||
return eNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an XOR node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Dec_Edge_t Dec_GraphAddNodeMux( Dec_Graph_t * pGraph, Dec_Edge_t eEdgeC, Dec_Edge_t eEdgeT, Dec_Edge_t eEdgeE, int Type )
|
||||
{
|
||||
Dec_Edge_t eNode0, eNode1, eNode;
|
||||
if ( Type == 0 )
|
||||
{
|
||||
// derive the first AND
|
||||
eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT );
|
||||
// derive the second AND
|
||||
eEdgeC.fCompl ^= 1;
|
||||
eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE );
|
||||
// derive the final OR
|
||||
eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// complement the arguments
|
||||
eEdgeT.fCompl ^= 1;
|
||||
eEdgeE.fCompl ^= 1;
|
||||
// derive the first AND
|
||||
eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT );
|
||||
// derive the second AND
|
||||
eEdgeC.fCompl ^= 1;
|
||||
eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE );
|
||||
// derive the final OR
|
||||
eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
eNode.fCompl ^= 1;
|
||||
}
|
||||
return eNode;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
SRC +=
|
||||
|
|
@ -25,8 +25,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdio.h"
|
||||
#include <stdio.h>
|
||||
#include "vec.h"
|
||||
#include "mem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -34,16 +35,16 @@ extern "C" {
|
|||
|
||||
typedef struct Esop_Man_t_ Esop_Man_t;
|
||||
typedef struct Esop_Cube_t_ Esop_Cube_t;
|
||||
typedef struct Esop_MmFixed_t_ Esop_MmFixed_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
|
||||
Esop_MmFixed_t * pMemMan1; // memory manager for cubes
|
||||
Esop_MmFixed_t * pMemMan2; // memory manager for cubes
|
||||
Esop_MmFixed_t * pMemMan4; // memory manager for cubes
|
||||
Esop_MmFixed_t * pMemMan8; // memory manager for cubes
|
||||
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
|
||||
|
|
@ -99,12 +100,12 @@ static inline void Esop_CubeXorVar( Esop_Cube_t * p, int Var, int Value ) { p-
|
|||
static inline int Esop_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
|
||||
|
||||
/*=== esopMem.c ===========================================================*/
|
||||
extern Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize );
|
||||
extern void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose );
|
||||
extern char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p );
|
||||
extern void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry );
|
||||
extern void Esop_MmFixedRestart( Esop_MmFixed_t * p );
|
||||
extern int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p );
|
||||
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 );
|
||||
|
|
@ -142,13 +143,13 @@ static inline Esop_Cube_t * Esop_CubeAlloc( Esop_Man_t * p )
|
|||
{
|
||||
Esop_Cube_t * pCube;
|
||||
if ( p->nWords <= 1 )
|
||||
pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan1 );
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan1 );
|
||||
else if ( p->nWords <= 2 )
|
||||
pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan2 );
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan2 );
|
||||
else if ( p->nWords <= 4 )
|
||||
pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan4 );
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan4 );
|
||||
else if ( p->nWords <= 8 )
|
||||
pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan8 );
|
||||
pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan8 );
|
||||
pCube->pNext = NULL;
|
||||
pCube->nVars = p->nVars;
|
||||
pCube->nWords = p->nWords;
|
||||
|
|
@ -211,13 +212,13 @@ static inline Esop_Cube_t * Esop_CubeDup( Esop_Man_t * p, Esop_Cube_t * pCopy )
|
|||
static inline void Esop_CubeRecycle( Esop_Man_t * p, Esop_Cube_t * pCube )
|
||||
{
|
||||
if ( pCube->nWords <= 1 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );
|
||||
else if ( pCube->nWords <= 2 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );
|
||||
else if ( pCube->nWords <= 4 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );
|
||||
else if ( pCube->nWords <= 8 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -238,16 +239,16 @@ static inline void Esop_CoverRecycle( Esop_Man_t * p, Esop_Cube_t * pCover )
|
|||
return;
|
||||
if ( pCover->nWords <= 1 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );
|
||||
else if ( pCover->nWords <= 2 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );
|
||||
else if ( pCover->nWords <= 4 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );
|
||||
else if ( pCover->nWords <= 8 )
|
||||
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube );
|
||||
Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ Esop_Man_t * Esop_ManAlloc( int nVars )
|
|||
memset( pMan, 0, sizeof(Esop_Man_t) );
|
||||
pMan->nVars = nVars;
|
||||
pMan->nWords = Esop_BitWordNum( nVars * 2 );
|
||||
pMan->pMemMan1 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) );
|
||||
pMan->pMemMan2 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) );
|
||||
pMan->pMemMan4 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) );
|
||||
pMan->pMemMan8 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) );
|
||||
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
|
||||
|
|
@ -101,10 +101,10 @@ void Esop_ManClean( Esop_Man_t * p, int nSupp )
|
|||
***********************************************************************/
|
||||
void Esop_ManFree( Esop_Man_t * p )
|
||||
{
|
||||
Esop_MmFixedStop ( p->pMemMan1, 0 );
|
||||
Esop_MmFixedStop ( p->pMemMan2, 0 );
|
||||
Esop_MmFixedStop ( p->pMemMan4, 0 );
|
||||
Esop_MmFixedStop ( p->pMemMan8, 0 );
|
||||
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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,274 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [esopMem.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Memory managers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: esopMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "esop.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Esop_MmFixed_t_
|
||||
{
|
||||
// information about individual entries
|
||||
int nEntrySize; // the size of one entry
|
||||
int nEntriesAlloc; // the total number of entries allocated
|
||||
int nEntriesUsed; // the number of entries in use
|
||||
int nEntriesMax; // the max number of entries in use
|
||||
char * pEntriesFree; // the linked list of free entries
|
||||
|
||||
// this is where the memory is stored
|
||||
int nChunkSize; // the size of one chunk
|
||||
int nChunksAlloc; // the maximum number of memory chunks
|
||||
int nChunks; // the current number of memory chunks
|
||||
char ** pChunks; // the allocated memory
|
||||
|
||||
// statistics
|
||||
int nMemoryUsed; // memory used in the allocated entries
|
||||
int nMemoryAlloc; // memory allocated
|
||||
};
|
||||
|
||||
struct Esop_MmFlex_t_
|
||||
{
|
||||
// information about individual entries
|
||||
int nEntriesUsed; // the number of entries allocated
|
||||
char * pCurrent; // the current pointer to free memory
|
||||
char * pEnd; // the first entry outside the free memory
|
||||
|
||||
// this is where the memory is stored
|
||||
int nChunkSize; // the size of one chunk
|
||||
int nChunksAlloc; // the maximum number of memory chunks
|
||||
int nChunks; // the current number of memory chunks
|
||||
char ** pChunks; // the allocated memory
|
||||
|
||||
// statistics
|
||||
int nMemoryUsed; // memory used in the allocated entries
|
||||
int nMemoryAlloc; // memory allocated
|
||||
};
|
||||
|
||||
struct Esop_MmStep_t_
|
||||
{
|
||||
int nMems; // the number of fixed memory managers employed
|
||||
Esop_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
|
||||
int nMapSize; // the size of the memory array
|
||||
Esop_MmFixed_t ** pMap; // maps the number of bytes into its memory manager
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates memory pieces of fixed size.]
|
||||
|
||||
Description [The size of the chunk is computed as the minimum of
|
||||
1024 entries and 64K. Can only work with entry size at least 4 byte long.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize )
|
||||
{
|
||||
Esop_MmFixed_t * p;
|
||||
|
||||
p = ALLOC( Esop_MmFixed_t, 1 );
|
||||
memset( p, 0, sizeof(Esop_MmFixed_t) );
|
||||
|
||||
p->nEntrySize = nEntrySize;
|
||||
p->nEntriesAlloc = 0;
|
||||
p->nEntriesUsed = 0;
|
||||
p->pEntriesFree = NULL;
|
||||
|
||||
if ( nEntrySize * (1 << 10) < (1<<16) )
|
||||
p->nChunkSize = (1 << 10);
|
||||
else
|
||||
p->nChunkSize = (1<<16) / nEntrySize;
|
||||
if ( p->nChunkSize < 8 )
|
||||
p->nChunkSize = 8;
|
||||
|
||||
p->nChunksAlloc = 64;
|
||||
p->nChunks = 0;
|
||||
p->pChunks = ALLOC( char *, p->nChunksAlloc );
|
||||
|
||||
p->nMemoryUsed = 0;
|
||||
p->nMemoryAlloc = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
if ( p == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
|
||||
p->nEntrySize, p->nChunkSize, p->nChunks );
|
||||
printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
|
||||
p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
|
||||
}
|
||||
for ( i = 0; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
free( p->pChunks );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p )
|
||||
{
|
||||
char * pTemp;
|
||||
int i;
|
||||
|
||||
// check if there are still free entries
|
||||
if ( p->nEntriesUsed == p->nEntriesAlloc )
|
||||
{ // need to allocate more entries
|
||||
assert( p->pEntriesFree == NULL );
|
||||
if ( p->nChunks == p->nChunksAlloc )
|
||||
{
|
||||
p->nChunksAlloc *= 2;
|
||||
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
|
||||
}
|
||||
p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
|
||||
p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
|
||||
// transform these entries into a linked list
|
||||
pTemp = p->pEntriesFree;
|
||||
for ( i = 1; i < p->nChunkSize; i++ )
|
||||
{
|
||||
*((char **)pTemp) = pTemp + p->nEntrySize;
|
||||
pTemp += p->nEntrySize;
|
||||
}
|
||||
// set the last link
|
||||
*((char **)pTemp) = NULL;
|
||||
// add the chunk to the chunk storage
|
||||
p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
|
||||
// add to the number of entries allocated
|
||||
p->nEntriesAlloc += p->nChunkSize;
|
||||
}
|
||||
// incrememt the counter of used entries
|
||||
p->nEntriesUsed++;
|
||||
if ( p->nEntriesMax < p->nEntriesUsed )
|
||||
p->nEntriesMax = p->nEntriesUsed;
|
||||
// return the first entry in the free entry list
|
||||
pTemp = p->pEntriesFree;
|
||||
p->pEntriesFree = *((char **)pTemp);
|
||||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry )
|
||||
{
|
||||
// decrement the counter of used entries
|
||||
p->nEntriesUsed--;
|
||||
// add the entry to the linked list of free entries
|
||||
*((char **)pEntry) = p->pEntriesFree;
|
||||
p->pEntriesFree = pEntry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description [Relocates all the memory except the first chunk.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Esop_MmFixedRestart( Esop_MmFixed_t * p )
|
||||
{
|
||||
int i;
|
||||
char * pTemp;
|
||||
|
||||
// deallocate all chunks except the first one
|
||||
for ( i = 1; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
p->nChunks = 1;
|
||||
// transform these entries into a linked list
|
||||
pTemp = p->pChunks[0];
|
||||
for ( i = 1; i < p->nChunkSize; i++ )
|
||||
{
|
||||
*((char **)pTemp) = pTemp + p->nEntrySize;
|
||||
pTemp += p->nEntrySize;
|
||||
}
|
||||
// set the last link
|
||||
*((char **)pTemp) = NULL;
|
||||
// set the free entry list
|
||||
p->pEntriesFree = p->pChunks[0];
|
||||
// set the correct statistics
|
||||
p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
|
||||
p->nMemoryUsed = 0;
|
||||
p->nEntriesAlloc = p->nChunkSize;
|
||||
p->nEntriesUsed = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p )
|
||||
{
|
||||
return p->nMemoryAlloc;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
SRC += src/temp/esop/esopMan.c \
|
||||
src/temp/esop/esopMem.c \
|
||||
src/temp/esop/esopMin.c \
|
||||
src/temp/esop/esopUtil.c
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ extern "C" {
|
|||
|
||||
typedef struct Ivy_Man_t_ Ivy_Man_t;
|
||||
typedef struct Ivy_Obj_t_ Ivy_Obj_t;
|
||||
typedef int Ivy_Edge_t;
|
||||
|
||||
// constant edges
|
||||
#define IVY_CONST0 1
|
||||
#define IVY_CONST1 0
|
||||
|
||||
// object types
|
||||
typedef enum {
|
||||
|
|
@ -102,10 +107,12 @@ struct Ivy_Man_t_
|
|||
int * pTable; // structural hash table
|
||||
int nTableSize; // structural hash table size
|
||||
// various data members
|
||||
int fCatchExor; // set to 1 to detect EXORs
|
||||
int fExtended; // set to 1 in extended mode
|
||||
int nTravIds; // the traversal ID
|
||||
int nLevelMax; // the maximum level
|
||||
void * pData; // the temporary data
|
||||
Vec_Int_t * vRequired; // required times
|
||||
// truth table of the 8-LUTs
|
||||
unsigned * pMemory; // memory for truth tables
|
||||
Vec_Int_t * vTruths; // offset for truth table of each node
|
||||
|
|
@ -118,6 +125,26 @@ struct Ivy_Man_t_
|
|||
};
|
||||
|
||||
|
||||
#define IVY_CUT_LIMIT 256
|
||||
#define IVY_CUT_INPUT 6
|
||||
|
||||
typedef struct Ivy_Cut_t_ Ivy_Cut_t;
|
||||
struct Ivy_Cut_t_
|
||||
{
|
||||
short nSize;
|
||||
short nSizeMax;
|
||||
int pArray[IVY_CUT_INPUT];
|
||||
unsigned uHash;
|
||||
};
|
||||
|
||||
typedef struct Ivy_Store_t_ Ivy_Store_t;
|
||||
struct Ivy_Store_t_
|
||||
{
|
||||
int nCuts;
|
||||
int nCutsMax;
|
||||
Ivy_Cut_t pCuts[IVY_CUT_LIMIT]; // storage for cuts
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -133,14 +160,6 @@ 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 int Ivy_FanCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
|
||||
static inline int Ivy_FanId( int Fan ) { return Fan >> 1; }
|
||||
static inline int Ivy_FanCompl( int Fan ) { return Fan & 1; }
|
||||
|
||||
static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; }
|
||||
static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; }
|
||||
static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; }
|
||||
|
||||
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)); }
|
||||
|
|
@ -153,6 +172,19 @@ static inline Ivy_Obj_t * Ivy_ManPi( Ivy_Man_t * p, int i ) { return p->pO
|
|||
static inline Ivy_Obj_t * Ivy_ManPo( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPos,i); }
|
||||
static inline Ivy_Obj_t * Ivy_ManObj( Ivy_Man_t * p, int i ) { return p->pObjs + i; }
|
||||
|
||||
static inline Ivy_Edge_t Ivy_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
|
||||
static inline int Ivy_EdgeId( Ivy_Edge_t Edge ) { return Edge >> 1; }
|
||||
static inline int Ivy_EdgeIsComplement( Ivy_Edge_t Edge ) { return Edge & 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeRegular( Ivy_Edge_t Edge ) { return (Edge >> 1) << 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeNot( Ivy_Edge_t Edge ) { return Edge ^ 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { return Edge ^ fCond; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeFromNode( Ivy_Obj_t * pNode ) { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) ); }
|
||||
static inline Ivy_Obj_t * Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); }
|
||||
|
||||
static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; }
|
||||
static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; }
|
||||
static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; }
|
||||
|
||||
static inline int Ivy_ManPiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PI]; }
|
||||
static inline int Ivy_ManPoNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PO]; }
|
||||
static inline int Ivy_ManAssertNum( Ivy_Man_t * p ) { return p->nObjs[IVY_ASSERT]; }
|
||||
|
|
@ -185,9 +217,9 @@ static inline int Ivy_ObjIsAnd( Ivy_Obj_t * pObj ) { assert( !Ivy
|
|||
static inline int Ivy_ObjIsExor( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXOR; }
|
||||
static inline int Ivy_ObjIsBuf( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_BUF; }
|
||||
static inline int Ivy_ObjIsNode( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; }
|
||||
static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; }
|
||||
static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; }
|
||||
static inline int Ivy_ObjIsHash( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; }
|
||||
static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; }
|
||||
static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; }
|
||||
|
||||
static inline int Ivy_ObjIsAndMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ANDM; }
|
||||
static inline int Ivy_ObjIsExorMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXORM; }
|
||||
|
|
@ -227,13 +259,9 @@ static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { assert( !Ivy
|
|||
static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin1(pObj), Ivy_ObjFaninC1(pObj) ); }
|
||||
static inline int Ivy_ObjLevelR( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->LevelR; }
|
||||
static inline int Ivy_ObjLevel( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Level; }
|
||||
static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return 1 + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); }
|
||||
static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return 1 + Ivy_ObjIsExor(pObj) + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); }
|
||||
static inline void Ivy_ObjClean( Ivy_Obj_t * pObj ) {
|
||||
int IdSaved = pObj->Id;
|
||||
if ( IdSaved == 54 )
|
||||
{
|
||||
int x = 0;
|
||||
}
|
||||
memset( pObj, 0, sizeof(Ivy_Obj_t) );
|
||||
pObj->Id = IdSaved;
|
||||
}
|
||||
|
|
@ -339,6 +367,8 @@ static inline int Ivy_ObjFaninNum( Ivy_Obj_t * pObj )
|
|||
// iterator over all objects, including those currently not used
|
||||
#define Ivy_ManForEachObj( p, pObj, i ) \
|
||||
for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ )
|
||||
#define Ivy_ManForEachObjReverse( p, pObj, i ) \
|
||||
for ( i = p->ObjIdNext - 1, pObj = p->pObjs + i; i >= 0; i--, pObj-- )
|
||||
// iterator over the primary inputs
|
||||
#define Ivy_ManForEachPi( p, pObj, i ) \
|
||||
for ( i = 0; i < Vec_IntSize(p->vPis) && ((pObj) = Ivy_ManPi(p, i)); i++ )
|
||||
|
|
@ -369,6 +399,9 @@ static inline int Ivy_ObjFaninNum( Ivy_Obj_t * pObj )
|
|||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== ivyBalance.c ========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel );
|
||||
extern Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel );
|
||||
/*=== ivyCanon.c ========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
|
|
@ -377,11 +410,13 @@ extern Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init );
|
|||
extern int Ivy_ManCheck( Ivy_Man_t * p );
|
||||
/*=== ivyCut.c ==========================================================*/
|
||||
extern void Ivy_ManSeqFindCut( Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize );
|
||||
/*=== ivyBalance.c ======================================================*/
|
||||
extern int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel );
|
||||
extern Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves );
|
||||
/*=== ivyDfs.c ==========================================================*/
|
||||
extern Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p );
|
||||
extern Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p );
|
||||
extern void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone );
|
||||
extern Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p );
|
||||
extern Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p );
|
||||
/*=== ivyDsd.c ==========================================================*/
|
||||
extern int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree );
|
||||
extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree );
|
||||
|
|
@ -399,6 +434,7 @@ extern Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type
|
|||
extern Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSol );
|
||||
/*=== ivyObj.c ==========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost );
|
||||
extern Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type );
|
||||
|
|
@ -415,8 +451,12 @@ extern Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
|||
extern Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 );
|
||||
extern Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC );
|
||||
extern Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs );
|
||||
/*=== ivyResyn.c =========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel );
|
||||
/*=== ivyRewrite.c =========================================================*/
|
||||
extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
|
||||
extern int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
|
||||
extern int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose );
|
||||
/*=== ivyTable.c ========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableInsert( Ivy_Obj_t * pObj );
|
||||
|
|
@ -437,6 +477,8 @@ extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObj
|
|||
extern unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth );
|
||||
extern Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin );
|
||||
extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p );
|
||||
extern int Ivy_ManReadLevels( Ivy_Man_t * p );
|
||||
extern Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,32 +17,18 @@
|
|||
Revision [$Id: ivyBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots );
|
||||
|
||||
// this procedure returns 1 if the node cannot be expanded
|
||||
static inline int Ivy_NodeStopFanin( Ivy_Obj_t * pNode, int iFanin )
|
||||
{
|
||||
if ( iFanin == 0 )
|
||||
return Ivy_ObjFanin0(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) > 1 || Ivy_ObjFaninC0(pNode);
|
||||
else
|
||||
return Ivy_ObjFanin1(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) > 1 || Ivy_ObjFaninC1(pNode);
|
||||
}
|
||||
|
||||
// this procedure returns 1 if the node cannot be recursively dereferenced
|
||||
static inline int Ivy_NodeBalanceDerefFanin( Ivy_Obj_t * pNode, int iFanin )
|
||||
{
|
||||
if ( iFanin == 0 )
|
||||
return Ivy_ObjFanin0(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) == 0 && !Ivy_ObjFaninC0(pNode);
|
||||
else
|
||||
return Ivy_ObjFanin1(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) == 0 && !Ivy_ObjFaninC1(pNode);
|
||||
}
|
||||
static int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
|
||||
static Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
|
||||
static int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
|
||||
static void Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor );
|
||||
static void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -59,44 +45,41 @@ static inline int Ivy_NodeBalanceDerefFanin( Ivy_Obj_t * pNode, int iFanin )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
|
||||
Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
|
||||
{
|
||||
Vec_Int_t * vNodes;
|
||||
Vec_Ptr_t * vFront, * vSpots;
|
||||
Ivy_Obj_t * pNode;
|
||||
int i;
|
||||
vSpots = Vec_PtrAlloc( 50 );
|
||||
vFront = Vec_PtrAlloc( 50 );
|
||||
vNodes = Ivy_ManDfs( p );
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pNode, i )
|
||||
Ivy_Man_t * pNew;
|
||||
Ivy_Obj_t * pObj, * pDriver;
|
||||
Vec_Vec_t * vStore;
|
||||
int i, NewNodeId;
|
||||
// clean the old manager
|
||||
Ivy_ManCleanTravId( p );
|
||||
// create the new manager
|
||||
pNew = Ivy_ManStart( Ivy_ManPiNum(p), Ivy_ManPoNum(p), Ivy_ManNodeNum(p) + 20000 );
|
||||
// map the nodes
|
||||
Ivy_ManConst1(p)->TravId = Ivy_EdgeFromNode( Ivy_ManConst1(pNew) );
|
||||
Ivy_ManForEachPi( p, pObj, i )
|
||||
pObj->TravId = Ivy_EdgeFromNode( Ivy_ManPi(pNew, i) );
|
||||
// balance the AIG
|
||||
vStore = Vec_VecAlloc( 50 );
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
// fix the fanin buffer problem
|
||||
Ivy_NodeFixBufferFanins( pNode );
|
||||
// skip node if it became a buffer
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
// skip nodes with one fanout if type of the node is the same as type of the fanout
|
||||
// such nodes will be processed when the fanouts are processed
|
||||
if ( Ivy_ObjRefs(pNode) == 1 && Ivy_ObjIsExor(pNode) == Ivy_ObjExorFanout(pNode) )
|
||||
continue;
|
||||
assert( Ivy_ObjRefs(pNode) > 0 );
|
||||
// do not balance the node if both if its fanins have more than one fanout
|
||||
if ( Ivy_NodeStopFanin(pNode, 0) && Ivy_NodeStopFanin(pNode, 1) )
|
||||
continue;
|
||||
// try balancing this node
|
||||
Ivy_NodeBalance( pNode, fUpdateLevel, vFront, vSpots );
|
||||
pDriver = Ivy_ObjReal( Ivy_ObjChild0(pObj) );
|
||||
NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(pDriver), vStore, 0, fUpdateLevel );
|
||||
NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(pDriver) );
|
||||
Ivy_ObjConnect( Ivy_ManPo(pNew, i), Ivy_EdgeToNode(pNew, NewNodeId) );
|
||||
}
|
||||
Vec_IntFree( vNodes );
|
||||
Vec_PtrFree( vSpots );
|
||||
Vec_PtrFree( vFront );
|
||||
return 1;
|
||||
Vec_VecFree( vStore );
|
||||
if ( i = Ivy_ManCleanup( pNew ) )
|
||||
printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
|
||||
// check the resulting AIG
|
||||
if ( !Ivy_ManCheck(pNew) )
|
||||
printf( "Ivy_ManBalance(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Dereferences MFFC of the node.]
|
||||
Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -105,152 +88,177 @@ int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeBalanceDeref_rec( Ivy_Obj_t * pNode )
|
||||
int Ivy_NodeCompareLevelsDecrease( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )
|
||||
{
|
||||
Ivy_Obj_t * pFan;
|
||||
// deref the first fanin
|
||||
pFan = Ivy_ObjFanin0(pNode);
|
||||
Ivy_ObjRefsDec( pFan );
|
||||
if ( Ivy_NodeBalanceDerefFanin(pNode, 0) )
|
||||
Ivy_NodeBalanceDeref_rec( pFan );
|
||||
// deref the second fanin
|
||||
pFan = Ivy_ObjFanin1(pNode);
|
||||
Ivy_ObjRefsDec( pFan );
|
||||
if ( Ivy_NodeBalanceDerefFanin(pNode, 1) )
|
||||
Ivy_NodeBalanceDeref_rec( pFan );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes nodes inside supergate and determines frontier.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeBalanceCollect_rec( Ivy_Obj_t * pNode, Vec_Ptr_t * vSpots, Vec_Ptr_t * vFront )
|
||||
{
|
||||
Ivy_Obj_t * pFanin;
|
||||
// skip visited nodes
|
||||
if ( Vec_PtrFind(vSpots, pNode) >= 0 )
|
||||
return;
|
||||
// collect node
|
||||
Vec_PtrPush( vSpots, pNode );
|
||||
// first fanin
|
||||
pFanin = Ivy_ObjFanin0(pNode);
|
||||
if ( Ivy_ObjRefs(pFanin) == 0 )
|
||||
Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront );
|
||||
else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild0(pNode)) >= 0 )
|
||||
Vec_PtrRemove( vFront, Ivy_ObjChild0(pNode) );
|
||||
else
|
||||
Vec_PtrPushUnique( vFront, Ivy_ObjChild0(pNode) );
|
||||
// second fanin
|
||||
pFanin = Ivy_ObjFanin1(pNode);
|
||||
if ( Ivy_ObjRefs(pFanin) == 0 )
|
||||
Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront );
|
||||
else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild1(pNode)) >= 0 )
|
||||
Vec_PtrRemove( vFront, Ivy_ObjChild1(pNode) );
|
||||
else
|
||||
Vec_PtrPushUnique( vFront, Ivy_ObjChild1(pNode) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two nodes by level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_BalanceCompareByLevel( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )
|
||||
{
|
||||
int Level1 = Ivy_ObjLevel( *pp1 );
|
||||
int Level2 = Ivy_ObjLevel( *pp2 );
|
||||
if ( Level1 > Level2 )
|
||||
int Diff = Ivy_Regular(*pp1)->Level - Ivy_Regular(*pp2)->Level;
|
||||
if ( Diff > 0 )
|
||||
return -1;
|
||||
if ( Level1 < Level2 )
|
||||
if ( Diff < 0 )
|
||||
return 1;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes nodes inside supergate and determines frontier.]
|
||||
Synopsis [Returns the ID of new node constructed.]
|
||||
|
||||
Description [Return 1 if the output needs to be complemented.]
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeBalancePrepare( Ivy_Obj_t * pNode, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots )
|
||||
int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
|
||||
{
|
||||
Ivy_Man_t * pMan = Ivy_ObjMan( pNode );
|
||||
Ivy_Obj_t * pObj, * pNext;
|
||||
int i, k, Counter = 0;
|
||||
// dereference the cone
|
||||
Ivy_NodeBalanceDeref_rec( pNode );
|
||||
// collect the frontier and the internal nodes
|
||||
Vec_PtrClear( vFront );
|
||||
Vec_PtrClear( vSpots );
|
||||
Ivy_NodeBalanceCollect_rec( pNode, vSpots, vFront );
|
||||
// remove all the nodes
|
||||
Vec_PtrForEachEntry( vSpots, pObj, i )
|
||||
{
|
||||
// skip the first entry (the node itself)
|
||||
if ( i == 0 ) continue;
|
||||
// collect the free entries
|
||||
Vec_IntPush( pMan->vFree, pObj->Id );
|
||||
Ivy_ObjDelete( pObj, 1 );
|
||||
Ivy_Obj_t * pObjNew;
|
||||
Vec_Ptr_t * vSuper;
|
||||
int i, NewNodeId;
|
||||
assert( !Ivy_IsComplement(pObjOld) );
|
||||
assert( !Ivy_ObjIsBuf(pObjOld) );
|
||||
// return if the result is known
|
||||
if ( Ivy_ObjIsConst1(pObjOld) )
|
||||
return pObjOld->TravId;
|
||||
if ( pObjOld->TravId )
|
||||
return pObjOld->TravId;
|
||||
assert( Ivy_ObjIsNode(pObjOld) );
|
||||
// get the implication supergate
|
||||
vSuper = Ivy_NodeBalanceCone( pObjOld, vStore, Level );
|
||||
if ( vSuper->nSize == 0 )
|
||||
{ // it means that the supergate contains two nodes in the opposite polarity
|
||||
pObjOld->TravId = Ivy_EdgeFromNode( Ivy_ManConst0(pNew) );
|
||||
return pObjOld->TravId;
|
||||
}
|
||||
// sort nodes by level in decreasing order
|
||||
qsort( (void *)Vec_PtrArray(vFront), Vec_PtrSize(vFront), sizeof(Ivy_Obj_t *),
|
||||
(int (*)(const void *, const void *))Ivy_BalanceCompareByLevel );
|
||||
// check if there are nodes and their complements
|
||||
Counter = 0;
|
||||
Vec_PtrForEachEntry( vFront, pObj, i )
|
||||
if ( vSuper->nSize < 2 )
|
||||
printf( "BUG!\n" );
|
||||
// for each old node, derive the new well-balanced node
|
||||
for ( i = 0; i < vSuper->nSize; i++ )
|
||||
{
|
||||
if ( i == Vec_PtrSize(vFront) - 1 )
|
||||
break;
|
||||
pNext = Vec_PtrEntry( vFront, i+1 );
|
||||
if ( Ivy_Regular(pObj) == Ivy_Regular(pNext) )
|
||||
{
|
||||
assert( pObj == Ivy_Not(pNext) );
|
||||
Vec_PtrWriteEntry( vFront, i, NULL );
|
||||
Vec_PtrWriteEntry( vFront, i+1, NULL );
|
||||
i++;
|
||||
Counter++;
|
||||
}
|
||||
NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
|
||||
NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(vSuper->pArray[i]) );
|
||||
vSuper->pArray[i] = Ivy_EdgeToNode( pNew, NewNodeId );
|
||||
}
|
||||
// if there are no complemented pairs, go ahead and balance
|
||||
if ( Counter == 0 )
|
||||
return 0;
|
||||
// if there are complemented pairs and this is AND, create const 0
|
||||
if ( Counter > 0 && Ivy_ObjIsAnd(pNode) )
|
||||
// build the supergate
|
||||
pObjNew = Ivy_NodeBalanceBuildSuper( vSuper, Ivy_ObjType(pObjOld), fUpdateLevel );
|
||||
vSuper->nSize = 0;
|
||||
// make sure the balanced node is not assigned
|
||||
assert( pObjOld->TravId == 0 );
|
||||
pObjOld->TravId = Ivy_EdgeFromNode( pObjNew );
|
||||
return pObjOld->TravId;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Builds implication supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel )
|
||||
{
|
||||
Ivy_Obj_t * pObj1, * pObj2;
|
||||
int LeftBound;
|
||||
assert( vSuper->nSize > 1 );
|
||||
// sort the new nodes by level in the decreasing order
|
||||
Vec_PtrSort( vSuper, Ivy_NodeCompareLevelsDecrease );
|
||||
// balance the nodes
|
||||
while ( vSuper->nSize > 1 )
|
||||
{
|
||||
Vec_PtrClear( vFront );
|
||||
Vec_PtrPush( vFront, Ivy_ManConst0(pMan) );
|
||||
// find the left bound on the node to be paired
|
||||
LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vSuper );
|
||||
// find the node that can be shared (if no such node, randomize choice)
|
||||
Ivy_NodeBalancePermute( vSuper, LeftBound, Type == IVY_EXOR );
|
||||
// pull out the last two nodes
|
||||
pObj1 = Vec_PtrPop(vSuper);
|
||||
pObj2 = Vec_PtrPop(vSuper);
|
||||
Ivy_NodeBalancePushUniqueOrderByLevel( vSuper, Ivy_Oper(pObj1, pObj2, Type) );
|
||||
}
|
||||
return Vec_PtrEntry(vSuper, 0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the nodes of the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeBalanceCone_rec( Ivy_Obj_t * pRoot, Ivy_Obj_t * pObj, Vec_Ptr_t * vSuper )
|
||||
{
|
||||
int RetValue1, RetValue2, i;
|
||||
// check if the node is visited
|
||||
if ( Ivy_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] == Ivy_Not(pObj) )
|
||||
return -1;
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
assert( Counter > 0 && Ivy_ObjIsExor(pNode) );
|
||||
// remove the pairs
|
||||
k = 0;
|
||||
Vec_PtrForEachEntry( vFront, pObj, i )
|
||||
if ( pObj )
|
||||
Vec_PtrWriteEntry( vFront, k++, pObj );
|
||||
Vec_PtrShrink( vFront, k );
|
||||
// add constant zero node if nothing is left
|
||||
if ( Vec_PtrSize(vFront) == 0 )
|
||||
Vec_PtrPush( vFront, Ivy_ManConst0(pMan) );
|
||||
// return 1 if the number of pairs is odd (need to complement the output)
|
||||
return Counter & 1;
|
||||
// if the new node is complemented or a PI, another gate begins
|
||||
if ( pObj != pRoot && (Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Ivy_ObjType(pRoot) || Ivy_ObjRefs(pObj) > 1) )
|
||||
{
|
||||
Vec_PtrPush( vSuper, pObj );
|
||||
Ivy_Regular(pObj)->fMarkB = 1;
|
||||
return 0;
|
||||
}
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
// go through the branches
|
||||
RetValue1 = Ivy_NodeBalanceCone_rec( pRoot, Ivy_ObjReal( Ivy_ObjChild0(pObj) ), vSuper );
|
||||
RetValue2 = Ivy_NodeBalanceCone_rec( pRoot, Ivy_ObjReal( Ivy_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 * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
int RetValue, i;
|
||||
assert( !Ivy_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 = Ivy_NodeBalanceCone_rec( pObj, pObj, vNodes );
|
||||
assert( vNodes->nSize > 1 );
|
||||
// unmark the visited nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Ivy_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*************************************************************
|
||||
|
|
@ -270,27 +278,27 @@ int Ivy_NodeBalancePrepare( Ivy_Obj_t * pNode, Vec_Ptr_t * vFront, Vec_Ptr_t * v
|
|||
***********************************************************************/
|
||||
int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
|
||||
{
|
||||
Ivy_Obj_t * pNodeRight, * pNodeLeft;
|
||||
Ivy_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;
|
||||
pNodeRight = Vec_PtrEntry( vSuper, Current );
|
||||
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
|
||||
pNodeLeft = Vec_PtrEntry( vSuper, Current );
|
||||
pObjLeft = Vec_PtrEntry( vSuper, Current );
|
||||
// if the level of this node is different, quit the loop
|
||||
if ( Ivy_Regular(pNodeLeft)->Level != Ivy_Regular(pNodeRight)->Level )
|
||||
if ( Ivy_Regular(pObjLeft)->Level != Ivy_Regular(pObjRight)->Level )
|
||||
break;
|
||||
}
|
||||
Current++;
|
||||
// get the node, for which the equality holds
|
||||
pNodeLeft = Vec_PtrEntry( vSuper, Current );
|
||||
assert( Ivy_Regular(pNodeLeft)->Level == Ivy_Regular(pNodeRight)->Level );
|
||||
pObjLeft = Vec_PtrEntry( vSuper, Current );
|
||||
assert( Ivy_Regular(pObjLeft)->Level == Ivy_Regular(pObjRight)->Level );
|
||||
return Current;
|
||||
}
|
||||
|
||||
|
|
@ -306,9 +314,9 @@ int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
|
||||
void Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor )
|
||||
{
|
||||
Ivy_Obj_t * pNode1, * pNode2, * pNode3, * pGhost;
|
||||
Ivy_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
|
||||
int RightBound, i;
|
||||
// get the right bound
|
||||
RightBound = Vec_PtrSize(vSuper) - 2;
|
||||
|
|
@ -316,19 +324,19 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound
|
|||
if ( LeftBound == RightBound )
|
||||
return;
|
||||
// get the two last nodes
|
||||
pNode1 = Vec_PtrEntry( vSuper, RightBound + 1 );
|
||||
pNode2 = Vec_PtrEntry( vSuper, RightBound );
|
||||
pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
|
||||
pObj2 = Vec_PtrEntry( vSuper, RightBound );
|
||||
// find the first node that can be shared
|
||||
for ( i = RightBound; i >= LeftBound; i-- )
|
||||
{
|
||||
pNode3 = Vec_PtrEntry( vSuper, i );
|
||||
pGhost = Ivy_ObjCreateGhost( pNode1, pNode3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );
|
||||
pObj3 = Vec_PtrEntry( vSuper, i );
|
||||
pGhost = Ivy_ObjCreateGhost( pObj1, pObj3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );
|
||||
if ( Ivy_TableLookup( pGhost ) )
|
||||
{
|
||||
if ( pNode3 == pNode2 )
|
||||
if ( pObj3 == pObj2 )
|
||||
return;
|
||||
Vec_PtrWriteEntry( vSuper, i, pNode2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pNode3 );
|
||||
Vec_PtrWriteEntry( vSuper, i, pObj2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -336,11 +344,11 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound
|
|||
// we did not find the node to share, randomize choice
|
||||
{
|
||||
int Choice = rand() % (RightBound - LeftBound + 1);
|
||||
pNode3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
|
||||
if ( pNode3 == pNode2 )
|
||||
pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
|
||||
if ( pObj3 == pObj2 )
|
||||
return;
|
||||
Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pNode2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pNode3 );
|
||||
Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 );
|
||||
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
@ -356,63 +364,24 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vFront, Ivy_Obj_t * pNode )
|
||||
void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Obj_t * pNode1, * pNode2;
|
||||
Ivy_Obj_t * pObj1, * pObj2;
|
||||
int i;
|
||||
if ( Vec_PtrPushUnique(vFront, pNode) )
|
||||
if ( Vec_PtrPushUnique(vStore, pObj) )
|
||||
return;
|
||||
// find the p of the node
|
||||
for ( i = vFront->nSize-1; i > 0; i-- )
|
||||
for ( i = vStore->nSize-1; i > 0; i-- )
|
||||
{
|
||||
pNode1 = vFront->pArray[i ];
|
||||
pNode2 = vFront->pArray[i-1];
|
||||
if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level )
|
||||
pObj1 = vStore->pArray[i ];
|
||||
pObj2 = vStore->pArray[i-1];
|
||||
if ( Ivy_Regular(pObj1)->Level <= Ivy_Regular(pObj2)->Level )
|
||||
break;
|
||||
vFront->pArray[i ] = pNode2;
|
||||
vFront->pArray[i-1] = pNode1;
|
||||
vStore->pArray[i ] = pObj2;
|
||||
vStore->pArray[i-1] = pObj1;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Balances one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots )
|
||||
{
|
||||
Ivy_Man_t * pMan = Ivy_ObjMan( pNode );
|
||||
Ivy_Obj_t * pFan0, * pFan1, * pNodeNew;
|
||||
int fCompl, LeftBound;
|
||||
// remove internal nodes and derive the frontier
|
||||
fCompl = Ivy_NodeBalancePrepare( pNode, vFront, vSpots );
|
||||
assert( Vec_PtrSize(vFront) > 0 );
|
||||
// balance the nodes
|
||||
while ( Vec_PtrSize(vFront) > 1 )
|
||||
{
|
||||
// find the left bound on the node to be paired
|
||||
LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vFront );
|
||||
// find the node that can be shared (if no such node, randomize choice)
|
||||
Ivy_NodeBalancePermute( pMan, vFront, LeftBound, Ivy_ObjIsExor(pNode) );
|
||||
// pull out the last two nodes
|
||||
pFan0 = Vec_PtrPop(vFront); assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan0)) );
|
||||
pFan1 = Vec_PtrPop(vFront); assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan1)) );
|
||||
// create the new node
|
||||
pNodeNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pFan0, pFan1, Ivy_ObjType(pNode), IVY_INIT_NONE) );
|
||||
// add the new node to the frontier
|
||||
Ivy_NodeBalancePushUniqueOrderByLevel( vFront, pNodeNew );
|
||||
}
|
||||
assert( Vec_PtrSize(vFront) == 1 );
|
||||
// perform the replacement
|
||||
Ivy_ObjReplace( pNode, Ivy_NotCond(Vec_PtrPop(vFront), fCompl), 1, 1 );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -200,180 +200,6 @@ void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInsi
|
|||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison for node pointers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindAlgCutCompare( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computing one algebraic cut.]
|
||||
|
||||
Description [Returns 1 if the tree-leaves of this node where traversed
|
||||
and found to have no external references (and have not been collected).
|
||||
Returns 0 if the tree-leaves have external references and are collected.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindAlgCut_rec( Ivy_Obj_t * pRoot, Ivy_Type_t Type, Vec_Ptr_t * vFront )
|
||||
{
|
||||
int RetValue0, RetValue1;
|
||||
Ivy_Obj_t * pRootR = Ivy_Regular(pRoot);
|
||||
assert( Type != IVY_EXOR || !Ivy_IsComplement(pRoot) );
|
||||
// if the node is a buffer skip through it
|
||||
if ( Ivy_ObjIsBuf(pRootR) )
|
||||
return Ivy_ManFindAlgCut_rec( Ivy_NotCond(Ivy_ObjChild0(pRootR), Ivy_IsComplement(pRoot)), Type, vFront );
|
||||
// if the node is the end of the tree, return
|
||||
if ( Ivy_IsComplement(pRoot) || Ivy_ObjIsCi(pRoot) || Ivy_ObjType(pRoot) != Type )
|
||||
{
|
||||
if ( Ivy_ObjRefs(pRootR) == 1 )
|
||||
return 1;
|
||||
assert( Ivy_ObjRefs(pRootR) > 1 );
|
||||
Vec_PtrPush( vFront, pRoot );
|
||||
return 0;
|
||||
}
|
||||
// branch on the node
|
||||
assert( Ivy_ObjIsNode(pRoot) );
|
||||
RetValue0 = Ivy_ManFindAlgCut_rec( Ivy_ObjChild0(pRoot), Type, vFront );
|
||||
RetValue1 = Ivy_ManFindAlgCut_rec( Ivy_ObjChild1(pRoot), Type, vFront );
|
||||
// the case when both have no external referenced
|
||||
if ( RetValue0 && RetValue1 )
|
||||
{
|
||||
if ( Ivy_ObjRefs(pRoot) == 1 )
|
||||
return 1;
|
||||
assert( Ivy_ObjRefs(pRoot) > 1 );
|
||||
Vec_PtrPush( vFront, pRoot );
|
||||
return 0;
|
||||
}
|
||||
// the case when one of them has external references
|
||||
if ( RetValue0 )
|
||||
Vec_PtrPush( vFront, Ivy_ObjChild0(pRoot) );
|
||||
if ( RetValue1 )
|
||||
Vec_PtrPush( vFront, Ivy_ObjChild1(pRoot) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computing one algebraic cut.]
|
||||
|
||||
Description [Algebraic cut stops when we hit (a) CI, (b) complemented edge,
|
||||
(c) boundary of different gates. Returns 1 if this is a pure tree.
|
||||
Returns -1 if the contant 0 is detected. Return 0 if the array can be used.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront )
|
||||
{
|
||||
Ivy_Obj_t * pObj, * pPrev;
|
||||
int RetValue, i, k;
|
||||
assert( !Ivy_IsComplement(pRoot) );
|
||||
// clear the frontier and collect the nodes
|
||||
Vec_PtrClear( vFront );
|
||||
RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront );
|
||||
// return if the node is the root of a tree
|
||||
if ( RetValue == 1 )
|
||||
return 1;
|
||||
// sort the entries to in increasing order
|
||||
Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare );
|
||||
// remove duplicated
|
||||
k = 1;
|
||||
Vec_PtrForEachEntryStart( vFront, pObj, i, 1 )
|
||||
{
|
||||
pPrev = (k == 0 ? NULL : Vec_PtrEntry(vFront, k-1));
|
||||
if ( pObj == pPrev )
|
||||
{
|
||||
if ( Ivy_ObjIsExor(pRoot) )
|
||||
k--;
|
||||
continue;
|
||||
}
|
||||
if ( pObj == Ivy_Not(pPrev) )
|
||||
return -1;
|
||||
Vec_PtrWriteEntry( vFront, k++, pObj );
|
||||
}
|
||||
if ( k == 0 )
|
||||
return -1;
|
||||
Vec_PtrShrink( vFront, k );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManTestCutsAlg( Ivy_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vFront;
|
||||
Ivy_Obj_t * pObj, * pTemp;
|
||||
int i, k, RetValue;
|
||||
vFront = Vec_PtrAlloc( 100 );
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( !Ivy_ObjIsNode(pObj) )
|
||||
continue;
|
||||
if ( Ivy_ObjIsMuxType(pObj) )
|
||||
{
|
||||
printf( "m " );
|
||||
continue;
|
||||
}
|
||||
if ( pObj->Id == 509 )
|
||||
{
|
||||
int y = 0;
|
||||
}
|
||||
|
||||
RetValue = Ivy_ManFindAlgCut( pObj, vFront );
|
||||
if ( Ivy_ObjIsExor(pObj) )
|
||||
printf( "x" );
|
||||
if ( RetValue == -1 )
|
||||
printf( "Const0 " );
|
||||
else if ( RetValue == 1 || Vec_PtrSize(vFront) <= 2 )
|
||||
printf( ". " );
|
||||
else
|
||||
printf( "%d ", Vec_PtrSize(vFront) );
|
||||
|
||||
printf( "( " );
|
||||
Vec_PtrForEachEntry( vFront, pTemp, k )
|
||||
printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) );
|
||||
printf( ")\n" );
|
||||
|
||||
if ( Vec_PtrSize(vFront) == 5 )
|
||||
{
|
||||
int x = 0;
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
Vec_PtrFree( vFront );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -639,8 +465,8 @@ int Ivy_ManFindBoolCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolu
|
|||
void Ivy_ManTestCutsBool( Ivy_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vFront, * vVolume, * vLeaves;
|
||||
Ivy_Obj_t * pObj, * pTemp;
|
||||
int i, k, RetValue;
|
||||
Ivy_Obj_t * pObj;//, * pTemp;
|
||||
int i, RetValue;//, k;
|
||||
vFront = Vec_PtrAlloc( 100 );
|
||||
vVolume = Vec_PtrAlloc( 100 );
|
||||
vLeaves = Vec_PtrAlloc( 100 );
|
||||
|
|
@ -673,6 +499,376 @@ void Ivy_ManTestCutsBool( Ivy_Man_t * p )
|
|||
Vec_PtrFree( vLeaves );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the hash value of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut )
|
||||
{
|
||||
int i;
|
||||
// for ( i = 1; i < pCut->nSize; i++ )
|
||||
// assert( pCut->pArray[i-1] < pCut->pArray[i] );
|
||||
pCut->uHash = 0;
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
pCut->uHash |= (1 << (pCut->pArray[i] % 31));
|
||||
return pCut->uHash;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes one node to the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Ivy_NodeCutShrink( Ivy_Cut_t * pCut, int iOld )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = k = 0; i < pCut->nSize; i++ )
|
||||
if ( pCut->pArray[i] != iOld )
|
||||
pCut->pArray[k++] = pCut->pArray[i];
|
||||
assert( k == pCut->nSize - 1 );
|
||||
pCut->nSize--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node to the cut.]
|
||||
|
||||
Description [Returns 1 if the cuts is still okay.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
if ( pCut->pArray[i] == iNew )
|
||||
return 1;
|
||||
// check if there is room
|
||||
if ( pCut->nSize == pCut->nSizeMax )
|
||||
return 0;
|
||||
// add the new one
|
||||
for ( i = pCut->nSize - 1; i >= 0; i-- )
|
||||
if ( pCut->pArray[i] > iNew )
|
||||
pCut->pArray[i+1] = pCut->pArray[i];
|
||||
else
|
||||
{
|
||||
assert( pCut->pArray[i] < iNew );
|
||||
break;
|
||||
}
|
||||
pCut->pArray[i+1] = iNew;
|
||||
pCut->nSize++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the cut exists.]
|
||||
|
||||
Description [Returns 1 if the cut exists.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeCutFindOrAdd( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew )
|
||||
{
|
||||
Ivy_Cut_t * pCut;
|
||||
int i, k;
|
||||
assert( pCutNew->uHash );
|
||||
// try to find the cut
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->uHash == pCutNew->uHash && pCut->nSize == pCutNew->nSize )
|
||||
{
|
||||
for ( k = 0; k < pCutNew->nSize; k++ )
|
||||
if ( pCut->pArray[k] != pCutNew->pArray[k] )
|
||||
break;
|
||||
if ( k == pCutNew->nSize )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
assert( pCutStore->nCuts < pCutStore->nCutsMax );
|
||||
// add the cut
|
||||
pCut = pCutStore->pCuts + pCutStore->nCuts++;
|
||||
*pCut = *pCutNew;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if pDom is contained in pCut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = 0; i < pDom->nSize; i++ )
|
||||
{
|
||||
for ( k = 0; k < pCut->nSize; k++ )
|
||||
if ( pDom->pArray[i] == pCut->pArray[k] )
|
||||
break;
|
||||
if ( k == pCut->nSize ) // node i in pDom is not contained in pCut
|
||||
return 0;
|
||||
}
|
||||
// every node in pDom is contained in pCut
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the cut exists.]
|
||||
|
||||
Description [Returns 1 if the cut exists.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeCutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew )
|
||||
{
|
||||
Ivy_Cut_t * pCut;
|
||||
int i, k;
|
||||
assert( pCutNew->uHash );
|
||||
// try to find the cut
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->nSize == 0 )
|
||||
continue;
|
||||
if ( pCut->nSize == pCutNew->nSize )
|
||||
{
|
||||
if ( pCut->uHash == pCutNew->uHash )
|
||||
{
|
||||
for ( k = 0; k < pCutNew->nSize; k++ )
|
||||
if ( pCut->pArray[k] != pCutNew->pArray[k] )
|
||||
break;
|
||||
if ( k == pCutNew->nSize )
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( pCut->nSize < pCutNew->nSize )
|
||||
{
|
||||
// skip the non-contained cuts
|
||||
if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash )
|
||||
continue;
|
||||
// check containment seriously
|
||||
if ( Ivy_CutCheckDominance( pCut, pCutNew ) )
|
||||
return 1;
|
||||
continue;
|
||||
}
|
||||
// check potential containment of other cut
|
||||
|
||||
// skip the non-contained cuts
|
||||
if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash )
|
||||
continue;
|
||||
// check containment seriously
|
||||
if ( Ivy_CutCheckDominance( pCutNew, pCut ) )
|
||||
{
|
||||
// remove the current cut
|
||||
// --pCutStore->nCuts;
|
||||
// for ( k = i; k < pCutStore->nCuts; k++ )
|
||||
// pCutStore->pCuts[k] = pCutStore->pCuts[k+1];
|
||||
// i--;
|
||||
pCut->nSize = 0;
|
||||
}
|
||||
}
|
||||
assert( pCutStore->nCuts < pCutStore->nCutsMax );
|
||||
// add the cut
|
||||
pCut = pCutStore->pCuts + pCutStore->nCuts++;
|
||||
*pCut = *pCutNew;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeCompactCuts( Ivy_Store_t * pCutStore )
|
||||
{
|
||||
Ivy_Cut_t * pCut;
|
||||
int i, k;
|
||||
for ( i = k = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->nSize == 0 )
|
||||
continue;
|
||||
pCutStore->pCuts[k++] = *pCut;
|
||||
}
|
||||
pCutStore->nCuts = k;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodePrintCut( Ivy_Cut_t * pCut )
|
||||
{
|
||||
int i;
|
||||
assert( pCut->nSize > 0 );
|
||||
printf( "%d : {", pCut->nSize );
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
printf( " %d", pCut->pArray[i] );
|
||||
printf( " }\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodePrintCuts( Ivy_Store_t * pCutStore )
|
||||
{
|
||||
int i;
|
||||
printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] );
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
Ivy_NodePrintCut( pCutStore->pCuts + i );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves )
|
||||
{
|
||||
static Ivy_Store_t CutStore, * pCutStore = &CutStore;
|
||||
Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
|
||||
Ivy_Man_t * pMan = Ivy_ObjMan(pObj);
|
||||
Ivy_Obj_t * pLeaf;
|
||||
int i, k;
|
||||
|
||||
assert( nLeaves <= IVY_CUT_INPUT );
|
||||
|
||||
// start the structure
|
||||
pCutStore->nCuts = 0;
|
||||
pCutStore->nCutsMax = IVY_CUT_LIMIT;
|
||||
// start the trivial cut
|
||||
pCutNew->uHash = 0;
|
||||
pCutNew->nSize = 1;
|
||||
pCutNew->nSizeMax = nLeaves;
|
||||
pCutNew->pArray[0] = pObj->Id;
|
||||
Ivy_NodeCutHash( pCutNew );
|
||||
// add the trivial cut
|
||||
Ivy_NodeCutFindOrAdd( pCutStore, pCutNew );
|
||||
assert( pCutStore->nCuts == 1 );
|
||||
|
||||
// explore the cuts
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
// expand this cut
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->nSize == 0 )
|
||||
continue;
|
||||
for ( k = 0; k < pCut->nSize; k++ )
|
||||
{
|
||||
pLeaf = Ivy_ObjObj( pObj, pCut->pArray[k] );
|
||||
if ( Ivy_ObjIsCi(pLeaf) )
|
||||
continue;
|
||||
*pCutNew = *pCut;
|
||||
Ivy_NodeCutShrink( pCutNew, pLeaf->Id );
|
||||
if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) )
|
||||
continue;
|
||||
if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) )
|
||||
continue;
|
||||
Ivy_NodeCutHash( pCutNew );
|
||||
Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew );
|
||||
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
|
||||
break;
|
||||
}
|
||||
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
|
||||
break;
|
||||
}
|
||||
Ivy_NodeCompactCuts( pCutStore );
|
||||
// Ivy_NodePrintCuts( pCutStore );
|
||||
return pCutStore;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManTestCutsAll( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver;
|
||||
int clk = clock();
|
||||
nNodeTotal = nNodeOver = 0;
|
||||
nCutsTotal = -Ivy_ManNodeNum(p);
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( !Ivy_ObjIsNode(pObj) )
|
||||
continue;
|
||||
nCutsCut = Ivy_NodeFindCutsAll( pObj, 4 )->nCuts;
|
||||
nCutsTotal += nCutsCut;
|
||||
nNodeOver += (nCutsCut == IVY_CUT_LIMIT);
|
||||
nNodeTotal++;
|
||||
}
|
||||
printf( "Total cuts = %6d. Trivial = %6d. Nodes = %6d. Satur = %6d. ",
|
||||
nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p )
|
|||
Vec_Int_t * vNodes;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
// make sure the nodes are not marked
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
// collect the nodes
|
||||
vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );
|
||||
if ( Ivy_ManLatchNum(p) > 0 )
|
||||
|
|
@ -107,7 +110,7 @@ void Ivy_ManDfsExt_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes )
|
|||
// traverse the fanins
|
||||
vFanins = Ivy_ObjGetFanins( pObj );
|
||||
Vec_IntForEachEntry( vFanins, Fanin, i )
|
||||
Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_FanId(Fanin)), vNodes );
|
||||
Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_EdgeId(Fanin)), vNodes );
|
||||
// add the node
|
||||
Vec_IntPush( vNodes, pObj->Id );
|
||||
}
|
||||
|
|
@ -134,7 +137,7 @@ Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p )
|
|||
vNodes = Vec_IntAlloc( 10 );
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pFanin = Ivy_ManObj( p, Ivy_FanId( Ivy_ObjReadFanin(pObj,0) ) );
|
||||
pFanin = Ivy_ManObj( p, Ivy_EdgeId( Ivy_ObjReadFanin(pObj,0) ) );
|
||||
Ivy_ManDfsExt_rec( pFanin, vNodes );
|
||||
}
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
|
||||
|
|
@ -145,6 +148,132 @@ Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p )
|
|||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects nodes in the cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCollectCone_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vCone )
|
||||
{
|
||||
if ( pObj->fMarkA )
|
||||
return;
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
{
|
||||
Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone );
|
||||
Vec_PtrPush( vCone, pObj );
|
||||
return;
|
||||
}
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone );
|
||||
Ivy_ManCollectCone_rec( Ivy_ObjFanin1(pObj), vCone );
|
||||
Vec_PtrPushUnique( vCone, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects nodes in the cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone )
|
||||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
int i;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
// mark the nodes
|
||||
Vec_PtrForEachEntry( vFront, pTemp, i )
|
||||
Ivy_Regular(pTemp)->fMarkA = 1;
|
||||
assert( pObj->fMarkA == 0 );
|
||||
// collect the cone
|
||||
Vec_PtrClear( vCone );
|
||||
Ivy_ManCollectCone_rec( pObj, vCone );
|
||||
// unmark the nodes
|
||||
Vec_PtrForEachEntry( vFront, pTemp, i )
|
||||
Ivy_Regular(pTemp)->fMarkA = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the nodes by level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p )
|
||||
{
|
||||
Vec_Vec_t * vNodes;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
vNodes = Vec_VecAlloc( 100 );
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
assert( !Ivy_ObjIsBuf(pObj) );
|
||||
if ( Ivy_ObjIsNode(pObj) )
|
||||
Vec_VecPush( vNodes, pObj->Level, pObj );
|
||||
}
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes required levels for each node.]
|
||||
|
||||
Description [Assumes topological ordering of the nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
Vec_Int_t * vLevelsR;
|
||||
Vec_Vec_t * vNodes;
|
||||
int i, k, Level, LevelMax;
|
||||
assert( p->vRequired == NULL );
|
||||
// start the required times
|
||||
vLevelsR = Vec_IntStart( Ivy_ManObjIdNext(p) );
|
||||
// iterate through the nodes in the reverse order
|
||||
vNodes = Ivy_ManLevelize( p );
|
||||
Vec_VecForEachEntryReverseReverse( vNodes, pObj, i, k )
|
||||
{
|
||||
Level = Vec_IntEntry( vLevelsR, pObj->Id ) + 1 + Ivy_ObjIsExor(pObj);
|
||||
if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId0(pObj) ) < Level )
|
||||
Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId0(pObj), Level );
|
||||
if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId1(pObj) ) < Level )
|
||||
Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId1(pObj), Level );
|
||||
}
|
||||
Vec_VecFree( vNodes );
|
||||
// convert it into the required times
|
||||
LevelMax = Ivy_ManReadLevels( p );
|
||||
//printf( "max %5d\n",LevelMax );
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
Level = Vec_IntEntry( vLevelsR, pObj->Id );
|
||||
Vec_IntWriteEntry( vLevelsR, pObj->Id, LevelMax - Level );
|
||||
//printf( "%5d : %5d %5d\n", pObj->Id, Level, LevelMax - Level );
|
||||
}
|
||||
p->vRequired = vLevelsR;
|
||||
return vLevelsR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax )
|
|||
p = ALLOC( Ivy_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Ivy_Man_t) );
|
||||
p->nTravIds = 1;
|
||||
p->fCatchExor = 1;
|
||||
// AIG nodes
|
||||
p->nObjsAlloc = 1 + nPis + nPos + nNodesMax;
|
||||
// p->nObjsAlloc += (p->nObjsAlloc & 1); // make it even
|
||||
|
|
@ -191,12 +192,13 @@ void Ivy_ManPrintStats( Ivy_Man_t * p )
|
|||
{
|
||||
printf( "A = %d. ", Ivy_ManAndNum(p) );
|
||||
printf( "X = %d. ", Ivy_ManExorNum(p) );
|
||||
printf( "B = %d. ", Ivy_ManBufNum(p) );
|
||||
printf( "B = %4d. ", Ivy_ManBufNum(p) );
|
||||
}
|
||||
printf( "MaxID = %d. ", p->ObjIdNext-1 );
|
||||
printf( "All = %d. ", p->nObjsAlloc );
|
||||
// printf( "MaxID = %d. ", p->ObjIdNext-1 );
|
||||
// printf( "All = %d. ", p->nObjsAlloc );
|
||||
printf( "Cre = %d. ", p->nCreated );
|
||||
printf( "Del = %d. ", p->nDeleted );
|
||||
printf( "Lev = %d. ", Ivy_ManReadLevels(p) );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,186 +24,140 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Ivy_Eval_t_ Ivy_Eval_t;
|
||||
struct Ivy_Eval_t_
|
||||
#define IVY_EVAL_LIMIT 128
|
||||
|
||||
typedef struct Ivy_Eva_t_ Ivy_Eva_t;
|
||||
struct Ivy_Eva_t_
|
||||
{
|
||||
unsigned Mask : 5; // the mask of covered nodes
|
||||
unsigned Weight : 3; // the number of covered nodes
|
||||
unsigned Cost : 4; // the number of overlapping nodes
|
||||
unsigned Level : 12; // the level of this node
|
||||
unsigned Fan0 : 4; // the first fanin
|
||||
unsigned Fan1 : 4; // the second fanin
|
||||
Ivy_Obj_t * pArg; // the argument node
|
||||
unsigned Mask; // the mask of covered nodes
|
||||
int Weight; // the number of covered nodes
|
||||
};
|
||||
|
||||
static Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
static void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs );
|
||||
static int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode );
|
||||
static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
|
||||
static void Ivy_MultiPrint( Ivy_Eva_t * pEvals, int nLeaves, int nEvals );
|
||||
static int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the well-balanced tree of gates.]
|
||||
|
||||
Description [Disregards levels and possible logic sharing.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pObj1, * pObj2;
|
||||
if ( nObjs == 1 )
|
||||
return ppObjs[0];
|
||||
pObj1 = Ivy_Multi_rec( ppObjs, nObjs/2, Type );
|
||||
pObj2 = Ivy_Multi_rec( ppObjs + nObjs/2, nObjs - nObjs/2, Type );
|
||||
return Ivy_Oper( pObj1, pObj2, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs a balanced tree while taking sharing into account.]
|
||||
|
||||
Description []
|
||||
Description [Returns 1 if the implementation exists.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgsInit, int nArgs, Ivy_Type_t Type )
|
||||
int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSols )
|
||||
{
|
||||
static char NumBits[32] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5};
|
||||
static Ivy_Eval_t pEvals[15+15*14/2];
|
||||
static Ivy_Obj_t * pArgs[16];
|
||||
Ivy_Eval_t * pEva, * pEvaBest;
|
||||
int nArgsNew, nEvals, i, k;
|
||||
Ivy_Obj_t * pTemp;
|
||||
static Ivy_Eva_t pEvals[IVY_EVAL_LIMIT];
|
||||
Ivy_Eva_t * pEval, * pFan0, * pFan1;
|
||||
Ivy_Obj_t * pObj, * pTemp;
|
||||
int nEvals, nEvalsOld, i, k, x, nLeaves;
|
||||
unsigned uMaskAll;
|
||||
|
||||
// consider the case of one argument
|
||||
assert( nArgs > 0 );
|
||||
if ( nArgs == 1 )
|
||||
return pArgsInit[0];
|
||||
// consider the case of two arguments
|
||||
if ( nArgs == 2 )
|
||||
return Ivy_Oper( pArgsInit[0], pArgsInit[1], Type );
|
||||
// consider special cases
|
||||
nLeaves = Vec_PtrSize(vLeaves);
|
||||
assert( nLeaves > 2 );
|
||||
if ( nLeaves > 32 || nLeaves + Vec_PtrSize(vCone) > IVY_EVAL_LIMIT )
|
||||
return 0;
|
||||
// if ( nLeaves == 1 )
|
||||
// return Vec_PtrEntry( vLeaves, 0 );
|
||||
// if ( nLeaves == 2 )
|
||||
// return Ivy_Oper( Vec_PtrEntry(vLeaves, 0), Vec_PtrEntry(vLeaves, 1), Type );
|
||||
|
||||
//Ivy_MultiEval( pArgsInit, nArgs, Type ); printf( "\n" );
|
||||
|
||||
// set the initial ones
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
// set the leaf entries
|
||||
uMaskAll = ((1 << nLeaves) - 1);
|
||||
nEvals = 0;
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
{
|
||||
pArgs[i] = pArgsInit[i];
|
||||
pEva = pEvals + i;
|
||||
pEva->Mask = (1 << i);
|
||||
pEva->Weight = 1;
|
||||
pEva->Cost = 0;
|
||||
pEva->Level = Ivy_Regular(pArgs[i])->Level;
|
||||
pEva->Fan0 = 0;
|
||||
pEva->Fan1 = 0;
|
||||
pEval = pEvals + nEvals;
|
||||
pEval->pArg = pObj;
|
||||
pEval->Mask = (1 << nEvals);
|
||||
pEval->Weight = 1;
|
||||
// mark the leaf
|
||||
Ivy_Regular(pObj)->TravId = nEvals;
|
||||
nEvals++;
|
||||
}
|
||||
|
||||
// propagate masks through the cone
|
||||
Vec_PtrForEachEntry( vCone, pObj, i )
|
||||
{
|
||||
pObj->TravId = nEvals + i;
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
pEvals[pObj->TravId].Mask = pEvals[Ivy_ObjFanin0(pObj)->TravId].Mask;
|
||||
else
|
||||
pEvals[pObj->TravId].Mask = pEvals[Ivy_ObjFanin0(pObj)->TravId].Mask | pEvals[Ivy_ObjFanin1(pObj)->TravId].Mask;
|
||||
}
|
||||
|
||||
// set the internal entries
|
||||
Vec_PtrForEachEntry( vCone, pObj, i )
|
||||
{
|
||||
if ( i == Vec_PtrSize(vCone) - 1 )
|
||||
break;
|
||||
// skip buffers
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
continue;
|
||||
// skip nodes without external fanout
|
||||
if ( Ivy_ObjRefs(pObj) == 0 )
|
||||
continue;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
pEval = pEvals + nEvals;
|
||||
pEval->pArg = pObj;
|
||||
pEval->Mask = pEvals[pObj->TravId].Mask;
|
||||
pEval->Weight = Extra_WordCountOnes(pEval->Mask);
|
||||
// mark the node
|
||||
pObj->TravId = nEvals;
|
||||
nEvals++;
|
||||
}
|
||||
|
||||
// find the available nodes
|
||||
pEvaBest = pEvals;
|
||||
nArgsNew = nArgs;
|
||||
for ( i = 1; i < nArgsNew; i++ )
|
||||
nEvalsOld = nEvals;
|
||||
for ( i = 1; i < nEvals; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)) )
|
||||
{
|
||||
pEva = pEvals + nArgsNew;
|
||||
pEva->Mask = pEvals[k].Mask | pEvals[i].Mask;
|
||||
pEva->Weight = NumBits[pEva->Mask];
|
||||
pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];
|
||||
pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);
|
||||
pEva->Fan0 = k;
|
||||
pEva->Fan1 = i;
|
||||
// assert( pEva->Level == (unsigned)Ivy_ObjLevel(pTemp) );
|
||||
// compare
|
||||
if ( pEvaBest->Weight < pEva->Weight ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level )
|
||||
pEvaBest = pEva;
|
||||
// save the argument
|
||||
pArgs[nArgsNew++] = pTemp;
|
||||
if ( nArgsNew == 15 )
|
||||
goto Outside;
|
||||
}
|
||||
{
|
||||
pFan0 = pEvals + i;
|
||||
pFan1 = pEvals + k;
|
||||
pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pFan0->pArg, pFan1->pArg, Type, IVY_INIT_NONE));
|
||||
// skip nodes in the cone
|
||||
if ( pTemp == NULL || pTemp->fMarkB )
|
||||
continue;
|
||||
// skip the leaves
|
||||
for ( x = 0; x < nLeaves; x++ )
|
||||
if ( pTemp == Ivy_Regular(vLeaves->pArray[x]) )
|
||||
break;
|
||||
if ( x < nLeaves )
|
||||
continue;
|
||||
pEval = pEvals + nEvals;
|
||||
pEval->pArg = pTemp;
|
||||
pEval->Mask = pFan0->Mask | pFan1->Mask;
|
||||
pEval->Weight = (pFan0->Mask & pFan1->Mask) ? Extra_WordCountOnes(pEval->Mask) : pFan0->Weight + pFan1->Weight;
|
||||
// save the argument
|
||||
pObj->TravId = nEvals;
|
||||
nEvals++;
|
||||
// quit if the number of entries exceeded the limit
|
||||
if ( nEvals == IVY_EVAL_LIMIT )
|
||||
goto Outside;
|
||||
// quit if we found an acceptable implementation
|
||||
if ( pEval->Mask == uMaskAll )
|
||||
goto Outside;
|
||||
}
|
||||
Outside:
|
||||
|
||||
// printf( "Best = %d.\n", pEvaBest - pEvals );
|
||||
|
||||
// the case of no common nodes
|
||||
if ( nArgsNew == nArgs )
|
||||
{
|
||||
Ivy_MultiSort( pArgs, nArgs );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
// the case of one common node
|
||||
if ( nArgsNew == nArgs + 1 )
|
||||
{
|
||||
assert( pEvaBest - pEvals == nArgs );
|
||||
k = 0;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( i != (int)pEvaBest->Fan0 && i != (int)pEvaBest->Fan1 )
|
||||
pArgs[k++] = pArgs[i];
|
||||
pArgs[k++] = pArgs[nArgs];
|
||||
assert( k == nArgs - 1 );
|
||||
nArgs = k;
|
||||
Ivy_MultiSort( pArgs, nArgs );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
// the case when there is a node that covers everything
|
||||
if ( (int)pEvaBest->Mask == ((1 << nArgs) - 1) )
|
||||
return Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );
|
||||
|
||||
// evaluate node pairs
|
||||
nEvals = nArgsNew;
|
||||
for ( i = 1; i < nArgsNew; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
{
|
||||
pEva = pEvals + nEvals;
|
||||
pEva->Mask = pEvals[k].Mask | pEvals[i].Mask;
|
||||
pEva->Weight = NumBits[pEva->Mask];
|
||||
pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];
|
||||
pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);
|
||||
pEva->Fan0 = k;
|
||||
pEva->Fan1 = i;
|
||||
// compare
|
||||
if ( pEvaBest->Weight < pEva->Weight ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level )
|
||||
pEvaBest = pEva;
|
||||
// save the argument
|
||||
nEvals++;
|
||||
}
|
||||
assert( pEvaBest - pEvals >= nArgsNew );
|
||||
|
||||
// printf( "Used (%d, %d).\n", pEvaBest->Fan0, pEvaBest->Fan1 );
|
||||
|
||||
// get the best implementation
|
||||
pTemp = Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );
|
||||
|
||||
// collect those not covered by EvaBest
|
||||
k = 0;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( (pEvaBest->Mask & (1 << i)) == 0 )
|
||||
pArgs[k++] = pArgs[i];
|
||||
pArgs[k++] = pTemp;
|
||||
assert( k == nArgs - (int)pEvaBest->Weight + 1 );
|
||||
nArgs = k;
|
||||
Ivy_MultiSort( pArgs, nArgs );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
// Ivy_MultiPrint( pEvals, nLeaves, nEvals );
|
||||
if ( !Ivy_MultiCover( pEvals, nLeaves, nEvals, nLimit, vSols ) )
|
||||
return 0;
|
||||
assert( Vec_PtrSize( vSols ) > 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements multi-input AND/EXOR operation.]
|
||||
Synopsis [Computes how many uncovered ones this one covers.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -212,212 +166,132 @@ Outside:
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
void Ivy_MultiPrint( Ivy_Eva_t * pEvals, int nLeaves, int nEvals )
|
||||
{
|
||||
Ivy_Obj_t * pNode0, * pNode1;
|
||||
if ( iNum < nArgs )
|
||||
return pArgs[iNum];
|
||||
pNode0 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan0, pArgs, nArgs, Type );
|
||||
pNode1 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan1, pArgs, nArgs, Type );
|
||||
return Ivy_Oper( pNode0, pNode1, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Selection-sorts the nodes in the decreasing over of level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs )
|
||||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
int i, j, iBest;
|
||||
|
||||
for ( i = 0; i < nArgs-1; i++ )
|
||||
{
|
||||
iBest = i;
|
||||
for ( j = i+1; j < nArgs; j++ )
|
||||
if ( Ivy_Regular(pArgs[j])->Level > Ivy_Regular(pArgs[iBest])->Level )
|
||||
iBest = j;
|
||||
pTemp = pArgs[i];
|
||||
pArgs[i] = pArgs[iBest];
|
||||
pArgs[iBest] = pTemp;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts a new node in the order by levels.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode )
|
||||
{
|
||||
Ivy_Obj_t * pNode1, * pNode2;
|
||||
int i;
|
||||
// try to find the node in the array
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( pArray[i] == pNode )
|
||||
return nArgs;
|
||||
// put the node last
|
||||
pArray[nArgs++] = pNode;
|
||||
// find the place to put the new node
|
||||
for ( i = nArgs-1; i > 0; i-- )
|
||||
{
|
||||
pNode1 = pArray[i ];
|
||||
pNode2 = pArray[i-1];
|
||||
if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level )
|
||||
break;
|
||||
pArray[i ] = pNode2;
|
||||
pArray[i-1] = pNode1;
|
||||
}
|
||||
return nArgs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Balances the array recursively.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pNodeNew;
|
||||
// consider the case of one argument
|
||||
assert( nArgs > 0 );
|
||||
if ( nArgs == 1 )
|
||||
return pArgs[0];
|
||||
// consider the case of two arguments
|
||||
if ( nArgs == 2 )
|
||||
return Ivy_Oper( pArgs[0], pArgs[1], Type );
|
||||
// get the last two nodes
|
||||
pNodeNew = Ivy_Oper( pArgs[nArgs-1], pArgs[nArgs-2], Type );
|
||||
// add the new node
|
||||
nArgs = Ivy_MultiPushUniqueOrderByLevel( pArgs, nArgs - 2, pNodeNew );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements multi-input AND/EXOR operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
Ivy_Eva_t * pEval;
|
||||
int i, k;
|
||||
int nArgsOld = nArgs;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
printf( "%d[%d] ", i, Ivy_Regular(pArgs[i])->Level );
|
||||
for ( i = 1; i < nArgs; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
for ( i = nLeaves; i < nEvals; i++ )
|
||||
{
|
||||
pEval = pEvals + i;
|
||||
printf( "%2d (id = %5d) : |", i-nLeaves, Ivy_ObjId(pEval->pArg) );
|
||||
for ( k = 0; k < nLeaves; k++ )
|
||||
{
|
||||
pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE));
|
||||
if ( pTemp != NULL )
|
||||
if ( pEval->Mask & (1 << k) )
|
||||
printf( "+" );
|
||||
else
|
||||
printf( " " );
|
||||
}
|
||||
printf( "| Lev = %d.\n", Ivy_ObjLevel(pEval->pArg) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes how many uncovered ones this one covers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_MultiWeight( unsigned uMask, int nMaskOnes, unsigned uFound )
|
||||
{
|
||||
assert( uMask & ~uFound );
|
||||
if ( (uMask & uFound) == 0 )
|
||||
return nMaskOnes;
|
||||
return Extra_WordCountOnes( uMask & ~uFound );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds the cover.]
|
||||
|
||||
Description [Returns 1 if the cover is found.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
Ivy_Eva_t * pEval, * pEvalBest;
|
||||
unsigned uMaskAll, uFound, uTemp;
|
||||
int i, k, BestK, WeightBest, WeightCur, LevelBest, LevelCur;
|
||||
uMaskAll = (nLeaves == 32)? (~(unsigned)0) : ((1 << nLeaves) - 1);
|
||||
uFound = 0;
|
||||
// solve the covering problem
|
||||
if ( fVerbose )
|
||||
printf( "Solution: " );
|
||||
Vec_PtrClear( vSols );
|
||||
for ( i = 0; i < nLimit; i++ )
|
||||
{
|
||||
BestK = -1;
|
||||
for ( k = nEvals - 1; k >= 0; k-- )
|
||||
{
|
||||
pEval = pEvals + k;
|
||||
if ( (pEval->Mask & ~uFound) == 0 )
|
||||
continue;
|
||||
if ( BestK == -1 )
|
||||
{
|
||||
printf( "%d[%d]=(%d,%d) ", nArgs, Ivy_Regular(pTemp)->Level, k, i );
|
||||
pArgs[nArgs++] = pTemp;
|
||||
BestK = k;
|
||||
pEvalBest = pEval;
|
||||
WeightBest = Ivy_MultiWeight( pEvalBest->Mask, pEvalBest->Weight, uFound );
|
||||
LevelBest = Ivy_ObjLevel( Ivy_Regular(pEvalBest->pArg) );
|
||||
continue;
|
||||
}
|
||||
// compare BestK and the new one (k)
|
||||
WeightCur = Ivy_MultiWeight( pEval->Mask, pEval->Weight, uFound );
|
||||
LevelCur = Ivy_ObjLevel( Ivy_Regular(pEval->pArg) );
|
||||
if ( WeightBest < WeightCur ||
|
||||
(WeightBest == WeightCur && LevelBest > LevelCur) )
|
||||
{
|
||||
BestK = k;
|
||||
pEvalBest = pEval;
|
||||
WeightBest = WeightCur;
|
||||
LevelBest = LevelCur;
|
||||
}
|
||||
}
|
||||
printf( " ((%d/%d)) ", nArgsOld, nArgs-nArgsOld );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Old code.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pArgsRef[5], * pTemp;
|
||||
int i, k, m, nArgsNew, Counter = 0;
|
||||
|
||||
|
||||
//Ivy_MultiEval( pArgs, nArgs, Type ); printf( "\n" );
|
||||
|
||||
|
||||
assert( Type == IVY_AND || Type == IVY_EXOR );
|
||||
assert( nArgs > 0 );
|
||||
if ( nArgs == 1 )
|
||||
return pArgs[0];
|
||||
|
||||
// find the nodes with more than one fanout
|
||||
nArgsNew = 0;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( Ivy_ObjRefs( Ivy_Regular(pArgs[i]) ) > 0 )
|
||||
pArgsRef[nArgsNew++] = pArgs[i];
|
||||
|
||||
// go through pairs
|
||||
if ( nArgsNew >= 2 )
|
||||
for ( i = 0; i < nArgsNew; i++ )
|
||||
for ( k = i + 1; k < nArgsNew; k++ )
|
||||
if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) )
|
||||
Counter++;
|
||||
// printf( "%d", Counter );
|
||||
|
||||
// go through pairs
|
||||
if ( nArgsNew >= 2 )
|
||||
for ( i = 0; i < nArgsNew; i++ )
|
||||
for ( k = i + 1; k < nArgsNew; k++ )
|
||||
if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) )
|
||||
assert( BestK != -1 );
|
||||
// if the cost is only 1, take the leaf
|
||||
if ( WeightBest == 1 && BestK >= nLeaves )
|
||||
{
|
||||
nArgsNew = 0;
|
||||
for ( m = 0; m < nArgs; m++ )
|
||||
if ( pArgs[m] != pArgsRef[i] && pArgs[m] != pArgsRef[k] )
|
||||
pArgs[nArgsNew++] = pArgs[m];
|
||||
pArgs[nArgsNew++] = pTemp;
|
||||
assert( nArgsNew == nArgs - 1 );
|
||||
return Ivy_Multi1( pArgs, nArgsNew, Type );
|
||||
uTemp = (pEvalBest->Mask & ~uFound);
|
||||
for ( k = 0; k < nLeaves; k++ )
|
||||
if ( uTemp & (1 << k) )
|
||||
break;
|
||||
assert( k < nLeaves );
|
||||
BestK = k;
|
||||
pEvalBest = pEvals + BestK;
|
||||
}
|
||||
return Ivy_Multi_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Old code.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
assert( Type == IVY_AND || Type == IVY_EXOR );
|
||||
assert( nArgs > 0 );
|
||||
return Ivy_Multi_rec( pArgs, nArgs, Type );
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( BestK < nLeaves )
|
||||
printf( "L(%d) ", BestK );
|
||||
else
|
||||
printf( "%d ", BestK - nLeaves );
|
||||
}
|
||||
// update the found set
|
||||
Vec_PtrPush( vSols, pEvalBest->pArg );
|
||||
uFound |= pEvalBest->Mask;
|
||||
if ( uFound == uMaskAll )
|
||||
break;
|
||||
}
|
||||
if ( uFound == uMaskAll )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " Found \n\n" );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " Not found \n\n" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,427 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyMulti.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Constructing multi-input AND/EXOR gates.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyMulti.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Ivy_Eval_t_ Ivy_Eval_t;
|
||||
struct Ivy_Eval_t_
|
||||
{
|
||||
unsigned Mask : 5; // the mask of covered nodes
|
||||
unsigned Weight : 3; // the number of covered nodes
|
||||
unsigned Cost : 4; // the number of overlapping nodes
|
||||
unsigned Level : 12; // the level of this node
|
||||
unsigned Fan0 : 4; // the first fanin
|
||||
unsigned Fan1 : 4; // the second fanin
|
||||
};
|
||||
|
||||
static Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
static void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs );
|
||||
static int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode );
|
||||
static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the well-balanced tree of gates.]
|
||||
|
||||
Description [Disregards levels and possible logic sharing.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pObj1, * pObj2;
|
||||
if ( nObjs == 1 )
|
||||
return ppObjs[0];
|
||||
pObj1 = Ivy_Multi_rec( ppObjs, nObjs/2, Type );
|
||||
pObj2 = Ivy_Multi_rec( ppObjs + nObjs/2, nObjs - nObjs/2, Type );
|
||||
return Ivy_Oper( pObj1, pObj2, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs a balanced tree while taking sharing into account.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgsInit, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
static char NumBits[32] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5};
|
||||
static Ivy_Eval_t pEvals[15+15*14/2];
|
||||
static Ivy_Obj_t * pArgs[16];
|
||||
Ivy_Eval_t * pEva, * pEvaBest;
|
||||
int nArgsNew, nEvals, i, k;
|
||||
Ivy_Obj_t * pTemp;
|
||||
|
||||
// consider the case of one argument
|
||||
assert( nArgs > 0 );
|
||||
if ( nArgs == 1 )
|
||||
return pArgsInit[0];
|
||||
// consider the case of two arguments
|
||||
if ( nArgs == 2 )
|
||||
return Ivy_Oper( pArgsInit[0], pArgsInit[1], Type );
|
||||
|
||||
//Ivy_MultiEval( pArgsInit, nArgs, Type ); printf( "\n" );
|
||||
|
||||
// set the initial ones
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
{
|
||||
pArgs[i] = pArgsInit[i];
|
||||
pEva = pEvals + i;
|
||||
pEva->Mask = (1 << i);
|
||||
pEva->Weight = 1;
|
||||
pEva->Cost = 0;
|
||||
pEva->Level = Ivy_Regular(pArgs[i])->Level;
|
||||
pEva->Fan0 = 0;
|
||||
pEva->Fan1 = 0;
|
||||
}
|
||||
|
||||
// find the available nodes
|
||||
pEvaBest = pEvals;
|
||||
nArgsNew = nArgs;
|
||||
for ( i = 1; i < nArgsNew; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)) )
|
||||
{
|
||||
pEva = pEvals + nArgsNew;
|
||||
pEva->Mask = pEvals[k].Mask | pEvals[i].Mask;
|
||||
pEva->Weight = NumBits[pEva->Mask];
|
||||
pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];
|
||||
pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);
|
||||
pEva->Fan0 = k;
|
||||
pEva->Fan1 = i;
|
||||
// assert( pEva->Level == (unsigned)Ivy_ObjLevel(pTemp) );
|
||||
// compare
|
||||
if ( pEvaBest->Weight < pEva->Weight ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level )
|
||||
pEvaBest = pEva;
|
||||
// save the argument
|
||||
pArgs[nArgsNew++] = pTemp;
|
||||
if ( nArgsNew == 15 )
|
||||
goto Outside;
|
||||
}
|
||||
Outside:
|
||||
|
||||
// printf( "Best = %d.\n", pEvaBest - pEvals );
|
||||
|
||||
// the case of no common nodes
|
||||
if ( nArgsNew == nArgs )
|
||||
{
|
||||
Ivy_MultiSort( pArgs, nArgs );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
// the case of one common node
|
||||
if ( nArgsNew == nArgs + 1 )
|
||||
{
|
||||
assert( pEvaBest - pEvals == nArgs );
|
||||
k = 0;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( i != (int)pEvaBest->Fan0 && i != (int)pEvaBest->Fan1 )
|
||||
pArgs[k++] = pArgs[i];
|
||||
pArgs[k++] = pArgs[nArgs];
|
||||
assert( k == nArgs - 1 );
|
||||
nArgs = k;
|
||||
Ivy_MultiSort( pArgs, nArgs );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
// the case when there is a node that covers everything
|
||||
if ( (int)pEvaBest->Mask == ((1 << nArgs) - 1) )
|
||||
return Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );
|
||||
|
||||
// evaluate node pairs
|
||||
nEvals = nArgsNew;
|
||||
for ( i = 1; i < nArgsNew; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
{
|
||||
pEva = pEvals + nEvals;
|
||||
pEva->Mask = pEvals[k].Mask | pEvals[i].Mask;
|
||||
pEva->Weight = NumBits[pEva->Mask];
|
||||
pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];
|
||||
pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);
|
||||
pEva->Fan0 = k;
|
||||
pEva->Fan1 = i;
|
||||
// compare
|
||||
if ( pEvaBest->Weight < pEva->Weight ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost ||
|
||||
pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level )
|
||||
pEvaBest = pEva;
|
||||
// save the argument
|
||||
nEvals++;
|
||||
}
|
||||
assert( pEvaBest - pEvals >= nArgsNew );
|
||||
|
||||
// printf( "Used (%d, %d).\n", pEvaBest->Fan0, pEvaBest->Fan1 );
|
||||
|
||||
// get the best implementation
|
||||
pTemp = Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );
|
||||
|
||||
// collect those not covered by EvaBest
|
||||
k = 0;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( (pEvaBest->Mask & (1 << i)) == 0 )
|
||||
pArgs[k++] = pArgs[i];
|
||||
pArgs[k++] = pTemp;
|
||||
assert( k == nArgs - (int)pEvaBest->Weight + 1 );
|
||||
nArgs = k;
|
||||
Ivy_MultiSort( pArgs, nArgs );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements multi-input AND/EXOR operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pNode0, * pNode1;
|
||||
if ( iNum < nArgs )
|
||||
return pArgs[iNum];
|
||||
pNode0 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan0, pArgs, nArgs, Type );
|
||||
pNode1 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan1, pArgs, nArgs, Type );
|
||||
return Ivy_Oper( pNode0, pNode1, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Selection-sorts the nodes in the decreasing over of level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs )
|
||||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
int i, j, iBest;
|
||||
|
||||
for ( i = 0; i < nArgs-1; i++ )
|
||||
{
|
||||
iBest = i;
|
||||
for ( j = i+1; j < nArgs; j++ )
|
||||
if ( Ivy_Regular(pArgs[j])->Level > Ivy_Regular(pArgs[iBest])->Level )
|
||||
iBest = j;
|
||||
pTemp = pArgs[i];
|
||||
pArgs[i] = pArgs[iBest];
|
||||
pArgs[iBest] = pTemp;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts a new node in the order by levels.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode )
|
||||
{
|
||||
Ivy_Obj_t * pNode1, * pNode2;
|
||||
int i;
|
||||
// try to find the node in the array
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( pArray[i] == pNode )
|
||||
return nArgs;
|
||||
// put the node last
|
||||
pArray[nArgs++] = pNode;
|
||||
// find the place to put the new node
|
||||
for ( i = nArgs-1; i > 0; i-- )
|
||||
{
|
||||
pNode1 = pArray[i ];
|
||||
pNode2 = pArray[i-1];
|
||||
if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level )
|
||||
break;
|
||||
pArray[i ] = pNode2;
|
||||
pArray[i-1] = pNode1;
|
||||
}
|
||||
return nArgs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Balances the array recursively.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pNodeNew;
|
||||
// consider the case of one argument
|
||||
assert( nArgs > 0 );
|
||||
if ( nArgs == 1 )
|
||||
return pArgs[0];
|
||||
// consider the case of two arguments
|
||||
if ( nArgs == 2 )
|
||||
return Ivy_Oper( pArgs[0], pArgs[1], Type );
|
||||
// get the last two nodes
|
||||
pNodeNew = Ivy_Oper( pArgs[nArgs-1], pArgs[nArgs-2], Type );
|
||||
// add the new node
|
||||
nArgs = Ivy_MultiPushUniqueOrderByLevel( pArgs, nArgs - 2, pNodeNew );
|
||||
return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements multi-input AND/EXOR operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pTemp;
|
||||
int i, k;
|
||||
int nArgsOld = nArgs;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
printf( "%d[%d] ", i, Ivy_Regular(pArgs[i])->Level );
|
||||
for ( i = 1; i < nArgs; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
{
|
||||
pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE));
|
||||
if ( pTemp != NULL )
|
||||
{
|
||||
printf( "%d[%d]=(%d,%d) ", nArgs, Ivy_Regular(pTemp)->Level, k, i );
|
||||
pArgs[nArgs++] = pTemp;
|
||||
}
|
||||
}
|
||||
printf( " ((%d/%d)) ", nArgsOld, nArgs-nArgsOld );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Old code.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pArgsRef[5], * pTemp;
|
||||
int i, k, m, nArgsNew, Counter = 0;
|
||||
|
||||
|
||||
//Ivy_MultiEval( pArgs, nArgs, Type ); printf( "\n" );
|
||||
|
||||
|
||||
assert( Type == IVY_AND || Type == IVY_EXOR );
|
||||
assert( nArgs > 0 );
|
||||
if ( nArgs == 1 )
|
||||
return pArgs[0];
|
||||
|
||||
// find the nodes with more than one fanout
|
||||
nArgsNew = 0;
|
||||
for ( i = 0; i < nArgs; i++ )
|
||||
if ( Ivy_ObjRefs( Ivy_Regular(pArgs[i]) ) > 0 )
|
||||
pArgsRef[nArgsNew++] = pArgs[i];
|
||||
|
||||
// go through pairs
|
||||
if ( nArgsNew >= 2 )
|
||||
for ( i = 0; i < nArgsNew; i++ )
|
||||
for ( k = i + 1; k < nArgsNew; k++ )
|
||||
if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) )
|
||||
Counter++;
|
||||
// printf( "%d", Counter );
|
||||
|
||||
// go through pairs
|
||||
if ( nArgsNew >= 2 )
|
||||
for ( i = 0; i < nArgsNew; i++ )
|
||||
for ( k = i + 1; k < nArgsNew; k++ )
|
||||
if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) )
|
||||
{
|
||||
nArgsNew = 0;
|
||||
for ( m = 0; m < nArgs; m++ )
|
||||
if ( pArgs[m] != pArgsRef[i] && pArgs[m] != pArgsRef[k] )
|
||||
pArgs[nArgsNew++] = pArgs[m];
|
||||
pArgs[nArgsNew++] = pTemp;
|
||||
assert( nArgsNew == nArgs - 1 );
|
||||
return Ivy_Multi1( pArgs, nArgsNew, Type );
|
||||
}
|
||||
return Ivy_Multi_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Old code.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
|
||||
{
|
||||
assert( Type == IVY_AND || Type == IVY_EXOR );
|
||||
assert( nArgs > 0 );
|
||||
return Ivy_Multi_rec( pArgs, nArgs, Type );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -51,6 +51,7 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost )
|
|||
// realloc the node array
|
||||
if ( p->ObjIdNext == p->nObjsAlloc )
|
||||
{
|
||||
printf( "AIG manager is being resized. In the current release, it is not allowed!\n" );
|
||||
Ivy_ManGrow( p );
|
||||
pGhost = Ivy_ManGhost( p );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )
|
|||
Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
{
|
||||
Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
|
||||
Ivy_Obj_t * pFan0, * pFan1;
|
||||
// Ivy_Obj_t * pFan0, * pFan1;
|
||||
// check trivial cases
|
||||
if ( p0 == p1 )
|
||||
return p0;
|
||||
|
|
@ -92,8 +92,8 @@ Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
|||
if ( Ivy_Regular(p1) == pConst1 )
|
||||
return p1 == pConst1 ? p0 : Ivy_Not(pConst1);
|
||||
// check if it can be an EXOR gate
|
||||
if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
|
||||
return Ivy_CanonExor( pFan0, pFan1 );
|
||||
// if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
|
||||
// return Ivy_CanonExor( pFan0, pFan1 );
|
||||
return Ivy_CanonAnd( p0, p1 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyResyn.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [AIG rewriting script.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyResyn.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs several passes of rewriting on the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * pMan, int fUpdateLevel )
|
||||
{
|
||||
int clk, fVerbose = 0;
|
||||
Ivy_Man_t * pTemp;
|
||||
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pMan, fUpdateLevel );
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 0 );
|
||||
clk = clock();
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, 0, 0 );
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 );
|
||||
clk = clock();
|
||||
if ( fVerbose ) Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 );
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 );
|
||||
clk = clock();
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 );
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyRwrAlg.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Algebraic AIG rewriting.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyRwrAlg.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
|
||||
static Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost );
|
||||
static int Ivy_NodeCountMffc( Ivy_Obj_t * pNode );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Algebraic AIG rewriting.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
|
||||
{
|
||||
Vec_Int_t * vRequired;
|
||||
Vec_Ptr_t * vFront, * vLeaves, * vCone, * vSol;
|
||||
Ivy_Obj_t * pObj, * pResult;
|
||||
int i, RetValue, LevelR, nNodesOld;
|
||||
int CountUsed, CountUndo;
|
||||
vRequired = fUpdateLevel? Ivy_ManRequiredLevels( p ) : NULL;
|
||||
vFront = Vec_PtrAlloc( 100 );
|
||||
vLeaves = Vec_PtrAlloc( 100 );
|
||||
vCone = Vec_PtrAlloc( 100 );
|
||||
vSol = Vec_PtrAlloc( 100 );
|
||||
// go through the nodes in the topological order
|
||||
CountUsed = CountUndo = 0;
|
||||
nNodesOld = Ivy_ManObjIdNext(p);
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
assert( !Ivy_ObjIsBuf(pObj) );
|
||||
if ( i >= nNodesOld )
|
||||
break;
|
||||
// skip no-nodes and MUX roots
|
||||
if ( !Ivy_ObjIsNode(pObj) || Ivy_ObjIsExor(pObj) || Ivy_ObjIsMuxType(pObj) )
|
||||
continue;
|
||||
// if ( pObj->Id > 297 ) // 296 --- 297
|
||||
// break;
|
||||
if ( pObj->Id == 297 )
|
||||
{
|
||||
int x = 0;
|
||||
}
|
||||
// get the largest algebraic cut
|
||||
RetValue = Ivy_ManFindAlgCut( pObj, vFront, vLeaves, vCone );
|
||||
// the case of a trivial tree cut
|
||||
if ( RetValue == 1 )
|
||||
continue;
|
||||
// the case of constant 0 cone
|
||||
if ( RetValue == -1 )
|
||||
{
|
||||
Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0 );
|
||||
continue;
|
||||
}
|
||||
assert( Vec_PtrSize(vLeaves) > 2 );
|
||||
// get the required level for this node
|
||||
LevelR = vRequired? Vec_IntEntry(vRequired, pObj->Id) : 1000000;
|
||||
// create a new cone
|
||||
pResult = Ivy_NodeRewriteAlg( pObj, vFront, vLeaves, vCone, vSol, LevelR, fUseZeroCost );
|
||||
if ( pResult == NULL || pResult == pObj )
|
||||
continue;
|
||||
assert( Vec_PtrSize(vSol) == 1 || !Ivy_IsComplement(pResult) );
|
||||
if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 )
|
||||
Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++;
|
||||
else
|
||||
Ivy_ObjReplace( pObj, pResult, 1, 0 ), CountUsed++;
|
||||
}
|
||||
printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo );
|
||||
Vec_PtrFree( vFront );
|
||||
Vec_PtrFree( vCone );
|
||||
Vec_PtrFree( vSol );
|
||||
if ( vRequired ) Vec_IntFree( vRequired );
|
||||
if ( i = Ivy_ManCleanup(p) )
|
||||
printf( "Cleanup after rewriting removed %d dangling nodes.\n", i );
|
||||
if ( !Ivy_ManCheck(p) )
|
||||
printf( "Ivy_ManRewriteAlg(): The check has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Analizes one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
Ivy_Obj_t * pTemp;
|
||||
int k, Counter, nMffc, RetValue;
|
||||
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( Ivy_ObjIsExor(pObj) )
|
||||
printf( "x " );
|
||||
else
|
||||
printf( " " );
|
||||
}
|
||||
|
||||
/*
|
||||
printf( "%d ", Vec_PtrSize(vFront) );
|
||||
printf( "( " );
|
||||
Vec_PtrForEachEntry( vFront, pTemp, k )
|
||||
printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) );
|
||||
printf( ")\n" );
|
||||
*/
|
||||
// collect nodes in the cone
|
||||
if ( Ivy_ObjIsExor(pObj) )
|
||||
Ivy_ManCollectCone( pObj, vFront, vCone );
|
||||
else
|
||||
Ivy_ManCollectCone( pObj, vLeaves, vCone );
|
||||
|
||||
// deref nodes in the cone
|
||||
Vec_PtrForEachEntry( vCone, pTemp, k )
|
||||
{
|
||||
Ivy_ObjRefsDec( Ivy_ObjFanin0(pTemp) );
|
||||
Ivy_ObjRefsDec( Ivy_ObjFanin1(pTemp) );
|
||||
pTemp->fMarkB = 1;
|
||||
}
|
||||
|
||||
// count the MFFC size
|
||||
Vec_PtrForEachEntry( vFront, pTemp, k )
|
||||
Ivy_Regular(pTemp)->fMarkA = 1;
|
||||
nMffc = Ivy_NodeCountMffc( pObj );
|
||||
Vec_PtrForEachEntry( vFront, pTemp, k )
|
||||
Ivy_Regular(pTemp)->fMarkA = 0;
|
||||
|
||||
if ( fVerbose )
|
||||
{
|
||||
Counter = 0;
|
||||
Vec_PtrForEachEntry( vCone, pTemp, k )
|
||||
Counter += (Ivy_ObjRefs(pTemp) > 0);
|
||||
printf( "%5d : Leaves = %2d. Cone = %2d. ConeRef = %2d. Mffc = %d. Lev = %d. LevR = %d.\n",
|
||||
pObj->Id, Vec_PtrSize(vFront), Vec_PtrSize(vCone), Counter-1, nMffc, Ivy_ObjLevel(pObj), LevelR );
|
||||
}
|
||||
/*
|
||||
printf( "Leaves:" );
|
||||
Vec_PtrForEachEntry( vLeaves, pTemp, k )
|
||||
printf( " %d%s", Ivy_Regular(pTemp)->Id, Ivy_IsComplement(pTemp)? "\'" : "" );
|
||||
printf( "\n" );
|
||||
printf( "Cone:\n" );
|
||||
Vec_PtrForEachEntry( vCone, pTemp, k )
|
||||
printf( " %5d = %d%s %d%s\n", pTemp->Id,
|
||||
Ivy_ObjFaninId0(pTemp), Ivy_ObjFaninC0(pTemp)? "\'" : "",
|
||||
Ivy_ObjFaninId1(pTemp), Ivy_ObjFaninC1(pTemp)? "\'" : "" );
|
||||
*/
|
||||
|
||||
RetValue = Ivy_MultiPlus( vLeaves, vCone, Ivy_ObjType(pObj), nMffc + fUseZeroCost, vSols );
|
||||
|
||||
// ref nodes in the cone
|
||||
Vec_PtrForEachEntry( vCone, pTemp, k )
|
||||
{
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin0(pTemp) );
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin1(pTemp) );
|
||||
pTemp->fMarkA = 0;
|
||||
pTemp->fMarkB = 0;
|
||||
}
|
||||
|
||||
if ( !RetValue )
|
||||
return NULL;
|
||||
|
||||
if ( Vec_PtrSize( vSols ) == 1 )
|
||||
return Vec_PtrEntry( vSols, 0 );
|
||||
return Ivy_NodeBalanceBuildSuper( vSols, Ivy_ObjType(pObj), 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison for node pointers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeCountMffc_rec( Ivy_Obj_t * pNode )
|
||||
{
|
||||
if ( Ivy_ObjRefs(pNode) > 0 || Ivy_ObjIsCi(pNode) || pNode->fMarkA )
|
||||
return 0;
|
||||
assert( pNode->fMarkB );
|
||||
pNode->fMarkA = 1;
|
||||
// printf( "%d ", pNode->Id );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
return Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) );
|
||||
return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison for node pointers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeCountMffc( Ivy_Obj_t * pNode )
|
||||
{
|
||||
assert( pNode->fMarkB );
|
||||
return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison for node pointers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindAlgCutCompare( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computing one algebraic cut.]
|
||||
|
||||
Description [Returns 1 if the tree-leaves of this node where traversed
|
||||
and found to have no external references (and have not been collected).
|
||||
Returns 0 if the tree-leaves have external references and are collected.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindAlgCut_rec( Ivy_Obj_t * pObj, Ivy_Type_t Type, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone )
|
||||
{
|
||||
int RetValue0, RetValue1;
|
||||
Ivy_Obj_t * pObjR = Ivy_Regular(pObj);
|
||||
assert( !Ivy_ObjIsBuf(pObjR) );
|
||||
assert( Type != IVY_EXOR || !Ivy_IsComplement(pObj) );
|
||||
|
||||
// make sure the node is not visited twice in different polarities
|
||||
if ( Ivy_IsComplement(pObj) )
|
||||
{ // if complemented, mark B
|
||||
if ( pObjR->fMarkA )
|
||||
return -1;
|
||||
pObjR->fMarkB = 1;
|
||||
}
|
||||
else
|
||||
{ // if non-complicated, mark A
|
||||
if ( pObjR->fMarkB )
|
||||
return -1;
|
||||
pObjR->fMarkA = 1;
|
||||
}
|
||||
Vec_PtrPush( vCone, pObjR );
|
||||
|
||||
// if the node is the end of the tree, return
|
||||
if ( Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Type )
|
||||
{
|
||||
if ( Ivy_ObjRefs(pObjR) == 1 )
|
||||
return 1;
|
||||
assert( Ivy_ObjRefs(pObjR) > 1 );
|
||||
Vec_PtrPush( vFront, pObj );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// branch on the node
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
// what if buffer has more than one fanout???
|
||||
RetValue0 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild0(pObj) ), Type, vFront, vCone );
|
||||
RetValue1 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild1(pObj) ), Type, vFront, vCone );
|
||||
if ( RetValue0 == -1 || RetValue1 == -1 )
|
||||
return -1;
|
||||
|
||||
// the case when both have no external references
|
||||
if ( RetValue0 && RetValue1 )
|
||||
{
|
||||
if ( Ivy_ObjRefs(pObj) == 1 )
|
||||
return 1;
|
||||
assert( Ivy_ObjRefs(pObj) > 1 );
|
||||
Vec_PtrPush( vFront, pObj );
|
||||
return 0;
|
||||
}
|
||||
// the case when one of them has external references
|
||||
if ( RetValue0 )
|
||||
Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild0(pObj) ) );
|
||||
if ( RetValue1 )
|
||||
Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild1(pObj) ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computing one algebraic cut.]
|
||||
|
||||
Description [Algebraic cut stops when we hit (a) CI, (b) complemented edge,
|
||||
(c) boundary of different gates. Returns 1 if this is a pure tree.
|
||||
Returns -1 if the contant 0 is detected. Return 0 if the array can be used.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
|
||||
{
|
||||
Ivy_Obj_t * pObj, * pPrev;
|
||||
int RetValue, i;
|
||||
assert( !Ivy_IsComplement(pRoot) );
|
||||
assert( Ivy_ObjIsNode(pRoot) );
|
||||
// clear the frontier and collect the nodes
|
||||
Vec_PtrClear( vCone );
|
||||
Vec_PtrClear( vFront );
|
||||
Vec_PtrClear( vLeaves );
|
||||
RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront, vCone );
|
||||
// clean the marks
|
||||
Vec_PtrForEachEntry( vCone, pObj, i )
|
||||
pObj->fMarkA = pObj->fMarkB = 0;
|
||||
// quit if the same node is found in both polarities
|
||||
if ( RetValue == -1 )
|
||||
return -1;
|
||||
// return if the node is the root of a tree
|
||||
if ( RetValue == 1 )
|
||||
return 1;
|
||||
// return if the cut is composed of two nodes
|
||||
if ( Vec_PtrSize(vFront) <= 2 )
|
||||
return 1;
|
||||
// sort the entries in increasing order
|
||||
Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare );
|
||||
// remove duplicates from vFront and save the nodes in vLeaves
|
||||
pPrev = Vec_PtrEntry(vFront, 0);
|
||||
Vec_PtrPush( vLeaves, pPrev );
|
||||
Vec_PtrForEachEntryStart( vFront, pObj, i, 1 )
|
||||
{
|
||||
// compare current entry and the previous entry
|
||||
if ( pObj == pPrev )
|
||||
{
|
||||
if ( Ivy_ObjIsExor(pRoot) ) // A <+> A = 0
|
||||
{
|
||||
// vLeaves are no longer structural support of pRoot!!!
|
||||
Vec_PtrPop(vLeaves);
|
||||
pPrev = Vec_PtrSize(vLeaves) == 0 ? NULL : Vec_PtrEntryLast(vLeaves);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( pObj == Ivy_Not(pPrev) )
|
||||
{
|
||||
assert( Ivy_ObjIsAnd(pRoot) );
|
||||
return -1;
|
||||
}
|
||||
pPrev = pObj;
|
||||
Vec_PtrPush( vLeaves, pObj );
|
||||
}
|
||||
if ( Vec_PtrSize(vLeaves) == 0 )
|
||||
return -1;
|
||||
if ( Vec_PtrSize(vLeaves) <= 2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,597 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyRwtPre.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Rewriting based on precomputation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyRwtPre.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
#include "deco.h"
|
||||
#include "rwt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums );
|
||||
static int Ivy_NodeMffcLabel( Ivy_Obj_t * pObj );
|
||||
static int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost );
|
||||
static Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut,
|
||||
Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth );
|
||||
|
||||
static int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
|
||||
static void Ivy_GraphUpdateNetwork( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs incremental rewriting of the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose )
|
||||
{
|
||||
Rwt_Man_t * pManRwt;
|
||||
Ivy_Obj_t * pNode;
|
||||
int i, nNodes, nGain;
|
||||
int clk, clkStart = clock();
|
||||
// start the rewriting manager
|
||||
pManRwt = Rwt_ManStart( 0 );
|
||||
if ( pManRwt == NULL )
|
||||
return 0;
|
||||
// compute the reverse levels if level update is requested
|
||||
if ( fUpdateLevel )
|
||||
Ivy_ManRequiredLevels( p );
|
||||
// resynthesize each node once
|
||||
nNodes = Ivy_ManObjIdNext( p );
|
||||
Ivy_ManForEachObj( p, pNode, i )
|
||||
{
|
||||
if ( !Ivy_ObjIsNode(pNode) )
|
||||
continue;
|
||||
// fix the fanin buffer problem
|
||||
Ivy_NodeFixBufferFanins( pNode );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
// stop if all nodes have been tried once
|
||||
if ( i >= nNodes )
|
||||
break;
|
||||
// skip the nodes with many fanouts
|
||||
// if ( Ivy_ObjRefs(pNode) > 1000 )
|
||||
// continue;
|
||||
// for each cut, try to resynthesize it
|
||||
nGain = Rwt_NodeRewrite( pManRwt, pNode, fUpdateLevel, fUseZeroCost );
|
||||
if ( nGain > 0 || nGain == 0 && fUseZeroCost )
|
||||
{
|
||||
Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt);
|
||||
int fCompl = Rwt_ManReadCompl(pManRwt);
|
||||
/*
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "USING: (" );
|
||||
Vec_PtrForEachEntry( Rwt_ManReadLeaves(pManRwt), pObj, i )
|
||||
printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pObj)) );
|
||||
printf( ") Gain = %d.\n", nGain );
|
||||
}
|
||||
if ( nGain > 0 )
|
||||
{ // print stats on the MFFC
|
||||
extern void Ivy_NodeMffsConeSuppPrint( Ivy_Obj_t * pNode );
|
||||
printf( "Node %6d : Gain = %4d ", pNode->Id, nGain );
|
||||
Ivy_NodeMffsConeSuppPrint( pNode );
|
||||
}
|
||||
*/
|
||||
// complement the FF if needed
|
||||
clk = clock();
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
Ivy_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
Rwt_ManAddTimeUpdate( pManRwt, clock() - clk );
|
||||
}
|
||||
}
|
||||
Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
|
||||
// print stats
|
||||
if ( fVerbose )
|
||||
Rwt_ManPrintStats( pManRwt );
|
||||
// delete the managers
|
||||
Rwt_ManStop( pManRwt );
|
||||
// fix the levels
|
||||
if ( fUpdateLevel )
|
||||
Vec_IntFree( p->vRequired ), p->vRequired = NULL;
|
||||
// check
|
||||
if ( i = Ivy_ManCleanup(p) )
|
||||
printf( "Cleanup after rewriting removed %d dangling nodes.\n", i );
|
||||
if ( !Ivy_ManCheck(p) )
|
||||
printf( "Ivy_ManRewritePre(): The check has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs rewriting for one node.]
|
||||
|
||||
Description [This procedure considers all the cuts computed for the node
|
||||
and tries to rewrite each of them using the "forest" of different AIG
|
||||
structures precomputed and stored in the RWR manager.
|
||||
Determines the best rewriting and computes the gain in the number of AIG
|
||||
nodes in the final network. In the end, p->vFanins contains information
|
||||
about the best cut that can be used for rewriting, while p->pGraph gives
|
||||
the decomposition dag (represented using decomposition graph data structure).
|
||||
Returns gain in the number of nodes or -1 if node cannot be rewritten.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost )
|
||||
{
|
||||
int fVeryVerbose = 0;
|
||||
Dec_Graph_t * pGraph;
|
||||
Ivy_Store_t * pStore;
|
||||
Ivy_Cut_t * pCut;
|
||||
Ivy_Obj_t * pFanin;
|
||||
unsigned uPhase, uTruthBest, uTruth;
|
||||
char * pPerm;
|
||||
int Required, nNodesSaved, nNodesSaveCur;
|
||||
int i, c, GainCur, GainBest = -1;
|
||||
int clk, clk2;
|
||||
|
||||
p->nNodesConsidered++;
|
||||
// get the required times
|
||||
Required = fUpdateLevel? Vec_IntEntry( Ivy_ObjMan(pNode)->vRequired, pNode->Id ) : 1000000;
|
||||
// get the node's cuts
|
||||
clk = clock();
|
||||
pStore = Ivy_NodeFindCutsAll( pNode, 5 );
|
||||
p->timeCut += clock() - clk;
|
||||
|
||||
// go through the cuts
|
||||
clk = clock();
|
||||
for ( c = 1; c < pStore->nCuts; c++ )
|
||||
{
|
||||
pCut = pStore->pCuts + c;
|
||||
// consider only 4-input cuts
|
||||
if ( pCut->nSize != 4 )
|
||||
continue;
|
||||
// skip the cuts with buffers
|
||||
for ( i = 0; i < (int)pCut->nSize; i++ )
|
||||
if ( Ivy_ObjIsBuf( Ivy_ObjObj(pNode, pCut->pArray[i]) ) )
|
||||
break;
|
||||
if ( i != pCut->nSize )
|
||||
continue;
|
||||
|
||||
// if ( pNode->Id == 82 )
|
||||
// Ivy_NodePrintCut( pCut );
|
||||
|
||||
// get the fanin permutation
|
||||
clk2 = clock();
|
||||
uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize ); // truth table
|
||||
p->timeTruth += clock() - clk2;
|
||||
pPerm = p->pPerms4[ p->pPerms[uTruth] ];
|
||||
uPhase = p->pPhases[uTruth];
|
||||
// collect fanins with the corresponding permutation/phase
|
||||
Vec_PtrClear( p->vFaninsCur );
|
||||
Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 );
|
||||
for ( i = 0; i < (int)pCut->nSize; i++ )
|
||||
{
|
||||
pFanin = Ivy_ObjObj( pNode, pCut->pArray[pPerm[i]] );
|
||||
assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) );
|
||||
pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
|
||||
Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
|
||||
}
|
||||
clk2 = clock();
|
||||
/*
|
||||
printf( "Considering: (" );
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pFanin)) );
|
||||
printf( ")\n" );
|
||||
*/
|
||||
// mark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
|
||||
// label MFFC with current ID
|
||||
Ivy_ManIncrementTravId( Ivy_ObjMan(pNode) );
|
||||
nNodesSaved = Ivy_NodeMffcLabel( pNode );
|
||||
// unmark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
|
||||
p->timeMffc += clock() - clk2;
|
||||
|
||||
// evaluate the cut
|
||||
clk2 = clock();
|
||||
pGraph = Rwt_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
|
||||
p->timeEval += clock() - clk2;
|
||||
|
||||
// check if the cut is better than the current best one
|
||||
if ( pGraph != NULL && GainBest < GainCur )
|
||||
{
|
||||
// save this form
|
||||
nNodesSaveCur = nNodesSaved;
|
||||
GainBest = GainCur;
|
||||
p->pGraph = pGraph;
|
||||
p->fCompl = ((uPhase & (1<<4)) > 0);
|
||||
uTruthBest = uTruth;
|
||||
// collect fanins in the
|
||||
Vec_PtrClear( p->vFanins );
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Vec_PtrPush( p->vFanins, pFanin );
|
||||
}
|
||||
}
|
||||
p->timeRes += clock() - clk;
|
||||
|
||||
if ( GainBest == -1 )
|
||||
return -1;
|
||||
|
||||
// printf( "%d", nNodesSaveCur - GainBest );
|
||||
/*
|
||||
if ( GainBest > 0 )
|
||||
{
|
||||
if ( Rwt_CutIsintean( pNode, p->vFanins ) )
|
||||
printf( "b" );
|
||||
else
|
||||
{
|
||||
printf( "Node %d : ", pNode->Id );
|
||||
Vec_PtrForEachEntry( p->vFanins, pFanin, i )
|
||||
printf( "%d ", Ivy_Regular(pFanin)->Id );
|
||||
printf( "a" );
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ( GainBest > 0 )
|
||||
if ( p->fCompl )
|
||||
printf( "c" );
|
||||
else
|
||||
printf( "." );
|
||||
*/
|
||||
|
||||
// copy the leaves
|
||||
Vec_PtrForEachEntry( p->vFanins, pFanin, i )
|
||||
Dec_GraphNode(p->pGraph, i)->pFunc = pFanin;
|
||||
|
||||
p->nScores[p->pMap[uTruthBest]]++;
|
||||
p->nNodesGained += GainBest;
|
||||
if ( fUseZeroCost || GainBest > 0 )
|
||||
p->nNodesRewritten++;
|
||||
|
||||
// report the progress
|
||||
if ( fVeryVerbose && GainBest > 0 )
|
||||
{
|
||||
printf( "Node %6d : ", Ivy_ObjId(pNode) );
|
||||
printf( "Fanins = %d. ", p->vFanins->nSize );
|
||||
printf( "Save = %d. ", nNodesSaveCur );
|
||||
printf( "Add = %d. ", nNodesSaveCur-GainBest );
|
||||
printf( "GAIN = %d. ", GainBest );
|
||||
printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 );
|
||||
printf( "Class = %d. ", p->pMap[uTruthBest] );
|
||||
printf( "\n" );
|
||||
}
|
||||
return GainBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [References/references the node and returns MFFC size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeRefDeref( Ivy_Obj_t * pNode, int fReference, int fLabel )
|
||||
{
|
||||
Ivy_Obj_t * pNode0, * pNode1;
|
||||
int Counter;
|
||||
// label visited nodes
|
||||
if ( fLabel )
|
||||
Ivy_ObjSetTravIdCurrent( pNode );
|
||||
// skip the CI
|
||||
if ( Ivy_ObjIsCi(pNode) )
|
||||
return 0;
|
||||
assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) );
|
||||
// process the internal node
|
||||
pNode0 = Ivy_ObjFanin0(pNode);
|
||||
pNode1 = Ivy_ObjFanin1(pNode);
|
||||
Counter = Ivy_ObjIsNode(pNode);
|
||||
if ( fReference )
|
||||
{
|
||||
if ( pNode0->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode0, fReference, fLabel );
|
||||
if ( Ivy_ObjIsNode(pNode) && pNode1->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode1, fReference, fLabel );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( pNode0->nRefs > 0 );
|
||||
assert( pNode1->nRefs > 0 );
|
||||
if ( --pNode0->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode0, fReference, fLabel );
|
||||
if ( Ivy_ObjIsNode(pNode) && --pNode1->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode1, fReference, fLabel );
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the size of MFFC and labels nodes with the current TravId.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeMffcLabel( Ivy_Obj_t * pNode )
|
||||
{
|
||||
int nConeSize1, nConeSize2;
|
||||
assert( !Ivy_IsComplement( pNode ) );
|
||||
assert( Ivy_ObjIsNode( pNode ) );
|
||||
nConeSize1 = Ivy_NodeRefDeref( pNode, 0, 1 ); // dereference
|
||||
nConeSize2 = Ivy_NodeRefDeref( pNode, 1, 0 ); // reference
|
||||
assert( nConeSize1 == nConeSize2 );
|
||||
assert( nConeSize1 > 0 );
|
||||
return nConeSize1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_NodeGetTruth_rec( Ivy_Obj_t * pObj, int * pNums, int nNums )
|
||||
{
|
||||
static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
unsigned uTruth0, uTruth1;
|
||||
int i;
|
||||
for ( i = 0; i < nNums; i++ )
|
||||
if ( pObj->Id == pNums[i] )
|
||||
return uMasks[i];
|
||||
assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
|
||||
uTruth0 = Ivy_NodeGetTruth_rec( Ivy_ObjFanin0(pObj), pNums, nNums );
|
||||
if ( Ivy_ObjFaninC0(pObj) )
|
||||
uTruth0 = ~uTruth0;
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
return uTruth0;
|
||||
uTruth1 = Ivy_NodeGetTruth_rec( Ivy_ObjFanin1(pObj), pNums, nNums );
|
||||
if ( Ivy_ObjFaninC1(pObj) )
|
||||
uTruth1 = ~uTruth1;
|
||||
return uTruth0 & uTruth1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums )
|
||||
{
|
||||
assert( nNums < 6 );
|
||||
return Ivy_NodeGetTruth_rec( pObj, pNums, nNums );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Evaluates the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
|
||||
{
|
||||
Vec_Ptr_t * vSubgraphs;
|
||||
Dec_Graph_t * pGraphBest, * pGraphCur;
|
||||
Rwt_Node_t * pNode, * pFanin;
|
||||
int nNodesAdded, GainBest, i, k;
|
||||
// find the matching class of subgraphs
|
||||
vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
|
||||
p->nSubgraphs += vSubgraphs->nSize;
|
||||
// determine the best subgraph
|
||||
GainBest = -1;
|
||||
Vec_PtrForEachEntry( vSubgraphs, pNode, i )
|
||||
{
|
||||
// get the current graph
|
||||
pGraphCur = (Dec_Graph_t *)pNode->pNext;
|
||||
// copy the leaves
|
||||
Vec_PtrForEachEntry( vFaninsCur, pFanin, k )
|
||||
Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
|
||||
// detect how many unlabeled nodes will be reused
|
||||
nNodesAdded = Ivy_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax );
|
||||
if ( nNodesAdded == -1 )
|
||||
continue;
|
||||
assert( nNodesSaved >= nNodesAdded );
|
||||
// count the gain at this node
|
||||
if ( GainBest < nNodesSaved - nNodesAdded )
|
||||
{
|
||||
GainBest = nNodesSaved - nNodesAdded;
|
||||
pGraphBest = pGraphCur;
|
||||
}
|
||||
}
|
||||
if ( GainBest == -1 )
|
||||
return NULL;
|
||||
*pGainBest = GainBest;
|
||||
return pGraphBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of new nodes added when using this graph.]
|
||||
|
||||
Description [AIG nodes for the fanins should be assigned to pNode->pFunc
|
||||
of the leaves of the graph before calling this procedure.
|
||||
Returns -1 if the number of nodes and levels exceeded the given limit or
|
||||
the number of levels exceeded the maximum allowed level.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax )
|
||||
{
|
||||
Dec_Node_t * pNode, * pNode0, * pNode1;
|
||||
Ivy_Obj_t * pAnd, * pAnd0, * pAnd1;
|
||||
int i, Counter, LevelNew, LevelOld;
|
||||
// check for constant function or a literal
|
||||
if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) )
|
||||
return 0;
|
||||
// set the levels of the leaves
|
||||
Dec_GraphForEachLeaf( pGraph, pNode, i )
|
||||
pNode->Level = Ivy_Regular(pNode->pFunc)->Level;
|
||||
// compute the AIG size after adding the internal nodes
|
||||
Counter = 0;
|
||||
Dec_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
// get the children of this node
|
||||
pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
|
||||
pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
|
||||
// get the AIG nodes corresponding to the children
|
||||
pAnd0 = pNode0->pFunc;
|
||||
pAnd1 = pNode1->pFunc;
|
||||
if ( pAnd0 && pAnd1 )
|
||||
{
|
||||
// if they are both present, find the resulting node
|
||||
pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl );
|
||||
pAnd = Ivy_TableLookup( Ivy_ObjCreateGhost(pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) );
|
||||
// return -1 if the node is the same as the original root
|
||||
if ( Ivy_Regular(pAnd) == pRoot )
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
pAnd = NULL;
|
||||
// count the number of added nodes
|
||||
if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(Ivy_Regular(pAnd)) )
|
||||
{
|
||||
if ( ++Counter > NodeMax )
|
||||
return -1;
|
||||
}
|
||||
// count the number of new levels
|
||||
LevelNew = 1 + RWT_MAX( pNode0->Level, pNode1->Level );
|
||||
if ( pAnd )
|
||||
{
|
||||
if ( Ivy_Regular(pAnd) == Ivy_ObjConst1(pRoot) )
|
||||
LevelNew = 0;
|
||||
else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd0) )
|
||||
LevelNew = (int)Ivy_Regular(pAnd0)->Level;
|
||||
else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd1) )
|
||||
LevelNew = (int)Ivy_Regular(pAnd1)->Level;
|
||||
LevelOld = (int)Ivy_Regular(pAnd)->Level;
|
||||
// assert( LevelNew == LevelOld );
|
||||
}
|
||||
if ( LevelNew > LevelMax )
|
||||
return -1;
|
||||
pNode->pFunc = pAnd;
|
||||
pNode->Level = LevelNew;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the decomposition graph into the AIG.]
|
||||
|
||||
Description [AIG nodes for the fanins should be assigned to pNode->pFunc
|
||||
of the leaves of the graph before calling this procedure.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
|
||||
{
|
||||
Ivy_Obj_t * pAnd0, * pAnd1;
|
||||
Dec_Node_t * pNode;
|
||||
int i;
|
||||
// check for constant function
|
||||
if ( Dec_GraphIsConst(pGraph) )
|
||||
return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) );
|
||||
// check for a literal
|
||||
if ( Dec_GraphIsVar(pGraph) )
|
||||
return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
// build the AIG nodes corresponding to the AND gates of the graph
|
||||
Dec_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
|
||||
pNode->pFunc = Ivy_And( pAnd0, pAnd1 );
|
||||
}
|
||||
// complement the result if necessary
|
||||
return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Replaces MFFC of the node by the new factored form.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_GraphUpdateNetwork( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
|
||||
{
|
||||
Ivy_Obj_t * pRootNew;
|
||||
int nNodesNew, nNodesOld;
|
||||
nNodesOld = Ivy_ManNodeNum(Ivy_ObjMan(pRoot));
|
||||
// create the new structure of nodes
|
||||
pRootNew = Ivy_GraphToNetwork( Ivy_ObjMan(pRoot), pGraph );
|
||||
// remove the old nodes
|
||||
// Ivy_AigReplace( pMan->pManFunc, pRoot, pRootNew, fUpdateLevel );
|
||||
Ivy_ObjReplace( pRoot, pRootNew, 1, 0 );
|
||||
// compare the gains
|
||||
nNodesNew = Ivy_ManNodeNum(Ivy_ObjMan(pRoot));
|
||||
assert( nGain <= nNodesOld - nNodesNew );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -362,6 +362,222 @@ Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p )
|
|||
return vLatches;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManReadLevels( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, LevelMax = 0;
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pObj = Ivy_ObjFanin0(pObj);
|
||||
LevelMax = IVY_MAX( LevelMax, (int)pObj->Level );
|
||||
}
|
||||
return LevelMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the real fanin.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Obj_t * pFanin;
|
||||
if ( !Ivy_ObjIsBuf( Ivy_Regular(pObj) ) )
|
||||
return pObj;
|
||||
pFanin = Ivy_ObjReal( Ivy_ObjChild0(Ivy_Regular(pObj)) );
|
||||
return Ivy_NotCond( pFanin, Ivy_IsComplement(pObj) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the cube has exactly one 1.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_TruthHasOneOne( unsigned uCube )
|
||||
{
|
||||
return (uCube & (uCube - 1)) == 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are distance-1.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_TruthCubesDist1( unsigned uCube1, unsigned uCube2 )
|
||||
{
|
||||
unsigned uTemp = uCube1 | uCube2;
|
||||
return Ivy_TruthHasOneOne( (uTemp >> 1) & uTemp & 0x55555555 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes differ in only one literal.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_TruthCubesDiff1( unsigned uCube1, unsigned uCube2 )
|
||||
{
|
||||
unsigned uTemp = uCube1 ^ uCube2;
|
||||
return Ivy_TruthHasOneOne( ((uTemp >> 1) | uTemp) & 0x55555555 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Combines two distance 1 cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Ivy_TruthCubesMerge( unsigned uCube1, unsigned uCube2 )
|
||||
{
|
||||
unsigned uTemp;
|
||||
uTemp = uCube1 | uCube2;
|
||||
uTemp &= (uTemp >> 1) & 0x55555555;
|
||||
assert( Ivy_TruthHasOneOne(uTemp) );
|
||||
uTemp |= (uTemp << 1);
|
||||
return (uCube1 | uCube2) ^ uTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Estimates the number of AIG nodes in the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_TruthEstimateNodes( unsigned * pTruth, int nVars )
|
||||
{
|
||||
static unsigned short uResult[256];
|
||||
static unsigned short uCover[81*81];
|
||||
static char pVarCount[81*81];
|
||||
int nMints, uCube, uCubeNew, i, k, c, nCubes, nRes, Counter;
|
||||
assert( nVars <= 8 );
|
||||
// create the cover
|
||||
nCubes = 0;
|
||||
nMints = (1 << nVars);
|
||||
for ( i = 0; i < nMints; i++ )
|
||||
if ( pTruth[i/32] & (1 << (i & 31)) )
|
||||
{
|
||||
uCube = 0;
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( i & (1 << k) )
|
||||
uCube |= (1 << ((k<<1)+1));
|
||||
else
|
||||
uCube |= (1 << ((k<<1)+0));
|
||||
uCover[nCubes] = uCube;
|
||||
pVarCount[nCubes] = nVars;
|
||||
nCubes++;
|
||||
// Extra_PrintBinary( stdout, &uCube, 8 ); printf( "\n" );
|
||||
}
|
||||
assert( nCubes <= 256 );
|
||||
// reduce the cover by building larger cubes
|
||||
for ( i = 1; i < nCubes; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
if ( pVarCount[i] && pVarCount[i] == pVarCount[k] && Ivy_TruthCubesDist1(uCover[i], uCover[k]) )
|
||||
{
|
||||
uCubeNew = Ivy_TruthCubesMerge(uCover[i], uCover[k]);
|
||||
for ( c = i; c < nCubes; c++ )
|
||||
if ( uCubeNew == uCover[c] )
|
||||
break;
|
||||
if ( c != nCubes )
|
||||
continue;
|
||||
uCover[nCubes] = uCubeNew;
|
||||
pVarCount[nCubes] = pVarCount[i] - 1;
|
||||
nCubes++;
|
||||
assert( nCubes < 81*81 );
|
||||
// Extra_PrintBinary( stdout, &uCubeNew, 8 ); printf( "\n" );
|
||||
// c = c;
|
||||
}
|
||||
// compact the cover
|
||||
nRes = 0;
|
||||
for ( i = nCubes -1; i >= 0; i-- )
|
||||
{
|
||||
for ( k = 0; k < nRes; k++ )
|
||||
if ( (uCover[i] & uResult[k]) == uResult[k] )
|
||||
break;
|
||||
if ( k != nRes )
|
||||
continue;
|
||||
uResult[nRes++] = uCover[i];
|
||||
}
|
||||
// count the number of literals
|
||||
Counter = 0;
|
||||
for ( i = 0; i < nRes; i++ )
|
||||
{
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( uResult[i] & (3 << (k<<1)) )
|
||||
Counter++;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tests the cover procedure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TruthEstimateNodesTest()
|
||||
{
|
||||
unsigned uTruth[8];
|
||||
int i;
|
||||
for ( i = 0; i < 8; i++ )
|
||||
uTruth[i] = ~(unsigned)0;
|
||||
uTruth[3] ^= (1 << 13);
|
||||
// uTruth[4] = 0xFFFFF;
|
||||
// uTruth[0] = 0xFF;
|
||||
// uTruth[0] ^= (1 << 3);
|
||||
printf( "Number = %d.\n", Ivy_TruthEstimateNodes(uTruth, 8) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ SRC += src/temp/ivy/ivyBalance.c \
|
|||
src/temp/ivy/ivyMulti.c \
|
||||
src/temp/ivy/ivyObj.c \
|
||||
src/temp/ivy/ivyOper.c \
|
||||
src/temp/ivy/ivyRewrite.c \
|
||||
src/temp/ivy/ivyResyn.c \
|
||||
src/temp/ivy/ivyRwrPre.c \
|
||||
src/temp/ivy/ivySeq.c \
|
||||
src/temp/ivy/ivyTable.c \
|
||||
src/temp/ivy/ivyUndo.c \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,560 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [esopMem.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Memory managers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: esopMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "mem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Mem_Fixed_t_
|
||||
{
|
||||
// information about individual entries
|
||||
int nEntrySize; // the size of one entry
|
||||
int nEntriesAlloc; // the total number of entries allocated
|
||||
int nEntriesUsed; // the number of entries in use
|
||||
int nEntriesMax; // the max number of entries in use
|
||||
char * pEntriesFree; // the linked list of free entries
|
||||
|
||||
// this is where the memory is stored
|
||||
int nChunkSize; // the size of one chunk
|
||||
int nChunksAlloc; // the maximum number of memory chunks
|
||||
int nChunks; // the current number of memory chunks
|
||||
char ** pChunks; // the allocated memory
|
||||
|
||||
// statistics
|
||||
int nMemoryUsed; // memory used in the allocated entries
|
||||
int nMemoryAlloc; // memory allocated
|
||||
};
|
||||
|
||||
struct Mem_Flex_t_
|
||||
{
|
||||
// information about individual entries
|
||||
int nEntriesUsed; // the number of entries allocated
|
||||
char * pCurrent; // the current pointer to free memory
|
||||
char * pEnd; // the first entry outside the free memory
|
||||
|
||||
// this is where the memory is stored
|
||||
int nChunkSize; // the size of one chunk
|
||||
int nChunksAlloc; // the maximum number of memory chunks
|
||||
int nChunks; // the current number of memory chunks
|
||||
char ** pChunks; // the allocated memory
|
||||
|
||||
// statistics
|
||||
int nMemoryUsed; // memory used in the allocated entries
|
||||
int nMemoryAlloc; // memory allocated
|
||||
};
|
||||
|
||||
struct Mem_Step_t_
|
||||
{
|
||||
int nMems; // the number of fixed memory managers employed
|
||||
Mem_Fixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
|
||||
int nMapSize; // the size of the memory array
|
||||
Mem_Fixed_t ** pMap; // maps the number of bytes into its memory manager
|
||||
};
|
||||
|
||||
#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))))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates memory pieces of fixed size.]
|
||||
|
||||
Description [The size of the chunk is computed as the minimum of
|
||||
1024 entries and 64K. Can only work with entry size at least 4 byte long.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mem_Fixed_t * Mem_FixedStart( int nEntrySize )
|
||||
{
|
||||
Mem_Fixed_t * p;
|
||||
|
||||
p = ALLOC( Mem_Fixed_t, 1 );
|
||||
memset( p, 0, sizeof(Mem_Fixed_t) );
|
||||
|
||||
p->nEntrySize = nEntrySize;
|
||||
p->nEntriesAlloc = 0;
|
||||
p->nEntriesUsed = 0;
|
||||
p->pEntriesFree = NULL;
|
||||
|
||||
if ( nEntrySize * (1 << 10) < (1<<16) )
|
||||
p->nChunkSize = (1 << 10);
|
||||
else
|
||||
p->nChunkSize = (1<<16) / nEntrySize;
|
||||
if ( p->nChunkSize < 8 )
|
||||
p->nChunkSize = 8;
|
||||
|
||||
p->nChunksAlloc = 64;
|
||||
p->nChunks = 0;
|
||||
p->pChunks = ALLOC( char *, p->nChunksAlloc );
|
||||
|
||||
p->nMemoryUsed = 0;
|
||||
p->nMemoryAlloc = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_FixedStop( Mem_Fixed_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
if ( p == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
|
||||
p->nEntrySize, p->nChunkSize, p->nChunks );
|
||||
printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
|
||||
p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
|
||||
}
|
||||
for ( i = 0; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
free( p->pChunks );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Mem_FixedEntryFetch( Mem_Fixed_t * p )
|
||||
{
|
||||
char * pTemp;
|
||||
int i;
|
||||
|
||||
// check if there are still free entries
|
||||
if ( p->nEntriesUsed == p->nEntriesAlloc )
|
||||
{ // need to allocate more entries
|
||||
assert( p->pEntriesFree == NULL );
|
||||
if ( p->nChunks == p->nChunksAlloc )
|
||||
{
|
||||
p->nChunksAlloc *= 2;
|
||||
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
|
||||
}
|
||||
p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
|
||||
p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
|
||||
// transform these entries into a linked list
|
||||
pTemp = p->pEntriesFree;
|
||||
for ( i = 1; i < p->nChunkSize; i++ )
|
||||
{
|
||||
*((char **)pTemp) = pTemp + p->nEntrySize;
|
||||
pTemp += p->nEntrySize;
|
||||
}
|
||||
// set the last link
|
||||
*((char **)pTemp) = NULL;
|
||||
// add the chunk to the chunk storage
|
||||
p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
|
||||
// add to the number of entries allocated
|
||||
p->nEntriesAlloc += p->nChunkSize;
|
||||
}
|
||||
// incrememt the counter of used entries
|
||||
p->nEntriesUsed++;
|
||||
if ( p->nEntriesMax < p->nEntriesUsed )
|
||||
p->nEntriesMax = p->nEntriesUsed;
|
||||
// return the first entry in the free entry list
|
||||
pTemp = p->pEntriesFree;
|
||||
p->pEntriesFree = *((char **)pTemp);
|
||||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry )
|
||||
{
|
||||
// decrement the counter of used entries
|
||||
p->nEntriesUsed--;
|
||||
// add the entry to the linked list of free entries
|
||||
*((char **)pEntry) = p->pEntriesFree;
|
||||
p->pEntriesFree = pEntry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description [Relocates all the memory except the first chunk.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_FixedRestart( Mem_Fixed_t * p )
|
||||
{
|
||||
int i;
|
||||
char * pTemp;
|
||||
|
||||
// deallocate all chunks except the first one
|
||||
for ( i = 1; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
p->nChunks = 1;
|
||||
// transform these entries into a linked list
|
||||
pTemp = p->pChunks[0];
|
||||
for ( i = 1; i < p->nChunkSize; i++ )
|
||||
{
|
||||
*((char **)pTemp) = pTemp + p->nEntrySize;
|
||||
pTemp += p->nEntrySize;
|
||||
}
|
||||
// set the last link
|
||||
*((char **)pTemp) = NULL;
|
||||
// set the free entry list
|
||||
p->pEntriesFree = p->pChunks[0];
|
||||
// set the correct statistics
|
||||
p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
|
||||
p->nMemoryUsed = 0;
|
||||
p->nEntriesAlloc = p->nChunkSize;
|
||||
p->nEntriesUsed = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mem_FixedReadMemUsage( Mem_Fixed_t * p )
|
||||
{
|
||||
return p->nMemoryAlloc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates entries of flexible size.]
|
||||
|
||||
Description [Can only work with entry size at least 4 byte long.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mem_Flex_t * Mem_FlexStart()
|
||||
{
|
||||
Mem_Flex_t * p;
|
||||
|
||||
p = ALLOC( Mem_Flex_t, 1 );
|
||||
memset( p, 0, sizeof(Mem_Flex_t) );
|
||||
|
||||
p->nEntriesUsed = 0;
|
||||
p->pCurrent = NULL;
|
||||
p->pEnd = NULL;
|
||||
|
||||
p->nChunkSize = (1 << 12);
|
||||
p->nChunksAlloc = 64;
|
||||
p->nChunks = 0;
|
||||
p->pChunks = ALLOC( char *, p->nChunksAlloc );
|
||||
|
||||
p->nMemoryUsed = 0;
|
||||
p->nMemoryAlloc = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_FlexStop( Mem_Flex_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
if ( p == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
|
||||
p->nChunkSize, p->nChunks );
|
||||
printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
|
||||
p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
|
||||
}
|
||||
for ( i = 0; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
free( p->pChunks );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes )
|
||||
{
|
||||
char * pTemp;
|
||||
// check if there are still free entries
|
||||
if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
|
||||
{ // need to allocate more entries
|
||||
if ( p->nChunks == p->nChunksAlloc )
|
||||
{
|
||||
p->nChunksAlloc *= 2;
|
||||
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
|
||||
}
|
||||
if ( nBytes > p->nChunkSize )
|
||||
{
|
||||
// resize the chunk size if more memory is requested than it can give
|
||||
// (ideally, this should never happen)
|
||||
p->nChunkSize = 2 * nBytes;
|
||||
}
|
||||
p->pCurrent = ALLOC( char, p->nChunkSize );
|
||||
p->pEnd = p->pCurrent + p->nChunkSize;
|
||||
p->nMemoryAlloc += p->nChunkSize;
|
||||
// add the chunk to the chunk storage
|
||||
p->pChunks[ p->nChunks++ ] = p->pCurrent;
|
||||
}
|
||||
assert( p->pCurrent + nBytes <= p->pEnd );
|
||||
// increment the counter of used entries
|
||||
p->nEntriesUsed++;
|
||||
// keep track of the memory used
|
||||
p->nMemoryUsed += nBytes;
|
||||
// return the next entry
|
||||
pTemp = p->pCurrent;
|
||||
p->pCurrent += nBytes;
|
||||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mem_FlexReadMemUsage( Mem_Flex_t * p )
|
||||
{
|
||||
return p->nMemoryAlloc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the hierarchical memory manager.]
|
||||
|
||||
Description [This manager can allocate entries of any size.
|
||||
Iternally they are mapped into the entries with the number of bytes
|
||||
equal to the power of 2. The smallest entry size is 8 bytes. The
|
||||
next one is 16 bytes etc. So, if the user requests 6 bytes, he gets
|
||||
8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc.
|
||||
The input parameters "nSteps" says how many fixed memory managers
|
||||
are employed internally. Calling this procedure with nSteps equal
|
||||
to 10 results in 10 hierarchically arranged internal memory managers,
|
||||
which can allocate up to 4096 (1Kb) entries. Requests for larger
|
||||
entries are handed over to malloc() and then free()ed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mem_Step_t * Mem_StepStart( int nSteps )
|
||||
{
|
||||
Mem_Step_t * p;
|
||||
int i, k;
|
||||
p = ALLOC( Mem_Step_t, 1 );
|
||||
memset( p, 0, sizeof(Mem_Step_t) );
|
||||
p->nMems = nSteps;
|
||||
// start the fixed memory managers
|
||||
p->pMems = ALLOC( Mem_Fixed_t *, p->nMems );
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
p->pMems[i] = Mem_FixedStart( (8<<i) );
|
||||
// set up the mapping of the required memory size into the corresponding manager
|
||||
p->nMapSize = (4<<p->nMems);
|
||||
p->pMap = ALLOC( Mem_Fixed_t *, p->nMapSize+1 );
|
||||
p->pMap[0] = NULL;
|
||||
for ( k = 1; k <= 4; k++ )
|
||||
p->pMap[k] = p->pMems[0];
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
for ( k = (4<<i)+1; k <= (8<<i); k++ )
|
||||
p->pMap[k] = p->pMems[i];
|
||||
//for ( i = 1; i < 100; i ++ )
|
||||
//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the memory manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_StepStop( Mem_Step_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
Mem_FixedStop( p->pMems[i], fVerbose );
|
||||
// if ( p->pLargeChunks )
|
||||
// {
|
||||
// for ( i = 0; i < p->nLargeChunks; i++ )
|
||||
// free( p->pLargeChunks[i] );
|
||||
// free( p->pLargeChunks );
|
||||
// }
|
||||
free( p->pMems );
|
||||
free( p->pMap );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Mem_StepEntryFetch( Mem_Step_t * p, int nBytes )
|
||||
{
|
||||
if ( nBytes == 0 )
|
||||
return NULL;
|
||||
if ( nBytes > p->nMapSize )
|
||||
{
|
||||
// printf( "Allocating %d bytes.\n", nBytes );
|
||||
/*
|
||||
if ( p->nLargeChunks == p->nLargeChunksAlloc )
|
||||
{
|
||||
if ( p->nLargeChunksAlloc == 0 )
|
||||
p->nLargeChunksAlloc = 5;
|
||||
p->nLargeChunksAlloc *= 2;
|
||||
p->pLargeChunks = REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc );
|
||||
}
|
||||
p->pLargeChunks[ p->nLargeChunks++ ] = ALLOC( char, nBytes );
|
||||
return p->pLargeChunks[ p->nLargeChunks - 1 ];
|
||||
*/
|
||||
return ALLOC( char, nBytes );
|
||||
}
|
||||
return Mem_FixedEntryFetch( p->pMap[nBytes] );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_StepEntryRecycle( Mem_Step_t * p, char * pEntry, int nBytes )
|
||||
{
|
||||
if ( nBytes == 0 )
|
||||
return;
|
||||
if ( nBytes > p->nMapSize )
|
||||
{
|
||||
free( pEntry );
|
||||
return;
|
||||
}
|
||||
Mem_FixedEntryRecycle( p->pMap[nBytes], pEntry );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mem_StepReadMemUsage( Mem_Step_t * p )
|
||||
{
|
||||
int i, nMemTotal = 0;
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
nMemTotal += p->pMems[i]->nMemoryAlloc;
|
||||
return nMemTotal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [mem.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Memory management.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: mem.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __MEM_H__
|
||||
#define __MEM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Mem_Fixed_t_ Mem_Fixed_t;
|
||||
typedef struct Mem_Flex_t_ Mem_Flex_t;
|
||||
typedef struct Mem_Step_t_ Mem_Step_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== mem.c ===========================================================*/
|
||||
// fixed-size-block memory manager
|
||||
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 );
|
||||
// flexible-size-block memory manager
|
||||
extern Mem_Flex_t * Mem_FlexStart();
|
||||
extern void Mem_FlexStop( Mem_Flex_t * p, int fVerbose );
|
||||
extern char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes );
|
||||
extern int Mem_FlexReadMemUsage( Mem_Flex_t * p );
|
||||
// hierarchical memory manager
|
||||
extern Mem_Step_t * Mem_StepStart( int nSteps );
|
||||
extern void Mem_StepStop( Mem_Step_t * p, int fVerbose );
|
||||
extern char * Mem_StepEntryFetch( Mem_Step_t * p, int nBytes );
|
||||
extern void Mem_StepEntryRecycle( Mem_Step_t * p, char * pEntry, int nBytes );
|
||||
extern int Mem_StepReadMemUsage( Mem_Step_t * p );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
SRC += src/temp/mem/mem.c
|
||||
|
|
@ -40,8 +40,8 @@ typedef struct Pla_Obj_t_ Pla_Obj_t;
|
|||
struct Pla_Obj_t_
|
||||
{
|
||||
unsigned fFixed : 1; // fixed node
|
||||
unsigned Depth : 7; // the depth in terms of LUTs/PLAs
|
||||
unsigned nRefs : 24; // the number of references
|
||||
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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,8 +45,10 @@ static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
|
|||
***********************************************************************/
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, 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
|
||||
|
|
@ -60,6 +62,14 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
|
|||
}
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
if ( fUseRewriting )
|
||||
{
|
||||
// simplify
|
||||
pMan = Ivy_ManResyn( pManExt = pMan, 1 );
|
||||
Ivy_ManStop( pManExt );
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
// perform decomposition/mapping into PLAs/LUTs
|
||||
pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
|
||||
Ivy_ManStop( pMan );
|
||||
|
|
@ -150,10 +160,10 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
|
|||
pObjNew = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntForEachEntry( vIvyFanins, Fanin, k )
|
||||
{
|
||||
pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_FanId(Fanin) );
|
||||
pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_EdgeId(Fanin) );
|
||||
pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
|
||||
Abc_ObjAddFanin( pObjNew, pFaninNew );
|
||||
pCompls[k] = Ivy_FanCompl(Fanin);
|
||||
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 );
|
||||
|
|
@ -176,10 +186,10 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
|
|||
// 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_FanId(Fanin) );
|
||||
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_FanCompl(Fanin) ) // complement
|
||||
if ( Ivy_EdgeIsComplement(Fanin) ) // complement
|
||||
{
|
||||
// pFaninNew = Abc_NodeCreateInv(pNtkNew, pFaninNew);
|
||||
if ( Abc_ObjIsCi(pFaninNew) )
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld )
|
|||
{
|
||||
pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) );
|
||||
Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 );
|
||||
Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_FanCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) );
|
||||
Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_EdgeCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) );
|
||||
}
|
||||
// compute the LUT functions
|
||||
Pla_ManToAigLutFuncs( pNew, pOld );
|
||||
|
|
@ -118,7 +118,7 @@ Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )
|
|||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFaninOld = Ivy_ObjObj( pObjOld, Entry );
|
||||
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninOld->TravId, 0) );
|
||||
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninOld->TravId, 0) );
|
||||
}
|
||||
// get the new object
|
||||
pObjNew = Ivy_ManObj(pNew, ObjNewId);
|
||||
|
|
@ -140,7 +140,7 @@ Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )
|
|||
Esop_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp );
|
||||
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninNew->Id, 0) );
|
||||
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninNew->Id, 0) );
|
||||
}
|
||||
// get the new object
|
||||
pObjNew = Ivy_ManObj(pNew, ObjNewId);
|
||||
|
|
@ -168,7 +168,7 @@ 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_FanCreate(0, !fConst1) );
|
||||
Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate(0, !fConst1) );
|
||||
return pObjNew;
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t
|
|||
if ( Value == 3 )
|
||||
continue;
|
||||
pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) );
|
||||
Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate( pFaninOld->TravId, Value==1 ) );
|
||||
Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate( pFaninOld->TravId, Value==1 ) );
|
||||
}
|
||||
assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits );
|
||||
return pObjNew;
|
||||
|
|
@ -262,7 +262,7 @@ int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )
|
|||
// point it to the constant 1 node
|
||||
vFanins = Ivy_ObjGetFanins( pObjNew );
|
||||
Vec_IntClear( vFanins );
|
||||
Vec_IntPush( vFanins, Ivy_FanCreate(0, 1) );
|
||||
Vec_IntPush( vFanins, Ivy_EdgeCreate(0, 1) );
|
||||
}
|
||||
memcpy( pTruth, pComputed, sizeof(unsigned) * 8 );
|
||||
// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" );
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj )
|
|||
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 );
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )
|
|||
vFanins = Ivy_ObjGetFanins( pObj );
|
||||
Vec_IntForEachEntry( vFanins, Fanin, k )
|
||||
{
|
||||
pFanin = Ivy_ManObj(p, Ivy_FanId(Fanin));
|
||||
pFanin = Ivy_ManObj(p, Ivy_EdgeId(Fanin));
|
||||
pObj->Level = IVY_MAX( pObj->Level, pFanin->Level );
|
||||
}
|
||||
pObj->Level += 1;
|
||||
|
|
@ -335,7 +335,7 @@ void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )
|
|||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
Fanin = Ivy_ObjReadFanin(pObj, 0);
|
||||
pFanin = Ivy_ManObj( p, Ivy_FanId(Fanin) );
|
||||
pFanin = Ivy_ManObj( p, Ivy_EdgeId(Fanin) );
|
||||
pObj->Level = pFanin->Level;
|
||||
Delay = IVY_MAX( Delay, (int)pObj->Level );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC += src/temp/rwt/rwtDec.c \
|
||||
src/temp/rwt/rwtMan.c \
|
||||
src/temp/rwt/rwtUtil.c
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rwt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware AIG rewriting package.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rwt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __RWT_H__
|
||||
#define __RWT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "mem.h"
|
||||
#include "vec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define RWT_LIMIT 1048576/4 // ((1 << 20)
|
||||
#define RWT_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define RWT_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
typedef struct Rwt_Man_t_ Rwt_Man_t;
|
||||
typedef struct Rwt_Node_t_ Rwt_Node_t;
|
||||
|
||||
struct Rwt_Man_t_
|
||||
{
|
||||
// internal lookups
|
||||
int nFuncs; // number of four var functions
|
||||
unsigned short * puCanons; // canonical forms
|
||||
char * pPhases; // canonical phases
|
||||
char * pPerms; // canonical permutations
|
||||
unsigned char * pMap; // mapping of functions into class numbers
|
||||
unsigned short * pMapInv; // mapping of classes into functions
|
||||
char * pPractical; // practical NPN classes
|
||||
char ** pPerms4; // four-var permutations
|
||||
// node space
|
||||
Vec_Ptr_t * vForest; // all the nodes
|
||||
Rwt_Node_t ** pTable; // the hash table of nodes by their canonical form
|
||||
Vec_Vec_t * vClasses; // the nodes of the equivalence classes
|
||||
Mem_Fixed_t * pMmNode; // memory for nodes and cuts
|
||||
// statistical variables
|
||||
int nTravIds; // the counter of traversal IDs
|
||||
int nConsidered; // the number of nodes considered
|
||||
int nAdded; // the number of nodes added to lists
|
||||
int nClasses; // the number of NN classes
|
||||
// the result of resynthesis
|
||||
int fCompl; // indicates if the output of FF should be complemented
|
||||
void * pGraph; // the decomposition tree (temporary)
|
||||
Vec_Ptr_t * vFanins; // the fanins array (temporary)
|
||||
Vec_Ptr_t * vFaninsCur; // the fanins array (temporary)
|
||||
Vec_Int_t * vLevNums; // the array of levels (temporary)
|
||||
Vec_Ptr_t * vNodesTemp; // the nodes in MFFC (temporary)
|
||||
// node statistics
|
||||
int nNodesConsidered;
|
||||
int nNodesRewritten;
|
||||
int nNodesGained;
|
||||
int nScores[222];
|
||||
int nCutsGood;
|
||||
int nCutsBad;
|
||||
int nSubgraphs;
|
||||
// runtime statistics
|
||||
int timeStart;
|
||||
int timeTruth;
|
||||
int timeCut;
|
||||
int timeRes;
|
||||
int timeEval;
|
||||
int timeMffc;
|
||||
int timeUpdate;
|
||||
int timeTotal;
|
||||
};
|
||||
|
||||
struct Rwt_Node_t_ // 24 bytes
|
||||
{
|
||||
int Id; // ID
|
||||
int TravId; // traversal ID
|
||||
unsigned uTruth : 16; // truth table
|
||||
unsigned Volume : 8; // volume
|
||||
unsigned Level : 6; // level
|
||||
unsigned fUsed : 1; // mark
|
||||
unsigned fExor : 1; // mark
|
||||
Rwt_Node_t * p0; // first child
|
||||
Rwt_Node_t * p1; // second child
|
||||
Rwt_Node_t * pNext; // next in the table
|
||||
};
|
||||
|
||||
// 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)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== rwrDec.c ========================================================*/
|
||||
extern void Rwt_ManPreprocess( Rwt_Man_t * p );
|
||||
/*=== rwrMan.c ========================================================*/
|
||||
extern Rwt_Man_t * Rwt_ManStart( int fPrecompute );
|
||||
extern void Rwt_ManStop( Rwt_Man_t * p );
|
||||
extern void Rwt_ManPrintStats( Rwt_Man_t * p );
|
||||
extern void Rwt_ManPrintStatsFile( Rwt_Man_t * p );
|
||||
extern void * Rwt_ManReadDecs( Rwt_Man_t * p );
|
||||
extern Vec_Ptr_t * Rwt_ManReadLeaves( Rwt_Man_t * p );
|
||||
extern int Rwt_ManReadCompl( Rwt_Man_t * p );
|
||||
extern void Rwt_ManAddTimeCuts( Rwt_Man_t * p, int Time );
|
||||
extern void Rwt_ManAddTimeUpdate( Rwt_Man_t * p, int Time );
|
||||
extern void Rwt_ManAddTimeTotal( Rwt_Man_t * p, int Time );
|
||||
/*=== rwrUtil.c ========================================================*/
|
||||
extern void Rwt_ManLoadFromArray( Rwt_Man_t * p, int fVerbose );
|
||||
extern char * Rwt_ManGetPractical( Rwt_Man_t * p );
|
||||
extern Rwt_Node_t * Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute );
|
||||
extern void Rwt_ManIncTravId( Rwt_Man_t * p );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rwtDec.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware AIG rewriting package.]
|
||||
|
||||
Synopsis [Evaluation and decomposition procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rwtDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rwt.h"
|
||||
#include "deco.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Dec_Graph_t * Rwt_NodePreprocess( Rwt_Man_t * p, Rwt_Node_t * pNode );
|
||||
static Dec_Edge_t Rwt_TravCollect_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, Dec_Graph_t * pGraph );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Preprocesses computed library of subgraphs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManPreprocess( Rwt_Man_t * p )
|
||||
{
|
||||
Dec_Graph_t * pGraph;
|
||||
Rwt_Node_t * pNode;
|
||||
int i, k;
|
||||
// put the nodes into the structure
|
||||
p->pMapInv = ALLOC( unsigned short, 222 );
|
||||
memset( p->pMapInv, 0, sizeof(unsigned short) * 222 );
|
||||
p->vClasses = Vec_VecStart( 222 );
|
||||
for ( i = 0; i < p->nFuncs; i++ )
|
||||
{
|
||||
if ( p->pTable[i] == NULL )
|
||||
continue;
|
||||
// consider all implementations of this function
|
||||
for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext )
|
||||
{
|
||||
assert( pNode->uTruth == p->pTable[i]->uTruth );
|
||||
assert( p->pMap[pNode->uTruth] >= 0 && p->pMap[pNode->uTruth] < 222 );
|
||||
Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode );
|
||||
p->pMapInv[ p->pMap[pNode->uTruth] ] = p->puCanons[pNode->uTruth];
|
||||
}
|
||||
}
|
||||
// compute decomposition forms for each node and verify them
|
||||
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
|
||||
{
|
||||
pGraph = Rwt_NodePreprocess( p, pNode );
|
||||
pNode->pNext = (Rwt_Node_t *)pGraph;
|
||||
// assert( pNode->uTruth == (Dec_GraphDeriveTruth(pGraph) & 0xFFFF) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Preprocesses subgraphs rooted at this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Graph_t * Rwt_NodePreprocess( Rwt_Man_t * p, Rwt_Node_t * pNode )
|
||||
{
|
||||
Dec_Graph_t * pGraph;
|
||||
Dec_Edge_t eRoot;
|
||||
assert( !Rwt_IsComplement(pNode) );
|
||||
// consider constant
|
||||
if ( pNode->uTruth == 0 )
|
||||
return Dec_GraphCreateConst0();
|
||||
// consider the case of elementary var
|
||||
if ( pNode->uTruth == 0x00FF )
|
||||
return Dec_GraphCreateLeaf( 3, 4, 1 );
|
||||
// start the subgraphs
|
||||
pGraph = Dec_GraphCreate( 4 );
|
||||
// collect the nodes
|
||||
Rwt_ManIncTravId( p );
|
||||
eRoot = Rwt_TravCollect_rec( p, pNode, pGraph );
|
||||
Dec_GraphSetRoot( pGraph, eRoot );
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Edge_t Rwt_TravCollect_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, Dec_Graph_t * pGraph )
|
||||
{
|
||||
Dec_Edge_t eNode0, eNode1, eNode;
|
||||
// elementary variable
|
||||
if ( pNode->fUsed )
|
||||
return Dec_EdgeCreate( pNode->Id - 1, 0 );
|
||||
// previously visited node
|
||||
if ( pNode->TravId == p->nTravIds )
|
||||
return Dec_IntToEdge( pNode->Volume );
|
||||
pNode->TravId = p->nTravIds;
|
||||
// solve for children
|
||||
eNode0 = Rwt_TravCollect_rec( p, Rwt_Regular(pNode->p0), pGraph );
|
||||
if ( Rwt_IsComplement(pNode->p0) )
|
||||
eNode0.fCompl = !eNode0.fCompl;
|
||||
eNode1 = Rwt_TravCollect_rec( p, Rwt_Regular(pNode->p1), pGraph );
|
||||
if ( Rwt_IsComplement(pNode->p1) )
|
||||
eNode1.fCompl = !eNode1.fCompl;
|
||||
// create the decomposition node(s)
|
||||
if ( pNode->fExor )
|
||||
eNode = Dec_GraphAddNodeXor( pGraph, eNode0, eNode1, 0 );
|
||||
else
|
||||
eNode = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
|
||||
// save the result
|
||||
pNode->Volume = Dec_EdgeToInt( eNode );
|
||||
return eNode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,358 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rwtMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware AIG rewriting package.]
|
||||
|
||||
Synopsis [Rewriting manager.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rwtMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rwt.h"
|
||||
#include "deco.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned short * s_puCanons = NULL;
|
||||
static char * s_pPhases = NULL;
|
||||
static char * s_pPerms = NULL;
|
||||
static unsigned char * s_pMap = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts residual rewriting manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManGlobalStart()
|
||||
{
|
||||
if ( s_puCanons == NULL )
|
||||
Extra_Truth4VarNPN( &s_puCanons, &s_pPhases, &s_pPerms, &s_pMap );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts residual rewriting manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManGlobalStop()
|
||||
{
|
||||
if ( s_puCanons == NULL ) free( s_puCanons );
|
||||
if ( s_pPhases == NULL ) free( s_pPhases );
|
||||
if ( s_pPerms == NULL ) free( s_pPerms );
|
||||
if ( s_pMap == NULL ) free( s_pMap );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts rewriting manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Rwt_Man_t * Rwt_ManStart( int fPrecompute )
|
||||
{
|
||||
Rwt_Man_t * p;
|
||||
int clk = clock();
|
||||
clk = clock();
|
||||
p = ALLOC( Rwt_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Rwt_Man_t) );
|
||||
p->nFuncs = (1<<16);
|
||||
// copy the global tables
|
||||
Rwt_ManGlobalStart();
|
||||
p->puCanons = s_puCanons;
|
||||
p->pPhases = s_pPhases;
|
||||
p->pPerms = s_pPerms;
|
||||
p->pMap = s_pMap;
|
||||
// initialize practical NPN classes
|
||||
p->pPractical = Rwt_ManGetPractical( p );
|
||||
// create the table
|
||||
p->pTable = ALLOC( Rwt_Node_t *, p->nFuncs );
|
||||
memset( p->pTable, 0, sizeof(Rwt_Node_t *) * p->nFuncs );
|
||||
// create the elementary nodes
|
||||
p->pMmNode = Mem_FixedStart( sizeof(Rwt_Node_t) );
|
||||
p->vForest = Vec_PtrAlloc( 100 );
|
||||
Rwt_ManAddVar( p, 0x0000, fPrecompute ); // constant 0
|
||||
Rwt_ManAddVar( p, 0xAAAA, fPrecompute ); // var A
|
||||
Rwt_ManAddVar( p, 0xCCCC, fPrecompute ); // var B
|
||||
Rwt_ManAddVar( p, 0xF0F0, fPrecompute ); // var C
|
||||
Rwt_ManAddVar( p, 0xFF00, fPrecompute ); // var D
|
||||
p->nClasses = 5;
|
||||
// other stuff
|
||||
p->nTravIds = 1;
|
||||
p->pPerms4 = Extra_Permutations( 4 );
|
||||
p->vLevNums = Vec_IntAlloc( 50 );
|
||||
p->vFanins = Vec_PtrAlloc( 50 );
|
||||
p->vFaninsCur = Vec_PtrAlloc( 50 );
|
||||
p->vNodesTemp = Vec_PtrAlloc( 50 );
|
||||
if ( fPrecompute )
|
||||
{ // precompute subgraphs
|
||||
// Rwt_ManPrecompute( p );
|
||||
// Rwt_ManPrint( p );
|
||||
// Rwt_ManWriteToArray( p );
|
||||
}
|
||||
else
|
||||
{ // load saved subgraphs
|
||||
Rwt_ManLoadFromArray( p, 0 );
|
||||
// Rwt_ManPrint( p );
|
||||
Rwt_ManPreprocess( p );
|
||||
}
|
||||
p->timeStart = clock() - clk;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops rewriting manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManStop( Rwt_Man_t * p )
|
||||
{
|
||||
if ( p->vClasses )
|
||||
{
|
||||
Rwt_Node_t * pNode;
|
||||
int i, k;
|
||||
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
|
||||
Dec_GraphFree( (Dec_Graph_t *)pNode->pNext );
|
||||
}
|
||||
if ( p->vClasses ) Vec_VecFree( p->vClasses );
|
||||
Vec_PtrFree( p->vNodesTemp );
|
||||
Vec_PtrFree( p->vForest );
|
||||
Vec_IntFree( p->vLevNums );
|
||||
Vec_PtrFree( p->vFanins );
|
||||
Vec_PtrFree( p->vFaninsCur );
|
||||
Mem_FixedStop( p->pMmNode, 0 );
|
||||
FREE( p->pMapInv );
|
||||
free( p->pTable );
|
||||
free( p->pPractical );
|
||||
free( p->pPerms4 );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManPrintStats( Rwt_Man_t * p )
|
||||
{
|
||||
int i, Counter = 0;
|
||||
for ( i = 0; i < 222; i++ )
|
||||
Counter += (p->nScores[i] > 0);
|
||||
|
||||
printf( "Rewriting statistics:\n" );
|
||||
printf( "Total cuts tries = %8d.\n", p->nCutsGood );
|
||||
printf( "Bad cuts found = %8d.\n", p->nCutsBad );
|
||||
printf( "Total subgraphs = %8d.\n", p->nSubgraphs );
|
||||
printf( "Used NPN classes = %8d.\n", Counter );
|
||||
printf( "Nodes considered = %8d.\n", p->nNodesConsidered );
|
||||
printf( "Nodes rewritten = %8d.\n", p->nNodesRewritten );
|
||||
printf( "Calculated gain = %8d.\n", p->nNodesGained );
|
||||
PRT( "Start ", p->timeStart );
|
||||
PRT( "Cuts ", p->timeCut );
|
||||
PRT( "Truth ", p->timeTruth );
|
||||
PRT( "Resynthesis ", p->timeRes );
|
||||
PRT( " Mffc ", p->timeMffc );
|
||||
PRT( " Eval ", p->timeEval );
|
||||
PRT( "Update ", p->timeUpdate );
|
||||
PRT( "TOTAL ", p->timeTotal );
|
||||
|
||||
|
||||
printf( "The scores are:\n" );
|
||||
for ( i = 0; i < 222; i++ )
|
||||
if ( p->nScores[i] > 0 )
|
||||
{
|
||||
extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
|
||||
printf( "%3d = %8d canon = %5d ", i, p->nScores[i], p->pMapInv[i] );
|
||||
Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) );
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManPrintStatsFile( Rwt_Man_t * p )
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "stats.txt", "a+" );
|
||||
fprintf( pTable, "%d ", p->nCutsGood );
|
||||
fprintf( pTable, "%d ", p->nSubgraphs );
|
||||
fprintf( pTable, "%d ", p->nNodesRewritten );
|
||||
fprintf( pTable, "%d", p->nNodesGained );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Rwt_ManReadDecs( Rwt_Man_t * p )
|
||||
{
|
||||
return p->pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Rwt_ManReadLeaves( Rwt_Man_t * p )
|
||||
{
|
||||
return p->vFanins;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwt_ManReadCompl( Rwt_Man_t * p )
|
||||
{
|
||||
return p->fCompl;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManAddTimeCuts( Rwt_Man_t * p, int Time )
|
||||
{
|
||||
p->timeCut += Time;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManAddTimeUpdate( Rwt_Man_t * p, int Time )
|
||||
{
|
||||
p->timeUpdate += Time;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the resynthesis manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManAddTimeTotal( Rwt_Man_t * p, int Time )
|
||||
{
|
||||
p->timeTotal += Time;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Precomputes AIG subgraphs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_Precompute()
|
||||
{
|
||||
Rwt_Man_t * p;
|
||||
p = Rwt_ManStart( 1 );
|
||||
Rwt_ManStop( p );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,665 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rwtUtil.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware AIG rewriting package.]
|
||||
|
||||
Synopsis [Various utilities.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rwtUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rwt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// precomputed data
|
||||
#ifdef _WIN32
|
||||
unsigned short s_RwtPracticalClasses[];
|
||||
unsigned short s_RwtAigSubgraphs[];
|
||||
#else
|
||||
static unsigned short s_RwtPracticalClasses[];
|
||||
static unsigned short s_RwtAigSubgraphs[];
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the node to the end of the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ListAddToTail( Rwt_Node_t ** ppList, Rwt_Node_t * pNode )
|
||||
{
|
||||
Rwt_Node_t * pTemp;
|
||||
// find the last one
|
||||
for ( pTemp = *ppList; pTemp; pTemp = pTemp->pNext )
|
||||
ppList = &pTemp->pNext;
|
||||
// attach at the end
|
||||
*ppList = pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Rwt_Node_t * Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute )
|
||||
{
|
||||
Rwt_Node_t * pNew;
|
||||
pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode );
|
||||
pNew->Id = p->vForest->nSize;
|
||||
pNew->TravId = 0;
|
||||
pNew->uTruth = uTruth;
|
||||
pNew->Level = 0;
|
||||
pNew->Volume = 0;
|
||||
pNew->fUsed = 1;
|
||||
pNew->fExor = 0;
|
||||
pNew->p0 = NULL;
|
||||
pNew->p1 = NULL;
|
||||
pNew->pNext = NULL;
|
||||
Vec_PtrPush( p->vForest, pNew );
|
||||
if ( fPrecompute )
|
||||
Rwt_ListAddToTail( p->pTable + uTruth, pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Rwt_Node_t * Rwt_ManAddNode( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1, int fExor, int Level, int Volume )
|
||||
{
|
||||
Rwt_Node_t * pNew;
|
||||
unsigned uTruth;
|
||||
// compute truth table, leve, volume
|
||||
p->nConsidered++;
|
||||
if ( fExor )
|
||||
uTruth = (p0->uTruth ^ p1->uTruth);
|
||||
else
|
||||
uTruth = (Rwt_IsComplement(p0)? ~Rwt_Regular(p0)->uTruth : Rwt_Regular(p0)->uTruth) &
|
||||
(Rwt_IsComplement(p1)? ~Rwt_Regular(p1)->uTruth : Rwt_Regular(p1)->uTruth) & 0xFFFF;
|
||||
// create the new node
|
||||
pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode );
|
||||
pNew->Id = p->vForest->nSize;
|
||||
pNew->TravId = 0;
|
||||
pNew->uTruth = uTruth;
|
||||
pNew->Level = Level;
|
||||
pNew->Volume = Volume;
|
||||
pNew->fUsed = 0;
|
||||
pNew->fExor = fExor;
|
||||
pNew->p0 = p0;
|
||||
pNew->p1 = p1;
|
||||
pNew->pNext = NULL;
|
||||
Vec_PtrPush( p->vForest, pNew );
|
||||
// do not add if the node is not essential
|
||||
if ( uTruth != p->puCanons[uTruth] )
|
||||
return pNew;
|
||||
|
||||
// add to the list
|
||||
p->nAdded++;
|
||||
if ( p->pTable[uTruth] == NULL )
|
||||
p->nClasses++;
|
||||
Rwt_ListAddToTail( p->pTable + uTruth, pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_Trav_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, int * pVolume )
|
||||
{
|
||||
if ( pNode->fUsed || pNode->TravId == p->nTravIds )
|
||||
return;
|
||||
pNode->TravId = p->nTravIds;
|
||||
(*pVolume)++;
|
||||
if ( pNode->fExor )
|
||||
(*pVolume)++;
|
||||
Rwt_Trav_rec( p, Rwt_Regular(pNode->p0), pVolume );
|
||||
Rwt_Trav_rec( p, Rwt_Regular(pNode->p1), pVolume );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManIncTravId( Rwt_Man_t * p )
|
||||
{
|
||||
Rwt_Node_t * pNode;
|
||||
int i;
|
||||
if ( p->nTravIds++ < 0x8FFFFFFF )
|
||||
return;
|
||||
Vec_PtrForEachEntry( p->vForest, pNode, i )
|
||||
pNode->TravId = 0;
|
||||
p->nTravIds = 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwt_ManNodeVolume( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1 )
|
||||
{
|
||||
int Volume = 0;
|
||||
Rwt_ManIncTravId( p );
|
||||
Rwt_Trav_rec( p, p0, &Volume );
|
||||
Rwt_Trav_rec( p, p1, &Volume );
|
||||
return Volume;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Loads data.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwt_ManLoadFromArray( Rwt_Man_t * p, int fVerbose )
|
||||
{
|
||||
unsigned short * pArray = s_RwtAigSubgraphs;
|
||||
Rwt_Node_t * p0, * p1;
|
||||
unsigned Entry0, Entry1;
|
||||
int Level, Volume, nEntries, fExor;
|
||||
int i, clk = clock();
|
||||
|
||||
// reconstruct the forest
|
||||
for ( i = 0; ; i++ )
|
||||
{
|
||||
Entry0 = pArray[2*i + 0];
|
||||
Entry1 = pArray[2*i + 1];
|
||||
if ( Entry0 == 0 && Entry1 == 0 )
|
||||
break;
|
||||
// get EXOR flag
|
||||
fExor = (Entry0 & 1);
|
||||
Entry0 >>= 1;
|
||||
// get the nodes
|
||||
p0 = p->vForest->pArray[Entry0 >> 1];
|
||||
p1 = p->vForest->pArray[Entry1 >> 1];
|
||||
// compute the level and volume of the new nodes
|
||||
Level = 1 + RWT_MAX( p0->Level, p1->Level );
|
||||
Volume = 1 + Rwt_ManNodeVolume( p, p0, p1 );
|
||||
// set the complemented attributes
|
||||
p0 = Rwt_NotCond( p0, (Entry0 & 1) );
|
||||
p1 = Rwt_NotCond( p1, (Entry1 & 1) );
|
||||
// add the node
|
||||
// Rwt_ManTryNode( p, p0, p1, Level, Volume );
|
||||
Rwt_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor );
|
||||
}
|
||||
nEntries = i - 1;
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded );
|
||||
printf( "The number of nodes loaded = %d. ", nEntries ); PRT( "Loading", clock() - clk );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create practical classes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Rwt_ManGetPractical( Rwt_Man_t * p )
|
||||
{
|
||||
char * pPractical;
|
||||
int i;
|
||||
pPractical = ALLOC( char, p->nFuncs );
|
||||
memset( pPractical, 0, sizeof(char) * p->nFuncs );
|
||||
pPractical[0] = 1;
|
||||
for ( i = 1; ; i++ )
|
||||
{
|
||||
if ( s_RwtPracticalClasses[i] == 0 )
|
||||
break;
|
||||
pPractical[ s_RwtPracticalClasses[i] ] = 1;
|
||||
}
|
||||
return pPractical;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the following 135 practical NPN classes of 4-variable functions were computed
|
||||
// by considering all 4-input cuts appearing in IWLS, MCNC, and ISCAS benchmarks
|
||||
static unsigned short s_RwtPracticalClasses[] =
|
||||
{
|
||||
0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019, 0x001b,
|
||||
0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e, 0x007f, 0x00ff,
|
||||
0x0116, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f, 0x012c, 0x012d, 0x012f, 0x013c,
|
||||
0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016f, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183,
|
||||
0x0186, 0x0189, 0x018b, 0x018f, 0x0198, 0x0199, 0x019b, 0x01a8, 0x01a9, 0x01aa, 0x01ab,
|
||||
0x01ac, 0x01ad, 0x01ae, 0x01af, 0x01bf, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef, 0x01fe,
|
||||
0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035f, 0x0368,
|
||||
0x0369, 0x036c, 0x036e, 0x037d, 0x03c0, 0x03c1, 0x03c3, 0x03c7, 0x03cf, 0x03d4, 0x03d5,
|
||||
0x03d7, 0x03d8, 0x03d9, 0x03dc, 0x03dd, 0x03de, 0x03fc, 0x0660, 0x0661, 0x0666, 0x0669,
|
||||
0x066f, 0x0676, 0x067e, 0x0690, 0x0696, 0x0697, 0x069f, 0x06b1, 0x06b6, 0x06f0, 0x06f2,
|
||||
0x06f6, 0x06f9, 0x0776, 0x0778, 0x07b0, 0x07b1, 0x07b4, 0x07bc, 0x07f0, 0x07f2, 0x07f8,
|
||||
0x0ff0, 0x1683, 0x1696, 0x1698, 0x169e, 0x16e9, 0x178e, 0x17e8, 0x18e7, 0x19e6, 0x1be4,
|
||||
0x1ee1, 0x3cc3, 0x6996, 0x0000
|
||||
};
|
||||
|
||||
static unsigned short s_RwtAigSubgraphs[] =
|
||||
{
|
||||
0x0008,0x0002, 0x000a,0x0002, 0x0008,0x0003, 0x000a,0x0003, 0x0009,0x0002,
|
||||
0x000c,0x0002, 0x000e,0x0002, 0x000c,0x0003, 0x000e,0x0003, 0x000d,0x0002,
|
||||
0x000c,0x0004, 0x000e,0x0004, 0x000c,0x0005, 0x000e,0x0005, 0x000d,0x0004,
|
||||
0x0010,0x0002, 0x0012,0x0002, 0x0010,0x0003, 0x0012,0x0003, 0x0011,0x0002,
|
||||
0x0010,0x0004, 0x0012,0x0004, 0x0010,0x0005, 0x0012,0x0005, 0x0011,0x0004,
|
||||
0x0010,0x0006, 0x0012,0x0006, 0x0010,0x0007, 0x0012,0x0007, 0x0011,0x0006,
|
||||
0x0016,0x0005, 0x0014,0x0006, 0x0016,0x0006, 0x0014,0x0007, 0x0016,0x0007,
|
||||
0x0015,0x0006, 0x0014,0x0008, 0x0016,0x0008, 0x0014,0x0009, 0x0016,0x0009,
|
||||
0x0015,0x0008, 0x0018,0x0006, 0x001a,0x0006, 0x0018,0x0007, 0x001a,0x0007,
|
||||
0x0019,0x0006, 0x0018,0x0009, 0x001a,0x0009, 0x0019,0x0008, 0x001e,0x0005,
|
||||
0x001c,0x0006, 0x001e,0x0006, 0x001c,0x0007, 0x001e,0x0007, 0x001d,0x0006,
|
||||
0x001c,0x0008, 0x001e,0x0008, 0x001c,0x0009, 0x001e,0x0009, 0x001d,0x0008,
|
||||
0x0020,0x0006, 0x0022,0x0006, 0x0020,0x0007, 0x0022,0x0007, 0x0021,0x0006,
|
||||
0x0020,0x0008, 0x0022,0x0008, 0x0020,0x0009, 0x0022,0x0009, 0x0021,0x0008,
|
||||
0x0024,0x0006, 0x0026,0x0006, 0x0024,0x0007, 0x0026,0x0007, 0x0025,0x0006,
|
||||
0x0026,0x0008, 0x0024,0x0009, 0x0026,0x0009, 0x0025,0x0008, 0x0028,0x0004,
|
||||
0x002a,0x0004, 0x0028,0x0005, 0x002a,0x0007, 0x0028,0x0008, 0x002a,0x0009,
|
||||
0x0029,0x0008, 0x002a,0x000b, 0x0029,0x000a, 0x002a,0x000f, 0x0029,0x000e,
|
||||
0x002a,0x0011, 0x002a,0x0013, 0x002c,0x0004, 0x002e,0x0004, 0x002c,0x0005,
|
||||
0x002c,0x0009, 0x002e,0x0009, 0x002d,0x0008, 0x002d,0x000c, 0x002e,0x000f,
|
||||
0x002e,0x0011, 0x002e,0x0012, 0x0030,0x0004, 0x0032,0x0007, 0x0032,0x0009,
|
||||
0x0031,0x0008, 0x0032,0x000b, 0x0032,0x000d, 0x0032,0x000f, 0x0031,0x000e,
|
||||
0x0032,0x0013, 0x0034,0x0004, 0x0036,0x0004, 0x0034,0x0005, 0x0036,0x0005,
|
||||
0x0035,0x0004, 0x0036,0x0008, 0x0034,0x0009, 0x0036,0x0009, 0x0035,0x0008,
|
||||
0x0036,0x000b, 0x0036,0x000d, 0x0036,0x0011, 0x0035,0x0010, 0x0036,0x0013,
|
||||
0x0038,0x0004, 0x0039,0x0004, 0x0038,0x0009, 0x003a,0x0009, 0x0039,0x0008,
|
||||
0x0038,0x000b, 0x003a,0x000b, 0x003a,0x000d, 0x003a,0x0011, 0x003a,0x0012,
|
||||
0x0038,0x0013, 0x003a,0x0013, 0x003c,0x0002, 0x003e,0x0002, 0x003c,0x0003,
|
||||
0x003e,0x0005, 0x003e,0x0007, 0x003c,0x0008, 0x003e,0x0008, 0x003c,0x0009,
|
||||
0x003e,0x0009, 0x003d,0x0008, 0x003e,0x000d, 0x003e,0x0011, 0x003e,0x0013,
|
||||
0x003e,0x0017, 0x003e,0x001b, 0x003e,0x001d, 0x0040,0x0002, 0x0042,0x0002,
|
||||
0x0042,0x0005, 0x0041,0x0006, 0x0042,0x0008, 0x0041,0x0008, 0x0042,0x000d,
|
||||
0x0042,0x0011, 0x0042,0x0015, 0x0042,0x0019, 0x0042,0x001b, 0x0042,0x001c,
|
||||
0x0041,0x001c, 0x0044,0x0002, 0x0046,0x0003, 0x0045,0x0004, 0x0046,0x0007,
|
||||
0x0045,0x0008, 0x0046,0x000b, 0x0046,0x000f, 0x0046,0x0013, 0x0045,0x0012,
|
||||
0x0046,0x0017, 0x0046,0x001b, 0x0046,0x0021, 0x0048,0x0002, 0x004a,0x0002,
|
||||
0x0048,0x0003, 0x004a,0x0003, 0x0049,0x0002, 0x0048,0x0008, 0x004a,0x0008,
|
||||
0x0048,0x0009, 0x004a,0x0009, 0x0049,0x0008, 0x004a,0x000b, 0x004a,0x000f,
|
||||
0x004a,0x0011, 0x004a,0x0012, 0x004a,0x0013, 0x004a,0x0015, 0x004a,0x0019,
|
||||
0x004a,0x001b, 0x004a,0x001d, 0x004c,0x0002, 0x004c,0x0003, 0x004d,0x0002,
|
||||
0x004c,0x0008, 0x004e,0x0008, 0x004c,0x0009, 0x004e,0x0009, 0x004d,0x0008,
|
||||
0x004c,0x000b, 0x004e,0x000b, 0x004c,0x000f, 0x004e,0x000f, 0x004e,0x0011,
|
||||
0x004c,0x0012, 0x004c,0x0013, 0x004e,0x0013, 0x004e,0x0015, 0x004c,0x0017,
|
||||
0x004e,0x0019, 0x004c,0x001b, 0x004e,0x001b, 0x004c,0x001c, 0x004c,0x001d,
|
||||
0x004e,0x001d, 0x0050,0x0004, 0x0052,0x0004, 0x0050,0x0006, 0x0052,0x0009,
|
||||
0x0052,0x000d, 0x0052,0x000f, 0x0052,0x0013, 0x0052,0x0017, 0x0052,0x0019,
|
||||
0x0052,0x001d, 0x0052,0x001f, 0x0052,0x0021, 0x0052,0x0023, 0x0052,0x0024,
|
||||
0x0052,0x0025, 0x0051,0x0024, 0x0052,0x0027, 0x0054,0x0004, 0x0056,0x0004,
|
||||
0x0054,0x0005, 0x0056,0x0006, 0x0054,0x0007, 0x0056,0x0011, 0x0056,0x001b,
|
||||
0x0056,0x001e, 0x0054,0x001f, 0x0056,0x001f, 0x0056,0x0020, 0x0054,0x0021,
|
||||
0x0055,0x0020, 0x0056,0x0024, 0x0054,0x0025, 0x0056,0x0025, 0x0055,0x0024,
|
||||
0x0054,0x0027, 0x0056,0x0027, 0x0055,0x0026, 0x005a,0x0007, 0x005a,0x0009,
|
||||
0x005a,0x000b, 0x005a,0x0015, 0x005a,0x001f, 0x0059,0x0020, 0x0058,0x0024,
|
||||
0x005a,0x0024, 0x005a,0x0027, 0x0059,0x0026, 0x005c,0x0004, 0x005e,0x0004,
|
||||
0x005c,0x0005, 0x005e,0x0006, 0x005c,0x0007, 0x005d,0x0006, 0x005e,0x000d,
|
||||
0x005e,0x0013, 0x005e,0x0017, 0x005c,0x001f, 0x005d,0x001e, 0x005e,0x0020,
|
||||
0x005e,0x0021, 0x005e,0x0022, 0x005e,0x0023, 0x005c,0x0024, 0x005e,0x0024,
|
||||
0x005c,0x0025, 0x005e,0x0025, 0x005d,0x0024, 0x005e,0x0026, 0x005e,0x0027,
|
||||
0x0062,0x0004, 0x0061,0x0004, 0x0062,0x0006, 0x0061,0x0006, 0x0060,0x000f,
|
||||
0x0060,0x0013, 0x0062,0x0013, 0x0060,0x0019, 0x0062,0x001c, 0x0060,0x001d,
|
||||
0x0062,0x001d, 0x0062,0x001f, 0x0060,0x0021, 0x0060,0x0023, 0x0062,0x0024,
|
||||
0x0060,0x0027, 0x0061,0x0026, 0x0064,0x0002, 0x0066,0x0002, 0x0064,0x0006,
|
||||
0x0066,0x0007, 0x0066,0x0009, 0x0066,0x000d, 0x0066,0x0013, 0x0066,0x0015,
|
||||
0x0066,0x0017, 0x0066,0x0019, 0x0066,0x001a, 0x0065,0x001a, 0x0066,0x001f,
|
||||
0x0066,0x0023, 0x0066,0x0027, 0x0066,0x002f, 0x0066,0x0030, 0x006a,0x0002,
|
||||
0x0068,0x0003, 0x0068,0x0006, 0x006a,0x0006, 0x006a,0x0011, 0x0068,0x0016,
|
||||
0x0068,0x0017, 0x006a,0x0017, 0x006a,0x001a, 0x006a,0x001b, 0x006a,0x0025,
|
||||
0x006a,0x002d, 0x006e,0x0003, 0x006e,0x0007, 0x006e,0x0009, 0x006e,0x000b,
|
||||
0x006e,0x0015, 0x006e,0x0016, 0x006e,0x0017, 0x006c,0x001a, 0x006e,0x001a,
|
||||
0x006e,0x001f, 0x006e,0x002b, 0x006e,0x0035, 0x0070,0x0002, 0x0070,0x0003,
|
||||
0x0072,0x0006, 0x0070,0x0007, 0x0071,0x0006, 0x0072,0x000b, 0x0072,0x000f,
|
||||
0x0072,0x0013, 0x0070,0x0015, 0x0071,0x0014, 0x0072,0x0017, 0x0072,0x0018,
|
||||
0x0070,0x0019, 0x0072,0x0019, 0x0070,0x001a, 0x0070,0x001b, 0x0072,0x001b,
|
||||
0x0071,0x001a, 0x0072,0x0021, 0x0072,0x0029, 0x0076,0x0002, 0x0076,0x0003,
|
||||
0x0075,0x0002, 0x0076,0x0006, 0x0074,0x0007, 0x0076,0x0007, 0x0075,0x0006,
|
||||
0x0076,0x000d, 0x0076,0x0011, 0x0076,0x0013, 0x0075,0x0014, 0x0076,0x0019,
|
||||
0x0076,0x001a, 0x0076,0x001b, 0x0075,0x001c, 0x0074,0x0023, 0x0075,0x0022,
|
||||
0x0074,0x0026, 0x0076,0x0026, 0x0074,0x0027, 0x0076,0x002b, 0x0076,0x002f,
|
||||
0x0078,0x0002, 0x0078,0x0004, 0x007a,0x0004, 0x007a,0x0005, 0x0079,0x0004,
|
||||
0x007a,0x0009, 0x007a,0x000a, 0x007a,0x000b, 0x007a,0x000d, 0x007a,0x000f,
|
||||
0x007a,0x0010, 0x007a,0x0011, 0x007a,0x0012, 0x007a,0x0013, 0x007a,0x0017,
|
||||
0x007a,0x001b, 0x007a,0x0021, 0x007a,0x0027, 0x007a,0x002b, 0x007a,0x002f,
|
||||
0x007a,0x0030, 0x0079,0x0034, 0x007a,0x0039, 0x007a,0x003a, 0x007e,0x0002,
|
||||
0x007c,0x0004, 0x007e,0x0004, 0x007e,0x000c, 0x007c,0x000d, 0x007e,0x0011,
|
||||
0x007e,0x0013, 0x007e,0x001b, 0x007e,0x0025, 0x007e,0x002d, 0x007e,0x0037,
|
||||
0x0082,0x0003, 0x0082,0x0005, 0x0082,0x0009, 0x0082,0x000b, 0x0080,0x0010,
|
||||
0x0082,0x0010, 0x0082,0x0012, 0x0082,0x0015, 0x0082,0x001f, 0x0082,0x002b,
|
||||
0x0082,0x0035, 0x0082,0x0039, 0x0082,0x003f, 0x0084,0x0002, 0x0086,0x0002,
|
||||
0x0084,0x0003, 0x0086,0x0003, 0x0085,0x0002, 0x0086,0x0004, 0x0084,0x0005,
|
||||
0x0085,0x0004, 0x0086,0x000a, 0x0084,0x000b, 0x0085,0x000a, 0x0086,0x000d,
|
||||
0x0086,0x000e, 0x0086,0x000f, 0x0084,0x0010, 0x0084,0x0011, 0x0086,0x0011,
|
||||
0x0085,0x0010, 0x0084,0x0012, 0x0084,0x0013, 0x0086,0x0013, 0x0085,0x0012,
|
||||
0x0086,0x0019, 0x0086,0x0023, 0x0086,0x0029, 0x0086,0x0033, 0x0086,0x0039,
|
||||
0x008a,0x0003, 0x0089,0x0002, 0x0088,0x0004, 0x008a,0x0004, 0x0088,0x0005,
|
||||
0x0089,0x0004, 0x008a,0x000b, 0x008a,0x0010, 0x0088,0x0011, 0x008a,0x0011,
|
||||
0x0089,0x0010, 0x0088,0x0012, 0x008a,0x0012, 0x0089,0x0012, 0x008a,0x0017,
|
||||
0x008a,0x001b, 0x0089,0x0020, 0x008a,0x0025, 0x0088,0x0027, 0x008a,0x002b,
|
||||
0x008a,0x002f, 0x008a,0x0039, 0x0088,0x003a, 0x008d,0x0044, 0x0092,0x0009,
|
||||
0x0092,0x0025, 0x0092,0x0029, 0x0092,0x002d, 0x0092,0x0033, 0x0092,0x0037,
|
||||
0x0092,0x003d, 0x0092,0x0041, 0x0095,0x0002, 0x0095,0x0004, 0x0095,0x0010,
|
||||
0x0095,0x0012, 0x0096,0x0021, 0x0096,0x0029, 0x0095,0x002e, 0x0096,0x0030,
|
||||
0x0096,0x0033, 0x0096,0x003a, 0x0096,0x0043, 0x009a,0x0008, 0x009a,0x0009,
|
||||
0x0099,0x0008, 0x009a,0x0011, 0x009a,0x0023, 0x009a,0x0033, 0x009a,0x003d,
|
||||
0x009a,0x0044, 0x009a,0x0045, 0x0099,0x0044, 0x009d,0x0002, 0x009e,0x0008,
|
||||
0x009c,0x0009, 0x009e,0x0009, 0x009d,0x0008, 0x009e,0x0011, 0x009d,0x0010,
|
||||
0x009e,0x001f, 0x009e,0x003f, 0x00a0,0x0009, 0x00a0,0x0011, 0x00a2,0x0030,
|
||||
0x00a2,0x0033, 0x00a6,0x0006, 0x00a6,0x0007, 0x00a6,0x0011, 0x00a6,0x0044,
|
||||
0x00a6,0x004b, 0x00aa,0x0007, 0x00aa,0x0015, 0x00ae,0x0006, 0x00ae,0x0011,
|
||||
0x00ae,0x001b, 0x00ae,0x0025, 0x00ae,0x003d, 0x00ae,0x0041, 0x00ae,0x0043,
|
||||
0x00ae,0x0045, 0x00b2,0x0006, 0x00b0,0x0007, 0x00b1,0x0006, 0x00b2,0x0017,
|
||||
0x00b1,0x0016, 0x00b0,0x0019, 0x00b2,0x0021, 0x00b2,0x003d, 0x00b5,0x004a,
|
||||
0x00ba,0x0009, 0x00ba,0x000f, 0x00bc,0x0009, 0x00be,0x0009, 0x00be,0x000f,
|
||||
0x00bd,0x000e, 0x00be,0x0017, 0x00c2,0x0009, 0x00c2,0x0019, 0x00c2,0x001f,
|
||||
0x00c2,0x0033, 0x00c6,0x0009, 0x00c5,0x000e, 0x00c6,0x0015, 0x00c6,0x0023,
|
||||
0x00c4,0x002d, 0x00c6,0x002f, 0x00c5,0x002e, 0x00c6,0x0045, 0x00ce,0x0007,
|
||||
0x00ce,0x0021, 0x00ce,0x0023, 0x00ce,0x0025, 0x00ce,0x0027, 0x00ce,0x0033,
|
||||
0x00ce,0x003d, 0x00d2,0x0006, 0x00d0,0x0015, 0x00d0,0x001b, 0x00d2,0x001b,
|
||||
0x00d1,0x001a, 0x00d0,0x001f, 0x00d2,0x0025, 0x00d1,0x0024, 0x00d2,0x0037,
|
||||
0x00d2,0x0041, 0x00d2,0x0045, 0x00d9,0x0044, 0x00e1,0x0004, 0x00e2,0x000d,
|
||||
0x00e2,0x0021, 0x00e0,0x003a, 0x00e6,0x003d, 0x00e6,0x0061, 0x00e6,0x0067,
|
||||
0x00e9,0x0004, 0x00ea,0x0008, 0x00ea,0x0009, 0x00ea,0x0039, 0x00e9,0x0038,
|
||||
0x00ea,0x003f, 0x00ec,0x000d, 0x00ee,0x000d, 0x00ee,0x0037, 0x00f2,0x003d,
|
||||
0x00f2,0x0062, 0x00f5,0x0002, 0x00fa,0x0017, 0x00fa,0x003d, 0x00fe,0x0006,
|
||||
0x00fd,0x0006, 0x00fc,0x0015, 0x00fe,0x001b, 0x00fc,0x0025, 0x00fe,0x0025,
|
||||
0x00fd,0x0024, 0x00fe,0x0041, 0x00fe,0x004d, 0x00fd,0x004e, 0x0101,0x0014,
|
||||
0x0106,0x004d, 0x010a,0x0009, 0x010a,0x000b, 0x0109,0x000a, 0x010a,0x004f,
|
||||
0x010a,0x0058, 0x010e,0x0008, 0x010c,0x0009, 0x010e,0x0009, 0x010d,0x0008,
|
||||
0x010e,0x000b, 0x010e,0x002b, 0x010d,0x002a, 0x010e,0x0035, 0x010e,0x003d,
|
||||
0x010e,0x003f, 0x010e,0x0049, 0x010e,0x0057, 0x010d,0x0056, 0x010d,0x0058,
|
||||
0x0111,0x0004, 0x0111,0x0006, 0x0110,0x0009, 0x0112,0x0009, 0x0111,0x0008,
|
||||
0x0112,0x002f, 0x0110,0x0035, 0x0110,0x0037, 0x0112,0x0039, 0x0112,0x003d,
|
||||
0x0112,0x003f, 0x0112,0x0045, 0x0111,0x0044, 0x0112,0x004b, 0x0112,0x0059,
|
||||
0x0112,0x0069, 0x0112,0x007f, 0x0116,0x0009, 0x0115,0x0008, 0x0114,0x000b,
|
||||
0x0116,0x000b, 0x0116,0x0058, 0x011a,0x0015, 0x011a,0x001f, 0x011a,0x002b,
|
||||
0x011a,0x003f, 0x011a,0x0049, 0x011a,0x0085, 0x011e,0x0007, 0x011e,0x0019,
|
||||
0x011e,0x001b, 0x011e,0x0023, 0x011e,0x0027, 0x011e,0x002f, 0x011e,0x0043,
|
||||
0x011e,0x004b, 0x011e,0x004e, 0x011e,0x004f, 0x011e,0x005f, 0x011e,0x0061,
|
||||
0x011e,0x0065, 0x011e,0x0083, 0x0122,0x0006, 0x0120,0x0007, 0x0122,0x0007,
|
||||
0x0121,0x0006, 0x0122,0x0049, 0x0121,0x004e, 0x0122,0x008f, 0x0125,0x0004,
|
||||
0x0124,0x0007, 0x0125,0x0006, 0x0124,0x001b, 0x0126,0x001b, 0x0126,0x0045,
|
||||
0x0126,0x0087, 0x0128,0x0007, 0x0129,0x0006, 0x012a,0x0019, 0x012a,0x003d,
|
||||
0x012a,0x0051, 0x012a,0x0065, 0x012a,0x0083, 0x012d,0x005a, 0x0132,0x0009,
|
||||
0x0132,0x008f, 0x0134,0x0009, 0x0135,0x003e, 0x013a,0x003d, 0x013a,0x0044,
|
||||
0x0139,0x0044, 0x013e,0x0009, 0x013d,0x0008, 0x013c,0x003d, 0x013c,0x0044,
|
||||
0x013c,0x0053, 0x013e,0x008f, 0x013e,0x0095, 0x0142,0x0044, 0x0142,0x0097,
|
||||
0x0142,0x009e, 0x0144,0x0007, 0x0148,0x0015, 0x0148,0x001c, 0x0148,0x001f,
|
||||
0x0148,0x0026, 0x0149,0x0086, 0x014d,0x0006, 0x014e,0x0044, 0x014d,0x0048,
|
||||
0x014e,0x009e, 0x0152,0x0009, 0x0151,0x00a6, 0x0155,0x0030, 0x015d,0x003a,
|
||||
0x0162,0x009e, 0x0164,0x000f, 0x0164,0x0013, 0x0169,0x000e, 0x0174,0x0009,
|
||||
0x0179,0x0008, 0x0180,0x0009, 0x0181,0x0044, 0x0186,0x0044, 0x0185,0x0044,
|
||||
0x018a,0x0068, 0x0195,0x004e, 0x01a6,0x0009, 0x01a5,0x0008, 0x01b1,0x003a,
|
||||
0x01c4,0x0029, 0x01c4,0x0030, 0x01ca,0x008f, 0x01ca,0x0095, 0x01cc,0x0029,
|
||||
0x01cc,0x0033, 0x01ce,0x003d, 0x01d6,0x00b2, 0x01d8,0x0009, 0x01d9,0x002a,
|
||||
0x01d9,0x0056, 0x01d9,0x00a4, 0x01dd,0x003a, 0x01e2,0x00b2, 0x01e6,0x0013,
|
||||
0x01e6,0x009f, 0x01e6,0x00ba, 0x01e6,0x00c0, 0x01e6,0x00d3, 0x01e6,0x00d5,
|
||||
0x01e6,0x00e5, 0x01e8,0x0005, 0x01f2,0x0013, 0x01f2,0x0095, 0x01f2,0x009f,
|
||||
0x01f2,0x00ba, 0x01f2,0x00c0, 0x01f2,0x00d3, 0x0202,0x008f, 0x0202,0x0095,
|
||||
0x0202,0x00f3, 0x0202,0x00f9, 0x020a,0x0044, 0x0209,0x00b4, 0x020e,0x0009,
|
||||
0x020d,0x0008, 0x020c,0x003d, 0x020c,0x0044, 0x020c,0x0053, 0x020e,0x008f,
|
||||
0x020e,0x0095, 0x020c,0x00b1, 0x020e,0x00f3, 0x020e,0x00f9, 0x0210,0x0013,
|
||||
0x0211,0x0024, 0x0210,0x0026, 0x0219,0x0004, 0x021e,0x008f, 0x021e,0x0095,
|
||||
0x0221,0x003a, 0x0230,0x0009, 0x0236,0x0009, 0x0234,0x0029, 0x0234,0x0030,
|
||||
0x0234,0x0033, 0x0234,0x003a, 0x0234,0x003d, 0x0234,0x0044, 0x0235,0x00a6,
|
||||
0x023a,0x0009, 0x023d,0x003a, 0x0245,0x0044, 0x0249,0x003a, 0x024e,0x009e,
|
||||
0x024e,0x0106, 0x0251,0x0026, 0x0258,0x0013, 0x0259,0x0024, 0x0258,0x0061,
|
||||
0x0259,0x0086, 0x0258,0x00c7, 0x0258,0x00df, 0x0259,0x00ec, 0x0258,0x00fc,
|
||||
0x025d,0x0024, 0x025d,0x00de, 0x0260,0x00f6, 0x0268,0x0009, 0x0269,0x0044,
|
||||
0x0268,0x00f3, 0x0268,0x00f9, 0x026d,0x003a, 0x0270,0x0068, 0x0275,0x003a,
|
||||
0x027a,0x0044, 0x0279,0x0044, 0x027e,0x007e, 0x0281,0x0044, 0x0285,0x0008,
|
||||
0x028d,0x0006, 0x028d,0x00d2, 0x0295,0x00cc, 0x0296,0x00f6, 0x0295,0x00f8,
|
||||
0x0299,0x0030, 0x029e,0x007e, 0x029d,0x0080, 0x02a6,0x008f, 0x02a6,0x0095,
|
||||
0x02aa,0x0029, 0x02aa,0x0030, 0x02b5,0x0008, 0x02b9,0x003a, 0x02bd,0x0004,
|
||||
0x02bd,0x00fc, 0x02c2,0x00b2, 0x02c1,0x00b4, 0x02c4,0x0029, 0x02c8,0x0029,
|
||||
0x02c8,0x0033, 0x02ca,0x003d, 0x02ce,0x0029, 0x02ce,0x0030, 0x02d2,0x0068,
|
||||
0x02d1,0x006a, 0x02d5,0x006a, 0x02d9,0x0008, 0x02de,0x012c, 0x02e2,0x012c,
|
||||
0x02e4,0x0009, 0x02e5,0x002a, 0x02e5,0x0056, 0x02e5,0x012c, 0x02ea,0x0029,
|
||||
0x02ea,0x0030, 0x02e9,0x0030, 0x02ec,0x0029, 0x02ec,0x0030, 0x02ee,0x012c,
|
||||
0x02f1,0x0068, 0x02f1,0x00b2, 0x02f1,0x0108, 0x02f1,0x012c, 0x02f6,0x0013,
|
||||
0x02f6,0x0015, 0x02f6,0x001f, 0x02f6,0x0030, 0x02f6,0x0065, 0x02f6,0x0067,
|
||||
0x02f6,0x009f, 0x02f6,0x00b6, 0x02f6,0x00b9, 0x02f6,0x00c0, 0x02f6,0x00cf,
|
||||
0x02f6,0x0107, 0x02f6,0x010b, 0x02f6,0x010f, 0x02f6,0x0115, 0x02f6,0x012d,
|
||||
0x02f6,0x0134, 0x02f6,0x0153, 0x02f6,0x0171, 0x02f6,0x0176, 0x02f8,0x0003,
|
||||
0x02fa,0x017b, 0x02fc,0x00ba, 0x02fc,0x00d3, 0x0302,0x0013, 0x0302,0x001f,
|
||||
0x0302,0x0030, 0x0302,0x005d, 0x0302,0x0065, 0x0302,0x0067, 0x0302,0x0099,
|
||||
0x0302,0x009f, 0x0302,0x00ad, 0x0302,0x00b9, 0x0302,0x00c0, 0x0302,0x00cf,
|
||||
0x0301,0x00d2, 0x0301,0x00fe, 0x0302,0x0107, 0x0302,0x010b, 0x0302,0x010f,
|
||||
0x0302,0x0117, 0x0302,0x0134, 0x0302,0x0153, 0x0302,0x0157, 0x0302,0x0176,
|
||||
0x0306,0x0029, 0x0308,0x00b2, 0x0309,0x00dc, 0x030d,0x00f8, 0x0312,0x00f3,
|
||||
0x0318,0x007e, 0x031d,0x0080, 0x0321,0x0008, 0x0321,0x0094, 0x0326,0x017b,
|
||||
0x0326,0x0181, 0x0329,0x012e, 0x032a,0x017b, 0x032a,0x0181, 0x032e,0x008f,
|
||||
0x032e,0x0095, 0x032e,0x00f3, 0x032e,0x00f9, 0x0332,0x0009, 0x0331,0x0008,
|
||||
0x0330,0x003d, 0x0330,0x0044, 0x0330,0x0053, 0x0332,0x008f, 0x0332,0x0095,
|
||||
0x0330,0x00b1, 0x0332,0x00f3, 0x0332,0x00f9, 0x0330,0x0127, 0x0332,0x017b,
|
||||
0x0332,0x0181, 0x033c,0x0013, 0x033c,0x001c, 0x033d,0x0086, 0x033d,0x00ec,
|
||||
0x033d,0x0172, 0x033e,0x019d, 0x0345,0x0002, 0x0344,0x008f, 0x0344,0x00f3,
|
||||
0x034d,0x0030, 0x0352,0x0033, 0x0354,0x0029, 0x0354,0x0030, 0x035a,0x0009,
|
||||
0x035a,0x017b, 0x035a,0x019b, 0x035a,0x01a2, 0x035e,0x0181, 0x0360,0x0009,
|
||||
0x0366,0x0009, 0x0364,0x0029, 0x0364,0x0030, 0x0364,0x0033, 0x0364,0x003a,
|
||||
0x0364,0x003d, 0x0364,0x0044, 0x0369,0x0030, 0x0370,0x0029, 0x0370,0x0030,
|
||||
0x0376,0x0033, 0x037a,0x0009, 0x037a,0x019b, 0x037a,0x01a2, 0x037c,0x0009,
|
||||
0x0382,0x0181, 0x0386,0x0009, 0x0384,0x0029, 0x0384,0x0030, 0x0384,0x0033,
|
||||
0x0384,0x003a, 0x0384,0x003d, 0x0384,0x0044, 0x038a,0x0044, 0x038a,0x009e,
|
||||
0x038a,0x0106, 0x038a,0x0198, 0x038d,0x010e, 0x038d,0x0152, 0x038d,0x0158,
|
||||
0x0392,0x009e, 0x0392,0x0106, 0x0392,0x0198, 0x0395,0x0086, 0x0395,0x009a,
|
||||
0x0395,0x00ec, 0x0395,0x0172, 0x0398,0x014e, 0x0398,0x0175, 0x0398,0x018d,
|
||||
0x039c,0x0023, 0x039c,0x0027, 0x039c,0x00ef, 0x039c,0x0139, 0x039c,0x0168,
|
||||
0x03a0,0x0019, 0x03a0,0x001d, 0x03a0,0x0023, 0x03a0,0x0027, 0x03a1,0x004e,
|
||||
0x03a4,0x0162, 0x03a4,0x0183, 0x03a8,0x0013, 0x03a8,0x0027, 0x03a8,0x0133,
|
||||
0x03a8,0x0148, 0x03a8,0x0181, 0x03ac,0x0013, 0x03ac,0x0027, 0x03b0,0x017b,
|
||||
0x03b0,0x0181, 0x03b4,0x004b, 0x03b4,0x00e0, 0x03b4,0x00fb, 0x03b8,0x000f,
|
||||
0x03b8,0x0013, 0x03b8,0x00ab, 0x03b8,0x00bf, 0x03b8,0x00d0, 0x03bd,0x00da,
|
||||
0x03bd,0x012c, 0x03c8,0x000f, 0x03c8,0x0013, 0x03c8,0x0019, 0x03c8,0x001d,
|
||||
0x03cd,0x0086, 0x03cd,0x00ec, 0x03cd,0x0172, 0x03d2,0x00e0, 0x03d2,0x00ef,
|
||||
0x03d2,0x0112, 0x03d2,0x0139, 0x03d2,0x0168, 0x03d6,0x017b, 0x03d6,0x0181,
|
||||
0x03da,0x0133, 0x03da,0x0148, 0x03e2,0x0023, 0x03e2,0x0027, 0x03e6,0x0027,
|
||||
0x03e6,0x0181, 0x03ee,0x017b, 0x03ee,0x0181, 0x03fe,0x003d, 0x0401,0x012a,
|
||||
0x0401,0x019e, 0x0405,0x01a0, 0x040a,0x000d, 0x040a,0x011f, 0x040a,0x016f,
|
||||
0x040d,0x012a, 0x0412,0x017b, 0x041a,0x0033, 0x041a,0x003d, 0x041a,0x0181,
|
||||
0x0421,0x0086, 0x0421,0x009a, 0x0421,0x00ec, 0x0421,0x0172, 0x042e,0x0205,
|
||||
0x043a,0x0205, 0x043e,0x017b, 0x0442,0x01f5, 0x044c,0x0007, 0x0452,0x0033,
|
||||
0x0452,0x01ce, 0x0452,0x01d0, 0x0452,0x01f1, 0x0452,0x01fb, 0x0452,0x0225,
|
||||
0x0454,0x0005, 0x045a,0x0033, 0x045a,0x0181, 0x045a,0x01ce, 0x045a,0x01d0,
|
||||
0x045a,0x01f1, 0x0469,0x01de, 0x046e,0x0181, 0x047a,0x01ce, 0x047a,0x01f1,
|
||||
0x0485,0x012c, 0x0489,0x012c, 0x0490,0x01d8, 0x0496,0x0033, 0x0496,0x003d,
|
||||
0x0498,0x008f, 0x0498,0x00f3, 0x049e,0x0044, 0x049e,0x0221, 0x04a1,0x0006,
|
||||
0x04a2,0x0044, 0x04a6,0x0221, 0x04a9,0x0004, 0x04ac,0x0027, 0x04b1,0x009a,
|
||||
0x04b6,0x0097, 0x04b8,0x0027, 0x04c6,0x0219, 0x04ca,0x017b, 0x04cc,0x004b,
|
||||
0x04d0,0x00ab, 0x04d6,0x017b, 0x04d8,0x000f, 0x04d8,0x0019, 0x04d8,0x0033,
|
||||
0x04d8,0x003d, 0x04de,0x003d, 0x04de,0x0103, 0x04de,0x018b, 0x04de,0x0231,
|
||||
0x04e2,0x0044, 0x04e2,0x009e, 0x04e2,0x0106, 0x04e2,0x0198, 0x04e5,0x01a4,
|
||||
0x04e5,0x01b6, 0x04ea,0x009e, 0x04ea,0x0106, 0x04ea,0x0198, 0x04ed,0x002e,
|
||||
0x04ed,0x0038, 0x04ed,0x00a2, 0x04f1,0x0086, 0x04f1,0x009a, 0x04f1,0x00ec,
|
||||
0x04f1,0x0172, 0x04f9,0x004e, 0x04f8,0x0229, 0x04f8,0x022d, 0x0500,0x023e,
|
||||
0x0504,0x0217, 0x0510,0x00f3, 0x0514,0x0043, 0x0514,0x004d, 0x0514,0x00c3,
|
||||
0x0514,0x013d, 0x0514,0x0215, 0x0514,0x0232, 0x0515,0x0260, 0x0519,0x002a,
|
||||
0x0518,0x0030, 0x0518,0x0067, 0x0518,0x00c9, 0x0518,0x01eb, 0x0518,0x01ef,
|
||||
0x051c,0x0139, 0x051c,0x0168, 0x0520,0x0027, 0x0526,0x014e, 0x0526,0x0175,
|
||||
0x0526,0x018d, 0x052d,0x0200, 0x0532,0x0021, 0x0532,0x00bf, 0x0532,0x00d0,
|
||||
0x0532,0x0239, 0x0532,0x0266, 0x053d,0x0024, 0x053d,0x00da, 0x054a,0x000f,
|
||||
0x054a,0x00ab, 0x054a,0x023a, 0x054e,0x0043, 0x054e,0x004d, 0x054e,0x00c3,
|
||||
0x054e,0x013d, 0x054e,0x0215, 0x054e,0x0232, 0x054e,0x029d, 0x0552,0x014e,
|
||||
0x0552,0x018d, 0x0556,0x00f3, 0x0556,0x01e4, 0x055a,0x0299, 0x055d,0x0086,
|
||||
0x055d,0x009a, 0x055d,0x00ec, 0x055d,0x0172, 0x0566,0x01dc, 0x0566,0x02a5,
|
||||
0x056d,0x020a, 0x057a,0x003d, 0x057a,0x01d4, 0x057a,0x01f3, 0x0579,0x025e,
|
||||
0x057e,0x0139, 0x057e,0x0168, 0x0581,0x0006, 0x0586,0x017b, 0x0586,0x0181,
|
||||
0x0586,0x028c, 0x0588,0x0007, 0x058e,0x0033, 0x058e,0x008f, 0x058e,0x01d0,
|
||||
0x058e,0x027c, 0x0590,0x0003, 0x0596,0x0033, 0x0596,0x008f, 0x0596,0x0095,
|
||||
0x0596,0x01d0, 0x0596,0x027c, 0x05a2,0x026f, 0x05a5,0x0284, 0x05aa,0x017b,
|
||||
0x05ac,0x0205, 0x05b2,0x008f, 0x05b6,0x017b, 0x05b8,0x01da, 0x05c1,0x0276,
|
||||
0x05c6,0x0248, 0x05c8,0x0247, 0x05c8,0x027e, 0x05cc,0x003d, 0x05cc,0x01d4,
|
||||
0x05cc,0x01f3, 0x05d0,0x014e, 0x05d0,0x018d, 0x05da,0x00f9, 0x05dd,0x0006,
|
||||
0x05de,0x0044, 0x05e5,0x002e, 0x05e6,0x02f1, 0x05ea,0x01d4, 0x05ea,0x01f3,
|
||||
0x05ea,0x022d, 0x05ed,0x0002, 0x05f6,0x0027, 0x05fa,0x0097, 0x05fc,0x003d,
|
||||
0x0602,0x003d, 0x0606,0x00f3, 0x060a,0x0027, 0x060e,0x003d, 0x060e,0x0103,
|
||||
0x060e,0x018b, 0x060e,0x0231, 0x060e,0x02d1, 0x0611,0x01fc, 0x0611,0x0234,
|
||||
0x061a,0x0287, 0x061d,0x0214, 0x0621,0x01d4, 0x062a,0x0027, 0x062a,0x022d,
|
||||
0x062e,0x009e, 0x062e,0x0106, 0x062e,0x0198, 0x0632,0x009e, 0x0632,0x0106,
|
||||
0x0632,0x0198, 0x0639,0x0042, 0x0639,0x00b2, 0x0639,0x0108, 0x063d,0x01f8,
|
||||
0x0641,0x0086, 0x0641,0x009a, 0x0641,0x00ec, 0x0641,0x0172, 0x0645,0x0044,
|
||||
0x0649,0x0042, 0x0648,0x0087, 0x0648,0x00ed, 0x0648,0x0173, 0x0649,0x01a0,
|
||||
0x0648,0x0241, 0x0648,0x026f, 0x0648,0x02df, 0x0648,0x0307, 0x064c,0x023a,
|
||||
0x064c,0x02b3, 0x0651,0x0062, 0x0650,0x0217, 0x0651,0x02ac, 0x0650,0x02d6,
|
||||
0x0655,0x0042, 0x065d,0x0042, 0x0664,0x02b1, 0x0664,0x02ce, 0x0669,0x0238,
|
||||
0x066d,0x002a, 0x066c,0x0039, 0x066d,0x01f6, 0x066c,0x0213, 0x066c,0x022e,
|
||||
0x066d,0x02a2, 0x066c,0x02e1, 0x0671,0x002a, 0x0670,0x0030, 0x0670,0x0067,
|
||||
0x0670,0x00c9, 0x0670,0x01eb, 0x0670,0x01ef, 0x0670,0x02c3, 0x0675,0x0020,
|
||||
0x0678,0x0133, 0x0678,0x0148, 0x067c,0x0027, 0x0681,0x023a, 0x0684,0x0021,
|
||||
0x0684,0x00bf, 0x0684,0x00d0, 0x0689,0x01fc, 0x068e,0x0162, 0x068e,0x0183,
|
||||
0x0691,0x0200, 0x0696,0x0023, 0x0696,0x00e0, 0x0696,0x00fb, 0x0696,0x0268,
|
||||
0x069a,0x0282, 0x069d,0x007e, 0x06a2,0x004b, 0x06a2,0x023e, 0x06a2,0x02dc,
|
||||
0x06a6,0x0097, 0x06aa,0x02b1, 0x06aa,0x02ce, 0x06ae,0x0039, 0x06ae,0x0213,
|
||||
0x06ae,0x022e, 0x06ae,0x02e1, 0x06b2,0x0162, 0x06b2,0x0183, 0x06b6,0x0023,
|
||||
0x06b6,0x00e0, 0x06b6,0x00fb, 0x06ba,0x008f, 0x06ba,0x01e4, 0x06be,0x034b,
|
||||
0x06c1,0x0086, 0x06c1,0x009a, 0x06c1,0x00ec, 0x06c1,0x0172, 0x06c6,0x01da,
|
||||
0x06c6,0x0280, 0x06c6,0x0351, 0x06ce,0x008f, 0x06d2,0x01e3, 0x06d2,0x0287,
|
||||
0x06d2,0x0353, 0x06d6,0x027a, 0x06d6,0x029b, 0x06da,0x0033, 0x06da,0x01ce,
|
||||
0x06da,0x01f1, 0x06de,0x0133, 0x06de,0x0148, 0x06e2,0x0021, 0x06e2,0x00bf,
|
||||
0x06e2,0x00d0, 0x06e5,0x023a, 0x06e9,0x0004, 0x06ee,0x028c, 0x06ee,0x0338,
|
||||
0x06f2,0x0328, 0x06f2,0x0330, 0x06f4,0x0005, 0x06f9,0x01e0, 0x06fe,0x0328,
|
||||
0x06fe,0x0330, 0x0702,0x003d, 0x0702,0x00f3, 0x0702,0x0330, 0x0704,0x0003,
|
||||
0x070a,0x003d, 0x070a,0x00f3, 0x070a,0x01d4, 0x070a,0x01f3, 0x070a,0x0330,
|
||||
0x0711,0x032a, 0x0711,0x032e, 0x0716,0x003d, 0x0718,0x0205, 0x0718,0x0282,
|
||||
0x071e,0x00f3, 0x0720,0x01dc, 0x0720,0x02a5, 0x0726,0x0324, 0x072a,0x028a,
|
||||
0x072a,0x02a7, 0x0729,0x031c, 0x0729,0x032a, 0x072e,0x003d, 0x072e,0x00f9,
|
||||
0x072e,0x022d, 0x072e,0x0248, 0x072e,0x02e4, 0x0730,0x003d, 0x0730,0x0247,
|
||||
0x0730,0x02e3, 0x0730,0x0324, 0x0732,0x0324, 0x0739,0x032e, 0x073e,0x003d,
|
||||
0x0740,0x003d, 0x0744,0x027a, 0x0744,0x029b, 0x0748,0x0033, 0x0748,0x01ce,
|
||||
0x0748,0x01f1, 0x074c,0x0162, 0x074c,0x0183, 0x0750,0x0023, 0x0750,0x00e0,
|
||||
0x0750,0x00fb, 0x0755,0x0246, 0x075a,0x0095, 0x075a,0x0397, 0x075d,0x0004,
|
||||
0x076a,0x03b3, 0x076d,0x0002, 0x0772,0x02fb, 0x0772,0x0301, 0x0772,0x0315,
|
||||
0x0772,0x0397, 0x0776,0x008f, 0x077e,0x0027, 0x078a,0x00a1, 0x0792,0x009d,
|
||||
0x0792,0x00c3, 0x0792,0x02fb, 0x0792,0x0301, 0x0792,0x0315, 0x0792,0x03bd,
|
||||
0x0796,0x0027, 0x0796,0x024f, 0x079e,0x009d, 0x07a6,0x009d, 0x07a6,0x02fb,
|
||||
0x07a6,0x0301, 0x07a6,0x0315, 0x07a6,0x03bd, 0x07aa,0x0027, 0x07aa,0x024f,
|
||||
0x07ae,0x009d, 0x07b9,0x004e, 0x07b8,0x0087, 0x07b8,0x00ed, 0x07b8,0x0173,
|
||||
0x07b8,0x0197, 0x07b9,0x021a, 0x07b9,0x02b8, 0x07b9,0x0364, 0x07be,0x0029,
|
||||
0x07be,0x0030, 0x07c0,0x017b, 0x07c6,0x017b, 0x07c8,0x00f3, 0x07ce,0x00f3,
|
||||
0x07d0,0x008f, 0x07d6,0x008f, 0x07d9,0x01e8, 0x07dd,0x0292, 0x07e2,0x0053,
|
||||
0x07e6,0x008f, 0x07e6,0x00f3, 0x07e6,0x017b, 0x07e8,0x0029, 0x07e8,0x0030,
|
||||
0x07ec,0x0021, 0x07ec,0x02ad, 0x07f2,0x0181, 0x07f2,0x0315, 0x07f4,0x0021,
|
||||
0x07f8,0x020f, 0x07fd,0x002e, 0x0800,0x008f, 0x0805,0x0006, 0x0809,0x03c2,
|
||||
0x080d,0x0084, 0x0812,0x0009, 0x0811,0x0008, 0x0812,0x00f3, 0x0812,0x00f9,
|
||||
0x0812,0x017b, 0x0812,0x0181, 0x0814,0x0033, 0x0818,0x0023, 0x081c,0x0285,
|
||||
0x0826,0x03bd, 0x082c,0x008f, 0x082c,0x017b, 0x0832,0x0043, 0x0832,0x011b,
|
||||
0x0832,0x01b3, 0x0832,0x01c3, 0x0835,0x032a, 0x0838,0x0085, 0x0839,0x032a,
|
||||
0x083e,0x0049, 0x083d,0x0084, 0x083e,0x02fb, 0x083e,0x0301, 0x083e,0x0315,
|
||||
0x083e,0x0397, 0x0842,0x0009, 0x0841,0x0008, 0x0844,0x0009, 0x0846,0x008f,
|
||||
0x084a,0x0033, 0x084e,0x0285, 0x0851,0x009a, 0x0856,0x00a1, 0x0859,0x031c,
|
||||
0x085d,0x00b2, 0x0861,0x0012, 0x0861,0x02cc, 0x0865,0x0058, 0x0865,0x007e,
|
||||
0x0869,0x004a, 0x0871,0x0010, 0x0876,0x003d, 0x0879,0x032c, 0x087e,0x0089,
|
||||
0x0882,0x0229, 0x0882,0x022d, 0x0882,0x02c7, 0x0882,0x02cb, 0x0886,0x0021,
|
||||
0x0886,0x02ad, 0x0885,0x0356, 0x088a,0x0017, 0x088a,0x020f, 0x0889,0x0354,
|
||||
0x088d,0x009c, 0x0892,0x0089, 0x0895,0x0246, 0x089a,0x03bd, 0x089e,0x008f,
|
||||
0x089e,0x02f9, 0x089e,0x0313, 0x08a1,0x032a, 0x08a6,0x0053, 0x08a6,0x0095,
|
||||
0x08a6,0x0397, 0x08a8,0x017b, 0x08ad,0x031a, 0x08b2,0x017b, 0x08b4,0x00f3,
|
||||
0x08b5,0x02a0, 0x08b8,0x0089, 0x08c1,0x0024, 0x08c4,0x00f3, 0x08c9,0x007e,
|
||||
0x08cd,0x007c, 0x08cd,0x0222, 0x08cd,0x0294, 0x08d1,0x003a, 0x08d6,0x0009,
|
||||
0x08d9,0x003a, 0x08dc,0x001f, 0x08e0,0x008f, 0x08e0,0x017b, 0x08e4,0x0009,
|
||||
0x08e8,0x01ed, 0x08ed,0x031c, 0x08f2,0x003d, 0x08f6,0x008f, 0x08f6,0x017b,
|
||||
0x08fa,0x0009, 0x08fe,0x003d, 0x0902,0x01e9, 0x0904,0x01e9, 0x0904,0x0381,
|
||||
0x090a,0x03b1, 0x090d,0x031a, 0x0910,0x0299, 0x0914,0x034b, 0x0919,0x0008,
|
||||
0x091c,0x0033, 0x091c,0x003d, 0x0920,0x0027, 0x0924,0x0027, 0x0924,0x01fb,
|
||||
0x092a,0x01ce, 0x092a,0x01f1, 0x092d,0x031c, 0x0930,0x001f, 0x0936,0x00c5,
|
||||
0x0938,0x00c5, 0x0938,0x0381, 0x093c,0x001b, 0x0942,0x017d, 0x094a,0x0027,
|
||||
0x094e,0x0027, 0x094e,0x01fb, 0x0952,0x03b1, 0x095a,0x0029, 0x095a,0x0030,
|
||||
0x095d,0x0030, 0x0961,0x0030, 0x0966,0x02f9, 0x0966,0x0313, 0x0968,0x02eb,
|
||||
0x096d,0x0008, 0x0970,0x017b, 0x0974,0x0033, 0x0979,0x0150, 0x097d,0x009a,
|
||||
0x0982,0x0293, 0x0984,0x0293, 0x0984,0x0379, 0x098a,0x02eb, 0x098e,0x0009,
|
||||
0x0992,0x003d, 0x0996,0x003d, 0x0999,0x0062, 0x099e,0x003d, 0x09a0,0x0027,
|
||||
0x09a5,0x0144, 0x09a8,0x02b5, 0x09ae,0x008f, 0x09ae,0x009d, 0x09b2,0x004d,
|
||||
0x09b2,0x0053, 0x09b2,0x00c3, 0x09b2,0x013d, 0x09b2,0x01c5, 0x09b2,0x0271,
|
||||
0x09b4,0x0025, 0x09ba,0x0033, 0x09ba,0x0079, 0x09bc,0x0015, 0x09c2,0x013f,
|
||||
0x09c4,0x013f, 0x09c4,0x0379, 0x09ca,0x02b5, 0x09cd,0x0006, 0x09da,0x0009,
|
||||
0x09d9,0x0008, 0x09dc,0x000b, 0x09dc,0x004f, 0x09dd,0x0086, 0x09e0,0x0009,
|
||||
0x09e6,0x00a1, 0x09e8,0x0009, 0x09ed,0x0086, 0x09f2,0x001f, 0x09f2,0x002f,
|
||||
0x09f2,0x0049, 0x09f2,0x006f, 0x09f2,0x0085, 0x09f2,0x0091, 0x09f2,0x00a9,
|
||||
0x09f2,0x00d3, 0x09f2,0x00d7, 0x09f2,0x011d, 0x09f2,0x0121, 0x09f2,0x0235,
|
||||
0x09f2,0x0393, 0x09f6,0x0324, 0x09f8,0x0049, 0x09f8,0x00a9, 0x09f8,0x011d,
|
||||
0x09fe,0x001f, 0x09fe,0x0029, 0x09fe,0x0033, 0x09fe,0x003d, 0x09fe,0x0085,
|
||||
0x09fe,0x008f, 0x09fe,0x00d3, 0x0a00,0x003d, 0x0a06,0x012d, 0x0a0e,0x00b3,
|
||||
0x0a10,0x000b, 0x0a10,0x0387, 0x0a16,0x0059, 0x0a18,0x0009, 0x0a1e,0x0043,
|
||||
0x0a24,0x0085, 0x0a2a,0x0009, 0x0a2d,0x0008, 0x0a32,0x028a, 0x0a32,0x02a7,
|
||||
0x0a31,0x031c, 0x0a35,0x032e, 0x0a39,0x0006, 0x0a3a,0x0105, 0x0a3a,0x024f,
|
||||
0x0a3c,0x0299, 0x0a42,0x01ed, 0x0a46,0x0299, 0x0a48,0x01ed, 0x0a4c,0x0059,
|
||||
0x0a52,0x000b, 0x0a52,0x0387, 0x0a56,0x000b, 0x0a5e,0x0009, 0x0a60,0x003d,
|
||||
0x0a66,0x0105, 0x0a6a,0x0195, 0x0a6c,0x000b, 0x0a76,0x0053, 0x0a78,0x0009,
|
||||
0x0a7a,0x008f, 0x0a82,0x0299, 0x0a86,0x01ed, 0x0a8a,0x0027, 0x0a8e,0x004b,
|
||||
0x0a92,0x003d, 0x0a95,0x0322, 0x0a99,0x0038, 0x0a99,0x0090, 0x0a9c,0x0061,
|
||||
0x0a9c,0x00c7, 0x0a9c,0x012d, 0x0a9c,0x016f, 0x0a9c,0x017d, 0x0a9c,0x02c9,
|
||||
0x0a9c,0x0383, 0x0aa1,0x0010, 0x0aa4,0x00b3, 0x0aa8,0x002f, 0x0aac,0x0027,
|
||||
0x0ab0,0x004b, 0x0ab4,0x0043, 0x0ab9,0x0090, 0x0abd,0x0010, 0x0ac4,0x0019,
|
||||
0x0acc,0x00f5, 0x0acc,0x022b, 0x0acc,0x037b, 0x0ad2,0x008f, 0x0ad2,0x01f1,
|
||||
0x0ad6,0x0324, 0x0ad9,0x0330, 0x0ade,0x008f, 0x0ade,0x01f1, 0x0ae0,0x017b,
|
||||
0x0ae4,0x008f, 0x0ae9,0x004e, 0x0aee,0x0027, 0x0af2,0x028a, 0x0af2,0x02a7,
|
||||
0x0af1,0x031c, 0x0af6,0x0027, 0x0af9,0x031c, 0x0afe,0x00e9, 0x0afe,0x02bb,
|
||||
0x0b02,0x000b, 0x0b06,0x00f5, 0x0b06,0x022b, 0x0b06,0x037b, 0x0b0a,0x003d,
|
||||
0x0000,0x0000
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
SRC +=
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/**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
|
||||
|
||||
#include "vecInt.h"
|
||||
#include "vecStr.h"
|
||||
#include "vecPtr.h"
|
||||
#include "vecVec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,753 @@
|
|||
/**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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 []
|
||||
|
||||
***********************************************************************/
|
||||
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;
|
||||
pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
|
||||
// pArray = ALLOC( int, 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 [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 last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPop( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
if ( i == p->nSize )
|
||||
return 0;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare1( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare2( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSort( Vec_Int_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare1 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSortUnsigned( Vec_Int_t * p )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,559 @@
|
|||
/**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_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;
|
||||
Vec_PtrGrow( 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;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Moves the first nItems to the end.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
|
||||
{
|
||||
assert( nItems < p->nSize );
|
||||
Vec_PtrGrow( p, nItems + p->nSize );
|
||||
memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
|
||||
memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
|
||||
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecStr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of characters.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_STR_H__
|
||||
#define __VEC_STR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Str_t_ Vec_Str_t;
|
||||
struct Vec_Str_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
char * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_StrForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAlloc( int nCap )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrStart( int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = Vec_StrAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( char, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFree( Vec_Str_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrReleaseArray( Vec_Str_t * p )
|
||||
{
|
||||
char * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrArray( Vec_Str_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSize( Vec_Str_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntry( Vec_Str_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntryLast( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );
|
||||
p->nCap = 2 * nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_StrGrow( p, nSize );
|
||||
p->nSize = nSize;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrClear( Vec_Str_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_StrGrow( p, 16 );
|
||||
else
|
||||
Vec_StrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Appends the string to the char vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrAppend( Vec_Str_t * p, char * pString )
|
||||
{
|
||||
int i, nLength = strlen(pString);
|
||||
Vec_StrGrow( p, p->nSize + nLength );
|
||||
for ( i = 0; i < nLength; i++ )
|
||||
p->pArray[p->nSize + i] = pString[i];
|
||||
p->nSize += nLength;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrPop( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare1( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecVec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable vector of resizable vectors.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_VEC_H__
|
||||
#define __VEC_VEC_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Vec_t_ Vec_Vec_t;
|
||||
struct Vec_Vec_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through levels
|
||||
#define Vec_VecForEachLevel( vGlob, vVec, i ) \
|
||||
for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
|
||||
for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
|
||||
// iteratores through entries
|
||||
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
|
||||
for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; i <= LevelStop; i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
p = ALLOC( Vec_Vec_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecStart( int nSize )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
int i;
|
||||
p = Vec_VecAlloc( nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = nSize;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= Level + 1 )
|
||||
return;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i <= Level; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSize( Vec_Vec_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecFree( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrFree( vVec );
|
||||
Vec_PtrFree( (Vec_Ptr_t *)p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector of vectors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSizeSize( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i, Counter = 0;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Counter += vVec->nSize;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecClear( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrClear( vVec );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i < Level + 1; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
Vec_VecPush( p, Level, Entry );
|
||||
else
|
||||
Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
SRC += src/opt/xyz/xyzBuild.c \
|
||||
src/opt/xyz/xyzCore.c \
|
||||
src/opt/xyz/xyzMan.c \
|
||||
src/opt/xyz/xyzMinEsop.c \
|
||||
src/opt/xyz/xyzMinMan.c \
|
||||
src/opt/xyz/xyzMinSop.c \
|
||||
src/opt/xyz/xyzMinUtil.c \
|
||||
src/opt/xyz/xyzTest.c
|
||||
SRC += src/temp/xyz/xyzBuild.c \
|
||||
src/temp/xyz/xyzCore.c \
|
||||
src/temp/xyz/xyzMan.c \
|
||||
src/temp/xyz/xyzMinEsop.c \
|
||||
src/temp/xyz/xyzMinMan.c \
|
||||
src/temp/xyz/xyzMinSop.c \
|
||||
src/temp/xyz/xyzMinUtil.c \
|
||||
src/temp/xyz/xyzTest.c
|
||||
|
|
|
|||
Loading…
Reference in New Issue