Commit 81fae91a by Alan Mishchenko

Version abc70225

parent fb51057e
......@@ -23,7 +23,7 @@ OPTFLAGS := -g -O
CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES))
CXXFLAGS += $(CFLAGS)
LIBS := -ldl -rdynamic -lreadline -ltermcap libhmetis.a
LIBS := -ldl -rdynamic -lreadline -ltermcap
SRC :=
GARBAGE := core core.* *.stackdump ./tags $(PROG)
......
......@@ -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 lib/libhmetis.lib /nologo /subsystem:console /profile /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"
......@@ -75,7 +75,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 /debug /machine:I386 /pdbtype:sept
# 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 lib/libhmetis.lib /nologo /subsystem:console /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept
# 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 /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept
!ENDIF
......@@ -102,6 +102,10 @@ SOURCE=.\src\base\abc\abcAig.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcBlifMv.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcCheck.c
# End Source File
# Begin Source File
......@@ -1990,10 +1994,6 @@ SOURCE=.\src\map\if\ifMap.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifPrepro.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifReduce.c
# End Source File
# Begin Source File
......
......@@ -278,6 +278,22 @@ int Mem_FixedReadMemUsage( Mem_Fixed_t * p )
return p->nMemoryAlloc;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mem_FixedReadMaxEntriesUsed( Mem_Fixed_t * p )
{
return p->nEntriesMax;
}
/**Function*************************************************************
......
......@@ -45,6 +45,7 @@ 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 );
extern int Mem_FixedReadMaxEntriesUsed( 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 );
......
......@@ -316,6 +316,7 @@ static inline Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) { return Ab
static inline Abc_Obj_t * Abc_NtkCreateBi( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BI ); }
static inline Abc_Obj_t * Abc_NtkCreateBo( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BO ); }
static inline Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_ASSERT ); }
static inline Abc_Obj_t * Abc_NtkCreateNet( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_NET ); }
static inline Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_NODE ); }
static inline Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_LATCH ); }
static inline Abc_Obj_t * Abc_NtkCreateWhitebox( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_WHITEBOX ); }
......@@ -535,6 +536,15 @@ extern void Abc_AigUpdateStop( Abc_Aig_t * pMan );
extern void Abc_AigUpdateReset( Abc_Aig_t * pMan );
/*=== abcAttach.c ==========================================================*/
extern int Abc_NtkAttach( Abc_Ntk_t * pNtk );
/*=== abcBlifMv.c ==========================================================*/
extern void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk );
extern void Abc_NtkFreeMvVars( Abc_Ntk_t * pNtk );
extern void Abc_NtkSetMvVarValues( Abc_Obj_t * pObj, int nValues );
extern Abc_Ntk_t * Abc_NtkStrashBlifMv( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkInsertBlifMv( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtkLogic );
extern int Abc_NtkConvertToBlifMv( Abc_Ntk_t * pNtk );
extern char * Abc_NodeConvertSopToMvSop( int nVars, Vec_Int_t * vSop0, Vec_Int_t * vSop1 );
extern int Abc_NodeEvalMvCost( int nVars, Vec_Int_t * vSop0, Vec_Int_t * vSop1 );
/*=== abcBalance.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate, bool fSelective, bool fUpdateLevel );
/*=== abcCheck.c ==========================================================*/
......@@ -544,6 +554,9 @@ extern bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk );
extern bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj );
extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fOnlyPis, int fComb );
extern int Abc_NtkIsAcyclicHierarchy( Abc_Ntk_t * pNtk );
extern int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk );
extern int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk );
extern int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk );
/*=== abcCollapse.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose );
/*=== abcCut.c ==========================================================*/
......@@ -616,6 +629,7 @@ extern void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtk );
extern void Abc_LibPrint( Abc_Lib_t * pLib );
extern int Abc_LibAddModel( Abc_Lib_t * pLib, Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_LibFindModelByName( Abc_Lib_t * pLib, char * pName );
extern int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib );
extern Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib );
/*=== abcMiter.c ==========================================================*/
extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk );
......@@ -682,7 +696,7 @@ extern void Abc_NtkAddDummyBoxNames( Abc_Ntk_t * pNtk );
extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
/*=== abcNetlist.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk, int fDirect );
extern Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk );
/*=== abcNtbdd.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi );
......@@ -783,6 +797,10 @@ extern int Abc_SopIsExorType( char * pSop );
extern bool Abc_SopCheck( char * pSop, int nFanins );
extern char * Abc_SopFromTruthBin( char * pTruth );
extern char * Abc_SopFromTruthHex( char * pTruth );
extern char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues );
extern char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues );
extern char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues );
extern char * Abc_SopDecoderLog( Extra_MmFlex_t * pMan, int nValues );
/*=== abcStrash.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup );
extern Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
......
......@@ -277,6 +277,19 @@ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
}
}
Vec_IntFree( vNameIds );
// make sure the CI names are unique
if ( !Abc_NtkCheckUniqueCiNames(pNtk) )
return 0;
// make sure the CO names are unique
if ( !Abc_NtkCheckUniqueCoNames(pNtk) )
return 0;
// make sure that if a CO has the same name as a CI, they point directly
if ( !Abc_NtkCheckUniqueCioNames(pNtk) )
return 0;
return 1;
}
......@@ -804,6 +817,121 @@ int Abc_NtkIsAcyclicHierarchy( Abc_Ntk_t * pNtk )
return RetValue;
}
/**Function*************************************************************
Synopsis [Returns 0 if CI names are repeated.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkNamesCompare( char ** pName1, char ** pName2 )
{
return strcmp( *pName1, *pName2 );
}
/**Function*************************************************************
Synopsis [Returns 0 if CI names are repeated.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNames;
Abc_Obj_t * pObj;
int i, fRetValue = 1;
assert( !Abc_NtkIsNetlist(pNtk) );
vNames = Vec_PtrAlloc( Abc_NtkCiNum(pNtk) );
Abc_NtkForEachCi( pNtk, pObj, i )
Vec_PtrPush( vNames, Abc_ObjName(pObj) );
Vec_PtrSort( vNames, Abc_NtkNamesCompare );
for ( i = 1; i < Abc_NtkCiNum(pNtk); i++ )
if ( !strcmp( Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) ) )
{
printf( "Abc_NtkCheck: Repeated CI names: %s and %s.\n", Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) );
fRetValue = 0;
}
Vec_PtrFree( vNames );
return fRetValue;
}
/**Function*************************************************************
Synopsis [Returns 0 if CO names are repeated.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNames;
Abc_Obj_t * pObj;
int i, fRetValue = 1;
assert( !Abc_NtkIsNetlist(pNtk) );
vNames = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pObj, i )
Vec_PtrPush( vNames, Abc_ObjName(pObj) );
Vec_PtrSort( vNames, Abc_NtkNamesCompare );
for ( i = 1; i < Abc_NtkCoNum(pNtk); i++ )
{
// printf( "%s\n", Vec_PtrEntry(vNames,i) );
if ( !strcmp( Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) ) )
{
printf( "Abc_NtkCheck: Repeated CO names: %s and %s.\n", Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) );
fRetValue = 0;
}
}
Vec_PtrFree( vNames );
return fRetValue;
}
/**Function*************************************************************
Synopsis [Returns 0 if there is a pair of CI/CO with the same name and logic in between.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj, * pObjCi;
int i, nCiId, fRetValue = 1;
assert( !Abc_NtkIsNetlist(pNtk) );
Abc_NtkForEachCo( pNtk, pObj, i )
{
nCiId = Nm_ManFindIdByName( pNtk->pManName, Abc_ObjName(pObj), ABC_OBJ_PI );
if ( nCiId == -1 )
nCiId = Nm_ManFindIdByName( pNtk->pManName, Abc_ObjName(pObj), ABC_OBJ_BO );
if ( nCiId == -1 )
continue;
pObjCi = Abc_NtkObj( pNtk, nCiId );
assert( !strcmp( Abc_ObjName(pObj), Abc_ObjName(pObjCi) ) );
if ( Abc_ObjFanin0(pObj) != pObjCi )
{
printf( "Abc_NtkCheck: A CI/CO pair share the name (%s) but do not link directly.\n", Abc_ObjName(pObj) );
fRetValue = 0;
}
}
return fRetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -884,6 +884,7 @@ int Abc_NtkLevelReverse_rec( Abc_Obj_t * pNode )
if ( pNode->Level < (unsigned)Level )
pNode->Level = Level;
}
if ( Abc_ObjFaninNum(pNode) > 0 )
pNode->Level++;
return pNode->Level;
}
......@@ -975,8 +976,8 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
if ( Abc_NodeIsTravIdCurrent(pNode) )
{
fprintf( stdout, "Network \"%s\" contains combinational loop!\n", Abc_NtkName(pNtk) );
fprintf( stdout, "Node \"%s\" is encountered twice on the following path:\n", Abc_ObjName(pNode) );
fprintf( stdout, " %s", Abc_ObjIsNode(pNode)? Abc_ObjName(pNode) : Abc_NtkName(pNode->pData) );
fprintf( stdout, "Node \"%s\" is encountered twice on the following path:\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
fprintf( stdout, " %s", Abc_ObjIsNode(pNode)? Abc_ObjName(Abc_ObjFanout0(pNode)) : Abc_NtkName(pNode->pData) );
return 0;
}
// mark this node as a node on the current path
......@@ -1041,7 +1042,7 @@ bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk )
if ( fAcyclic = Abc_NtkIsAcyclic_rec(pNode) )
continue;
// stop as soon as the first loop is detected
fprintf( stdout, " (cone of CO \"%s\")\n", Abc_ObjName(pNode) );
fprintf( stdout, " (cone of CO \"%s\")\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
break;
}
return fAcyclic;
......
......@@ -880,6 +880,22 @@ int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Converts SOP functions into BLIF-MV functions.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkSopToBlifMv( Abc_Ntk_t * pNtk )
{
return 1;
}
/**Function*************************************************************
Synopsis [Convers logic network to the SOP form.]
Description []
......
......@@ -108,8 +108,11 @@ Abc_Lib_t * Abc_LibDupBlackboxes( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave )
Abc_Lib_t * pLibNew;
Abc_Ntk_t * pNtkTemp;
int i;
assert( Vec_PtrSize(pLib->vTops) > 0 );
assert( Vec_PtrSize(pLib->vModules) > 1 );
pLibNew = Abc_LibCreate( pLib->pName );
// pLibNew->pManFunc = pNtkSave->pManFunc;
Vec_PtrPush( pLibNew->vTops, pNtkSave );
Vec_PtrPush( pLibNew->vModules, pNtkSave );
Vec_PtrForEachEntry( pLib->vModules, pNtkTemp, i )
if ( Abc_NtkHasBlackbox( pNtkTemp ) )
......@@ -215,7 +218,50 @@ Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib )
return pNtk;
}
/**Function*************************************************************
Synopsis [Detects the top-level models.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib )
{
Abc_Ntk_t * pNtk, * pNtkBox;
Abc_Obj_t * pObj;
int i, k;
assert( Vec_PtrSize( pLib->vModules ) > 0 );
// clear the models
Vec_PtrForEachEntry( pLib->vModules, pNtk, i )
pNtk->fHieVisited = 0;
// mark all the models reachable from other models
Vec_PtrForEachEntry( pLib->vModules, pNtk, i )
{
Abc_NtkForEachBox( pNtk, pObj, k )
{
if ( Abc_ObjIsLatch(pObj) )
continue;
if ( pObj->pData == NULL )
continue;
pNtkBox = pObj->pData;
pNtkBox->fHieVisited = 1;
}
}
// collect the models that are not marked
Vec_PtrClear( pLib->vTops );
Vec_PtrForEachEntry( pLib->vModules, pNtk, i )
{
if ( pNtk->fHieVisited == 0 )
Vec_PtrPush( pLib->vTops, pNtk );
else
pNtk->fHieVisited = 0;
}
return Vec_PtrSize( pLib->vTops );
}
/**Function*************************************************************
......
......@@ -55,7 +55,7 @@ Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk )
return Abc_NtkAigToLogicSop( pNtk );
assert( Abc_NtkIsNetlist(pNtk) );
// consider simple case when there is hierarchy
assert( pNtk->pDesign == NULL );
// assert( pNtk->pDesign == NULL );
assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
assert( Abc_NtkBlackboxNum(pNtk) == 0 );
// start the network
......@@ -90,7 +90,7 @@ Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk, int fDirect )
Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew, * pNtkTemp;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
......@@ -151,6 +151,11 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
// remove dangling nodes
Abc_NtkCleanup( pNtk, 0 );
// make sure the CO names are unique
Abc_NtkCheckUniqueCiNames( pNtk );
Abc_NtkCheckUniqueCoNames( pNtk );
Abc_NtkCheckUniqueCioNames( pNtk );
// assert( Abc_NtkLogicHasSimpleCos(pNtk) );
if ( !Abc_NtkLogicHasSimpleCos(pNtk) )
{
......@@ -213,7 +218,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
// duplicate EXDC
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkToNetlist( pNtk->pExdc, 0 );
pNtkNew->pExdc = Abc_NtkToNetlist( pNtk->pExdc );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkLogicToNetlist(): Network check has failed.\n" );
return pNtkNew;
......
......@@ -264,18 +264,23 @@ void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsNetlist(pNtk) );
// check if constant 0 net is used
pNet = Abc_NtkFindOrCreateNet( pNtk, "1\'b0" );
pNet = Abc_NtkFindNet( pNtk, "1\'b0" );
if ( pNet )
{
if ( Abc_ObjFanoutNum(pNet) == 0 )
Abc_NtkDeleteObj(pNet);
else if ( Abc_ObjFaninNum(pNet) == 0 )
Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst0(pNtk) );
}
// check if constant 1 net is used
pNet = Abc_NtkFindOrCreateNet( pNtk, "1\'b1" );
pNet = Abc_NtkFindNet( pNtk, "1\'b1" );
if ( pNet )
{
if ( Abc_ObjFanoutNum(pNet) == 0 )
Abc_NtkDeleteObj(pNet);
else if ( Abc_ObjFaninNum(pNet) == 0 )
Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst1(pNtk) );
}
// fix the net drivers
Abc_NtkFixNonDrivenNets( pNtk );
......@@ -872,7 +877,10 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
// free node attributes
Vec_PtrForEachEntry( pNtk->vAttrs, pAttrMan, i )
if ( pAttrMan )
{
//printf( "deleting attr\n" );
Vec_AttFree( pAttrMan, 1 );
}
Vec_PtrFree( pNtk->vAttrs );
FREE( pNtk->pName );
FREE( pNtk->pSpec );
......@@ -892,16 +900,12 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
***********************************************************************/
void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
{
char Buffer[10];
Vec_Ptr_t * vNets;
Abc_Obj_t * pNet, * pNode;
int i;
if ( Abc_NtkNodeNum(pNtk) == 0 )
{
// pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
return;
}
// check for non-driven nets
vNets = Vec_PtrAlloc( 100 );
......@@ -910,13 +914,6 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
if ( Abc_ObjFaninNum(pNet) > 0 )
continue;
// add the constant 0 driver
if ( Abc_NtkHasBlifMv(pNtk) )
{
pNode = Abc_NtkCreateNode( pNtk );
sprintf( Buffer, "%d\n0\n", Abc_ObjMvVarNum(pNet) );
pNode->pData = Abc_SopRegister( pNtk->pManFunc, Buffer );
}
else
pNode = Abc_NtkCreateNodeConst0( pNtk );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
......@@ -927,7 +924,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
// print the warning
if ( vNets->nSize > 0 )
{
printf( "Constant-0 drivers added to %d non-driven nets in network \"%s\":\n", Vec_PtrSize(vNets), pNtk->pName );
printf( "Warning: Constant-0 drivers added to %d non-driven nets in network \"%s\":\n", Vec_PtrSize(vNets), pNtk->pName );
Vec_PtrForEachEntry( vNets, pNet, i )
{
printf( "%s%s", (i? ", ": ""), Abc_ObjName(pNet) );
......
......@@ -349,7 +349,7 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName
{
if ( Abc_NtkIsStrash(pNtkNew) )
{}
else if ( Abc_NtkHasSop(pNtkNew) )
else if ( Abc_NtkHasSop(pNtkNew) || Abc_NtkHasBlifMv(pNtkNew) )
pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pObj->pData );
else if ( Abc_NtkHasBdd(pNtkNew) )
pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData);
......@@ -558,8 +558,9 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
assert( Abc_NtkIsNetlist(pNtk) );
if ( pName && (pNet = Abc_NtkFindNet( pNtk, pName )) )
return pNet;
//printf( "Creating net %s.\n", pName );
// create a new net
pNet = Abc_NtkCreateObj( pNtk, ABC_OBJ_NET );
pNet = Abc_NtkCreateNet( pNtk );
if ( pName )
Nm_ManStoreIdName( pNtk->pManName, pNet->Id, pNet->Type, pName, NULL );
return pNet;
......@@ -581,7 +582,7 @@ Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk )
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkHasSop(pNtk) )
if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData );
......@@ -610,7 +611,7 @@ Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk )
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkHasSop(pNtk) )
if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData );
......
......@@ -933,6 +933,139 @@ char * Abc_SopFromTruthHex( char * pTruth )
return pSopCover;
}
/**Function*************************************************************
Synopsis [Creates one encoder node.]
Description [Produces MV-SOP for BLIF-MV representation.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues )
{
char Buffer[32];
assert( iValue < nValues );
sprintf( Buffer, "d0\n%d 1\n", iValue );
return Abc_SopRegister( pMan, Buffer );
}
/**Function*************************************************************
Synopsis [Creates one encoder node.]
Description [Produces MV-SOP for BLIF-MV representation.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues )
{
char * pResult;
Vec_Str_t * vSop;
int v, Counter, fFirst = 1, nBits = Extra_Base2Log(nValues);
assert( iBit < nBits );
// count the number of literals
Counter = 0;
for ( v = 0; v < nValues; v++ )
Counter += ( (v & (1 << iBit)) > 0 );
// create the cover
vSop = Vec_StrAlloc( 100 );
Vec_StrPrintStr( vSop, "d0\n" );
if ( Counter > 1 )
Vec_StrPrintStr( vSop, "(" );
for ( v = 0; v < nValues; v++ )
if ( v & (1 << iBit) )
{
if ( fFirst )
fFirst = 0;
else
Vec_StrPush( vSop, ',' );
Vec_StrPrintNum( vSop, v );
}
if ( Counter > 1 )
Vec_StrPrintStr( vSop, ")" );
Vec_StrPrintStr( vSop, " 1\n" );
Vec_StrPush( vSop, 0 );
pResult = Abc_SopRegister( pMan, Vec_StrArray(vSop) );
Vec_StrFree( vSop );
return pResult;
}
/**Function*************************************************************
Synopsis [Creates the decoder node.]
Description [Produces MV-SOP for BLIF-MV representation.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues )
{
char * pResult;
Vec_Str_t * vSop;
int i, k;
assert( nValues > 1 );
vSop = Vec_StrAlloc( 100 );
for ( i = 0; i < nValues; i++ )
{
for ( k = 0; k < nValues; k++ )
{
if ( k == i )
Vec_StrPrintStr( vSop, "1 " );
else
Vec_StrPrintStr( vSop, "- " );
}
Vec_StrPrintNum( vSop, i );
Vec_StrPush( vSop, '\n' );
}
Vec_StrPush( vSop, 0 );
pResult = Abc_SopRegister( pMan, Vec_StrArray(vSop) );
Vec_StrFree( vSop );
return pResult;
}
/**Function*************************************************************
Synopsis [Creates the decover node.]
Description [Produces MV-SOP for BLIF-MV representation.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopDecoderLog( Extra_MmFlex_t * pMan, int nValues )
{
char * pResult;
Vec_Str_t * vSop;
int i, b, nBits = Extra_Base2Log(nValues);
assert( nValues > 1 && nValues <= (1<<nBits) );
vSop = Vec_StrAlloc( 100 );
for ( i = 0; i < nValues; i++ )
{
for ( b = 0; b < nBits; b++ )
{
Vec_StrPrintNum( vSop, (int)((i & (1 << b)) > 0) );
Vec_StrPush( vSop, ' ' );
}
Vec_StrPrintNum( vSop, i );
Vec_StrPush( vSop, '\n' );
}
Vec_StrPush( vSop, 0 );
pResult = Abc_SopRegister( pMan, Vec_StrArray(vSop) );
Vec_StrFree( vSop );
return pResult;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -55,43 +55,6 @@ void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan )
/**Function*************************************************************
Synopsis [Starts the Mv-Var manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk )
{
Vec_Att_t * pAttMan;
assert( Abc_NtkMvVar(pNtk) == NULL );
pAttMan = Vec_AttAlloc( 0, Abc_NtkObjNumMax(pNtk) + 1, Extra_MmFlexStart(), Extra_MmFlexStop, NULL, NULL );
Vec_PtrWriteEntry( pNtk->vAttrs, VEC_ATTR_MVVAR, pAttMan );
}
/**Function*************************************************************
Synopsis [Stops the Mv-Var manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFreeMvVars( Abc_Ntk_t * pNtk )
{
void * pUserMan;
pUserMan = Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, 0 );
Extra_MmFlexStop( pUserMan );
}
/**Function*************************************************************
Synopsis [Increments the current traversal ID of the network.]
Description []
......@@ -754,12 +717,6 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachCo( pNtk, pNode, i )
{
/*
if ( strcmp( Abc_ObjName(pNode), "g704" ) == 0 )
{
int s = 1;
}
*/
// if the driver is complemented, this is an error
pDriver = Abc_ObjFanin0(pNode);
if ( Abc_ObjFaninC0(pNode) )
......
SRC += src/base/abc/abcAig.c \
src/base/abc/abcBlifMv.c \
src/base/abc/abcCheck.c \
src/base/abc/abcDfs.c \
src/base/abc/abcFanio.c \
......
......@@ -125,9 +125,9 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
pIfMan = If_ManStart( pPars );
// print warning about excessive memory usage
if ( 1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nEntrySize / (1<<30) > 0.5 )
printf( "Warning: The mapper is about to allocate %.1f Gb for to represent %d cuts per node.\n",
1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nEntrySize / (1<<30), pPars->nCutsMax );
if ( 1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nObjBytes / (1<<30) > 1.0 )
printf( "Warning: The mapper will allocate %.1f Gb for to represent the subject graph with %d AIG nodes.\n",
1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nObjBytes / (1<<30), Abc_NtkObjNum(pNtk) );
// create PIs and remember them in the old nodes
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)If_ManConst1( pIfMan );
......@@ -184,7 +184,7 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
Vec_Int_t * vCover;
int i, nDupGates;
// create the new network
if ( pIfMan->pPars->fUseBdds || pIfMan->pPars->fUseCnfs )
if ( pIfMan->pPars->fUseBdds || pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
else if ( pIfMan->pPars->fUseSops )
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
......@@ -214,7 +214,7 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
if ( Abc_ObjFanoutNum(pNodeNew) == 0 )
Abc_NtkDeleteObj( pNodeNew );
// minimize the node
if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseBdds )
if ( pIfMan->pPars->fUseBdds || pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
Abc_NtkSweep( pNtkNew, 0 );
if ( pIfMan->pPars->fUseBdds )
Abc_NtkBddReorder( pNtkNew, 0 );
......@@ -251,7 +251,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
// create a new node
pNodeNew = Abc_NtkCreateNode( pNtkNew );
pCutBest = If_ObjCutBest( pIfObj );
if ( pIfMan->pPars->fUseCnfs )
if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
{
If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
......@@ -269,7 +269,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
// transform truth table into the BDD
pNodeNew->pData = Kit_TruthToBdd( pNtkNew->pManFunc, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), 0 ); Cudd_Ref(pNodeNew->pData);
}
else if ( pIfMan->pPars->fUseCnfs )
else if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
{
// transform truth table into the BDD
pNodeNew->pData = Kit_TruthToBdd( pNtkNew->pManFunc, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), 1 ); Cudd_Ref(pNodeNew->pData);
......@@ -329,7 +329,7 @@ Hop_Obj_t * Abc_NodeIfToHop_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_
If_Cut_t * pCut;
Hop_Obj_t * gFunc, * gFunc0, * gFunc1;
// get the best cut
pCut = If_ObjCutTriv(pIfObj);
pCut = If_ObjCutBest(pIfObj);
// if the cut is visited, return the result
if ( If_CutData(pCut) )
return If_CutData(pCut);
......@@ -367,14 +367,14 @@ Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t *
assert( pCut->nLeaves > 1 );
// set the leaf variables
If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
If_CutSetData( If_ObjCutTriv(pLeaf), Hop_IthVar(pHopMan, i) );
If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) );
// recursively compute the function while collecting visited cuts
Vec_PtrClear( pIfMan->vTemp );
gFunc = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp );
// printf( "%d ", Vec_PtrSize(p->vTemp) );
// clean the cuts
If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
If_CutSetData( If_ObjCutTriv(pLeaf), NULL );
If_CutSetData( If_ObjCutBest(pLeaf), NULL );
Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i )
If_CutSetData( pCut, NULL );
return gFunc;
......
......@@ -27,14 +27,16 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NtkRenodeEvalAig( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalBdd( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalSop( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalCnf( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalAig( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalMv( If_Cut_t * pCut );
static reo_man * s_pReo = NULL;
static DdManager * s_pDd = NULL;
static Vec_Int_t * s_vMemory = NULL;
static Vec_Int_t * s_vMemory2 = NULL;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......@@ -51,7 +53,7 @@ static Vec_Int_t * s_vMemory = NULL;
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nFlowIters, int nAreaIters, int fArea, int fUseBdds, int fUseSops, int fUseCnfs, int fVerbose )
Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nFlowIters, int nAreaIters, int fArea, int fUseBdds, int fUseSops, int fUseCnfs, int fUseMv, int fVerbose )
{
extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
If_Par_t Pars, * pPars = &Pars;
......@@ -85,6 +87,7 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nF
pPars->fUseBdds = fUseBdds;
pPars->fUseSops = fUseSops;
pPars->fUseCnfs = fUseCnfs;
pPars->fUseMv = fUseMv;
if ( fUseBdds )
pPars->pFuncCost = Abc_NtkRenodeEvalBdd;
else if ( fUseSops )
......@@ -94,6 +97,8 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nF
pPars->fArea = 1;
pPars->pFuncCost = Abc_NtkRenodeEvalCnf;
}
else if ( fUseMv )
pPars->pFuncCost = Abc_NtkRenodeEvalMv;
else
pPars->pFuncCost = Abc_NtkRenodeEvalAig;
......@@ -109,6 +114,7 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nF
{
assert( s_vMemory == NULL );
s_vMemory = Vec_IntAlloc( 1 << 16 );
s_vMemory2 = Vec_IntAlloc( 1 << 16 );
}
// perform mapping/renoding
......@@ -125,7 +131,9 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nF
else
{
Vec_IntFree( s_vMemory );
Vec_IntFree( s_vMemory2 );
s_vMemory = NULL;
s_vMemory2 = NULL;
}
return pNtkNew;
......@@ -133,6 +141,35 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int nF
/**Function*************************************************************
Synopsis [Computes the cost based on the factored form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRenodeEvalAig( If_Cut_t * pCut )
{
Kit_Graph_t * pGraph;
int i, nNodes;
pGraph = Kit_TruthToGraph( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory );
if ( pGraph == NULL )
{
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
pCut->pPerm[i] = 100;
return IF_COST_MAX;
}
nNodes = Kit_GraphNodeNum( pGraph );
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
pCut->pPerm[i] = Kit_GraphLeafDepth_rec( pGraph, Kit_GraphNodeLast(pGraph), Kit_GraphNode(pGraph, i) );
Kit_GraphFree( pGraph );
return nNodes;
}
/**Function*************************************************************
Synopsis [Computes the cost based on the BDD size after reordering.]
Description []
......@@ -178,7 +215,7 @@ int Abc_NtkRenodeEvalSop( If_Cut_t * pCut )
pCut->pPerm[i] = 1;
RetValue = Kit_TruthIsop( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory, 1 );
if ( RetValue == -1 )
return ABC_INFINITY;
return IF_COST_MAX;
assert( RetValue == 0 || RetValue == 1 );
return Vec_IntSize( s_vMemory );
}
......@@ -197,12 +234,13 @@ int Abc_NtkRenodeEvalSop( If_Cut_t * pCut )
int Abc_NtkRenodeEvalCnf( If_Cut_t * pCut )
{
int i, RetValue, nClauses;
// set internal mapper parameters
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
pCut->pPerm[i] = 1;
// compute ISOP for the positive phase
RetValue = Kit_TruthIsop( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory, 0 );
if ( RetValue == -1 )
return ABC_INFINITY;
return IF_COST_MAX;
assert( RetValue == 0 || RetValue == 1 );
nClauses = Vec_IntSize( s_vMemory );
// compute ISOP for the negative phase
......@@ -210,7 +248,7 @@ int Abc_NtkRenodeEvalCnf( If_Cut_t * pCut )
RetValue = Kit_TruthIsop( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory, 0 );
Kit_TruthNot( If_CutTruth(pCut), If_CutTruth(pCut), If_CutLeaveNum(pCut) );
if ( RetValue == -1 )
return ABC_INFINITY;
return IF_COST_MAX;
assert( RetValue == 0 || RetValue == 1 );
nClauses += Vec_IntSize( s_vMemory );
return nClauses;
......@@ -218,7 +256,7 @@ int Abc_NtkRenodeEvalCnf( If_Cut_t * pCut )
/**Function*************************************************************
Synopsis [Computes the cost based on the factored form.]
Synopsis [Computes the cost of MV-SOP of the cut function.]
Description []
......@@ -227,22 +265,29 @@ int Abc_NtkRenodeEvalCnf( If_Cut_t * pCut )
SeeAlso []
***********************************************************************/
int Abc_NtkRenodeEvalAig( If_Cut_t * pCut )
int Abc_NtkRenodeEvalMv( If_Cut_t * pCut )
{
Kit_Graph_t * pGraph;
int i, nNodes;
pGraph = Kit_TruthToGraph( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory );
if ( pGraph == NULL )
{
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
pCut->pPerm[i] = 100;
return ABC_INFINITY;
}
nNodes = Kit_GraphNodeNum( pGraph );
int i, RetValue;
// set internal mapper parameters
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
pCut->pPerm[i] = Kit_GraphLeafDepth_rec( pGraph, Kit_GraphNodeLast(pGraph), Kit_GraphNode(pGraph, i) );
Kit_GraphFree( pGraph );
return nNodes;
pCut->pPerm[i] = 1;
// compute ISOP for the positive phase
RetValue = Kit_TruthIsop( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory, 0 );
if ( RetValue == -1 )
return IF_COST_MAX;
assert( RetValue == 0 || RetValue == 1 );
// compute ISOP for the negative phase
Kit_TruthNot( If_CutTruth(pCut), If_CutTruth(pCut), If_CutLeaveNum(pCut) );
RetValue = Kit_TruthIsop( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory2, 0 );
Kit_TruthNot( If_CutTruth(pCut), If_CutTruth(pCut), If_CutLeaveNum(pCut) );
if ( RetValue == -1 )
return IF_COST_MAX;
assert( RetValue == 0 || RetValue == 1 );
// return the cost of the cut
RetValue = Abc_NodeEvalMvCost( If_CutLeaveNum(pCut), s_vMemory, s_vMemory2 );
if ( RetValue >= IF_COST_MAX )
return IF_COST_MAX;
return RetValue;
}
////////////////////////////////////////////////////////////////////////
......
......@@ -1265,7 +1265,7 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
}
// write out the current network
pNetlist = Abc_NtkToNetlist(pNtk,0);
pNetlist = Abc_NtkToNetlist(pNtk);
if ( pNetlist == NULL )
{
fprintf( pErr, "Cannot produce the intermediate network.\n" );
......@@ -1406,7 +1406,7 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
}
// write out the current network
pNetlist = Abc_NtkToNetlist(pNtk,0);
pNetlist = Abc_NtkToNetlist(pNtk);
if ( pNetlist == NULL )
{
fprintf( pErr, "Cannot produce the intermediate network.\n" );
......@@ -1552,7 +1552,7 @@ int CmdCommandCapo( Abc_Frame_t * pAbc, int argc, char **argv )
}
// write out the current network
pNetlist = Abc_NtkToNetlist(pNtk,0);
pNetlist = Abc_NtkToNetlist(pNtk);
if ( pNetlist == NULL )
{
fprintf( pErr, "Cannot produce the intermediate network.\n" );
......
......@@ -95,8 +95,7 @@ extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName,
extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
/*=== abcWriteBlifMv.c ==========================================================*/
extern void Io_WriteBlifMvDesign( Abc_Lib_t * pLib, char * FileName );
extern void Io_WriteBlifMvNetlist( Abc_Ntk_t * pNtk, char * FileName );
extern void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName );
/*=== abcWriteBench.c =========================================================*/
extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName );
/*=== abcWriteCnf.c ===========================================================*/
......
......@@ -45,14 +45,21 @@ Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck )
{
Abc_Ntk_t * pNtk;
Abc_Lib_t * pDesign;
int RetValue;
// parse the verilog file
pDesign = Ver_ParseFile( pFileName, NULL, fCheck, 1 );
if ( pDesign == NULL )
return NULL;
/*
// detect top-level model
RetValue = Abc_LibFindTopLevelModels( pDesign );
pNtk = Vec_PtrEntry( pDesign->vTops, 0 );
if ( RetValue > 1 )
printf( "Warning: The design has %d root-level modules. The first one (%s) will be used.\n",
Vec_PtrSize(pDesign->vTops), pNtk->pName );
// extract the master network
pNtk = Vec_PtrEntryLast( pDesign->vModules );
pNtk->pDesign = pDesign;
pDesign->pManFunc = NULL;
......@@ -67,35 +74,11 @@ Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck )
}
else
{
// bring the root model to the beginning
for ( i = Vec_PtrSize(pDesign->vModules) - 2; i >= 0; i-- )
Vec_PtrWriteEntry(pDesign->vModules, i+1, Vec_PtrEntry(pDesign->vModules, i) );
Vec_PtrWriteEntry(pDesign->vModules, 0, pNtk );
// check that there is no cyclic dependency
Abc_NtkIsAcyclicHierarchy( pNtk );
}
*/
// extract the master network
pNtk = Vec_PtrEntry( pDesign->vModules, 0 );
pNtk->pDesign = pDesign;
pDesign->pManFunc = NULL;
//Io_WriteVerilog( pNtk, "_temp.v" );
// verify the design for cyclic dependence
assert( Vec_PtrSize(pDesign->vModules) > 0 );
if ( Vec_PtrSize(pDesign->vModules) == 1 )
{
// printf( "Warning: The design is not hierarchical.\n" );
Abc_LibFree( pDesign, pNtk );
pNtk->pDesign = NULL;
pNtk->pSpec = Extra_UtilStrsav( pFileName );
}
else
{
// check that there is no cyclic dependency
Abc_NtkIsAcyclicHierarchy( pNtk );
}
return pNtk;
}
......
......@@ -225,7 +225,7 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName )
// write the buffer
fwrite( pBuffer, 1, Pos, pFile );
free( pBuffer );
/*
// write the symbol table
// write PIs
Abc_NtkForEachPi( pNtk, pObj, i )
......@@ -236,7 +236,7 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName )
// write POs
Abc_NtkForEachPo( pNtk, pObj, i )
fprintf( pFile, "o%d %s\n", i, Abc_ObjName(pObj) );
*/
// write the comment
fprintf( pFile, "c\n" );
fprintf( pFile, "%s\n", pNtk->pName );
......
......@@ -56,7 +56,7 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
Abc_Ntk_t * pNtkTemp;
// derive the netlist
pNtkTemp = Abc_NtkToNetlist(pNtk,0);
pNtkTemp = Abc_NtkToNetlist(pNtk);
if ( pNtkTemp == NULL )
{
fprintf( stdout, "Writing BLIF has failed.\n" );
......@@ -80,6 +80,8 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
FILE * pFile;
Abc_Ntk_t * pNtkTemp;
int i;
assert( Abc_NtkIsNetlist(pNtk) );
// start writing the file
pFile = fopen( FileName, "w" );
......@@ -96,18 +98,6 @@ void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
// write the hierarchy if present
if ( Abc_NtkBlackboxNum(pNtk) > 0 )
{
Abc_Ntk_t * pNtkTemp;
int i;
/*
Abc_Obj_t * pObj;
Abc_NtkForEachBlackbox( pNtk, pObj, i )
{
pNtkTemp = pObj->pData;
assert( pNtkTemp != NULL && Abc_NtkHasBlackbox(pNtkTemp) );
fprintf( pFile, "\n\n" );
Io_NtkWrite( pFile, pNtkTemp, fWriteLatches );
}
*/
Vec_PtrForEachEntry( pNtk->pDesign->vModules, pNtkTemp, i )
{
if ( pNtkTemp == pNtk )
......
......@@ -26,7 +26,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk );
......@@ -52,49 +52,34 @@ static void Io_NtkWriteBlifMvValues( FILE * pFile, Abc_Obj_t * pNode );
SeeAlso []
***********************************************************************/
void Io_WriteBlifMvDesign( Abc_Lib_t * pLib, char * FileName )
void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName )
{
FILE * pFile;
Abc_Ntk_t * pNtk;
Abc_Ntk_t * pNtkTemp;
int i;
assert( Abc_NtkIsNetlist(pNtk) );
assert( Abc_NtkHasBlifMv(pNtk) );
// start writing the file
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteBlifMvDesign(): Cannot open the output file.\n" );
fprintf( stdout, "Io_WriteBlifMv(): Cannot open the output file.\n" );
return;
}
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pLib->pName, Extra_TimeStamp() );
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
// write the master network
Vec_PtrForEachEntry( pLib->vModules, pNtk, i )
Io_NtkWriteBlifMv( pFile, pNtk );
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Write the network into a BLIF file with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteBlifMvNetlist( Abc_Ntk_t * pNtk, char * FileName )
{
FILE * pFile;
// start writing the file
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
// write the remaining networks
if ( pNtk->pDesign )
{
fprintf( stdout, "Io_WriteMvNetlist(): Cannot open the output file.\n" );
return;
Vec_PtrForEachEntry( pNtk->pDesign->vModules, pNtkTemp, i )
{
if ( pNtkTemp == pNtk )
continue;
fprintf( pFile, "\n\n" );
Io_NtkWriteBlifMv( pFile, pNtkTemp );
}
}
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
// write the master network
Io_NtkWriteBlifMv( pFile, pNtk );
fclose( pFile );
}
......@@ -185,7 +170,7 @@ void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk )
Io_NtkWriteBlifMvLatch( pFile, pLatch );
fprintf( pFile, "\n" );
}
/*
// write the subcircuits
assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
if ( Abc_NtkBlackboxNum(pNtk) > 0 )
......@@ -195,6 +180,18 @@ void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk )
Io_NtkWriteBlifMvSubckt( pFile, pNode );
fprintf( pFile, "\n" );
}
*/
if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
{
fprintf( pFile, "\n" );
Abc_NtkForEachBox( pNtk, pNode, i )
{
if ( Abc_ObjIsLatch(pNode) )
continue;
Io_NtkWriteBlifMvSubckt( pFile, pNode );
}
fprintf( pFile, "\n" );
}
// write each internal node
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
......@@ -414,26 +411,32 @@ void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode )
Abc_Obj_t * pFanin;
char * pCur;
int nValues, iFanin, i;
fprintf( pFile, "\n" );
// write .mv directives for the fanins
pCur = Abc_ObjData(pNode);
fprintf( pFile, "\n" );
Abc_ObjForEachFanin( pNode, pFanin, i )
{
nValues = atoi(pCur);
// nValues = atoi(pCur);
nValues = Abc_ObjMvVarNum( pFanin );
if ( nValues > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pFanin), nValues );
while ( *pCur++ != ' ' );
// while ( *pCur++ != ' ' );
}
// write .mv directives for the node
nValues = atoi(pCur);
// nValues = atoi(pCur);
nValues = Abc_ObjMvVarNum( Abc_ObjFanout0(pNode) );
if ( nValues > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), nValues );
while ( *pCur++ != '\n' );
// while ( *pCur++ != '\n' );
// write the .names line
fprintf( pFile, ".table" );
Io_NtkWriteBlifMvNodeFanins( pFile, pNode );
fprintf( pFile, "\n" );
// write the cubes
pCur = Abc_ObjData(pNode);
if ( *pCur == 'd' )
{
fprintf( pFile, ".default " );
......
......@@ -277,6 +277,8 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
{
if ( (int)pNode->Level != Level )
continue;
if ( Abc_ObjFaninNum(pNode) == 0 )
continue;
// fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id );
if ( Abc_NtkIsStrash(pNtk) )
pSopString = "";
......@@ -313,7 +315,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
// check if the costant node is present
if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
{
fprintf( pFile, " Node%d [label = \"Const1\"", pNode->Id );
fprintf( pFile, " Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) );
fprintf( pFile, ", shape = ellipse" );
if ( pNode->fMarkB )
fprintf( pFile, ", style = filled" );
......
......@@ -56,6 +56,7 @@ struct Ver_Man_t_
ProgressBar * pProgress;
// current design
Abc_Lib_t * pDesign;
st_table * tName2Suffix;
// error handling
FILE * Output;
int fTopLevel;
......@@ -67,6 +68,7 @@ struct Ver_Man_t_
Vec_Int_t * vStackOp;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......
......@@ -120,7 +120,7 @@ void * Ver_FormulaParser( char * pFormula, void * pMan, Vec_Ptr_t * vNames, Vec_
case '\r':
case '\n':
continue;
/*
// treat Constant 0 as a variable
case VER_PARSE_SYM_CONST0:
Vec_PtrPush( vStackFn, Hop_ManConst0(pMan) ); // Cudd_Ref( Hop_ManConst0(pMan) );
......@@ -144,7 +144,7 @@ void * Ver_FormulaParser( char * pFormula, void * pMan, Vec_Ptr_t * vNames, Vec_
}
Flag = VER_PARSE_FLAG_VAR;
break;
*/
case VER_PARSE_SYM_NEGBEF1:
case VER_PARSE_SYM_NEGBEF2:
if ( Flag == VER_PARSE_FLAG_VAR )
......
SRC += src/bdd/cas/casCore.c \
src/bdd/cas/casDec
src/bdd/cas/casDec.c
......@@ -41,54 +41,98 @@
***********************************************************************/
int If_ManPerformMapping( If_Man_t * p )
{
If_Obj_t * pObj;
int clkTotal = clock();
int RetValue, i;
p->pPars->fAreaOnly = p->pPars->fArea; // temporary
// create the CI cutsets
If_ManSetupCiCutSets( p );
// allocate memory for other cutsets
If_ManSetupSetAll( p );
// try sequential mapping
if ( p->pPars->fSeqMap )
{
int RetValue;
// printf( "Currently sequential mapping is not performed.\n" );
RetValue = If_ManPerformMappingSeq( p );
if ( p->pPars->fVerbose )
{
PRT( "Total time", clock() - clkTotal );
}
return RetValue;
// return 1;
}
// set arrival times and trivial cuts at const 1 and PIs
If_ManConst1(p)->Cuts[0].Delay = 0.0;
If_ManForEachCi( p, pObj, i )
pObj->Cuts[0].Delay = p->pPars->pTimesArr[i];
// set the fanout estimates of the PIs
return If_ManPerformMappingComb( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_ManPerformMappingComb( If_Man_t * p )
{
If_Obj_t * pObj;
int clkTotal = clock();
int i;
// set arrival times and fanout estimates
If_ManForEachCi( p, pObj, i )
{
If_ObjSetArrTime( pObj, p->pPars->pTimesArr[i] );
pObj->EstRefs = (float)1.0;
}
// delay oriented mapping
if ( p->pPars->fPreprocess && !p->pPars->fArea && p->pPars->nCutsMax >= 4 )
If_ManPerformMappingPreprocess( p );
else
if ( p->pPars->fPreprocess && !p->pPars->fArea )
{
// map for delay
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 1, "Delay" );
// map for delay second option
p->pPars->fFancy = 1;
If_ManResetOriginalRefs( p );
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 1, "Delay-2" );
p->pPars->fFancy = 0;
// map for area
p->pPars->fArea = 1;
If_ManResetOriginalRefs( p );
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 1, "Area" );
p->pPars->fArea = 0;
}
else
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0, "Delay" );
// try to improve area by expanding and reducing the cuts
if ( p->pPars->fExpRed && !p->pPars->fTruth )
If_ManImproveMapping( p );
// area flow oriented mapping
for ( i = 0; i < p->pPars->nFlowIters; i++ )
{
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 1, 1, "Flow" );
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 1, 0, "Flow" );
if ( p->pPars->fExpRed && !p->pPars->fTruth )
If_ManImproveMapping( p );
}
// area oriented mapping
for ( i = 0; i < p->pPars->nAreaIters; i++ )
{
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2, 1, "Area" );
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2, 0, "Area" );
if ( p->pPars->fExpRed && !p->pPars->fTruth )
If_ManImproveMapping( p );
}
if ( p->pPars->fVerbose )
{
// printf( "Total memory = %7.2f Mb. Peak cut memory = %7.2f Mb. ",
// 1.0 * (p->nObjBytes + 2*sizeof(void *)) * If_ManObjNum(p) / (1<<20),
// 1.0 * p->nSetBytes * Mem_FixedReadMaxEntriesUsed(p->pMemSet) / (1<<20) );
PRT( "Total time", clock() - clkTotal );
}
// printf( "Cross cut memory = %d.\n", Mem_FixedReadMaxEntriesUsed(p->pMemSet) );
return 1;
}
......
......@@ -87,13 +87,14 @@ static inline int If_CutCheckEquality( If_Cut_t * pDom, If_Cut_t * pCut )
SeeAlso []
***********************************************************************/
int If_CutFilter( If_Man_t * p, If_Cut_t * pCut )
int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut )
{
If_Cut_t * pTemp;
int i;
for ( i = 0; i < p->nCuts; i++ )
int i, k;
assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
for ( i = 0; i < pCutSet->nCuts; i++ )
{
pTemp = p->ppCuts[i];
pTemp = pCutSet->ppCuts[i];
if ( pTemp->nLeaves > pCut->nLeaves )
{
// do not fiter the first cut
......@@ -105,10 +106,15 @@ int If_CutFilter( If_Man_t * p, If_Cut_t * pCut )
// check containment seriously
if ( If_CutCheckDominance( pCut, pTemp ) )
{
// removed contained cut
p->ppCuts[i] = p->ppCuts[p->nCuts-1];
p->ppCuts[p->nCuts-1] = pTemp;
p->nCuts--;
// p->ppCuts[i] = p->ppCuts[p->nCuts-1];
// p->ppCuts[p->nCuts-1] = pTemp;
// p->nCuts--;
// i--;
// remove contained cut
for ( k = i; k < pCutSet->nCuts; k++ )
pCutSet->ppCuts[k] = pCutSet->ppCuts[k+1];
pCutSet->ppCuts[pCutSet->nCuts] = pTemp;
pCutSet->nCuts--;
i--;
}
}
......@@ -290,6 +296,7 @@ int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
if ( !If_CutMergeOrdered( pCut0, pCut1, pCut ) )
return 0;
}
pCut->uSign = pCut0->uSign | pCut1->uSign;
return 1;
}
......@@ -400,6 +407,7 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
***********************************************************************/
void If_ManSortCuts( If_Man_t * p, int Mode )
{
/*
// sort the cuts
if ( Mode || p->pPars->fArea ) // area
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea );
......@@ -407,6 +415,115 @@ void If_ManSortCuts( If_Man_t * p, int Mode )
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelayOld );
else
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay );
*/
}
/**Function*************************************************************
Synopsis [Comparison function for two cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1 )
{
if ( p->SortMode == 1 ) // area
{
if ( pC0->Area < pC1->Area - 0.0001 )
return -1;
if ( pC0->Area > pC1->Area + 0.0001 )
return 1;
if ( pC0->AveRefs > pC1->AveRefs )
return -1;
if ( pC0->AveRefs < pC1->AveRefs )
return 1;
if ( pC0->nLeaves < pC1->nLeaves )
return -1;
if ( pC0->nLeaves > pC1->nLeaves )
return 1;
if ( pC0->Delay < pC1->Delay - 0.0001 )
return -1;
if ( pC0->Delay > pC1->Delay + 0.0001 )
return 1;
return 0;
}
if ( p->SortMode == 0 ) // delay
{
if ( pC0->Delay < pC1->Delay - 0.0001 )
return -1;
if ( pC0->Delay > pC1->Delay + 0.0001 )
return 1;
if ( pC0->nLeaves < pC1->nLeaves )
return -1;
if ( pC0->nLeaves > pC1->nLeaves )
return 1;
if ( pC0->Area < pC1->Area - 0.0001 )
return -1;
if ( pC0->Area > pC1->Area + 0.0001 )
return 1;
return 0;
}
assert( p->SortMode == 2 ); // delay old
if ( pC0->Delay < pC1->Delay - 0.0001 )
return -1;
if ( pC0->Delay > pC1->Delay + 0.0001 )
return 1;
if ( pC0->Area < pC1->Area - 0.0001 )
return -1;
if ( pC0->Area > pC1->Area + 0.0001 )
return 1;
if ( pC0->nLeaves < pC1->nLeaves )
return -1;
if ( pC0->nLeaves > pC1->nLeaves )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Performs incremental sorting of cuts.]
Description [Currently only the trivial sorting is implemented.]
SideEffects []
SeeAlso []
***********************************************************************/
void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
{
// int Counter = 0;
int i;
// the new cut is the last one
assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
assert( pCutSet->nCuts <= pCutSet->nCutsMax );
// cut structure is empty
if ( pCutSet->nCuts == 0 )
{
pCutSet->nCuts++;
return;
}
// the cut will be added - find its place
for ( i = pCutSet->nCuts-1; i >= 0; i-- )
{
// Counter++;
if ( If_ManSortCompare( p, pCutSet->ppCuts[i], pCut ) <= 0 )
break;
pCutSet->ppCuts[i+1] = pCutSet->ppCuts[i];
pCutSet->ppCuts[i] = pCut;
}
// printf( "%d ", Counter );
// update the number of cuts
if ( pCutSet->nCuts < pCutSet->nCutsMax )
pCutSet->nCuts++;
}
/**Function*************************************************************
......@@ -635,7 +752,7 @@ void If_CutLift( If_Cut_t * pCut )
SeeAlso []
***********************************************************************/
void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
void If_CutCopy( If_Man_t * p, If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
{
int * pLeaves;
char * pPerm;
......@@ -645,17 +762,11 @@ void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
pPerm = pCutDest->pPerm;
pTruth = pCutDest->pTruth;
// copy the cut info
*pCutDest = *pCutSrc;
memcpy( pCutDest, pCutSrc, p->nCutBytes );
// restore the arrays
pCutDest->pLeaves = pLeaves;
pCutDest->pPerm = pPerm;
pCutDest->pTruth = pTruth;
// copy the array data
memcpy( pCutDest->pLeaves, pCutSrc->pLeaves, sizeof(int) * pCutSrc->nLeaves );
if ( pCutSrc->pPerm )
memcpy( pCutDest->pPerm, pCutSrc->pPerm, sizeof(unsigned) * If_CutPermWords(pCutSrc->nLimit) );
if ( pCutSrc->pTruth )
memcpy( pCutDest->pTruth, pCutSrc->pTruth, sizeof(unsigned) * If_CutTruthWords(pCutSrc->nLimit) );
}
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [ifPrepro.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Selects the starting mapping.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [$Id: ifPrepro.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
***********************************************************************/
#include "if.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void If_ManPerformMappingMoveBestCut( If_Man_t * p, int iPosNew, int iPosOld );
static void If_ManPerformMappingAdjust( If_Man_t * p, int nCuts );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Merges the results of delay, relaxed delay and area-based mapping.]
Description [Delay target may be different from minimum delay!!!]
SideEffects []
SeeAlso []
***********************************************************************/
void If_ManPerformMappingPreprocess( If_Man_t * p )
{
float delayArea, delayDelay, delayPure;
int clk = clock();
assert( p->pPars->nCutsMax >= 4 );
// perform min-area mapping and move the cut to the end
p->pPars->fArea = 1;
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0, "Start delay" );
p->pPars->fArea = 0;
delayArea = If_ManDelayMax( p, 0 );
if ( p->pPars->DelayTarget != -1 && delayArea < p->pPars->DelayTarget - p->fEpsilon )
delayArea = p->pPars->DelayTarget;
If_ManPerformMappingMoveBestCut( p, p->pPars->nCutsMax - 1, 1 );
// perfrom min-delay mapping and move the cut to the end
p->pPars->fFancy = 1;
If_ManPerformMappingRound( p, p->pPars->nCutsMax - 1, 0, 0, "Start delay-2" );
p->pPars->fFancy = 0;
delayDelay = If_ManDelayMax( p, 0 );
if ( p->pPars->DelayTarget != -1 && delayDelay < p->pPars->DelayTarget - p->fEpsilon )
delayDelay = p->pPars->DelayTarget;
If_ManPerformMappingMoveBestCut( p, p->pPars->nCutsMax - 2, 1 );
// perform min-delay mapping
If_ManPerformMappingRound( p, p->pPars->nCutsMax - 2, 0, 0, "Start flow" );
delayPure = If_ManDelayMax( p, 0 );
if ( p->pPars->DelayTarget != -1 && delayPure < p->pPars->DelayTarget - p->fEpsilon )
delayPure = p->pPars->DelayTarget;
// decide what to do
if ( delayPure < delayDelay - p->fEpsilon && delayPure < delayArea - p->fEpsilon )
{
// copy the remaining two cuts
if ( p->pPars->nCutsMax > 4 )
{
If_ManPerformMappingMoveBestCut( p, 2, p->pPars->nCutsMax - 2 );
If_ManPerformMappingMoveBestCut( p, 3, p->pPars->nCutsMax - 1 );
}
If_ManComputeRequired( p, 1 );
If_ManPerformMappingAdjust( p, 4 );
}
else if ( delayDelay < delayArea - p->fEpsilon )
{
If_ManPerformMappingMoveBestCut( p, 1, p->pPars->nCutsMax - 2 );
If_ManPerformMappingMoveBestCut( p, 2, p->pPars->nCutsMax - 1 );
If_ManComputeRequired( p, 1 );
If_ManPerformMappingAdjust( p, 3 );
}
else
{
If_ManPerformMappingMoveBestCut( p, 1, p->pPars->nCutsMax - 1 );
If_ManComputeRequired( p, 1 );
If_ManPerformMappingAdjust( p, 2 );
}
If_ManComputeRequired( p, 1 );
if ( p->pPars->fVerbose )
{
printf( "S: Del = %6.2f. Area = %8.2f. Nets = %6d. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
p->RequiredGlo, p->AreaGlo, p->nNets, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk );
}
}
/**Function*************************************************************
Synopsis [Moves the best cut to the given position.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_ManPerformMappingMoveBestCut( If_Man_t * p, int iPosNew, int iPosOld )
{
If_Obj_t * pObj;
int i;
assert( iPosOld != iPosNew );
assert( iPosOld > 0 && iPosOld < p->pPars->nCutsMax );
assert( iPosNew > 0 && iPosNew < p->pPars->nCutsMax );
If_ManForEachNode( p, pObj, i )
If_CutCopy( pObj->Cuts + iPosNew, pObj->Cuts + iPosOld );
}
/**Function*************************************************************
Synopsis [Adjusts mapping for the given cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_ManPerformMappingAdjust( If_Man_t * p, int nCuts )
{
If_Cut_t * pCut, * pCutBest;
If_Obj_t * pObj;
int i, c;
assert( nCuts >= 2 && nCuts <= 4 );
If_ManForEachNode( p, pObj, i )
{
pCutBest = NULL;
for ( c = 1; c < nCuts; c++ )
{
pCut = pObj->Cuts + c;
pCut->Delay = If_CutDelay( p, pCut );
pCut->Area = If_CutFlow( p, pCut );
assert( pCutBest || pCut->Delay < pObj->Required + p->fEpsilon );
if ( pCutBest == NULL ||
(pCut->Delay < pObj->Required + p->fEpsilon &&
pCut->Area < pCutBest->Area - p->fEpsilon) )
pCutBest = pCut;
}
assert( pCutBest != NULL );
// check if we need to move
if ( pCutBest != pObj->Cuts + 1 )
If_CutCopy( pObj->Cuts + 1, pCutBest );
// set the number of cuts
pObj->nCuts = 2;
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -52,11 +52,11 @@ void If_ManImproveMapping( If_Man_t * p )
clk = clock();
If_ManImproveExpand( p, p->pPars->nLutSize );
If_ManComputeRequired( p, 0 );
If_ManComputeRequired( p );
if ( p->pPars->fVerbose )
{
printf( "E: Del = %6.2f. Area = %8.2f. Nets = %6d. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
p->RequiredGlo, p->AreaGlo, p->nNets, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
printf( "E: Del = %6.2f. Ar = %8.2f. Net = %6d. Cut = %8d. ",
p->RequiredGlo, p->AreaGlo, p->nNets, p->nCutsMerged );
PRT( "T", clock() - clk );
}
......@@ -488,6 +488,7 @@ void If_ManImproveNodeFaninCompact( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
***********************************************************************/
void If_ManImproveNodeReduce( If_Man_t * p, If_Obj_t * pObj, int nLimit )
{
/*
If_Cut_t * pCut, * pCut0, * pCut1, * pCutR;
If_Obj_t * pFanin0, * pFanin1;
float AreaBef, AreaAft;
......@@ -537,13 +538,14 @@ void If_ManImproveNodeReduce( If_Man_t * p, If_Obj_t * pObj, int nLimit )
AreaAft = If_CutAreaDerefed( p, pCutR, IF_INFINITY );
// update the best cut
if ( AreaAft < AreaBef - p->fEpsilon && pCutR->Delay < pObj->Required + p->fEpsilon )
If_CutCopy( pCut, pCutR );
If_CutCopy( p, pCut, pCutR );
}
// recompute the delay of the best cut
pCut->Delay = If_CutDelay( p, pCut );
// ref the cut if the node is refed
if ( pObj->nRefs > 0 )
If_CutRef( p, pCut, IF_INFINITY );
*/
}
/**Function*************************************************************
......@@ -562,13 +564,7 @@ void If_ManImproveReduce( If_Man_t * p, int nLimit )
If_Obj_t * pObj;
int i;
If_ManForEachNode( p, pObj, i )
{
if ( 278 == i )
{
int s = 0;
}
If_ManImproveNodeReduce( p, pObj, nLimit );
}
}
////////////////////////////////////////////////////////////////////////
......
......@@ -61,11 +61,9 @@ void If_ManCleanNodeCopy( If_Man_t * p )
void If_ManCleanCutData( If_Man_t * p )
{
If_Obj_t * pObj;
If_Cut_t * pCut;
int i, k;
int i;
If_ManForEachObj( p, pObj, i )
If_ObjForEachCut( pObj, pCut, k )
If_CutSetData( pCut, NULL );
If_CutSetData( If_ObjCutBest(pObj), NULL );
}
/**Function*************************************************************
......@@ -113,20 +111,20 @@ float If_ManDelayMax( If_Man_t * p, int fSeq )
{
assert( p->pPars->nLatches > 0 );
If_ManForEachPo( p, pObj, i )
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) )
DelayBest = If_ObjArrTime(If_ObjFanin0(pObj));
}
else if ( p->pPars->fLatchPaths )
{
If_ManForEachLatch( p, pObj, i )
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
If_ManForEachLatchInput( p, pObj, i )
if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) )
DelayBest = If_ObjArrTime(If_ObjFanin0(pObj));
}
else
{
If_ManForEachCo( p, pObj, i )
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) )
DelayBest = If_ObjArrTime(If_ObjFanin0(pObj));
}
return DelayBest;
}
......@@ -142,13 +140,30 @@ float If_ManDelayMax( If_Man_t * p, int fSeq )
SeeAlso []
***********************************************************************/
void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
void If_ManComputeRequired( If_Man_t * p )
{
If_Obj_t * pObj;
int i;
// compute area, clean required times, collect nodes used in the mapping
p->nNets = 0;
p->AreaGlo = If_ManScanMapping( p );
// consider the case when the required times are given
if ( p->pPars->pTimesReq )
{
assert( !p->pPars->fAreaOnly );
// make sure that the required time hold
If_ManForEachCo( p, pObj, i )
{
if ( If_ObjArrTime(If_ObjFanin0(pObj)) > p->pPars->pTimesReq[i] + p->fEpsilon )
printf( "Required times are violated for output %d (arr = %d; req = %d).\n",
i, (int)If_ObjArrTime(If_ObjFanin0(pObj)), (int)p->pPars->pTimesReq[i] );
If_ObjFanin0(pObj)->Required = p->pPars->pTimesReq[i];
}
}
else
{
// get the global required times
p->RequiredGlo = If_ManDelayMax( p, 0 );
// update the required times according to the target
......@@ -156,20 +171,29 @@ void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
{
if ( p->RequiredGlo > p->pPars->DelayTarget + p->fEpsilon )
{
if ( fFirstTime )
if ( p->fNextRound == 0 )
{
p->fNextRound = 1;
printf( "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->pPars->DelayTarget );
}
}
else if ( p->RequiredGlo < p->pPars->DelayTarget - p->fEpsilon )
{
if ( fFirstTime )
if ( p->fNextRound == 0 )
{
p->fNextRound = 1;
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->RequiredGlo, p->pPars->DelayTarget );
}
p->RequiredGlo = p->pPars->DelayTarget;
}
}
// do not propagate required times if area minimization is requested
if ( p->pPars->fAreaOnly )
return;
// set the required times for the POs
if ( p->pPars->fLatchPaths )
{
If_ManForEachLatch( p, pObj, i )
If_ManForEachLatchInput( p, pObj, i )
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
}
else
......@@ -177,6 +201,7 @@ void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
If_ManForEachCo( p, pObj, i )
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
}
}
// go through the nodes in the reverse topological order
Vec_PtrForEachEntry( p->vMapped, pObj, i )
If_CutPropagateRequired( p, If_ObjCutBest(pObj), pObj->Required );
......@@ -236,6 +261,7 @@ float If_ManScanMapping( If_Man_t * p )
If_ManForEachObj( p, pObj, i )
{
pObj->Required = IF_FLOAT_LARGE;
pObj->nVisits = pObj->nVisitsCopy;
pObj->nRefs = 0;
}
// allocate place to store the nodes
......@@ -318,6 +344,83 @@ float If_ManScanMappingSeq( If_Man_t * p )
return aArea;
}
/**Function*************************************************************
Synopsis [Computes area, references, and nodes used in the mapping.]
Description [Collects the nodes in reverse topological order in array
p->vMapping.]
SideEffects []
SeeAlso []
***********************************************************************/
void If_ManResetOriginalRefs( If_Man_t * p )
{
If_Obj_t * pObj;
int i;
If_ManForEachObj( p, pObj, i )
pObj->nRefs = 0;
If_ManForEachObj( p, pObj, i )
{
if ( If_ObjIsAnd(pObj) )
{
pObj->pFanin0->nRefs++;
pObj->pFanin1->nRefs++;
}
else if ( If_ObjIsCo(pObj) )
pObj->pFanin0->nRefs++;
}
}
/**Function*************************************************************
Synopsis [Computes cross-cut of the circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_ManCrossCut( If_Man_t * p )
{
If_Obj_t * pObj, * pFanin;
int i, nCutSize = 0, nCutSizeMax = 0;
If_ManForEachObj( p, pObj, i )
{
if ( !If_ObjIsAnd(pObj) )
continue;
// consider the node
if ( nCutSizeMax < ++nCutSize )
nCutSizeMax = nCutSize;
if ( pObj->nVisits == 0 )
nCutSize--;
// consider the fanins
pFanin = If_ObjFanin0(pObj);
if ( !If_ObjIsCi(pFanin) && --pFanin->nVisits == 0 )
nCutSize--;
pFanin = If_ObjFanin1(pObj);
if ( !If_ObjIsCi(pFanin) && --pFanin->nVisits == 0 )
nCutSize--;
// consider the choice class
if ( pObj->fRepr )
for ( pFanin = pObj; pFanin; pFanin = pFanin->pEquiv )
if ( !If_ObjIsCi(pFanin) && --pFanin->nVisits == 0 )
nCutSize--;
}
If_ManForEachObj( p, pObj, i )
{
assert( If_ObjIsCi(pObj) || pObj->fVisit == 0 );
pObj->nVisits = pObj->nVisitsCopy;
}
assert( nCutSize == 0 );
// printf( "Max cross cut size = %6d.\n", nCutSizeMax );
return nCutSizeMax;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -2,7 +2,6 @@ SRC += src/map/if/ifCore.c \
src/map/if/ifCut.c \
src/map/if/ifMan.c \
src/map/if/ifMap.c \
src/map/if/ifPrepro.c \
src/map/if/ifReduce.c \
src/map/if/ifSeq.c \
src/map/if/ifTime.c \
......
......@@ -49,7 +49,7 @@ extern int isspace( int c ); // to silence the warning in VS
SeeAlso []
***********************************************************************/
Mio_Library_t * Mio_LibraryRead( Abc_Frame_t * pAbc, char * FileName, char * ExcludeFile, int fVerbose )
Mio_Library_t * Mio_LibraryRead( void * pAbc, char * FileName, char * ExcludeFile, int fVerbose )
{
Mio_Library_t * pLib;
int num;
......@@ -486,7 +486,7 @@ void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
SeeAlso []
***********************************************************************/
int Mio_LibraryReadExclude( Abc_Frame_t * pAbc, char * ExcludeFile, st_table * tExcludeGate )
int Mio_LibraryReadExclude( void * pAbc, char * ExcludeFile, st_table * tExcludeGate )
{
int nDel = 0;
FILE *pEx;
......
......@@ -349,6 +349,7 @@ extern char * Extra_MmFixedEntryFetch( Extra_MmFixed_t * p );
extern void Extra_MmFixedEntryRecycle( Extra_MmFixed_t * p, char * pEntry );
extern void Extra_MmFixedRestart( Extra_MmFixed_t * p );
extern int Extra_MmFixedReadMemUsage( Extra_MmFixed_t * p );
extern int Extra_MmFixedReadMaxEntriesUsed( Extra_MmFixed_t * p );
// flexible-size-block memory manager
extern Extra_MmFlex_t * Extra_MmFlexStart();
extern void Extra_MmFlexStop( Extra_MmFlex_t * p );
......
......@@ -310,6 +310,21 @@ int Extra_MmFixedReadMemUsage( Extra_MmFixed_t * p )
return p->nMemoryAlloc;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Extra_MmFixedReadMaxEntriesUsed( Extra_MmFixed_t * p )
{
return p->nEntriesMax;
}
/**Function*************************************************************
......@@ -326,7 +341,7 @@ int Extra_MmFixedReadMemUsage( Extra_MmFixed_t * p )
Extra_MmFlex_t * Extra_MmFlexStart()
{
Extra_MmFlex_t * p;
//printf( "allocing flex\n" );
p = ALLOC( Extra_MmFlex_t, 1 );
memset( p, 0, sizeof(Extra_MmFlex_t) );
......@@ -379,6 +394,7 @@ void Extra_MmFlexStop( Extra_MmFlex_t * p )
int i;
if ( p == NULL )
return;
//printf( "deleting flex\n" );
for ( i = 0; i < p->nChunks; i++ )
free( p->pChunks[i] );
free( p->pChunks );
......
......@@ -403,6 +403,59 @@ static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_StrPrintNum( Vec_Str_t * p, int Num )
{
int i, nDigits;
if ( Num < 0 )
{
Vec_StrPush( p, '-' );
Num = -Num;
}
if ( Num < 10 )
{
Vec_StrPush( p, (char)('0' + Num) );
return;
}
nDigits = Extra_Base10Log( Num );
Vec_StrGrow( p, p->nSize + nDigits );
for ( i = nDigits - 1; i >= 0; i-- )
{
Vec_StrWriteEntry( p, p->nSize + i, (char)('0' + Num % 10) );
Num /= 10;
}
assert( Num == 0 );
p->nSize += nDigits;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_StrPrintStr( Vec_Str_t * p, char * pStr )
{
int i, Length = strlen(pStr);
for ( i = 0; i < Length; i++ )
Vec_StrPush( p, pStr[i] );
}
/**Function*************************************************************
Synopsis [Appends the string to the char vector.]
Description []
......
......@@ -3,7 +3,7 @@
#ifndef LIBHMETIS_H_
#define LIBHMETIS_H_
void HMETIS_PartRecursive(int nvtxs,
static void HMETIS_PartRecursive(int nvtxs,
int nhedges,
int *vwgts,
int *eptr,
......@@ -13,10 +13,10 @@ void HMETIS_PartRecursive(int nvtxs,
int nbfactor,
int *options,
int *part,
int *edgecnt );
int *edgecnt ) {} //;
void HMETIS_PartKway(int nvtxs,
static void HMETIS_PartKway(int nvtxs,
int nhedges,
int *vwgts,
int *eptr,
......@@ -26,6 +26,6 @@ void HMETIS_PartKway(int nvtxs,
int nbfactor,
int *options,
int *part,
int *edgecnt );
int *edgecnt ) {} //;
#endif
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