Commit dce73ade by Alan Mishchenko

Version abc50902

parent 9c98ba17
......@@ -13,11 +13,14 @@ MODULES := src/base/abc src/base/cmd src/base/io src/base/main \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr \
src/sat/asat src/sat/csat src/sat/msat src/sat/fraig src/sat/sim \
src/seq \
src/sop/ft src/sop/mvc
src/sop/mvc
default: $(PROG)
CFLAGS += -Wall -Wno-unused-function -g -O $(patsubst %, -I%, $(MODULES))
OPTFLAGS := -DNDEBUG -O3
#OPTFLAGS := -g -O
CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES))
CXXFLAGS += $(CFLAGS)
LIBS :=
......
......@@ -865,22 +865,6 @@ SOURCE=.\src\sop\mvc\mvcSort.c
SOURCE=.\src\sop\mvc\mvcUtils.c
# End Source File
# End Group
# Begin Group "ft"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\sop\ft\ft.h
# End Source File
# Begin Source File
SOURCE=.\src\sop\ft\ftFactor.c
# End Source File
# Begin Source File
SOURCE=.\src\sop\ft\ftPrint.c
# End Source File
# End Group
# End Group
# Begin Group "sat"
......@@ -1220,6 +1204,26 @@ SOURCE=.\src\opt\cut\cutTruth.c
SOURCE=.\src\opt\dec\dec.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\dec\decAbc.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\dec\decFactor.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\dec\decMan.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\dec\decPrint.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\dec\decUtil.c
# End Source File
# End Group
# End Group
# Begin Group "map"
......
No preview for this file type
......@@ -20,7 +20,6 @@
#include "abc.h"
#include "mainInt.h"
#include "ft.h"
#include "fraig.h"
#include "fxu.h"
#include "cut.h"
......@@ -162,7 +161,6 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 );
Ft_FactorStartMan();
// Rwt_Man4ExploreStart();
// Map_Var3Print();
// Map_Var4Test();
......@@ -181,7 +179,6 @@ void Abc_Init( Abc_Frame_t * pAbc )
***********************************************************************/
void Abc_End()
{
Ft_FactorStopMan();
Abc_NtkFraigStoreClean();
// Rwt_Man4ExplorePrint();
}
......@@ -1707,7 +1704,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "This command can only be applied to an AIG.\n" );
return 1;
}
if ( Abc_NtkCountChoiceNodes(pNtk) )
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" );
return 1;
......@@ -1816,7 +1813,7 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "This command can only be applied to an AIG.\n" );
return 1;
}
if ( Abc_NtkCountChoiceNodes(pNtk) )
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" );
return 1;
......@@ -1957,7 +1954,7 @@ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv )
pArgvNew = argv + util_optind;
nArgcNew = argc - util_optind;
if ( !Abc_NtkPrepareCommand( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
return 1;
// compute the miter
......@@ -3858,7 +3855,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
pArgvNew = argv + util_optind;
nArgcNew = argc - util_optind;
if ( !Abc_NtkPrepareCommand( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
return 1;
// perform equivalence checking
......@@ -3943,7 +3940,7 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
pArgvNew = argv + util_optind;
nArgcNew = argc - util_optind;
if ( !Abc_NtkPrepareCommand( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
return 1;
// perform equivalence checking
......
......@@ -476,6 +476,7 @@ extern Abc_Ntk_t * Abc_NtkFraigRestore();
extern void Abc_NtkFraigStoreClean();
/*=== abcFunc.c ==========================================================*/
extern int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk );
extern DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop );
extern char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, Vec_Str_t * vCube, int fMode );
extern int Abc_NtkBddToSop( Abc_Ntk_t * pNtk );
extern void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, char ** ppSop0, char ** ppSop1 );
......@@ -509,6 +510,13 @@ extern char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pN
extern char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix );
extern void Abc_NtkCreateCioNamesTable( Abc_Ntk_t * pNtk );
extern void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode );
extern Vec_Ptr_t * Abc_NodeGetFakeNames( int nNames );
extern void Abc_NodeFreeNames( Vec_Ptr_t * vNames );
extern char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos );
extern int Abc_NodeCompareNames( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
extern void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb );
extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
/*=== abcNetlist.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk );
......@@ -546,7 +554,6 @@ extern int Abc_NodeMffcSize( Abc_Obj_t * pNode );
extern int Abc_NodeMffcSizeStop( Abc_Obj_t * pNode );
extern int Abc_NodeMffcLabel( Abc_Obj_t * pNode );
extern Vec_Ptr_t * Abc_NodeMffcCollect( Abc_Obj_t * pNode );
extern void Abc_NodeUpdate( Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, int nGain );
/*=== abcRenode.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple );
extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld );
......@@ -594,8 +601,6 @@ extern void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses,
/*=== abcStrash.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup );
extern Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_NodeStrashDec( Abc_Aig_t * pMan, Vec_Ptr_t * vFanins, Vec_Int_t * vForm );
extern int Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, Vec_Int_t * vLevels, int NodeMax, int LevelMax );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
/*=== abcSweep.c ==========================================================*/
extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose );
......@@ -622,13 +627,6 @@ extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk );
extern void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR );
extern int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj );
extern int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj );
/*=== abcTravId.c ==========================================================*/
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
extern void Abc_NodeSetTravId( Abc_Obj_t * pObj, int TravId );
extern void Abc_NodeSetTravIdCurrent( Abc_Obj_t * pObj );
extern void Abc_NodeSetTravIdPrevious( Abc_Obj_t * pObj );
extern bool Abc_NodeIsTravIdCurrent( Abc_Obj_t * pObj );
extern bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pObj );
/*=== abcUtil.c ==========================================================*/
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
......@@ -637,28 +635,22 @@ extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk );
extern double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode );
extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate );
extern void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode );
extern int Abc_NtkCountExors( Abc_Ntk_t * pNtk );
extern bool Abc_NodeIsExorType( Abc_Obj_t * pNode );
extern bool Abc_NodeIsMuxType( Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE );
extern int Abc_NtkCountChoiceNodes( Abc_Ntk_t * pNtk );
extern int Abc_NtkPrepareCommand( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc, Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 );
extern int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc, Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 );
extern void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
extern int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
extern Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode );
extern Vec_Ptr_t * Abc_NodeGetFakeNames( int nNames );
extern void Abc_NodeFreeNames( Vec_Ptr_t * vNames );
extern char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos );
extern void Abc_NtkAlphaOrderSignals( Abc_Ntk_t * pNtk, int fComb );
extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
extern Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk );
......
......@@ -661,8 +661,8 @@ bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
***********************************************************************/
bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_NtkAlphaOrderSignals( pNtk1, fComb );
Abc_NtkAlphaOrderSignals( pNtk2, fComb );
Abc_NtkOrderObjsByName( pNtk1, fComb );
Abc_NtkOrderObjsByName( pNtk2, fComb );
if ( !Abc_NtkCompareLatches( pNtk1, pNtk2, fComb ) )
return 0;
if ( !Abc_NtkComparePis( pNtk1, pNtk2, fComb ) )
......
......@@ -53,7 +53,7 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
assert( Abc_NtkIsStrash(pNtk) );
// print a warning about choice nodes
if ( Abc_NtkCountChoiceNodes( pNtk ) )
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Performing FPGA mapping with choices.\n" );
// perform FPGA mapping
......
......@@ -267,7 +267,7 @@ Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk )
Abc_NtkFinalize( pNtk, pNtkNew );
// print a warning about choice nodes
printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkCountChoiceNodes( pNtkNew ) );
printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkGetChoiceNum( pNtkNew ) );
// make sure that everything is okay
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
......
......@@ -24,7 +24,6 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, int nFanins );
static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
////////////////////////////////////////////////////////////////////////
......@@ -61,7 +60,7 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
pNode->pData = Abc_ConvertSopToBdd( dd, pNode->pData, Abc_ObjFaninNum(pNode) );
pNode->pData = Abc_ConvertSopToBdd( dd, pNode->pData );
if ( pNode->pData == NULL )
{
printf( "Abc_NtkSopToBdd: Error while converting SOP into BDD.\n" );
......@@ -89,43 +88,37 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, int nFanins )
DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop )
{
DdNode * bCube, * bTemp, * bVar, * bRes;
DdNode * bSum, * bCube, * bTemp, * bVar;
char * pCube;
int i, c;
bRes = Cudd_Not(dd->one); Cudd_Ref( bRes );
for ( c = 0; ; c++ )
int nVars, Value, v;
// start the cover
nVars = Abc_SopGetVarNum(pSop);
// check the logic function of the node
bSum = Cudd_ReadLogicZero(dd); Cudd_Ref( bSum );
Abc_SopForEachCube( pSop, nVars, pCube )
{
// get the cube
pCube = pSop + c * (nFanins + 3);
if ( *pCube == 0 )
break;
// construct BDD for the cube
bCube = dd->one; Cudd_Ref( bCube );
for ( i = 0; i < nFanins; i++ )
bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube );
Abc_CubeForEachVar( pCube, Value, v )
{
if ( pCube[i] == '0' )
bVar = Cudd_Not( dd->vars[i] );
else if ( pCube[i] == '1' )
bVar = dd->vars[i];
if ( Value == '0' )
bVar = Cudd_Not( Cudd_bddIthVar( dd, v ) );
else if ( Value == '1' )
bVar = Cudd_bddIthVar( dd, v );
else
continue;
bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
Cudd_RecursiveDeref( dd, bTemp );
}
bRes = Cudd_bddOr( dd, bTemp = bRes, bCube ); Cudd_Ref( bRes );
bSum = Cudd_bddOr( dd, bTemp = bSum, bCube ); Cudd_Ref( bSum );
Cudd_RecursiveDeref( dd, bTemp );
Cudd_RecursiveDeref( dd, bCube );
}
// decide if we need to complement the result
pCube = pSop + nFanins + 1;
assert( *pCube == '0' || *pCube == '1' );
if ( *pCube == '0' )
bRes = Cudd_Not(bRes);
Cudd_Deref( bRes );
return bRes;
// complement the result if necessary
bSum = Cudd_NotCond( bSum, !Abc_SopGetPhase(pSop) );
Cudd_Deref( bSum );
return bSum;
}
/**Function*************************************************************
......@@ -171,7 +164,7 @@ void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i )
if ( Abc_SopIsComplement(pNode->pData) )
{
bFunc = Abc_ConvertSopToBdd( dd, pNode->pData, Abc_ObjFaninNum(pNode) ); Cudd_Ref( bFunc );
bFunc = Abc_ConvertSopToBdd( dd, pNode->pData ); Cudd_Ref( bFunc );
pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, 1 );
Cudd_RecursiveDeref( dd, bFunc );
assert( !Abc_SopIsComplement(pNode->pData) );
......@@ -340,7 +333,7 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun
// verify
if ( fVerify )
{
bFuncNew = Abc_ConvertSopToBdd( dd, pSop, nFanins ); Cudd_Ref( bFuncNew );
bFuncNew = Abc_ConvertSopToBdd( dd, pSop ); Cudd_Ref( bFuncNew );
if ( bFuncOn == bFuncOnDc )
{
if ( bFuncNew != bFuncOn )
......
......@@ -79,7 +79,7 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
}
// print a warning about choice nodes
if ( Abc_NtkCountChoiceNodes( pNtk ) )
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Performing mapping with choices.\n" );
// perform the mapping
......@@ -442,7 +442,7 @@ Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
}
// print a warning about choice nodes
if ( Abc_NtkCountChoiceNodes( pNtk ) )
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Performing mapping with choices.\n" );
// perform the mapping
......
......@@ -269,6 +269,233 @@ void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) );
}
/**Function*************************************************************
Synopsis [Gets fanin node names.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pFanin;
int i;
vNodes = Vec_PtrAlloc( 100 );
Abc_ObjForEachFanin( pNode, pFanin, i )
Vec_PtrPush( vNodes, util_strsav(Abc_ObjName(pFanin)) );
return vNodes;
}
/**Function*************************************************************
Synopsis [Gets fanin node names.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeGetFakeNames( int nNames )
{
Vec_Ptr_t * vNames;
char Buffer[5];
int i;
vNames = Vec_PtrAlloc( nNames );
for ( i = 0; i < nNames; i++ )
{
if ( nNames < 26 )
{
Buffer[0] = 'a' + i;
Buffer[1] = 0;
}
else
{
Buffer[0] = 'a' + i%26;
Buffer[1] = '0' + i/26;
Buffer[2] = 0;
}
Vec_PtrPush( vNames, util_strsav(Buffer) );
}
return vNames;
}
/**Function*************************************************************
Synopsis [Gets fanin node names.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeFreeNames( Vec_Ptr_t * vNames )
{
int i;
if ( vNames == NULL )
return;
for ( i = 0; i < vNames->nSize; i++ )
free( vNames->pArray[i] );
Vec_PtrFree( vNames );
}
/**Function*************************************************************
Synopsis [Collects the CI or CO names.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos )
{
Abc_Obj_t * pObj;
char ** ppNames;
int i;
if ( fCollectCos )
{
ppNames = ALLOC( char *, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pObj, i )
ppNames[i] = Abc_ObjName(pObj);
}
else
{
ppNames = ALLOC( char *, Abc_NtkCiNum(pNtk) );
Abc_NtkForEachCi( pNtk, pObj, i )
ppNames[i] = Abc_ObjName(pObj);
}
return ppNames;
}
/**Function*************************************************************
Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeCompareNames( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
{
int Diff = strcmp( (char *)(*pp1)->pCopy, (char *)(*pp2)->pCopy );
if ( Diff < 0 )
return -1;
if ( Diff > 0 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Orders PIs/POs/latches alphabetically.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb )
{
Abc_Obj_t * pObj;
int i;
// temporarily store the names in the copy field
Abc_NtkForEachPi( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
Abc_NtkForEachPo( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
Abc_NtkForEachLatch( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
// order objects alphabetically
qsort( pNtk->vCis->pArray, pNtk->nPis, sizeof(Abc_Obj_t *),
(int (*)(const void *, const void *)) Abc_NodeCompareNames );
qsort( pNtk->vCos->pArray, pNtk->nPos, sizeof(Abc_Obj_t *),
(int (*)(const void *, const void *)) Abc_NodeCompareNames );
// if the comparison if combinational (latches as PIs/POs), order them too
if ( fComb )
{
qsort( pNtk->vLats->pArray, pNtk->nLatches, sizeof(Abc_Obj_t *),
(int (*)(const void *, const void *)) Abc_NodeCompareNames );
// add latches to make COs
Abc_NtkForEachLatch( pNtk, pObj, i )
{
Vec_PtrWriteEntry( pNtk->vCis, pNtk->nPis + i, pObj );
Vec_PtrWriteEntry( pNtk->vCos, pNtk->nPos + i, pObj );
}
}
// clean the copy fields
Abc_NtkForEachPi( pNtk, pObj, i )
pObj->pCopy = NULL;
Abc_NtkForEachPo( pNtk, pObj, i )
pObj->pCopy = NULL;
Abc_NtkForEachLatch( pNtk, pObj, i )
pObj->pCopy = NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkShortNames( Abc_Ntk_t * pNtk )
{
stmm_table * tObj2NameNew;
Abc_Obj_t * pObj;
char Buffer[100];
char * pNameNew;
int Length, i;
tObj2NameNew = stmm_init_table(stmm_ptrcmp, stmm_ptrhash);
// create new names and add them to the table
Length = Extra_Base10Log( Abc_NtkPiNum(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
{
sprintf( Buffer, "pi%0*d", Length, i );
pNameNew = Abc_NtkRegisterName( pNtk, Buffer );
stmm_insert( tObj2NameNew, (char *)pObj, pNameNew );
}
// create new names and add them to the table
Length = Extra_Base10Log( Abc_NtkPoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pObj, i )
{
sprintf( Buffer, "po%0*d", Length, i );
pNameNew = Abc_NtkRegisterName( pNtk, Buffer );
stmm_insert( tObj2NameNew, (char *)pObj, pNameNew );
}
// create new names and add them to the table
Length = Extra_Base10Log( Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pObj, i )
{
sprintf( Buffer, "lat%0*d", Length, i );
pNameNew = Abc_NtkRegisterName( pNtk, Buffer );
stmm_insert( tObj2NameNew, (char *)pObj, pNameNew );
}
stmm_free_table( pNtk->tObj2Name );
pNtk->tObj2Name = tObj2NameNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -313,7 +313,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
Vec_Ptr_t * vNodes;
int i, k;
assert( Abc_NtkIsStrash(pNtk) );
if ( Abc_NtkCountChoiceNodes(pNtk) )
if ( Abc_NtkGetChoiceNum(pNtk) )
printf( "Warning: Choice nodes are skipped.\n" );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP );
......
......@@ -19,7 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "ft.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -60,9 +60,9 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
else if ( Abc_NtkIsStrash(pNtk) )
{
fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
if ( Num = Abc_NtkCountChoiceNodes(pNtk) )
if ( Num = Abc_NtkGetChoiceNum(pNtk) )
fprintf( pFile, " (choice = %d)", Num );
if ( Num = Abc_NtkCountExors(pNtk) )
if ( Num = Abc_NtkGetExorNum(pNtk) )
fprintf( pFile, " (exor = %d)", Num );
}
else if ( Abc_NtkIsSeq(pNtk) )
......@@ -332,7 +332,7 @@ void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames )
***********************************************************************/
void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames )
{
Vec_Int_t * vFactor;
Dec_Graph_t * pGraph;
Vec_Ptr_t * vNamesIn;
if ( Abc_ObjIsCo(pNode) )
pNode = Abc_ObjFanin0(pNode);
......@@ -347,16 +347,16 @@ void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames )
return;
}
assert( Abc_ObjIsNode(pNode) );
vFactor = Ft_Factor( pNode->pData );
pGraph = Dec_Factor( pNode->pData );
if ( fUseRealNames )
{
vNamesIn = Abc_NodeGetFaninNames(pNode);
Ft_FactorPrint( stdout, vFactor, (char **)vNamesIn->pArray, Abc_ObjName(pNode) );
Dec_GraphPrint( stdout, pGraph, (char **)vNamesIn->pArray, Abc_ObjName(pNode) );
Abc_NodeFreeNames( vNamesIn );
}
else
Ft_FactorPrint( stdout, vFactor, (char **)NULL, Abc_ObjName(pNode) );
Vec_IntFree( vFactor );
Dec_GraphPrint( stdout, pGraph, (char **)NULL, Abc_ObjName(pNode) );
Dec_GraphFree( pGraph );
}
......
......@@ -19,7 +19,6 @@
***********************************************************************/
#include "abc.h"
#include "ft.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
......@@ -19,7 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "ft.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -34,10 +34,8 @@ struct Abc_ManRef_t_
int fVerbose; // the verbosity flag
// internal data structures
DdManager * dd; // the BDD manager
// Vec_Int_t * vReqTimes; // required times for each node
Vec_Str_t * vCube; // temporary
Vec_Int_t * vForm; // temporary
Vec_Int_t * vLevNums; // temporary
Vec_Ptr_t * vVisited; // temporary
Vec_Ptr_t * vLeaves; // temporary
// node statistics
......@@ -60,7 +58,7 @@ struct Abc_ManRef_t_
static void Abc_NtkManRefPrintStats( Abc_ManRef_t * p );
static Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose );
static void Abc_NtkManRefStop( Abc_ManRef_t * p );
static Vec_Int_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose );
static Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -88,11 +86,11 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool
ProgressBar * pProgress;
Abc_ManRef_t * pManRef;
Abc_ManCut_t * pManCut;
Dec_Graph_t * pFForm;
Vec_Ptr_t * vFanins;
Vec_Int_t * vForm;
Abc_Obj_t * pNode;
int i, nNodes;
int clk, clkStart = clock();
int i, nNodes;
assert( Abc_NtkIsStrash(pNtk) );
// cleanup the AIG
......@@ -109,27 +107,27 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// stop if all nodes have been tried once
if ( i >= nNodes )
break;
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// stop if all nodes have been tried once
if ( i >= nNodes )
break;
// compute a reconvergence-driven cut
clk = clock();
vFanins = Abc_NodeFindCut( pManCut, pNode, fUseDcs );
pManRef->timeCut += clock() - clk;
// evaluate this cut
clk = clock();
vForm = Abc_NodeRefactor( pManRef, pNode, vFanins, fUseZeros, fUseDcs, fVerbose );
pFForm = Abc_NodeRefactor( pManRef, pNode, vFanins, fUseZeros, fUseDcs, fVerbose );
pManRef->timeRes += clock() - clk;
if ( vForm == NULL )
if ( pFForm == NULL )
continue;
// acceptable replacement found, update the graph
clk = clock();
Abc_NodeUpdate( pNode, vFanins, vForm, pManRef->nLastGain );
Dec_GraphUpdateNetwork( pNode, pFForm, pManRef->nLastGain );
pManRef->timeNtk += clock() - clk;
Vec_IntFree( vForm );
Dec_GraphFree( pFForm );
}
Extra_ProgressBarStop( pProgress );
pManRef->timeTotal = clock() - clkStart;
......@@ -161,40 +159,33 @@ pManRef->timeTotal = clock() - clkStart;
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose )
Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose )
{
int fVeryVerbose = 0;
Abc_Obj_t * pFanin;
Vec_Int_t * vForm;
DdNode * bNodeFunc, * bNodeDc, * bNodeOn, * bNodeOnDc;
Dec_Graph_t * pFForm;
DdNode * bNodeFunc;
int nNodesSaved, nNodesAdded, i, clk;
char * pSop;
int nBddNodes, nFtNodes, nNodesSaved, nNodesAdded;
int i, Required, clk;
p->nNodesConsidered++;
// get the required level of this node
Required = Abc_NodeReadRequiredLevel( pNode );
// get the function of the cut
clk = clock();
bNodeFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pNode, vFanins, p->vVisited ); Cudd_Ref( bNodeFunc );
p->timeBdd += clock() - clk;
nBddNodes = Cudd_DagSize(bNodeFunc);
// if don't-care are used, transform the function into ISOP
if ( fUseDcs )
{
DdNode * bNodeDc, * bNodeOn, * bNodeOnDc;
int nMints, nMintsDc;
clk = clock();
// get the don't-cares
bNodeDc = Abc_NodeConeDcs( p->dd, p->dd->vars + vFanins->nSize, p->dd->vars, p->vLeaves, vFanins, p->vVisited ); Cudd_Ref( bNodeDc );
nMints = (1 << vFanins->nSize);
nMintsDc = (int)Cudd_CountMinterm( p->dd, bNodeDc, vFanins->nSize );
// printf( "Percentage of minterms = %5.2f.\n", 100.0 * nMintsDc / nMints );
// get the ISF
bNodeOn = Cudd_bddAnd( p->dd, bNodeFunc, Cudd_Not(bNodeDc) ); Cudd_Ref( bNodeOn );
bNodeOnDc = Cudd_bddOr ( p->dd, bNodeFunc, bNodeDc ); Cudd_Ref( bNodeOnDc );
......@@ -207,58 +198,52 @@ clk = clock();
p->timeDcs += clock() - clk;
}
//Extra_bddPrint( p->dd, bNodeFunc ); printf( "\n" );
// always accept the case of constant node
if ( Cudd_IsConstant(bNodeFunc) )
{
p->nLastGain = Abc_NodeMffcSize( pNode );
p->nNodesGained += p->nLastGain;
p->nNodesRefactored++;
// get the constant node
// pFanin = Abc_ObjNotCond( Abc_AigConst1(pNode->pNtk->pManFunc), Cudd_IsComplement(bNodeFunc) );
// Abc_AigReplace( pNode->pNtk->pManFunc, pNode, pFanin );
// Cudd_RecursiveDeref( p->dd, bNodeFunc );
//printf( "Gain = %d.\n", p->nLastGain );
Cudd_RecursiveDeref( p->dd, bNodeFunc );
return Ft_FactorConst( !Cudd_IsComplement(bNodeFunc) );
if ( Cudd_IsComplement(bNodeFunc) )
return Dec_GraphCreateConst0();
return Dec_GraphCreateConst1();
}
// get the SOP of the cut
clk = clock();
pSop = Abc_ConvertBddToSop( NULL, p->dd, bNodeFunc, bNodeFunc, vFanins->nSize, p->vCube, -1 );
p->timeSop += clock() - clk;
Cudd_RecursiveDeref( p->dd, bNodeFunc );
// get the factored form
clk = clock();
vForm = Ft_Factor( pSop );
p->timeFact += clock() - clk;
nFtNodes = Ft_FactorGetNumNodes( vForm );
pFForm = Dec_Factor( pSop );
free( pSop );
//Ft_FactorPrint( stdout, vForm, NULL, NULL );
p->timeFact += clock() - clk;
// mark the fanin boundary
// (can mark only essential fanins, belonging to bNodeFunc!!!)
// (can mark only essential fanins, belonging to bNodeFunc!)
Vec_PtrForEachEntry( vFanins, pFanin, i )
pFanin->vFanouts.nSize++;
// label MFFC with current traversal ID
Abc_NtkIncrementTravId( pNode->pNtk );
nNodesSaved = Abc_NodeMffcLabel( pNode );
// unmark the fanin boundary
// unmark the fanin boundary and set the fanins as leaves in the form
Vec_PtrForEachEntry( vFanins, pFanin, i )
{
pFanin->vFanouts.nSize--;
Dec_GraphNode(pFForm, i)->pFunc = pFanin;
}
// detect how many new nodes will be added (while taking into account reused nodes)
clk = clock();
nNodesAdded = Abc_NodeStrashDecCount( pNode->pNtk->pManFunc, pNode, vFanins, vForm,
p->vLevNums, nNodesSaved, Required );
nNodesAdded = Dec_GraphToNetworkCount( pNode, pFForm, nNodesSaved, Abc_NodeReadRequiredLevel(pNode) );
p->timeEval += clock() - clk;
// quit if there is no improvement
if ( nNodesAdded == -1 || nNodesAdded == nNodesSaved && !fUseZeros )
{
Vec_IntFree( vForm );
Cudd_RecursiveDeref( p->dd, bNodeFunc );
Dec_GraphFree( pFForm );
return NULL;
}
......@@ -272,14 +257,15 @@ p->timeEval += clock() - clk;
{
printf( "Node %6s : ", Abc_ObjName(pNode) );
printf( "Cone = %2d. ", vFanins->nSize );
printf( "BDD = %2d. ", nBddNodes );
printf( "FF = %2d. ", nFtNodes );
printf( "BDD = %2d. ", Cudd_DagSize(bNodeFunc) );
printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pFForm) );
printf( "MFFC = %2d. ", nNodesSaved );
printf( "Add = %2d. ", nNodesAdded );
printf( "GAIN = %2d. ", p->nLastGain );
printf( "\n" );
}
return vForm;
Cudd_RecursiveDeref( p->dd, bNodeFunc );
return pFForm;
}
......@@ -300,7 +286,6 @@ Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUse
p = ALLOC( Abc_ManRef_t, 1 );
memset( p, 0, sizeof(Abc_ManRef_t) );
p->vCube = Vec_StrAlloc( 100 );
p->vLevNums = Vec_IntAlloc( 100 );
p->vVisited = Vec_PtrAlloc( 100 );
p->nNodeSizeMax = nNodeSizeMax;
p->nConeSizeMax = nConeSizeMax;
......@@ -328,9 +313,7 @@ Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUse
void Abc_NtkManRefStop( Abc_ManRef_t * p )
{
Extra_StopManager( p->dd );
// Vec_IntFree( p->vReqTimes );
Vec_PtrFree( p->vVisited );
Vec_IntFree( p->vLevNums );
Vec_StrFree( p->vCube );
free( p );
}
......
......@@ -221,37 +221,6 @@ int Abc_NodeRefDerefStop( Abc_Obj_t * pNode, bool fReference )
return Counter;
}
/**Function*************************************************************
Synopsis [Replaces MFFC of the node by the new factored form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeUpdate( Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, int nGain )
{
Abc_Ntk_t * pNtk = pNode->pNtk;
Abc_Obj_t * pNodeNew;
int nNodesNew, nNodesOld;
nNodesOld = Abc_NtkNodeNum(pNtk);
// create the new structure of nodes
assert( vForm->nSize == 1 || Vec_PtrSize(vFanins) < Vec_IntSize(vForm) );
pNodeNew = Abc_NodeStrashDec( pNtk->pManFunc, vFanins, vForm );
// in some cases, the new node may have a minor redundancy
// (has to do with the precomputed subgraph library)
if ( !Abc_AigNodeIsAcyclic( Abc_ObjRegular(pNodeNew), pNode ) )
return;
// remove the old nodes
Abc_AigReplace( pNtk->pManFunc, pNode, pNodeNew );
// compare the gains
nNodesNew = Abc_NtkNodeNum(pNtk);
assert( nGain <= nNodesOld - nNodesNew );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -60,7 +60,7 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCn
assert( nFaninMax > 1 );
// print a warning about choice nodes
if ( Abc_NtkCountChoiceNodes( pNtk ) )
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the AIG are removed by renoding.\n" );
// define the boundary
......
......@@ -20,7 +20,7 @@
#include "abc.h"
#include "rwr.h"
#include "ft.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -85,13 +85,12 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUseZeros );
if ( nGain > 0 || nGain == 0 && fUseZeros )
{
Vec_Int_t * vForm = Rwr_ManReadDecs(pManRwr);
Vec_Ptr_t * vFanins = Rwr_ManReadFanins(pManRwr);
int fCompl = Rwr_ManReadCompl(pManRwr);
Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr);
int fCompl = Rwr_ManReadCompl(pManRwr);
// complement the FF if needed
if ( fCompl ) Ft_FactorComplement( vForm );
Abc_NodeUpdate( pNode, vFanins, vForm, nGain );
if ( fCompl ) Ft_FactorComplement( vForm );
if ( fCompl ) Dec_GraphComplement( pGraph );
Dec_GraphUpdateNetwork( pNode, pGraph, nGain );
if ( fCompl ) Dec_GraphComplement( pGraph );
}
}
Extra_ProgressBarStop( pProgress );
......
......@@ -55,7 +55,7 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode )
char * pNameOut;
assert( Abc_NtkIsBddLogic(pNode->pNtk) );
// create the file names
// create the file name
Abc_ShowGetFileName( Abc_ObjName(pNode), FileNameDot );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
......@@ -96,7 +96,7 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
int i;
assert( Abc_NtkIsStrash(pNtk) );
// create the file names
// create the file name
Abc_ShowGetFileName( pNtk->pName, FileNameDot );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
......@@ -119,7 +119,7 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Visualizes reconvergence driven cut at the node.]
Synopsis [Visualizes a reconvergence driven cut at the node.]
Description []
......@@ -158,7 +158,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax )
Vec_PtrForEachEntry( vNodesTfo, pTemp, i )
Vec_PtrPushUnique( vInside, pTemp );
// create the file names
// create the file name
Abc_ShowGetFileName( Abc_ObjName(pNode), FileNameDot );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
......
......@@ -20,7 +20,7 @@
#include "abc.h"
#include "extra.h"
#include "ft.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -59,7 +59,7 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
if ( Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk);
// print warning about choice nodes
if ( Abc_NtkCountChoiceNodes( pNtk ) )
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
// perform strashing
pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG );
......@@ -188,9 +188,6 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
// consider the case when the graph is an AIG
if ( Abc_NtkIsStrash(pNode->pNtk) )
{
// Abc_Obj_t * pChild0, * pChild1;
// pChild0 = Abc_ObjFanin0(pNode);
// pChild1 = Abc_ObjFanin1(pNode);
if ( Abc_NodeIsConst(pNode) )
return Abc_AigConst1(pMan);
return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
......@@ -202,14 +199,9 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
else
pSop = pNode->pData;
// consider the cconstant node
// consider the constant node
if ( Abc_NodeIsConst(pNode) )
{
// check if the SOP is constant
if ( Abc_SopIsConst1(pSop) )
return Abc_AigConst1(pMan);
return Abc_ObjNot( Abc_AigConst1(pMan) );
}
return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) );
// decide when to use factoring
if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
......@@ -273,199 +265,21 @@ Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop )
{
Vec_Int_t * vForm;
Vec_Ptr_t * vAnds;
Abc_Obj_t * pAnd, * pFanin;
Dec_Graph_t * pFForm;
Dec_Node_t * pNode;
Abc_Obj_t * pAnd;
int i;
// derive the factored form
vForm = Ft_Factor( pSop );
// perform factoring
pFForm = Dec_Factor( pSop );
// collect the fanins
vAnds = Vec_PtrAlloc( 20 );
Abc_ObjForEachFanin( pRoot, pFanin, i )
Vec_PtrPush( vAnds, pFanin->pCopy );
Dec_GraphForEachLeaf( pFForm, pNode, i )
pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy;
// perform strashing
pAnd = Abc_NodeStrashDec( pMan, vAnds, vForm );
Vec_PtrFree( vAnds );
Vec_IntFree( vForm );
return pAnd;
}
/**Function*************************************************************
Synopsis [Strashes the factored form into the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashDec( Abc_Aig_t * pMan, Vec_Ptr_t * vFanins, Vec_Int_t * vForm )
{
Abc_Obj_t * pAnd, * pAnd0, * pAnd1;
Ft_Node_t * pFtNode;
int i, nVars;
// sanity checks
nVars = Ft_FactorGetNumVars( vForm );
assert( nVars >= 0 );
assert( vForm->nSize > nVars );
// check for constant function
pFtNode = Ft_NodeRead( vForm, 0 );
if ( pFtNode->fConst )
return Abc_ObjNotCond( Abc_AigConst1(pMan), pFtNode->fCompl );
assert( nVars == vFanins->nSize );
// compute the function of other nodes
for ( i = nVars; i < vForm->nSize; i++ )
{
pFtNode = Ft_NodeRead( vForm, i );
pAnd0 = Abc_ObjNotCond( vFanins->pArray[pFtNode->iFanin0], pFtNode->fCompl0 );
pAnd1 = Abc_ObjNotCond( vFanins->pArray[pFtNode->iFanin1], pFtNode->fCompl1 );
pAnd = Abc_AigAnd( pMan, pAnd0, pAnd1 );
Vec_PtrPush( vFanins, pAnd );
//printf( "Adding " ); Abc_AigPrintNode( pAnd );
}
assert( vForm->nSize = vFanins->nSize );
// complement the result if necessary
pFtNode = Ft_NodeReadLast( vForm );
pAnd = Abc_ObjNotCond( pAnd, pFtNode->fCompl );
pAnd = Dec_GraphToNetwork( pMan, pFForm );
Dec_GraphFree( pFForm );
return pAnd;
}
/**Function*************************************************************
Synopsis [Counts the number of new nodes added when using this factored form,]
Description [Returns NodeMax + 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 Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, Vec_Int_t * vLevels, int NodeMax, int LevelMax )
{
Abc_Obj_t * pAnd, * pAnd0, * pAnd1, * pTop;
Ft_Node_t * pFtNode;
int i, nVars, LevelNew, LevelOld, Counter;
// sanity checks
nVars = Ft_FactorGetNumVars( vForm );
assert( nVars >= 0 );
assert( vForm->nSize > nVars );
// check for constant function
pFtNode = Ft_NodeRead( vForm, 0 );
if ( pFtNode->fConst )
return 0;
assert( nVars == vFanins->nSize );
// set the levels
Vec_IntClear( vLevels );
Vec_PtrForEachEntry( vFanins, pAnd, i )
Vec_IntPush( vLevels, Abc_ObjRegular(pAnd)->Level );
// compute the function of other nodes
Counter = 0;
for ( i = nVars; i < vForm->nSize; i++ )
{
pFtNode = Ft_NodeRead( vForm, i );
// check for buffer/inverter
if ( pFtNode->iFanin0 == pFtNode->iFanin1 )
{
assert( vForm->nSize == nVars + 1 );
pAnd = Vec_PtrEntry(vFanins, pFtNode->iFanin0);
pAnd = Abc_ObjNotCond( pAnd, pFtNode->fCompl );
Vec_PtrPush( vFanins, pAnd );
break;
}
pAnd0 = Vec_PtrEntry(vFanins, pFtNode->iFanin0);
pAnd1 = Vec_PtrEntry(vFanins, pFtNode->iFanin1);
if ( pAnd0 && pAnd1 )
{
pAnd0 = Abc_ObjNotCond( pAnd0, pFtNode->fCompl0 );
pAnd1 = Abc_ObjNotCond( pAnd1, pFtNode->fCompl1 );
pAnd = Abc_AigAndLookup( pMan, pAnd0, pAnd1 );
}
else
pAnd = NULL;
// count the number of added nodes
if ( pAnd == NULL || Abc_NodeIsTravIdCurrent( Abc_ObjRegular(pAnd) ) )
{
if ( pAnd )
{
//printf( "Reusing labeled " ); Abc_AigPrintNode( pAnd );
}
Counter++;
if ( Counter > NodeMax )
{
Vec_PtrShrink( vFanins, nVars );
return -1;
}
}
else
{
//printf( "Reusing " ); Abc_AigPrintNode( pAnd );
}
// count the number of new levels
LevelNew = -1;
if ( pAnd )
{
if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pMan) )
LevelNew = 0;
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) )
LevelNew = (int)Abc_ObjRegular(pAnd0)->Level;
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd1) )
LevelNew = (int)Abc_ObjRegular(pAnd1)->Level;
}
if ( LevelNew == -1 )
LevelNew = 1 + ABC_MAX( Vec_IntEntry(vLevels, pFtNode->iFanin0), Vec_IntEntry(vLevels, pFtNode->iFanin1) );
// assert( pAnd == NULL || LevelNew == LevelOld );
if ( pAnd )
{
LevelOld = (int)Abc_ObjRegular(pAnd)->Level;
if ( LevelNew != LevelOld )
{
int x = 0;
Abc_Obj_t * pFanin0, * pFanin1;
pFanin0 = Abc_ObjFanin0( Abc_ObjRegular(pAnd) );
pFanin1 = Abc_ObjFanin1( Abc_ObjRegular(pAnd) );
x = 0;
}
}
if ( LevelNew > LevelMax )
{
Vec_PtrShrink( vFanins, nVars );
return -1;
}
Vec_PtrPush( vFanins, pAnd );
Vec_IntPush( vLevels, LevelNew );
}
assert( vForm->nSize = vFanins->nSize );
// check if this is the same form
pTop = Vec_PtrEntryLast(vFanins);
if ( Abc_ObjRegular(pTop) == pRoot )
{
assert( !Abc_ObjIsComplement(pTop) );
Vec_PtrShrink( vFanins, nVars );
return -1;
}
Vec_PtrShrink( vFanins, nVars );
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -252,7 +252,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk )
pTime = ppTimes[pObj->Id];
if ( pTime->Worst != -ABC_INFINITY )
continue;
*pTime = pNtk->pManTime->tArrDef;
*pTime = pNtk->pManTime->tReqDef;
}
// set the 0 arrival times for latches and constant nodes
ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
......@@ -380,16 +380,16 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
// set the default timing
pNtkNew->pManTime->tArrDef = pNtkOld->pManTime->tArrDef;
pNtkNew->pManTime->tReqDef = pNtkOld->pManTime->tReqDef;
// set the PI timing
// set the CI timing
ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vArrs->pArray;
ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vArrs->pArray;
Abc_NtkForEachPi( pNtkOld, pObj, i )
*ppTimesNew[ Abc_NtkPi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
// set the PO timing
Abc_NtkForEachCi( pNtkOld, pObj, i )
*ppTimesNew[ Abc_NtkCi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
// set the CO timing
ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vReqs->pArray;
ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray;
Abc_NtkForEachPo( pNtkOld, pObj, i )
*ppTimesNew[ Abc_NtkPo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
Abc_NtkForEachCo( pNtkOld, pObj, i )
*ppTimesNew[ Abc_NtkCo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
}
/**Function*************************************************************
......
......@@ -45,7 +45,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
FILE * pFile;
Abc_Obj_t * pNode, * pTemp, * pPrev;
int LevelMin, LevelMax, fHasCos, Level, i;
int Limit = 200;
int Limit = 300;
if ( vNodes->nSize < 1 )
{
......@@ -109,8 +109,10 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
// fprintf( pFile, "ranksep = 0.5;\n" );
// fprintf( pFile, "nodesep = 0.5;\n" );
fprintf( pFile, "center = true;\n" );
// fprintf( pFile, "orientation = landscape;\n" );
// fprintf( pFile, "edge [fontsize = 10];\n" );
// fprintf( pFile, "edge [dir = none];\n" );
fprintf( pFile, "edge [dir = back];\n" );
fprintf( pFile, "\n" );
// labels on the left of the picture
......@@ -194,8 +196,9 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
{
if ( !Abc_ObjIsCo(pNode) )
continue;
fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
fprintf( pFile, ", shape = invtriangle" );
fprintf( pFile, " Node%d%s [label = \"%s%s\"", pNode->Id,
(Abc_ObjIsLatch(pNode)? "_in":""), Abc_ObjName(pNode), (Abc_ObjIsLatch(pNode)? "_in":"") );
fprintf( pFile, ", shape = %s", (Abc_ObjIsLatch(pNode)? "box":"invtriangle") );
if ( pNode->fMarkB )
fprintf( pFile, ", style = filled" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
......@@ -240,8 +243,9 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
{
if ( !Abc_ObjIsCi(pNode) )
continue;
fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
fprintf( pFile, ", shape = triangle" );
fprintf( pFile, " Node%d%s [label = \"%s%s\"", pNode->Id,
(Abc_ObjIsLatch(pNode)? "_out":""), Abc_ObjName(pNode), (Abc_ObjIsLatch(pNode)? "_out":"") );
fprintf( pFile, ", shape = %s", (Abc_ObjIsLatch(pNode)? "box":"triangle") );
if ( pNode->fMarkB )
fprintf( pFile, ", style = filled" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
......@@ -258,7 +262,8 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
{
if ( (int)pNode->Level != LevelMax )
continue;
fprintf( pFile, "title2 -> Node%d [style = invis];\n", pNode->Id );
fprintf( pFile, "title2 -> Node%d%s [style = invis];\n", pNode->Id,
(Abc_ObjIsLatch(pNode)? "_in":"") );
}
// generate edges
......@@ -269,10 +274,10 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
// generate the edge from this node to the next
if ( Abc_ObjFanin0(pNode)->fMarkC )
{
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, "Node%d%s", pNode->Id, (Abc_ObjIsLatch(pNode)? "_in":"") );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", Abc_ObjFaninId0(pNode) );
fprintf( pFile, " [style = %s]", Abc_ObjFaninC0(pNode)? "dashed" : "bold" );
fprintf( pFile, "Node%d%s", Abc_ObjFaninId0(pNode), (Abc_ObjIsLatch(Abc_ObjFanin0(pNode))? "_out":"") );
fprintf( pFile, " [style = %s]", Abc_ObjFaninC0(pNode)? "dotted" : "bold" );
fprintf( pFile, ";\n" );
}
if ( Abc_ObjFaninNum(pNode) == 1 )
......@@ -282,8 +287,8 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
{
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", Abc_ObjFaninId1(pNode) );
fprintf( pFile, " [style = %s]", Abc_ObjFaninC1(pNode)? "dashed" : "bold" );
fprintf( pFile, "Node%d%s", Abc_ObjFaninId1(pNode), (Abc_ObjIsLatch(Abc_ObjFanin1(pNode))? "_out":"") );
fprintf( pFile, " [style = %s]", Abc_ObjFaninC1(pNode)? "dotted" : "bold" );
fprintf( pFile, ";\n" );
}
// generate the edges between the equivalent nodes
......@@ -295,7 +300,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, "Node%d", pPrev->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pTemp->Id );
fprintf( pFile, " [style = %s]", (pPrev->fPhase ^ pTemp->fPhase)? "dashed" : "bold" );
fprintf( pFile, " [style = %s]", (pPrev->fPhase ^ pTemp->fPhase)? "dotted" : "bold" );
fprintf( pFile, ";\n" );
pPrev = pTemp;
}
......
......@@ -102,6 +102,9 @@ extern void Abc_FrameSetLibLut ( Abc_Frame_t * pFrame, void
extern void Abc_FrameSetLibGen ( Abc_Frame_t * pFrame, void * pLib );
extern void Abc_FrameSetLibSuper ( Abc_Frame_t * pFrame, void * pLib );
extern void * Abc_FrameReadManDd ( Abc_Frame_t * pFrame );
extern void * Abc_FrameReadManDec ( Abc_Frame_t * pFrame );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -20,6 +20,7 @@
#include "mainInt.h"
#include "abc.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -58,6 +59,9 @@ Abc_Frame_t * Abc_FrameAllocate()
// set the starting step
p->nSteps = 1;
p->fBatchMode = 0;
// initialize decomposition manager
p->pManDec = Dec_ManStart();
p->dd = Cudd_Init( 0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
return p;
}
......@@ -75,6 +79,8 @@ Abc_Frame_t * Abc_FrameAllocate()
***********************************************************************/
void Abc_FrameDeallocate( Abc_Frame_t * p )
{
Dec_ManStop( p->pManDec );
Extra_StopManager( p->dd );
Abc_FrameDeleteAllNetworks( p );
free( p );
p = NULL;
......@@ -417,17 +423,20 @@ Abc_Frame_t * Abc_FrameGetGlobalFrame()
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_FrameReadNtkStore ( Abc_Frame_t * pFrame ) { return pFrame->pStored; }
int Abc_FrameReadNtkStoreSize ( Abc_Frame_t * pFrame ) { return pFrame->nStored; }
void Abc_FrameSetNtkStore ( Abc_Frame_t * pFrame, Abc_Ntk_t * pNtk ) { pFrame->pStored = pNtk; }
void Abc_FrameSetNtkStoreSize ( Abc_Frame_t * pFrame, int nStored ) { pFrame->nStored = nStored; }
Abc_Ntk_t * Abc_FrameReadNtkStore ( Abc_Frame_t * pFrame ) { return pFrame->pStored; }
int Abc_FrameReadNtkStoreSize ( Abc_Frame_t * pFrame ) { return pFrame->nStored; }
void Abc_FrameSetNtkStore ( Abc_Frame_t * pFrame, Abc_Ntk_t * pNtk ) { pFrame->pStored = pNtk; }
void Abc_FrameSetNtkStoreSize ( Abc_Frame_t * pFrame, int nStored ) { pFrame->nStored = nStored;}
void * Abc_FrameReadLibLut ( Abc_Frame_t * pFrame ) { return pFrame->pLibLut; }
void * Abc_FrameReadLibGen ( Abc_Frame_t * pFrame ) { return pFrame->pLibGen; }
void * Abc_FrameReadLibSuper ( Abc_Frame_t * pFrame ) { return pFrame->pLibSuper; }
void Abc_FrameSetLibLut ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibLut = pLib; }
void Abc_FrameSetLibGen ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibGen = pLib; }
void Abc_FrameSetLibSuper ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibSuper = pLib; }
void Abc_FrameSetLibLut ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibLut = pLib; }
void Abc_FrameSetLibGen ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibGen = pLib; }
void Abc_FrameSetLibSuper ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibSuper = pLib; }
void * Abc_FrameReadManDd ( Abc_Frame_t * pFrame ) { return pFrame->dd; }
void * Abc_FrameReadManDec ( Abc_Frame_t * pFrame ) { return pFrame->pManDec; }
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -66,6 +66,9 @@ struct Abc_Frame_t_
// temporary storage for structural choices
Abc_Ntk_t * pStored; // the stored networks
int nStored; // the number of stored networks
// decomposition package
DdManager * dd; // temporary BDD package
void * pManDec; // decomposition manager
void * pLibLut; // the current LUT library
void * pLibGen; // the current genlib
......
/**CFile****************************************************************
FileName [decAbc.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Interface between the decomposition package and ABC network.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [$Id: decAbc.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**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 []
***********************************************************************/
Abc_Obj_t * Dec_GraphToNetwork( Abc_Aig_t * pMan, Dec_Graph_t * pGraph )
{
Abc_Obj_t * pAnd0, * pAnd1;
Dec_Node_t * pNode;
int i;
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
return Abc_ObjNotCond( Abc_AigConst1(pMan), Dec_GraphIsComplement(pGraph) );
// check for a literal
if ( Dec_GraphIsVar(pGraph) )
return Abc_ObjNotCond( 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 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
pAnd1 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
pNode->pFunc = Abc_AigAnd( pMan, pAnd0, pAnd1 );
}
// complement the result if necessary
return Abc_ObjNotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
}
/**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 Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax )
{
Abc_Aig_t * pMan = pRoot->pNtk->pManFunc;
Dec_Node_t * pNode, * pNode0, * pNode1;
Abc_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 = Abc_ObjRegular(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 = Abc_ObjNotCond( pAnd0, pNode->eEdge0.fCompl );
pAnd1 = Abc_ObjNotCond( pAnd1, pNode->eEdge1.fCompl );
pAnd = Abc_AigAndLookup( pMan, pAnd0, pAnd1 );
// return -1 if the node is the same as the original root
if ( Abc_ObjRegular(pAnd) == pRoot )
return -1;
}
else
pAnd = NULL;
// count the number of added nodes
if ( pAnd == NULL || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pAnd)) )
{
if ( ++Counter > NodeMax )
return -1;
}
// count the number of new levels
LevelNew = 1 + ABC_MAX( pNode0->Level, pNode1->Level );
if ( pAnd )
{
if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pMan) )
LevelNew = 0;
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) )
LevelNew = (int)Abc_ObjRegular(pAnd0)->Level;
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd1) )
LevelNew = (int)Abc_ObjRegular(pAnd1)->Level;
LevelOld = (int)Abc_ObjRegular(pAnd)->Level;
assert( LevelNew == LevelOld );
}
if ( LevelNew > LevelMax )
return -1;
pNode->pFunc = pAnd;
pNode->Level = LevelNew;
}
return Counter;
}
/**Function*************************************************************
Synopsis [Replaces MFFC of the node by the new factored form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain )
{
Abc_Obj_t * pRootNew;
Abc_Ntk_t * pNtk = pRoot->pNtk;
int nNodesNew, nNodesOld;
nNodesOld = Abc_NtkNodeNum(pNtk);
// create the new structure of nodes
pRootNew = Dec_GraphToNetwork( pNtk->pManFunc, pGraph );
// remove the old nodes
Abc_AigReplace( pNtk->pManFunc, pRoot, pRootNew );
// compare the gains
nNodesNew = Abc_NtkNodeNum(pNtk);
assert( nGain <= nNodesOld - nNodesNew );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [decMan.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Decomposition manager.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [$Id: decMan.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "mvc.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Start the MVC manager used in the factoring package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dec_Man_t * Dec_ManStart()
{
Dec_Man_t * p;
int clk = clock();
p = ALLOC( Dec_Man_t, 1 );
p->pMvcMem = Mvc_ManagerStart();
p->vCubes = Vec_IntAlloc( 8 );
p->vLits = Vec_IntAlloc( 8 );
// canonical forms, phases, perms
Extra_Truth4VarNPN( &p->puCanons, &p->pPhases, &p->pPerms, &p->pMap );
//PRT( "NPN classes precomputation time", clock() - clk );
return p;
}
/**Function*************************************************************
Synopsis [Stops the MVC maanager used in the factoring package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dec_ManStop( Dec_Man_t * p )
{
Mvc_ManagerFree( p->pMvcMem );
Vec_IntFree( p->vCubes );
Vec_IntFree( p->vLits );
free( p->puCanons );
free( p->pPhases );
free( p->pPerms );
free( p->pMap );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [decUtil.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Decomposition unitilies.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [$Id: decUtil.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Converts graph to BDD.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph )
{
DdNode * bFunc, * bFunc0, * bFunc1;
Dec_Node_t * pNode;
int i;
// sanity checks
assert( Dec_GraphLeaveNum(pGraph) >= 0 );
assert( Dec_GraphLeaveNum(pGraph) <= pGraph->nSize );
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
return Cudd_NotCond( b1, Dec_GraphIsComplement(pGraph) );
// check for a literal
if ( Dec_GraphIsVar(pGraph) )
return Cudd_NotCond( Cudd_bddIthVar(dd, Dec_GraphVarInt(pGraph)), Dec_GraphIsComplement(pGraph) );
// assign the elementary variables
Dec_GraphForEachLeaf( pGraph, pNode, i )
pNode->pFunc = Cudd_bddIthVar( dd, i );
// compute the function for each internal node
Dec_GraphForEachNode( pGraph, pNode, i )
{
bFunc0 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
bFunc1 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( pNode->pFunc );
}
// deref the intermediate results
bFunc = pNode->pFunc; Cudd_Ref( bFunc );
Dec_GraphForEachNode( pGraph, pNode, i )
Cudd_RecursiveDeref( dd, pNode->pFunc );
Cudd_Deref( bFunc );
// complement the result if necessary
return Cudd_NotCond( bFunc, Dec_GraphIsComplement(pGraph) );
}
/**Function*************************************************************
Synopsis [Derives the truth table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Dec_GraphDeriveTruth( Dec_Graph_t * pGraph )
{
unsigned uTruths[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
unsigned uTruth, uTruth0, uTruth1;
Dec_Node_t * pNode;
int i;
// sanity checks
assert( Dec_GraphLeaveNum(pGraph) >= 0 );
assert( Dec_GraphLeaveNum(pGraph) <= pGraph->nSize );
assert( Dec_GraphLeaveNum(pGraph) <= 5 );
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
return Dec_GraphIsComplement(pGraph)? 0 : ~((unsigned)0);
// check for a literal
if ( Dec_GraphIsVar(pGraph) )
return Dec_GraphIsComplement(pGraph)? ~uTruths[Dec_GraphVarInt(pGraph)] : uTruths[Dec_GraphVarInt(pGraph)];
// assign the elementary variables
Dec_GraphForEachLeaf( pGraph, pNode, i )
pNode->pFunc = (void *)uTruths[i];
// compute the function for each internal node
Dec_GraphForEachNode( pGraph, pNode, i )
{
uTruth0 = (unsigned)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc;
uTruth1 = (unsigned)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc;
uTruth0 = pNode->eEdge0.fCompl? ~uTruth0 : uTruth0;
uTruth1 = pNode->eEdge1.fCompl? ~uTruth1 : uTruth1;
uTruth = uTruth0 & uTruth1;
pNode->pFunc = (void *)uTruth;
}
// complement the result if necessary
return Dec_GraphIsComplement(pGraph)? ~uTruth : uTruth;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
SRC +=
SRC += src/opt/dec/decAbc.c \
src/opt/dec/decFactor.c \
src/opt/dec/decMan.c \
src/opt/dec/decPrint.c \
src/opt/dec/decUtil.c
......@@ -63,7 +63,7 @@ struct Rwr_Man_t_
int nClasses; // the number of NN classes
// the result of resynthesis
int fCompl; // indicates if the output of FF should be complemented
Vec_Int_t * vForm; // the decomposition tree (temporary)
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)
......@@ -125,8 +125,7 @@ extern void Rwr_ManIncTravId( Rwr_Man_t * p );
extern Rwr_Man_t * Rwr_ManStart( bool fPrecompute );
extern void Rwr_ManStop( Rwr_Man_t * p );
extern void Rwr_ManPrintStats( Rwr_Man_t * p );
extern Vec_Ptr_t * Rwr_ManReadFanins( Rwr_Man_t * p );
extern Vec_Int_t * Rwr_ManReadDecs( Rwr_Man_t * p );
extern void * Rwr_ManReadDecs( Rwr_Man_t * p );
extern int Rwr_ManReadCompl( Rwr_Man_t * p );
extern void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time );
extern void Rwr_ManAddTimeTotal( Rwr_Man_t * p, int Time );
......
......@@ -19,15 +19,14 @@
***********************************************************************/
#include "rwr.h"
#include "ft.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Vec_Int_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode );
static int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm );
static void Rwr_FactorVerify( Vec_Int_t * vForm, unsigned uTruth );
static Dec_Graph_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode );
static Dec_Edge_t Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Dec_Graph_t * pGraph );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -46,6 +45,7 @@ static void Rwr_FactorVerify( Vec_Int_t * vForm, unsigned uTruth );
***********************************************************************/
void Rwr_ManPreprocess( Rwr_Man_t * p )
{
Dec_Graph_t * pGraph;
Rwr_Node_t * pNode;
int i, k;
// put the nodes into the structure
......@@ -62,9 +62,13 @@ void Rwr_ManPreprocess( Rwr_Man_t * p )
Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode );
}
}
// compute decomposition forms for each node
// compute decomposition forms for each node and verify them
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
pNode->pNext = (Rwr_Node_t *)Rwr_NodePreprocess( p, pNode );
{
pGraph = Rwr_NodePreprocess( p, pNode );
pNode->pNext = (Rwr_Node_t *)pGraph;
assert( pNode->uTruth == (Dec_GraphDeriveTruth(pGraph) & 0xFFFF) );
}
}
/**Function*************************************************************
......@@ -78,28 +82,24 @@ void Rwr_ManPreprocess( Rwr_Man_t * p )
SeeAlso []
***********************************************************************/
Vec_Int_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode )
Dec_Graph_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode )
{
Vec_Int_t * vForm;
int i, Root;
Dec_Graph_t * pGraph;
Dec_Edge_t eRoot;
assert( !Rwr_IsComplement(pNode) );
// consider constant
if ( pNode->uTruth == 0 )
return Ft_FactorConst( 0 );
return Dec_GraphCreateConst0();
// consider the case of elementary var
if ( pNode->uTruth == 0x00FF )
return Ft_FactorVar( 3, 4, 1 );
// start the factored form
vForm = Vec_IntAlloc( 10 );
for ( i = 0; i < 4; i++ )
Vec_IntPush( vForm, 0 );
return Dec_GraphCreateLeaf( 3, 4, 1 );
// start the subgraphs
pGraph = Dec_GraphCreate( 4 );
// collect the nodes
Rwr_ManIncTravId( p );
Root = Rwr_TravCollect_rec( p, pNode, vForm );
if ( Root & 1 )
Ft_FactorComplement( vForm );
// verify the factored form
Rwr_FactorVerify( vForm, pNode->uTruth );
return vForm;
eRoot = Rwr_TravCollect_rec( p, pNode, pGraph );
Dec_GraphSetRoot( pGraph, eRoot );
return pGraph;
}
/**Function*************************************************************
......@@ -113,115 +113,31 @@ Vec_Int_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode )
SeeAlso []
***********************************************************************/
int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm )
Dec_Edge_t Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Dec_Graph_t * pGraph )
{
Ft_Node_t Node, NodeA, NodeB;
int Node0, Node1;
Dec_Edge_t eNode0, eNode1, eNode;
// elementary variable
if ( pNode->fUsed )
return ((pNode->Id - 1) << 1);
return Dec_EdgeCreate( pNode->Id - 1, 0 );
// previously visited node
if ( pNode->TravId == p->nTravIds )
return pNode->Volume;
return Dec_IntToEdge( pNode->Volume );
pNode->TravId = p->nTravIds;
// solve for children
Node0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), vForm );
Node1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), vForm );
eNode0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), pGraph );
if ( Rwr_IsComplement(pNode->p0) )
eNode0.fCompl = !eNode0.fCompl;
eNode1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), pGraph );
if ( Rwr_IsComplement(pNode->p1) )
eNode1.fCompl = !eNode1.fCompl;
// create the decomposition node(s)
if ( pNode->fExor )
{
assert( !Rwr_IsComplement(pNode->p0) );
assert( !Rwr_IsComplement(pNode->p1) );
NodeA.fIntern = 1;
NodeA.fConst = 0;
NodeA.fCompl = 0;
NodeA.fCompl0 = !(Node0 & 1);
NodeA.fCompl1 = (Node1 & 1);
NodeA.iFanin0 = (Node0 >> 1);
NodeA.iFanin1 = (Node1 >> 1);
Vec_IntPush( vForm, Ft_Node2Int(NodeA) );
NodeB.fIntern = 1;
NodeB.fConst = 0;
NodeB.fCompl = 0;
NodeB.fCompl0 = (Node0 & 1);
NodeB.fCompl1 = !(Node1 & 1);
NodeB.iFanin0 = (Node0 >> 1);
NodeB.iFanin1 = (Node1 >> 1);
Vec_IntPush( vForm, Ft_Node2Int(NodeB) );
Node.fIntern = 1;
Node.fConst = 0;
Node.fCompl = 0;
Node.fCompl0 = 1;
Node.fCompl1 = 1;
Node.iFanin0 = vForm->nSize - 2;
Node.iFanin1 = vForm->nSize - 1;
Vec_IntPush( vForm, Ft_Node2Int(Node) );
}
eNode = Dec_GraphAddNodeXor( pGraph, eNode0, eNode1 );
else
{
Node.fIntern = 1;
Node.fConst = 0;
Node.fCompl = 0;
Node.fCompl0 = Rwr_IsComplement(pNode->p0) ^ (Node0 & 1);
Node.fCompl1 = Rwr_IsComplement(pNode->p1) ^ (Node1 & 1);
Node.iFanin0 = (Node0 >> 1);
Node.iFanin1 = (Node1 >> 1);
Vec_IntPush( vForm, Ft_Node2Int(Node) );
}
// save the number of this node
pNode->Volume = ((vForm->nSize - 1) << 1) | pNode->fExor;
return pNode->Volume;
}
/**Function*************************************************************
Synopsis [Verifies the factored form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwr_FactorVerify( Vec_Int_t * vForm, unsigned uTruthGold )
{
Ft_Node_t * pFtNode;
Vec_Int_t * vTruths;
unsigned uTruth, uTruth0, uTruth1;
int i;
vTruths = Vec_IntAlloc( vForm->nSize );
Vec_IntPush( vTruths, 0xAAAA );
Vec_IntPush( vTruths, 0xCCCC );
Vec_IntPush( vTruths, 0xF0F0 );
Vec_IntPush( vTruths, 0xFF00 );
assert( Ft_FactorGetNumVars( vForm ) == 4 );
for ( i = 4; i < vForm->nSize; i++ )
{
pFtNode = Ft_NodeRead( vForm, i );
// make sure there are no elementary variables
assert( pFtNode->iFanin0 != pFtNode->iFanin1 );
uTruth0 = vTruths->pArray[pFtNode->iFanin0];
uTruth0 = pFtNode->fCompl0? ~uTruth0 : uTruth0;
uTruth1 = vTruths->pArray[pFtNode->iFanin1];
uTruth1 = pFtNode->fCompl1? ~uTruth1 : uTruth1;
uTruth = uTruth0 & uTruth1;
Vec_IntPush( vTruths, uTruth );
}
// complement if necessary
if ( pFtNode->fCompl )
uTruth = ~uTruth;
uTruth &= 0xFFFF;
if ( uTruth != uTruthGold )
printf( "Verification failed\n" );
Vec_IntFree( vTruths );
eNode = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
// save the result
pNode->Volume = Dec_EdgeToInt( eNode );
return eNode;
}
////////////////////////////////////////////////////////////////////////
......
......@@ -19,13 +19,13 @@
***********************************************************************/
#include "rwr.h"
#include "ft.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Vec_Int_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 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 );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -40,8 +40,8 @@ static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t
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->vForm gives
the decomposition tree (represented using factored form data structure).
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 []
......@@ -52,14 +52,14 @@ static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t
int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros )
{
int fVeryVerbose = 0;
Vec_Int_t * vForm;
Dec_Graph_t * pGraph;
Cut_Cut_t * pCut;
Abc_Obj_t * pFanin;
unsigned uPhase, uTruthBest;
char * pPerm;
int Required, nNodesSaved;
int i, GainCur, GainBest = -1;
int clk;
int clk, clk2;
p->nNodesConsidered++;
// get the required times
......@@ -109,14 +109,16 @@ clk = clock();
Abc_ObjRegular(pFanin)->vFanouts.nSize--;
// evaluate the cut
vForm = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur );
clk2 = clock();
pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur );
p->timeEval += clock() - clk2;
// check if the cut is better than the current best one
if ( vForm != NULL && GainBest < GainCur )
if ( pGraph != NULL && GainBest < GainCur )
{
// save this form
GainBest = GainCur;
p->vForm = vForm;
p->pGraph = pGraph;
p->fCompl = ((uPhase & (1<<4)) > 0);
uTruthBest = pCut->uTruth;
// collect fanins in the
......@@ -127,8 +129,12 @@ clk = clock();
}
p->timeRes += clock() - clk;
if ( GainBest == -1 || GainBest == 0 && !fUseZeros )
return GainBest;
if ( GainBest == -1 )
return -1;
// copy the leaves
Vec_PtrForEachEntry( p->vFanins, pFanin, i )
Dec_GraphNode(p->pGraph, i)->pFunc = pFanin;
p->nScores[p->pMap[uTruthBest]]++;
p->nNodesRewritten++;
......@@ -139,7 +145,7 @@ p->timeRes += clock() - clk;
{
printf( "Node %6s : ", Abc_ObjName(pNode) );
printf( "Fanins = %d. ", p->vFanins->nSize );
printf( "Cone = %2d. ", p->vForm->nSize - 4 );
printf( "Cone = %2d. ", Dec_GraphNodeNum(p->pGraph) );
printf( "GAIN = %2d. ", GainBest );
printf( "\n" );
}
......@@ -157,37 +163,40 @@ p->timeRes += clock() - clk;
SeeAlso []
***********************************************************************/
Vec_Int_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 )
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 )
{
Vec_Ptr_t * vSubgraphs;
Vec_Int_t * vFormBest;
Rwr_Node_t * pNode;
int nNodesAdded, GainBest = -1, i;
int clk = clock();
Dec_Graph_t * pGraphBest, * pGraphCur;
Rwr_Node_t * pNode, * pFanin;
int nNodesAdded, GainBest, i, k;
// find the matching class of subgraphs
vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[pCut->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 = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFaninsCur,
(Vec_Int_t *)pNode->pNext, p->vLevNums, nNodesSaved, LevelMax );
nNodesAdded = Dec_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;
vFormBest = (Vec_Int_t *)pNode->pNext;
GainBest = nNodesSaved - nNodesAdded;
pGraphBest = pGraphCur;
}
}
p->timeEval += clock() - clk;
if ( GainBest == -1 )
return NULL;
*pGainBest = GainBest;
return vFormBest;
return pGraphBest;
}
////////////////////////////////////////////////////////////////////////
......
......@@ -19,6 +19,8 @@
***********************************************************************/
#include "rwr.h"
#include "main.h"
#include "dec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -41,15 +43,18 @@
***********************************************************************/
Rwr_Man_t * Rwr_ManStart( bool fPrecompute )
{
Dec_Man_t * pManDec;
Rwr_Man_t * p;
int clk = clock();
clk = clock();
p = ALLOC( Rwr_Man_t, 1 );
memset( p, 0, sizeof(Rwr_Man_t) );
p->nFuncs = (1<<16);
// canonical forms, phases, perms
clk = clock();
Extra_Truth4VarNPN( &p->puCanons, &p->pPhases, &p->pPerms, &p->pMap );
//PRT( "NPN classes precomputation time", clock() - clk );
pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame());
p->puCanons = pManDec->puCanons;
p->pPhases = pManDec->pPhases;
p->pPerms = pManDec->pPerms;
p->pMap = pManDec->pMap;
// initialize practical NPN classes
p->pPractical = Rwr_ManGetPractical( p );
// create the table
......@@ -104,7 +109,7 @@ void Rwr_ManStop( Rwr_Man_t * p )
Rwr_Node_t * pNode;
int i, k;
Vec_VecForEachEntry( p->vClasses, pNode, i, k )
Vec_IntFree( (Vec_Int_t *)pNode->pNext );
Dec_GraphFree( (Dec_Graph_t *)pNode->pNext );
}
if ( p->vClasses ) Vec_VecFree( p->vClasses );
Vec_PtrFree( p->vForest );
......@@ -115,10 +120,6 @@ void Rwr_ManStop( Rwr_Man_t * p )
free( p->pTable );
free( p->pPractical );
free( p->pPerms4 );
free( p->puCanons );
free( p->pPhases );
free( p->pPerms );
free( p->pMap );
free( p );
}
......@@ -173,25 +174,9 @@ void Rwr_ManPrintStats( Rwr_Man_t * p )
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Rwr_ManReadFanins( Rwr_Man_t * p )
{
return p->vFanins;
}
/**Function*************************************************************
Synopsis [Stops the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Rwr_ManReadDecs( Rwr_Man_t * p )
void * Rwr_ManReadDecs( Rwr_Man_t * p )
{
return p->vForm;
return p->pGraph;
}
/**Function*************************************************************
......
/**CFile****************************************************************
FileName [ft.h]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Data structure for algebraic factoring.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [$Id: ft.h,v 1.1 2003/05/22 19:20:04 alanmi Exp $]
***********************************************************************/
#ifndef __FT_H__
#define __FT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// STRUCTURE DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Ft_Node_t_ Ft_Node_t;
struct Ft_Node_t_
{
// the first child
unsigned fCompl0 : 1; // complemented attribute
unsigned iFanin0 : 11; // fanin number
// the second child
unsigned fCompl1 : 1; // complemented attribute
unsigned iFanin1 : 11; // fanin number (1-based)
// other info
unsigned fIntern : 1; // marks any node that is not an elementary var
unsigned fConst : 1; // marks the constant 1 function
unsigned fCompl : 1; // marks the complement of topmost node
// printing info
unsigned fNodeOr : 1; // marks the original OR node
unsigned fEdge0 : 1; // marks the original complemented edge
unsigned fEdge1 : 1; // marks the original complemented edge
// some bits are unused
};
/*
The factored form of an SOP is an array (Vec_Int_t) of entries of type Ft_Node_t.
If the SOP has n input variables (some of them may not be in the true support)
the first n entries of the factored form array are zeros. The other entries of the array
represent the internal AND nodes of the factored form, and possibly the constant node.
This representation makes it easy to translate the factored form into an AIG.
The factored AND nodes contains fanins of the node and their complemented attributes
(using AIG semantics). The elementary variable (buffer or interver) are represented
as a node with the same fanins. For example: x' = AND( x', x' ).
The constant node is represented a special node with the constant flag set.
If the constant node and the elementary variable are present, no other internal
AND nodes are allowed in the factored form.
*/
// working with complemented attributes of objects
static inline bool Ptr_IsComplement( void * p ) { return (bool)(((unsigned)p) & 01); }
static inline void * Ptr_Regular( void * p ) { return (void *)((unsigned)(p) & ~01); }
static inline void * Ptr_Not( void * p ) { return (void *)((unsigned)(p) ^ 01); }
static inline void * Ptr_NotCond( void * p, int c ) { return (void *)((unsigned)(p) ^ (c)); }
static inline Ft_Node_t * Ft_NodeRead( Vec_Int_t * vForm, int i ) { return (Ft_Node_t *)vForm->pArray + i; }
static inline Ft_Node_t * Ft_NodeReadLast( Vec_Int_t * vForm ) { return (Ft_Node_t *)vForm->pArray + vForm->nSize - 1; }
static inline Ft_Node_t * Ft_NodeFanin0( Vec_Int_t * vForm, Ft_Node_t * pNode ) { assert( pNode->fIntern ); return (Ft_Node_t *)vForm->pArray + pNode->iFanin0; }
static inline Ft_Node_t * Ft_NodeFanin1( Vec_Int_t * vForm, Ft_Node_t * pNode ) { assert( pNode->fIntern ); return (Ft_Node_t *)vForm->pArray + pNode->iFanin1; }
static inline Ft_Node_t Ft_Int2Node( int Num ) { return *((Ft_Node_t *)&Num); }
static inline int Ft_Node2Int( Ft_Node_t Node ) { return *((int *)&Node); }
static inline void Ft_NodeClean( Ft_Node_t * pNode ) { *((int *)pNode) = 0; }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/*=== ftFactor.c =====================================================*/
extern void Ft_FactorStartMan();
extern void Ft_FactorStopMan();
extern Vec_Int_t * Ft_Factor( char * pSop );
extern int Ft_FactorGetNumNodes( Vec_Int_t * vForm );
extern int Ft_FactorGetNumVars( Vec_Int_t * vForm );
extern void Ft_FactorComplement( Vec_Int_t * vForm );
extern Vec_Int_t * Ft_FactorConst( int fConst1 );
extern Vec_Int_t * Ft_FactorVar( int iVar, int nVars, int fCompl );
/*=== ftPrint.c =====================================================*/
extern void Ft_FactorPrint( FILE * pFile, Vec_Int_t * vForm, char * pNamesIn[], char * pNameOut );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
SRC += src/sop/ft/ftFactor.c \
src/sop/ft/ftPrint.c
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment