Commit 2c7f6e39 by Alan Mishchenko

Version abc80330

parent 93c3f160
......@@ -19,7 +19,8 @@ MODULES := src/base/abc src/base/abci src/base/cmd \
src/aig/ivy src/aig/hop src/aig/rwt src/aig/deco \
src/aig/mem src/aig/dar src/aig/fra src/aig/cnf \
src/aig/csw src/aig/ioa src/aig/aig src/aig/kit \
src/aig/bdc src/aig/bar src/aig/ntl src/aig/tim
src/aig/bdc src/aig/bar src/aig/ntl src/aig/nwk src/aig/mfx \
src/aig/tim
default: $(PROG)
......
......@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/ntk" /I "src/aig/tim" /I "src/opt/mfs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
......@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/ntk" /I "src/aig/tim" /I "src/opt/mfs" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
......@@ -182,6 +182,10 @@ SOURCE=.\src\base\abci\abc.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcAbc8.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcAttach.c
# End Source File
# Begin Source File
......@@ -3002,10 +3006,6 @@ SOURCE=.\src\aig\aig\aigScl.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigSeq.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigShow.c
# End Source File
# Begin Source File
......@@ -3097,60 +3097,112 @@ SOURCE=.\src\aig\ntl\ntlTime.c
SOURCE=.\src\aig\ntl\ntlWriteBlif.c
# End Source File
# End Group
# Begin Group "ntk"
# Begin Group "tim"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\aig\tim\tim.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\tim\tim.h
# End Source File
# End Group
# Begin Group "nwk"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\aig\ntk\ntk.h
SOURCE=.\src\aig\nwk\nwk.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkBidec.c
SOURCE=.\src\aig\nwk\nwkBidec.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkCheck.c
SOURCE=.\src\aig\nwk\nwkCheck.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkDfs.c
SOURCE=.\src\aig\nwk\nwkDfs.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkFanio.c
SOURCE=.\src\aig\nwk\nwkFanio.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkMan.c
SOURCE=.\src\aig\nwk\nwkMan.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkMap.c
SOURCE=.\src\aig\nwk\nwkMap.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkObj.c
SOURCE=.\src\aig\nwk\nwkObj.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkTiming.c
SOURCE=.\src\aig\nwk\nwkSpeedup.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkUtil.c
SOURCE=.\src\aig\nwk\nwkStrash.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\nwk\nwkTiming.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\nwk\nwkUtil.c
# End Source File
# End Group
# Begin Group "tim"
# Begin Group "mfx"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\aig\tim\tim.c
SOURCE=.\src\aig\mfx\mfx.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\tim\tim.h
SOURCE=.\src\aig\mfx\mfxCore.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxDiv.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxInt.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxInter.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxMan.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxResub.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxSat.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxStrash.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\mfx\mfxWin.c
# End Source File
# End Group
# End Group
......
......@@ -471,6 +471,7 @@ extern void Aig_ManHaigRecord( Aig_Man_t * p );
/*=== aigMan.c ==========================================================*/
extern Aig_Man_t * Aig_ManStart( int nNodesMax );
extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p );
extern Aig_Obj_t * Aig_ManDup_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj );
extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered );
extern Aig_Man_t * Aig_ManDupWithoutPos( Aig_Man_t * p );
......
......@@ -102,6 +102,71 @@ Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p )
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG manager to have EXOR gates.]
Description [Assumes topological ordering of the nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjNew;
int i;
// create the new manager
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
pNew->fCatchExor = 1;
pNew->pName = Aig_UtilStrsav( p->pName );
pNew->nRegs = p->nRegs;
pNew->nAsserts = p->nAsserts;
if ( p->vFlopNums )
pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
// create the PIs
Aig_ManCleanData( p );
// duplicate internal nodes
Aig_ManForEachObj( p, pObj, i )
{
if ( Aig_ObjIsBuf(pObj) )
{
pObjNew = Aig_ObjChild0Copy(pObj);
}
else if ( Aig_ObjIsNode(pObj) )
{
pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
}
else if ( Aig_ObjIsPi(pObj) )
{
pObjNew = Aig_ObjCreatePi( pNew );
pObjNew->Level = pObj->Level;
}
else if ( Aig_ObjIsPo(pObj) )
{
pObjNew = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
}
else if ( Aig_ObjIsConst1(pObj) )
{
pObjNew = Aig_ManConst1(pNew);
}
else
assert( 0 );
Aig_Regular(pObjNew)->pHaig = pObj->pHaig;
pObj->pData = pObjNew;
}
Aig_ManCleanup( pNew );
// duplicate the timing manager
if ( p->pManTime )
pNew->pManTime = Tim_ManDup( p->pManTime, 0 );
// check the resulting network
if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDup(): The check has failed.\n" );
return pNew;
}
//#if 0
/**Function*************************************************************
......@@ -584,22 +649,24 @@ int Aig_ManHaigCounter( Aig_Man_t * pAig )
void Aig_ManPrintStats( Aig_Man_t * p )
{
int nChoices = Aig_ManCountChoices(p);
printf( "PI/PO = %5d/%5d ", Aig_ManPiNum(p), Aig_ManPoNum(p) );
printf( "A = %7d. ", Aig_ManAndNum(p) );
printf( "Eq = %7d. ", Aig_ManHaigCounter(p) );
if ( nChoices )
printf( "Ch = %5d. ", nChoices );
printf( "%-15s : ", p->pName );
printf( "pi = %5d ", Aig_ManPiNum(p) );
printf( "po = %5d ", Aig_ManPoNum(p) );
if ( Aig_ManRegNum(p) )
printf( "lat = %5d ", Aig_ManRegNum(p) );
printf( "and = %7d ", Aig_ManAndNum(p) );
// printf( "Eq = %7d ", Aig_ManHaigCounter(p) );
if ( Aig_ManExorNum(p) )
printf( "X = %5d. ", Aig_ManExorNum(p) );
printf( "xor = %5d ", Aig_ManExorNum(p) );
if ( nChoices )
printf( "ch = %5d ", nChoices );
if ( Aig_ManBufNum(p) )
printf( "B = %5d. ", Aig_ManBufNum(p) );
// printf( "Cre = %6d. ", p->nCreated );
// printf( "Del = %6d. ", p->nDeleted );
// printf( "Lev = %3d. ", Aig_ManCountLevels(p) );
printf( "Max = %7d. ", Aig_ManObjNumMax(p) );
printf( "Lev = %3d. ", Aig_ManLevels(p) );
if ( Aig_ManRegNum(p) )
printf( "Lat = %5d. ", Aig_ManRegNum(p) );
printf( "buf = %5d ", Aig_ManBufNum(p) );
// printf( "Cre = %6d ", p->nCreated );
// printf( "Del = %6d ", p->nDeleted );
// printf( "Lev = %3d ", Aig_ManCountLevels(p) );
// printf( "Max = %7d ", Aig_ManObjNumMax(p) );
printf( "lev = %3d", Aig_ManLevels(p) );
printf( "\n" );
fflush( stdout );
}
......
......@@ -80,6 +80,7 @@ extern void Dar_LibStart();
extern void Dar_LibStop();
/*=== darBalance.c ========================================================*/
extern Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel );
extern void Dar_BalancePrintStats( Aig_Man_t * p );
/*=== darCore.c ========================================================*/
extern void Dar_ManDefaultRwrParams( Dar_RwrPar_t * pPars );
extern int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars );
......@@ -93,6 +94,7 @@ extern Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbos
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose );
extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fVerbose );
extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose );
extern Aig_Man_t * Dar_ManBalanceXor( Aig_Man_t * pAig, int fExor, int fUpdateLevel, int fVerbose );
#ifdef __cplusplus
}
......
......@@ -88,13 +88,13 @@ Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbose )
pAig = Aig_ManDup( pTemp = pAig, 0 );
Aig_ManStop( pTemp );
if ( fVerbose ) Aig_ManPrintStats( pAig );
/*
// refactor
Dar_ManRefactor( pAig, pParsRef );
pAig = Aig_ManDup( pTemp = pAig, 0 );
Aig_ManStop( pTemp );
if ( fVerbose ) Aig_ManPrintStats( pAig );
*/
// balance
if ( fBalance )
{
......@@ -399,6 +399,35 @@ PRT( "Choicing time ", clock() - clk );
// return NULL;
}
/**Function*************************************************************
Synopsis [Reproduces script "compress2".]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Dar_ManBalanceXor( Aig_Man_t * pAig, int fExor, int fUpdateLevel, int fVerbose )
{
Aig_Man_t * pAigXor, * pRes;
if ( fExor )
{
pAigXor = Aig_ManDupExor( pAig );
if ( fVerbose )
Dar_BalancePrintStats( pAigXor );
pRes = Dar_ManBalance( pAigXor, fUpdateLevel );
Aig_ManStop( pAigXor );
}
else
{
pRes = Dar_ManBalance( pAig, fUpdateLevel );
}
return pRes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -258,7 +258,7 @@ static inline int Fra_ImpCreate( int Left, int Right )
/*=== fraCec.c ========================================================*/
extern int Fra_FraigSat( Aig_Man_t * pMan, sint64 nConfLimit, sint64 nInsLimit, int fVerbose );
extern int Fra_FraigCec( Aig_Man_t ** ppAig, int fVerbose );
extern int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int fVerbose );
extern int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nPartSize, int fVerbose );
/*=== fraClass.c ========================================================*/
extern int Fra_BmcNodeIsConst( Aig_Obj_t * pObj );
extern int Fra_BmcNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
......
......@@ -247,13 +247,13 @@ PRT( "Time", clock() - clk );
SeeAlso []
***********************************************************************/
int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int fVerbose )
int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nPartSize, int fVerbose )
{
Aig_Man_t * pAig;
Vec_Ptr_t * vParts;
int i, RetValue = 1, nOutputs;
// create partitions
vParts = Aig_ManMiterPartitioned( pMan1, pMan2, 100 );
vParts = Aig_ManMiterPartitioned( pMan1, pMan2, nPartSize );
// solve the partitions
nOutputs = -1;
Vec_PtrForEachEntry( vParts, pAig, i )
......@@ -295,6 +295,60 @@ int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int fVerbose
return RetValue;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int fPartition, int fVerbose )
{
//Abc_NtkDarCec( pNtk1, pNtk2, fPartition, fVerbose );
int RetValue, clkTotal = clock();
if ( Aig_ManPiNum(pMan1) != Aig_ManPiNum(pMan1) )
{
printf( "Abc_CommandAbc8Cec(): Miters have different number of PIs.\n" );
return 0;
}
if ( Aig_ManPoNum(pMan1) != Aig_ManPoNum(pMan1) )
{
printf( "Abc_CommandAbc8Cec(): Miters have different number of POs.\n" );
return 0;
}
assert( Aig_ManPiNum(pMan1) == Aig_ManPiNum(pMan1) );
assert( Aig_ManPoNum(pMan1) == Aig_ManPoNum(pMan1) );
if ( fPartition )
RetValue = Fra_FraigCecPartitioned( pMan1, pMan2, 100, fVerbose );
else
RetValue = Fra_FraigCecPartitioned( pMan1, pMan2, Aig_ManPoNum(pMan1), fVerbose );
// report the miter
if ( RetValue == 1 )
{
printf( "Networks are equivalent. " );
PRT( "Time", clock() - clkTotal );
}
else if ( RetValue == 0 )
{
printf( "Networks are NOT EQUIVALENT. " );
PRT( "Time", clock() - clkTotal );
}
else
{
printf( "Networks are UNDECIDED. " );
PRT( "Time", clock() - clkTotal );
}
fflush( stdout );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
/**CFile****************************************************************
FileName [mfx.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfx.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __MFX_H__
#define __MFX_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Mfx_Par_t_ Mfx_Par_t;
struct Mfx_Par_t_
{
// general parameters
int nWinTfoLevs; // the maximum fanout levels
int nFanoutsMax; // the maximum number of fanouts
int nDepthMax; // the maximum number of logic levels
int nDivMax; // the maximum number of divisors
int nWinSizeMax; // the maximum size of the window
int nGrowthLevel; // the maximum allowed growth in level
int nBTLimit; // the maximum number of conflicts in one SAT run
int fResub; // performs resubstitution
int fArea; // performs optimization for area
int fMoreEffort; // performs high-affort minimization
int fSwapEdge; // performs edge swapping
int fDelay; // performs optimization for delay
int fVerbose; // enable basic stats
int fVeryVerbose; // enable detailed stats
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== mfxCore.c ==========================================================*/
extern void Mfx_ParsDefault( Mfx_Par_t * pPars );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Core procedures of this package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_ParsDefault( Mfx_Par_t * pPars )
{
pPars->nWinTfoLevs = 2;
pPars->nFanoutsMax = 10;
pPars->nDepthMax = 20;
pPars->nDivMax = 250;
pPars->nWinSizeMax = 300;
pPars->nGrowthLevel = 0;
pPars->nBTLimit = 5000;
pPars->fResub = 1;
pPars->fArea = 0;
pPars->fMoreEffort = 0;
pPars->fSwapEdge = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_Resub( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
int clk;
p->nNodesTried++;
// prepare data structure for this node
Mfx_ManClean( p );
// compute window roots, window support, and window nodes
clk = clock();
p->vRoots = Mfx_ComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
p->vSupp = Nwk_ManSupportNodes( p->pNtk, (Nwk_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
p->vNodes = Nwk_ManDfsNodes( p->pNtk, (Nwk_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
p->timeWin += clock() - clk;
if ( p->pPars->nWinSizeMax && Vec_PtrSize(p->vNodes) > p->pPars->nWinSizeMax )
return 1;
// compute the divisors of the window
clk = clock();
// p->vDivs = Mfx_ComputeDivisors( p, pNode, Nwk_ObjRequired(pNode) - If_LutLibSlowestPinDelay(pNode->pMan->pLutLib) );
p->vDivs = Mfx_ComputeDivisors( p, pNode, AIG_INFINITY );
p->nTotalDivs += Vec_PtrSize(p->vDivs);
p->timeDiv += clock() - clk;
// construct AIG for the window
clk = clock();
p->pAigWin = Mfx_ConstructAig( p, pNode );
p->timeAig += clock() - clk;
// translate it into CNF
clk = clock();
p->pCnf = Cnf_DeriveSimple( p->pAigWin, 1 + Vec_PtrSize(p->vDivs) );
p->timeCnf += clock() - clk;
// create the SAT problem
clk = clock();
p->pSat = Mfx_CreateSolverResub( p, NULL, 0, 0 );
if ( p->pSat == NULL )
{
p->nNodesBad++;
return 1;
}
// solve the SAT problem
if ( p->pPars->fSwapEdge )
Mfx_EdgeSwapEval( p, pNode );
else
{
Mfx_ResubNode( p, pNode );
if ( p->pPars->fMoreEffort )
Mfx_ResubNode2( p, pNode );
}
p->timeSat += clock() - clk;
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_Node( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Hop_Obj_t * pObj;
int RetValue;
int nGain, clk;
p->nNodesTried++;
// prepare data structure for this node
Mfx_ManClean( p );
// compute window roots, window support, and window nodes
clk = clock();
p->vRoots = Mfx_ComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
p->vSupp = Nwk_ManSupportNodes( p->pNtk, (Nwk_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
p->vNodes = Nwk_ManDfsNodes( p->pNtk, (Nwk_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
p->timeWin += clock() - clk;
// count the number of patterns
// p->dTotalRatios += Mfx_ConstraintRatio( p, pNode );
// construct AIG for the window
clk = clock();
p->pAigWin = Mfx_ConstructAig( p, pNode );
p->timeAig += clock() - clk;
// translate it into CNF
clk = clock();
p->pCnf = Cnf_DeriveSimple( p->pAigWin, Nwk_ObjFaninNum(pNode) );
p->timeCnf += clock() - clk;
// create the SAT problem
clk = clock();
p->pSat = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 );
if ( p->pSat == NULL )
return 0;
// solve the SAT problem
RetValue = Mfx_SolveSat( p, pNode );
p->nTotConfLevel += p->pSat->stats.conflicts;
p->timeSat += clock() - clk;
if ( RetValue == 0 )
{
p->nTimeOutsLevel++;
p->nTimeOuts++;
return 0;
}
// minimize the local function of the node using bi-decomposition
assert( p->nFanins == Nwk_ObjFaninNum(pNode) );
pObj = Nwk_NodeIfNodeResyn( p->pManDec, pNode->pMan->pManHop, pNode->pFunc, p->nFanins, p->vTruth, p->uCare );
nGain = Hop_DagSize(pNode->pFunc) - Hop_DagSize(pObj);
if ( nGain >= 0 )
{
p->nNodesDec++;
p->nNodesGained += nGain;
p->nNodesGainedLevel += nGain;
pNode->pFunc = pObj;
}
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars )
{
Bdc_Par_t Pars = {0}, * pDecPars = &Pars;
// ProgressBar * pProgress;
Mfx_Man_t * p;
Tim_Man_t * pManTimeOld = NULL;
Nwk_Obj_t * pObj;
Vec_Vec_t * vLevels;
Vec_Ptr_t * vNodes;
int i, k, nNodes, nFaninMax, clk = clock(), clk2;
int nTotalNodesBeg = Nwk_ManNodeNum(pNtk);
int nTotalEdgesBeg = Nwk_ManGetTotalFanins(pNtk);
// check limits on the number of fanins
nFaninMax = Nwk_ManGetFaninMax(pNtk);
if ( pPars->fResub )
{
if ( nFaninMax > 8 )
{
printf( "Nodes with more than %d fanins will node be processed.\n", 8 );
nFaninMax = 8;
}
}
else
{
if ( nFaninMax > MFX_FANIN_MAX )
{
printf( "Nodes with more than %d fanins will node be processed.\n", MFX_FANIN_MAX );
nFaninMax = MFX_FANIN_MAX;
}
}
/*
// prepare timing information
if ( pNtk->pManTime )
{
// compute levels
Nwk_ManLevel( pNtk );
// compute delay trace with white-boxes
Nwk_ManDelayTraceLut( pNtk, pNtk->pLutLib );
// save the general timing manager
pManTimeOld = pNtk->pManTime;
// derive an approximate timing manager without white-boxes
pNtk->pManTime = Tim_ManDupApprox( pNtk->pManTime );
}
// compute delay trace with the given timing manager
Nwk_ManDelayTraceLut( pNtk, pNtk->pLutLib );
*/
// start the manager
p = Mfx_ManAlloc( pPars );
p->pNtk = pNtk;
p->nFaninMax = nFaninMax;
if ( !pPars->fResub )
{
pDecPars->nVarsMax = nFaninMax;
pDecPars->fVerbose = pPars->fVerbose;
p->vTruth = Vec_IntAlloc( 0 );
p->pManDec = Bdc_ManAlloc( pDecPars );
}
// compute don't-cares for each node
nNodes = 0;
p->nTotalNodesBeg = nTotalNodesBeg;
p->nTotalEdgesBeg = nTotalEdgesBeg;
if ( pPars->fResub )
{
// pProgress = Extra_ProgressBarStart( stdout, Nwk_ObjNumMax(pNtk) );
Nwk_ManForEachNode( pNtk, pObj, i )
{
if ( p->pPars->nDepthMax && pObj->Level > p->pPars->nDepthMax )
continue;
if ( Nwk_ObjFaninNum(pObj) < 2 || Nwk_ObjFaninNum(pObj) > nFaninMax )
continue;
// if ( !p->pPars->fVeryVerbose )
// Extra_ProgressBarUpdate( pProgress, i, NULL );
Mfx_Resub( p, pObj );
}
// Extra_ProgressBarStop( pProgress );
}
else
{
// pProgress = Extra_ProgressBarStart( stdout, Nwk_NodeNum(pNtk) );
vLevels = Nwk_ManLevelize( pNtk );
Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 )
{
// if ( !p->pPars->fVeryVerbose )
// Extra_ProgressBarUpdate( pProgress, nNodes, NULL );
p->nNodesGainedLevel = 0;
p->nTotConfLevel = 0;
p->nTimeOutsLevel = 0;
clk2 = clock();
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( p->pPars->nDepthMax && pObj->Level > p->pPars->nDepthMax )
break;
if ( Nwk_ObjFaninNum(pObj) < 2 || Nwk_ObjFaninNum(pObj) > nFaninMax )
continue;
Mfx_Node( p, pObj );
}
nNodes += Vec_PtrSize(vNodes);
if ( pPars->fVerbose )
{
printf( "Lev = %2d. Node = %5d. Ave gain = %5.2f. Ave conf = %5.2f. T/o = %6.2f %% ",
k, Vec_PtrSize(vNodes),
1.0*p->nNodesGainedLevel/Vec_PtrSize(vNodes),
1.0*p->nTotConfLevel/Vec_PtrSize(vNodes),
100.0*p->nTimeOutsLevel/Vec_PtrSize(vNodes) );
PRT( "Time", clock() - clk2 );
}
}
// Extra_ProgressBarStop( pProgress );
Vec_VecFree( vLevels );
}
p->nTotalNodesEnd = Nwk_ManNodeNum(pNtk);
p->nTotalEdgesEnd = Nwk_ManGetTotalFanins(pNtk);
/*
// reset the timing manager
if ( pNtk->pManTime )
{
Tim_ManStop( pNtk->pManTime );
pNtk->pManTime = pManTimeOld;
}
Nwk_ManVerifyLevel( pNtk );
*/
// free the manager
p->timeTotal = clock() - clk;
Mfx_ManStop( p );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxDiv.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Procedures to compute candidate divisors.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxDiv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Marks and collects the TFI cone of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MfxWinMarkTfi_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vCone )
{
Nwk_Obj_t * pFanin;
int i;
if ( Nwk_ObjIsTravIdCurrent(pObj) )
return;
Nwk_ObjSetTravIdCurrent( pObj );
if ( Nwk_ObjIsCi(pObj) )
{
Vec_PtrPush( vCone, pObj );
return;
}
assert( Nwk_ObjIsNode(pObj) );
// visit the fanins of the node
Nwk_ObjForEachFanin( pObj, pFanin, i )
Abc_MfxWinMarkTfi_rec( pFanin, vCone );
Vec_PtrPush( vCone, pObj );
}
/**Function*************************************************************
Synopsis [Marks and collects the TFI cone of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_MfxWinMarkTfi( Nwk_Obj_t * pNode )
{
Vec_Ptr_t * vCone;
vCone = Vec_PtrAlloc( 100 );
Abc_MfxWinMarkTfi_rec( pNode, vCone );
return vCone;
}
/**Function*************************************************************
Synopsis [Marks the TFO of the collected nodes up to the given level.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MfxWinSweepLeafTfo_rec( Nwk_Obj_t * pObj, int nLevelLimit )
{
Nwk_Obj_t * pFanout;
int i;
if ( Nwk_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit )
return;
if ( Nwk_ObjIsTravIdCurrent(pObj) )
return;
Nwk_ObjSetTravIdCurrent( pObj );
Nwk_ObjForEachFanout( pObj, pFanout, i )
Abc_MfxWinSweepLeafTfo_rec( pFanout, nLevelLimit );
}
/**Function*************************************************************
Synopsis [Dereferences the node's MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_MfxNodeDeref_rec( Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
int i, Counter = 1;
if ( Nwk_ObjIsCi(pNode) )
return 0;
Nwk_ObjSetTravIdCurrent( pNode );
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
assert( pFanin->nFanouts > 0 );
if ( --pFanin->nFanouts == 0 )
Counter += Abc_MfxNodeDeref_rec( pFanin );
}
return Counter;
}
/**Function*************************************************************
Synopsis [References the node's MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_MfxNodeRef_rec( Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
int i, Counter = 1;
if ( Nwk_ObjIsCi(pNode) )
return 0;
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
if ( pFanin->nFanouts++ == 0 )
Counter += Abc_MfxNodeRef_rec( pFanin );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Labels MFFC of the node with the current trav ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_MfxWinVisitMffc( Nwk_Obj_t * pNode )
{
int Count1, Count2;
assert( Nwk_ObjIsNode(pNode) );
// dereference the node (mark with the current trav ID)
Count1 = Abc_MfxNodeDeref_rec( pNode );
// reference it back
Count2 = Abc_MfxNodeRef_rec( pNode );
assert( Count1 == Count2 );
return Count1;
}
/**Function*************************************************************
Synopsis [Computes divisors and add them to nodes in the window.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, int nLevDivMax )
{
Vec_Ptr_t * vCone, * vDivs;
Nwk_Obj_t * pObj, * pFanout, * pFanin;
int k, f, m;
int nDivsPlus = 0, nTrueSupp;
assert( p->vDivs == NULL );
// mark the TFI with the current trav ID
Nwk_ManIncrementTravId( pNode->pMan );
vCone = Abc_MfxWinMarkTfi( pNode );
// count the number of PIs
nTrueSupp = 0;
Vec_PtrForEachEntry( vCone, pObj, k )
nTrueSupp += Nwk_ObjIsCi(pObj);
// printf( "%d(%d) ", Vec_PtrSize(p->vSupp), m );
// mark with the current trav ID those nodes that should not be divisors:
// (1) the node and its TFO
// (2) the MFFC of the node
// (3) the node's fanins (these are treated as a special case)
Nwk_ManIncrementTravId( pNode->pMan );
Abc_MfxWinSweepLeafTfo_rec( pNode, nLevDivMax );
Abc_MfxWinVisitMffc( pNode );
Nwk_ObjForEachFanin( pNode, pObj, k )
Nwk_ObjSetTravIdCurrent( pObj );
// at this point the nodes are marked with two trav IDs:
// nodes to be collected as divisors are marked with previous trav ID
// nodes to be avoided as divisors are marked with current trav ID
// start collecting the divisors
vDivs = Vec_PtrAlloc( p->pPars->nDivMax );
Vec_PtrForEachEntry( vCone, pObj, k )
{
if ( !Nwk_ObjIsTravIdPrevious(pObj) )
continue;
if ( (int)pObj->Level > nLevDivMax )
continue;
Vec_PtrPush( vDivs, pObj );
if ( Vec_PtrSize(vDivs) >= p->pPars->nDivMax )
break;
}
Vec_PtrFree( vCone );
// explore the fanouts of already collected divisors
if ( Vec_PtrSize(vDivs) < p->pPars->nDivMax )
Vec_PtrForEachEntry( vDivs, pObj, k )
{
// consider fanouts of this node
Nwk_ObjForEachFanout( pObj, pFanout, f )
{
// stop if there are too many fanouts
if ( f > 20 )
break;
// skip nodes that are already added
if ( Nwk_ObjIsTravIdPrevious(pFanout) )
continue;
// skip nodes in the TFO or in the MFFC of node
if ( Nwk_ObjIsTravIdCurrent(pFanout) )
continue;
// skip COs
if ( !Nwk_ObjIsNode(pFanout) )
continue;
// skip nodes with large level
if ( (int)pFanout->Level > nLevDivMax )
continue;
// skip nodes whose fanins are not divisors
Nwk_ObjForEachFanin( pFanout, pFanin, m )
if ( !Nwk_ObjIsTravIdPrevious(pFanin) )
break;
if ( m < Nwk_ObjFaninNum(pFanout) )
continue;
// make sure this divisor in not among the nodes
// Vec_PtrForEachEntry( p->vNodes, pFanin, m )
// assert( pFanout != pFanin );
// add the node to the divisors
Vec_PtrPush( vDivs, pFanout );
// Vec_PtrPush( p->vNodes, pFanout );
Vec_PtrPushUnique( p->vNodes, pFanout );
Nwk_ObjSetTravIdPrevious( pFanout );
nDivsPlus++;
if ( Vec_PtrSize(vDivs) >= p->pPars->nDivMax )
break;
}
if ( Vec_PtrSize(vDivs) >= p->pPars->nDivMax )
break;
}
// sort the divisors by level in the increasing order
Vec_PtrSort( vDivs, Nwk_NodeCompareLevelsIncrease );
// add the fanins of the node
Nwk_ObjForEachFanin( pNode, pFanin, k )
Vec_PtrPush( vDivs, pFanin );
/*
printf( "Node level = %d. ", Nwk_ObjLevel(p->pNode) );
Vec_PtrForEachEntryStart( vDivs, pObj, k, Vec_PtrSize(vDivs)-p->nDivsPlus )
printf( "%d ", Nwk_ObjLevel(pObj) );
printf( "\n" );
*/
//printf( "%d ", p->nDivsPlus );
// printf( "(%d+%d)(%d+%d+%d) ", Vec_PtrSize(p->vSupp), Vec_PtrSize(p->vNodes),
// nTrueSupp, Vec_PtrSize(vDivs)-nTrueSupp-nDivsPlus, nDivsPlus );
return vDivs;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Internal declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __MFX_INT_H__
#define __MFX_INT_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "nwk.h"
#include "mfx.h"
#include "aig.h"
#include "cnf.h"
#include "satSolver.h"
#include "satStore.h"
#include "bdc.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
#define MFX_FANIN_MAX 12
typedef struct Mfx_Man_t_ Mfx_Man_t;
struct Mfx_Man_t_
{
// input data
Mfx_Par_t * pPars;
Nwk_Man_t * pNtk;
Aig_Man_t * pCare;
Vec_Ptr_t * vSuppsInv;
int nFaninMax;
// intermeditate data for the node
Vec_Ptr_t * vRoots; // the roots of the window
Vec_Ptr_t * vSupp; // the support of the window
Vec_Ptr_t * vNodes; // the internal nodes of the window
Vec_Ptr_t * vDivs; // the divisors of the node
Vec_Int_t * vDivLits; // the SAT literals of divisor nodes
Vec_Int_t * vProjVars; // the projection variables
// intermediate simulation data
Vec_Ptr_t * vDivCexes; // the counter-example for dividors
int nDivWords; // the number of words
int nCexes; // the numbe rof current counter-examples
int nSatCalls;
int nSatCexes;
// used for bidecomposition
Vec_Int_t * vTruth;
Bdc_Man_t * pManDec;
int nNodesDec;
int nNodesGained;
int nNodesGainedLevel;
// solving data
Aig_Man_t * pAigWin; // window AIG with constraints
Cnf_Dat_t * pCnf; // the CNF for the window
sat_solver * pSat; // the SAT solver used
Int_Man_t * pMan; // interpolation manager;
Vec_Int_t * vMem; // memory for intermediate SOPs
Vec_Vec_t * vLevels; // levelized structure for updating
Vec_Ptr_t * vFanins; // the new set of fanins
int nTotConfLim; // total conflict limit
int nTotConfLevel; // total conflicts on this level
// the result of solving
int nFanins; // the number of fanins
int nWords; // the number of words
int nCares; // the number of care minterms
unsigned uCare[(MFX_FANIN_MAX<=5)?1:1<<(MFX_FANIN_MAX-5)]; // the computed care-set
// performance statistics
int nNodesTried;
int nNodesResub;
int nMintsCare;
int nMintsTotal;
int nNodesBad;
int nTotalDivs;
int nTimeOuts;
int nTimeOutsLevel;
int nDcMints;
double dTotalRatios;
// node/edge stats
int nTotalNodesBeg;
int nTotalNodesEnd;
int nTotalEdgesBeg;
int nTotalEdgesEnd;
// statistics
int timeWin;
int timeDiv;
int timeAig;
int timeCnf;
int timeSat;
int timeInt;
int timeTotal;
};
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== mfxDiv.c ==========================================================*/
extern Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, int nLevDivMax );
/*=== mfxInter.c ==========================================================*/
extern sat_solver * Mfx_CreateSolverResub( Mfx_Man_t * p, int * pCands, int nCands, int fInvert );
extern Hop_Obj_t * Mfx_Interplate( Mfx_Man_t * p, int * pCands, int nCands );
extern int Mfx_InterplateEval( Mfx_Man_t * p, int * pCands, int nCands );
/*=== mfxMan.c ==========================================================*/
extern Mfx_Man_t * Mfx_ManAlloc( Mfx_Par_t * pPars );
extern void Mfx_ManStop( Mfx_Man_t * p );
extern void Mfx_ManClean( Mfx_Man_t * p );
/*=== mfxResub.c ==========================================================*/
extern void Mfx_PrintResubStats( Mfx_Man_t * p );
extern int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode );
extern int Mfx_ResubNode( Mfx_Man_t * p, Nwk_Obj_t * pNode );
extern int Mfx_ResubNode2( Mfx_Man_t * p, Nwk_Obj_t * pNode );
/*=== mfxSat.c ==========================================================*/
extern int Mfx_SolveSat( Mfx_Man_t * p, Nwk_Obj_t * pNode );
/*=== mfxStrash.c ==========================================================*/
extern Aig_Man_t * Mfx_ConstructAig( Mfx_Man_t * p, Nwk_Obj_t * pNode );
extern double Mfx_ConstraintRatio( Mfx_Man_t * p, Nwk_Obj_t * pNode );
/*=== mfxWin.c ==========================================================*/
extern Vec_Ptr_t * Mfx_ComputeRoots( Nwk_Obj_t * pNode, int nWinTfoMax, int nFanoutLimit );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxInter.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Procedures for computing resub function by interpolation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxInter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
#include "kit.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Adds constraints for the two-input AND-gate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_SatAddXor( sat_solver * pSat, int iVarA, int iVarB, int iVarC )
{
lit Lits[3];
Lits[0] = toLitCond( iVarA, 1 );
Lits[1] = toLitCond( iVarB, 1 );
Lits[2] = toLitCond( iVarC, 1 );
if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
return 0;
Lits[0] = toLitCond( iVarA, 1 );
Lits[1] = toLitCond( iVarB, 0 );
Lits[2] = toLitCond( iVarC, 0 );
if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
return 0;
Lits[0] = toLitCond( iVarA, 0 );
Lits[1] = toLitCond( iVarB, 1 );
Lits[2] = toLitCond( iVarC, 0 );
if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
return 0;
Lits[0] = toLitCond( iVarA, 0 );
Lits[1] = toLitCond( iVarB, 0 );
Lits[2] = toLitCond( iVarC, 1 );
if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Creates miter for checking resubsitution.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
sat_solver * Mfx_CreateSolverResub( Mfx_Man_t * p, int * pCands, int nCands, int fInvert )
{
sat_solver * pSat;
Aig_Obj_t * pObjPo;
int Lits[2], status, iVar, i, c;
// get the literal for the output of F
pObjPo = Aig_ManPo( p->pAigWin, Aig_ManPoNum(p->pAigWin) - Vec_PtrSize(p->vDivs) - 1 );
Lits[0] = toLitCond( p->pCnf->pVarNums[pObjPo->Id], fInvert );
// collect the outputs of the divisors
Vec_IntClear( p->vProjVars );
Vec_PtrForEachEntryStart( p->pAigWin->vPos, pObjPo, i, Aig_ManPoNum(p->pAigWin) - Vec_PtrSize(p->vDivs) )
{
assert( p->pCnf->pVarNums[pObjPo->Id] >= 0 );
Vec_IntPush( p->vProjVars, p->pCnf->pVarNums[pObjPo->Id] );
}
assert( Vec_IntSize(p->vProjVars) == Vec_PtrSize(p->vDivs) );
// start the solver
pSat = sat_solver_new();
sat_solver_setnvars( pSat, 2 * p->pCnf->nVars + Vec_PtrSize(p->vDivs) );
if ( pCands )
sat_solver_store_alloc( pSat );
// load the first copy of the clauses
for ( i = 0; i < p->pCnf->nClauses; i++ )
{
if ( !sat_solver_addclause( pSat, p->pCnf->pClauses[i], p->pCnf->pClauses[i+1] ) )
{
sat_solver_delete( pSat );
return NULL;
}
}
// add the clause for the first output of F
if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) )
{
sat_solver_delete( pSat );
return NULL;
}
// bookmark the clauses of A
if ( pCands )
sat_solver_store_mark_clauses_a( pSat );
// transform the literals
for ( i = 0; i < p->pCnf->nLiterals; i++ )
p->pCnf->pClauses[0][i] += 2 * p->pCnf->nVars;
// load the second copy of the clauses
for ( i = 0; i < p->pCnf->nClauses; i++ )
{
if ( !sat_solver_addclause( pSat, p->pCnf->pClauses[i], p->pCnf->pClauses[i+1] ) )
{
sat_solver_delete( pSat );
return NULL;
}
}
// transform the literals
for ( i = 0; i < p->pCnf->nLiterals; i++ )
p->pCnf->pClauses[0][i] -= 2 * p->pCnf->nVars;
// add the clause for the second output of F
Lits[0] = 2 * p->pCnf->nVars + lit_neg( Lits[0] );
if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) )
{
sat_solver_delete( pSat );
return NULL;
}
if ( pCands )
{
// add relevant clauses for EXOR gates
for ( c = 0; c < nCands; c++ )
{
// get the variable number of this divisor
i = lit_var( pCands[c] ) - 2 * p->pCnf->nVars;
// get the corresponding SAT variable
iVar = Vec_IntEntry( p->vProjVars, i );
// add the corresponding EXOR gate
if ( !Mfx_SatAddXor( pSat, iVar, iVar + p->pCnf->nVars, 2 * p->pCnf->nVars + i ) )
{
sat_solver_delete( pSat );
return NULL;
}
// add the corresponding clause
if ( !sat_solver_addclause( pSat, pCands + c, pCands + c + 1 ) )
{
sat_solver_delete( pSat );
return NULL;
}
}
// bookmark the roots
sat_solver_store_mark_roots( pSat );
}
else
{
// add the clauses for the EXOR gates - and remember their outputs
Vec_IntForEachEntry( p->vProjVars, iVar, i )
{
if ( !Mfx_SatAddXor( pSat, iVar, iVar + p->pCnf->nVars, 2 * p->pCnf->nVars + i ) )
{
sat_solver_delete( pSat );
return NULL;
}
Vec_IntWriteEntry( p->vProjVars, i, 2 * p->pCnf->nVars + i );
}
// simplify the solver
status = sat_solver_simplify(pSat);
if ( status == 0 )
{
// printf( "Mfx_CreateSolverResub(): SAT solver construction has failed. Skipping node.\n" );
sat_solver_delete( pSat );
return NULL;
}
}
return pSat;
}
/**Function*************************************************************
Synopsis [Performs interpolation.]
Description [Derives the new function of the node.]
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Mfx_InterplateTruth( Mfx_Man_t * p, int * pCands, int nCands, int fInvert )
{
sat_solver * pSat;
Sto_Man_t * pCnf = NULL;
unsigned * puTruth;
int nFanins, status;
int c, i, * pGloVars;
// derive the SAT solver for interpolation
pSat = Mfx_CreateSolverResub( p, pCands, nCands, fInvert );
// solve the problem
status = sat_solver_solve( pSat, NULL, NULL, (sint64)p->pPars->nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
if ( status != l_False )
{
p->nTimeOuts++;
return NULL;
}
// get the learned clauses
pCnf = sat_solver_store_release( pSat );
sat_solver_delete( pSat );
// set the global variables
pGloVars = Int_ManSetGlobalVars( p->pMan, nCands );
for ( c = 0; c < nCands; c++ )
{
// get the variable number of this divisor
i = lit_var( pCands[c] ) - 2 * p->pCnf->nVars;
// get the corresponding SAT variable
pGloVars[c] = Vec_IntEntry( p->vProjVars, i );
}
// derive the interpolant
nFanins = Int_ManInterpolate( p->pMan, pCnf, 0, &puTruth );
Sto_ManFree( pCnf );
assert( nFanins == nCands );
return puTruth;
}
/**Function*************************************************************
Synopsis [Performs interpolation.]
Description [Derives the new function of the node.]
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_InterplateEval( Mfx_Man_t * p, int * pCands, int nCands )
{
unsigned * pTruth, uTruth0[2], uTruth1[2];
int nCounter;
pTruth = Mfx_InterplateTruth( p, pCands, nCands, 0 );
if ( nCands == 6 )
{
uTruth1[0] = pTruth[0];
uTruth1[1] = pTruth[1];
}
else
{
uTruth1[0] = pTruth[0];
uTruth1[1] = pTruth[0];
}
pTruth = Mfx_InterplateTruth( p, pCands, nCands, 1 );
if ( nCands == 6 )
{
uTruth0[0] = ~pTruth[0];
uTruth0[1] = ~pTruth[1];
}
else
{
uTruth0[0] = ~pTruth[0];
uTruth0[1] = ~pTruth[0];
}
nCounter = Extra_WordCountOnes( uTruth0[0] ^ uTruth1[0] );
nCounter += Extra_WordCountOnes( uTruth0[1] ^ uTruth1[1] );
// printf( "%d ", nCounter );
return nCounter;
}
/**Function*************************************************************
Synopsis [Performs interpolation.]
Description [Derives the new function of the node.]
SideEffects []
SeeAlso []
***********************************************************************/
Hop_Obj_t * Mfx_Interplate( Mfx_Man_t * p, int * pCands, int nCands )
{
extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
sat_solver * pSat;
Sto_Man_t * pCnf = NULL;
unsigned * puTruth;
Kit_Graph_t * pGraph;
Hop_Obj_t * pFunc;
int nFanins, status;
int c, i, * pGloVars;
// p->nDcMints += Mfx_InterplateEval( p, pCands, nCands );
// derive the SAT solver for interpolation
pSat = Mfx_CreateSolverResub( p, pCands, nCands, 0 );
// solve the problem
status = sat_solver_solve( pSat, NULL, NULL, (sint64)p->pPars->nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
if ( status != l_False )
{
p->nTimeOuts++;
return NULL;
}
// get the learned clauses
pCnf = sat_solver_store_release( pSat );
sat_solver_delete( pSat );
// set the global variables
pGloVars = Int_ManSetGlobalVars( p->pMan, nCands );
for ( c = 0; c < nCands; c++ )
{
// get the variable number of this divisor
i = lit_var( pCands[c] ) - 2 * p->pCnf->nVars;
// get the corresponding SAT variable
pGloVars[c] = Vec_IntEntry( p->vProjVars, i );
}
// derive the interpolant
nFanins = Int_ManInterpolate( p->pMan, pCnf, 0, &puTruth );
Sto_ManFree( pCnf );
assert( nFanins == nCands );
// transform interpolant into AIG
pGraph = Kit_TruthToGraph( puTruth, nFanins, p->vMem );
pFunc = Kit_GraphToHop( p->pNtk->pManHop, pGraph );
Kit_GraphFree( pGraph );
return pFunc;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Procedures working with the manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Mfx_Man_t * Mfx_ManAlloc( Mfx_Par_t * pPars )
{
Mfx_Man_t * p;
// start the manager
p = ALLOC( Mfx_Man_t, 1 );
memset( p, 0, sizeof(Mfx_Man_t) );
p->pPars = pPars;
p->vProjVars = Vec_IntAlloc( 100 );
p->vDivLits = Vec_IntAlloc( 100 );
p->nDivWords = Aig_BitWordNum(p->pPars->nDivMax + MFX_FANIN_MAX);
p->vDivCexes = Vec_PtrAllocSimInfo( p->pPars->nDivMax+MFX_FANIN_MAX+1, p->nDivWords );
p->pMan = Int_ManAlloc();
p->vMem = Vec_IntAlloc( 0 );
p->vLevels = Vec_VecStart( 32 );
p->vFanins = Vec_PtrAlloc( 32 );
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_ManClean( Mfx_Man_t * p )
{
if ( p->pAigWin )
Aig_ManStop( p->pAigWin );
if ( p->pCnf )
Cnf_DataFree( p->pCnf );
if ( p->pSat )
sat_solver_delete( p->pSat );
if ( p->vRoots )
Vec_PtrFree( p->vRoots );
if ( p->vSupp )
Vec_PtrFree( p->vSupp );
if ( p->vNodes )
Vec_PtrFree( p->vNodes );
if ( p->vDivs )
Vec_PtrFree( p->vDivs );
p->pAigWin = NULL;
p->pCnf = NULL;
p->pSat = NULL;
p->vRoots = NULL;
p->vSupp = NULL;
p->vNodes = NULL;
p->vDivs = NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_ManPrint( Mfx_Man_t * p )
{
if ( p->pPars->fResub )
{
printf( "Reduction in nodes = %5d. (%.2f %%) ",
p->nTotalNodesBeg-p->nTotalNodesEnd,
100.0*(p->nTotalNodesBeg-p->nTotalNodesEnd)/p->nTotalNodesBeg );
printf( "Reduction in edges = %5d. (%.2f %%) ",
p->nTotalEdgesBeg-p->nTotalEdgesEnd,
100.0*(p->nTotalEdgesBeg-p->nTotalEdgesEnd)/p->nTotalEdgesBeg );
printf( "\n" );
printf( "Nodes = %d. Try = %d. Resub = %d. Div = %d. SAT calls = %d. Timeouts = %d.\n",
Nwk_ManNodeNum(p->pNtk), p->nNodesTried, p->nNodesResub, p->nTotalDivs, p->nSatCalls, p->nTimeOuts );
if ( p->pPars->fSwapEdge )
printf( "Swappable edges = %d. Total edges = %d. Ratio = %5.2f.\n",
p->nNodesResub, Nwk_ManGetTotalFanins(p->pNtk), 1.00 * p->nNodesResub / Nwk_ManGetTotalFanins(p->pNtk) );
else
Mfx_PrintResubStats( p );
// printf( "Average ratio of DCs in the resubed nodes = %.2f.\n", 1.0*p->nDcMints/(64 * p->nNodesResub) );
}
else
{
printf( "Nodes = %d. Try = %d. Total mints = %d. Local DC mints = %d. Ratio = %5.2f.\n",
Nwk_ManNodeNum(p->pNtk), p->nNodesTried, p->nMintsTotal, p->nMintsTotal-p->nMintsCare,
1.0 * (p->nMintsTotal-p->nMintsCare) / p->nMintsTotal );
// printf( "Average ratio of sequential DCs in the global space = %5.2f.\n",
// 1.0-(p->dTotalRatios/p->nNodesTried) );
printf( "Nodes resyn = %d. Ratio = %5.2f. Total AIG node gain = %d. Timeouts = %d.\n",
p->nNodesDec, 1.0 * p->nNodesDec / p->nNodesTried, p->nNodesGained, p->nTimeOuts );
}
/*
PRTP( "Win", p->timeWin , p->timeTotal );
PRTP( "Div", p->timeDiv , p->timeTotal );
PRTP( "Aig", p->timeAig , p->timeTotal );
PRTP( "Cnf", p->timeCnf , p->timeTotal );
PRTP( "Sat", p->timeSat-p->timeInt , p->timeTotal );
PRTP( "Int", p->timeInt , p->timeTotal );
PRTP( "ALL", p->timeTotal , p->timeTotal );
*/
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_ManStop( Mfx_Man_t * p )
{
if ( p->pPars->fVerbose )
Mfx_ManPrint( p );
if ( p->vTruth )
Vec_IntFree( p->vTruth );
if ( p->pManDec )
Bdc_ManFree( p->pManDec );
if ( p->pCare )
Aig_ManStop( p->pCare );
if ( p->vSuppsInv )
Vec_VecFree( (Vec_Vec_t *)p->vSuppsInv );
Mfx_ManClean( p );
Int_ManFree( p->pMan );
Vec_IntFree( p->vMem );
Vec_VecFree( p->vLevels );
Vec_PtrFree( p->vFanins );
Vec_IntFree( p->vProjVars );
Vec_IntFree( p->vDivLits );
Vec_PtrFree( p->vDivCexes );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxResub.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Procedures to perform resubstitution.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxResub.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Updates the network after resubstitution.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_UpdateNetwork( Mfx_Man_t * p, Nwk_Obj_t * pObj, Vec_Ptr_t * vFanins, Hop_Obj_t * pFunc )
{
Nwk_Obj_t * pObjNew, * pFanin;
int k;
// create the new node
pObjNew = Nwk_ManCreateNode( pObj->pMan, Vec_PtrSize(vFanins), Nwk_ObjFanoutNum(pObj) );
if ( pObjNew->Id == 19969 )
{
int x = 0;
}
pObjNew->pFunc = pFunc;
Vec_PtrForEachEntry( vFanins, pFanin, k )
Nwk_ObjAddFanin( pObjNew, pFanin );
// replace the old node by the new node
//printf( "Replacing node " ); Nwk_ObjPrint( stdout, pObj );
//printf( "Inserting node " ); Nwk_ObjPrint( stdout, pObjNew );
// update the level of the node
Nwk_ManUpdate( pObj, pObjNew, p->vLevels );
}
/**Function*************************************************************
Synopsis [Prints resub candidate stats.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_PrintResubStats( Mfx_Man_t * p )
{
Nwk_Obj_t * pFanin, * pNode;
int i, k, nAreaCrits = 0, nAreaExpanse = 0;
int nFaninMax = Nwk_ManGetFaninMax(p->pNtk);
Nwk_ManForEachNode( p->pNtk, pNode, i )
Nwk_ObjForEachFanin( pNode, pFanin, k )
{
if ( !Nwk_ObjIsCi(pFanin) && Nwk_ObjFanoutNum(pFanin) == 1 )
{
nAreaCrits++;
nAreaExpanse += (int)(Nwk_ObjFaninNum(pNode) < nFaninMax);
}
}
printf( "Total area-critical fanins = %d. Belonging to expandable nodes = %d.\n",
nAreaCrits, nAreaExpanse );
}
/**Function*************************************************************
Synopsis [Tries resubstitution.]
Description [Returns 1 if it is feasible, or 0 if c-ex is found.]
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_TryResubOnce( Mfx_Man_t * p, int * pCands, int nCands )
{
unsigned * pData;
int RetValue, iVar, i;
p->nSatCalls++;
RetValue = sat_solver_solve( p->pSat, pCands, pCands + nCands, (sint64)p->pPars->nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
// assert( RetValue == l_False || RetValue == l_True );
if ( RetValue == l_False )
return 1;
if ( RetValue != l_True )
{
p->nTimeOuts++;
return -1;
}
p->nSatCexes++;
// store the counter-example
Vec_IntForEachEntry( p->vProjVars, iVar, i )
{
pData = Vec_PtrEntry( p->vDivCexes, i );
if ( !sat_solver_var_value( p->pSat, iVar ) ) // remove 0s!!!
{
assert( Aig_InfoHasBit(pData, p->nCexes) );
Aig_InfoXorBit( pData, p->nCexes );
}
}
p->nCexes++;
return 0;
}
/**Function*************************************************************
Synopsis [Performs resubstitution for the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_SolveSatResub( Mfx_Man_t * p, Nwk_Obj_t * pNode, int iFanin, int fOnlyRemove, int fSkipUpdate )
{
int fVeryVerbose = p->pPars->fVeryVerbose && Vec_PtrSize(p->vDivs) < 80;
unsigned * pData;
int pCands[MFX_FANIN_MAX];
int RetValue, iVar, i, nCands, nWords, w, clk;
Nwk_Obj_t * pFanin;
Hop_Obj_t * pFunc;
assert( iFanin >= 0 );
// clean simulation info
Vec_PtrFillSimInfo( p->vDivCexes, 0, p->nDivWords );
p->nCexes = 0;
if ( fVeryVerbose )
{
printf( "\n" );
printf( "Node %5d : Level = %2d. Divs = %3d. Fanin = %d (out of %d). MFFC = %d\n",
pNode->Id, pNode->Level, Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode),
iFanin, Nwk_ObjFaninNum(pNode),
Nwk_ObjFanoutNum(Nwk_ObjFanin(pNode, iFanin)) == 1 ? Nwk_ObjMffcLabel(Nwk_ObjFanin(pNode, iFanin)) : 0 );
}
// try fanins without the critical fanin
nCands = 0;
Vec_PtrClear( p->vFanins );
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
if ( i == iFanin )
continue;
Vec_PtrPush( p->vFanins, pFanin );
iVar = Vec_PtrSize(p->vDivs) - Nwk_ObjFaninNum(pNode) + i;
pCands[nCands++] = toLitCond( Vec_IntEntry( p->vProjVars, iVar ), 1 );
}
RetValue = Mfx_TryResubOnce( p, pCands, nCands );
if ( RetValue == -1 )
return 0;
if ( RetValue == 1 )
{
if ( fVeryVerbose )
printf( "Node %d: Fanin %d can be removed.\n", pNode->Id, iFanin );
p->nNodesResub++;
p->nNodesGainedLevel++;
if ( fSkipUpdate )
return 1;
clk = clock();
// derive the function
pFunc = Mfx_Interplate( p, pCands, nCands );
if ( pFunc == NULL )
return 0;
// update the network
Mfx_UpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( fOnlyRemove )
return 0;
if ( fVeryVerbose )
{
for ( i = 0; i < 8; i++ )
printf( " " );
for ( i = 0; i < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); i++ )
printf( "%d", i % 10 );
for ( i = 0; i < Nwk_ObjFaninNum(pNode); i++ )
if ( i == iFanin )
printf( "*" );
else
printf( "%c", 'a' + i );
printf( "\n" );
}
iVar = -1;
while ( 1 )
{
if ( fVeryVerbose )
{
printf( "%3d: %2d ", p->nCexes, iVar );
for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ )
{
pData = Vec_PtrEntry( p->vDivCexes, i );
printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) );
}
printf( "\n" );
}
// find the next divisor to try
nWords = Aig_BitWordNum(p->nCexes);
assert( nWords <= p->nDivWords );
for ( iVar = 0; iVar < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); iVar++ )
{
pData = Vec_PtrEntry( p->vDivCexes, iVar );
for ( w = 0; w < nWords; w++ )
if ( pData[w] != ~0 )
break;
if ( w == nWords )
break;
}
if ( iVar == Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode) )
return 0;
pCands[nCands] = toLitCond( Vec_IntEntry(p->vProjVars, iVar), 1 );
RetValue = Mfx_TryResubOnce( p, pCands, nCands+1 );
if ( RetValue == -1 )
return 0;
if ( RetValue == 1 )
{
if ( fVeryVerbose )
printf( "Node %d: Fanin %d can be replaced by divisor %d.\n", pNode->Id, iFanin, iVar );
p->nNodesResub++;
p->nNodesGainedLevel++;
if ( fSkipUpdate )
return 1;
clk = clock();
// derive the function
pFunc = Mfx_Interplate( p, pCands, nCands+1 );
if ( pFunc == NULL )
return 0;
// update the network
Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar) );
Mfx_UpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( p->nCexes >= p->pPars->nDivMax )
break;
}
return 0;
}
/**Function*************************************************************
Synopsis [Performs resubstitution for the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_SolveSatResub2( Mfx_Man_t * p, Nwk_Obj_t * pNode, int iFanin, int iFanin2 )
{
int fVeryVerbose = p->pPars->fVeryVerbose && Vec_PtrSize(p->vDivs) < 80;
unsigned * pData, * pData2;
int pCands[MFX_FANIN_MAX];
int RetValue, iVar, iVar2, i, w, nCands, clk, nWords, fBreak;
Nwk_Obj_t * pFanin;
Hop_Obj_t * pFunc;
assert( iFanin >= 0 );
assert( iFanin2 >= 0 || iFanin2 == -1 );
// clean simulation info
Vec_PtrFillSimInfo( p->vDivCexes, 0, p->nDivWords );
p->nCexes = 0;
if ( fVeryVerbose )
{
printf( "\n" );
printf( "Node %5d : Level = %2d. Divs = %3d. Fanins = %d/%d (out of %d). MFFC = %d\n",
pNode->Id, pNode->Level, Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode),
iFanin, iFanin2, Nwk_ObjFaninNum(pNode),
Nwk_ObjFanoutNum(Nwk_ObjFanin(pNode, iFanin)) == 1 ? Nwk_ObjMffcLabel(Nwk_ObjFanin(pNode, iFanin)) : 0 );
}
// try fanins without the critical fanin
nCands = 0;
Vec_PtrClear( p->vFanins );
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
if ( i == iFanin || i == iFanin2 )
continue;
Vec_PtrPush( p->vFanins, pFanin );
iVar = Vec_PtrSize(p->vDivs) - Nwk_ObjFaninNum(pNode) + i;
pCands[nCands++] = toLitCond( Vec_IntEntry( p->vProjVars, iVar ), 1 );
}
RetValue = Mfx_TryResubOnce( p, pCands, nCands );
if ( RetValue == -1 )
return 0;
if ( RetValue == 1 )
{
if ( fVeryVerbose )
printf( "Node %d: Fanins %d/%d can be removed.\n", pNode->Id, iFanin, iFanin2 );
p->nNodesResub++;
p->nNodesGainedLevel++;
clk = clock();
// derive the function
pFunc = Mfx_Interplate( p, pCands, nCands );
if ( pFunc == NULL )
return 0;
// update the network
Mfx_UpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( fVeryVerbose )
{
for ( i = 0; i < 11; i++ )
printf( " " );
for ( i = 0; i < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); i++ )
printf( "%d", i % 10 );
for ( i = 0; i < Nwk_ObjFaninNum(pNode); i++ )
if ( i == iFanin || i == iFanin2 )
printf( "*" );
else
printf( "%c", 'a' + i );
printf( "\n" );
}
iVar = iVar2 = -1;
while ( 1 )
{
if ( fVeryVerbose )
{
printf( "%3d: %2d %2d ", p->nCexes, iVar, iVar2 );
for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ )
{
pData = Vec_PtrEntry( p->vDivCexes, i );
printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) );
}
printf( "\n" );
}
// find the next divisor to try
nWords = Aig_BitWordNum(p->nCexes);
assert( nWords <= p->nDivWords );
fBreak = 0;
for ( iVar = 1; iVar < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); iVar++ )
{
pData = Vec_PtrEntry( p->vDivCexes, iVar );
for ( iVar2 = 0; iVar2 < iVar; iVar2++ )
{
pData2 = Vec_PtrEntry( p->vDivCexes, iVar2 );
for ( w = 0; w < nWords; w++ )
if ( (pData[w] | pData2[w]) != ~0 )
break;
if ( w == nWords )
{
fBreak = 1;
break;
}
}
if ( fBreak )
break;
}
if ( iVar == Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode) )
return 0;
pCands[nCands] = toLitCond( Vec_IntEntry(p->vProjVars, iVar2), 1 );
pCands[nCands+1] = toLitCond( Vec_IntEntry(p->vProjVars, iVar), 1 );
RetValue = Mfx_TryResubOnce( p, pCands, nCands+2 );
if ( RetValue == -1 )
return 0;
if ( RetValue == 1 )
{
if ( fVeryVerbose )
printf( "Node %d: Fanins %d/%d can be replaced by divisors %d/%d.\n", pNode->Id, iFanin, iFanin2, iVar, iVar2 );
p->nNodesResub++;
p->nNodesGainedLevel++;
clk = clock();
// derive the function
pFunc = Mfx_Interplate( p, pCands, nCands+2 );
if ( pFunc == NULL )
return 0;
// update the network
Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar2) );
Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar) );
assert( Vec_PtrSize(p->vFanins) == nCands + 2 );
Mfx_UpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( p->nCexes >= p->pPars->nDivMax )
break;
}
return 0;
}
/**Function*************************************************************
Synopsis [Evaluates the possibility of replacing given edge by another edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
int i;
Nwk_ObjForEachFanin( pNode, pFanin, i )
Mfx_SolveSatResub( p, pNode, i, 0, 1 );
return 0;
}
/**Function*************************************************************
Synopsis [Performs resubstitution for the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_ResubNode( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
int i;
// try replacing area critical fanins
Nwk_ObjForEachFanin( pNode, pFanin, i )
if ( !Nwk_ObjIsCi(pFanin) && Nwk_ObjFanoutNum(pFanin) == 1 )
{
if ( Mfx_SolveSatResub( p, pNode, i, 0, 0 ) )
return 1;
}
// try removing redundant edges
if ( !p->pPars->fArea )
{
Nwk_ObjForEachFanin( pNode, pFanin, i )
if ( Nwk_ObjIsCi(pFanin) || Nwk_ObjFanoutNum(pFanin) != 1 )
{
if ( Mfx_SolveSatResub( p, pNode, i, 1, 0 ) )
return 1;
}
}
if ( Nwk_ObjFaninNum(pNode) == p->nFaninMax )
return 0;
// try replacing area critical fanins while adding two new fanins
Nwk_ObjForEachFanin( pNode, pFanin, i )
if ( !Nwk_ObjIsCi(pFanin) && Nwk_ObjFanoutNum(pFanin) == 1 )
{
if ( Mfx_SolveSatResub2( p, pNode, i, -1 ) )
return 1;
}
return 0;
}
/**Function*************************************************************
Synopsis [Performs resubstitution for the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_ResubNode2( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin, * pFanin2;
int i, k;
/*
Nwk_ObjForEachFanin( pNode, pFanin, i )
if ( !Nwk_ObjIsCi(pFanin) && Nwk_ObjFanoutNum(pFanin) == 1 )
{
if ( Mfx_SolveSatResub( p, pNode, i, 0, 0 ) )
return 1;
}
*/
if ( Nwk_ObjFaninNum(pNode) < 2 )
return 0;
// try replacing one area critical fanin and one other fanin while adding two new fanins
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
if ( !Nwk_ObjIsCi(pFanin) && Nwk_ObjFanoutNum(pFanin) == 1 )
{
// consider second fanin to remove at the same time
Nwk_ObjForEachFanin( pNode, pFanin2, k )
{
if ( i != k && Mfx_SolveSatResub2( p, pNode, i, k ) )
return 1;
}
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Procedures to compute don't-cares using SAT.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Enumerates through the SAT assignments.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_SolveSat_iter( Mfx_Man_t * p )
{
int Lits[MFX_FANIN_MAX];
int RetValue, nBTLimit, iVar, b, Mint;
if ( p->nTotConfLim && p->nTotConfLim <= p->pSat->stats.conflicts )
return -1;
nBTLimit = p->nTotConfLim? p->nTotConfLim - p->pSat->stats.conflicts : 0;
RetValue = sat_solver_solve( p->pSat, NULL, NULL, (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
assert( RetValue == l_Undef || RetValue == l_True || RetValue == l_False );
if ( RetValue == l_Undef )
return -1;
if ( RetValue == l_False )
return 0;
p->nCares++;
// add SAT assignment to the solver
Mint = 0;
Vec_IntForEachEntry( p->vProjVars, iVar, b )
{
Lits[b] = toLit( iVar );
if ( sat_solver_var_value( p->pSat, iVar ) )
{
Mint |= (1 << b);
Lits[b] = lit_neg( Lits[b] );
}
}
assert( !Aig_InfoHasBit(p->uCare, Mint) );
Aig_InfoSetBit( p->uCare, Mint );
// add the blocking clause
RetValue = sat_solver_addclause( p->pSat, Lits, Lits + Vec_IntSize(p->vProjVars) );
if ( RetValue == 0 )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Enumerates through the SAT assignments.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mfx_SolveSat( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Aig_Obj_t * pObjPo;
int RetValue, i;
// collect projection variables
Vec_IntClear( p->vProjVars );
Vec_PtrForEachEntryStart( p->pAigWin->vPos, pObjPo, i, Aig_ManPoNum(p->pAigWin) - Nwk_ObjFaninNum(pNode) )
{
assert( p->pCnf->pVarNums[pObjPo->Id] >= 0 );
Vec_IntPush( p->vProjVars, p->pCnf->pVarNums[pObjPo->Id] );
}
// prepare the truth table of care set
p->nFanins = Vec_IntSize( p->vProjVars );
p->nWords = Aig_TruthWordNum( p->nFanins );
memset( p->uCare, 0, sizeof(unsigned) * p->nWords );
// iterate through the SAT assignments
p->nCares = 0;
p->nTotConfLim = p->pPars->nBTLimit;
while ( (RetValue = Mfx_SolveSat_iter(p)) == 1 );
if ( RetValue == -1 )
return 0;
// write statistics
p->nMintsCare += p->nCares;
p->nMintsTotal += (1<<p->nFanins);
if ( p->pPars->fVeryVerbose )
{
printf( "Node %4d : Care = %2d. Total = %2d. ", pNode->Id, p->nCares, (1<<p->nFanins) );
// Kit_TruthPrintBinary( stdout, p->uCare, (1<<p->nFanins) );
printf( "\n" );
}
// map the care
if ( p->nFanins > 4 )
return 1;
if ( p->nFanins == 4 )
p->uCare[0] = p->uCare[0] | (p->uCare[0] << 16);
if ( p->nFanins == 3 )
p->uCare[0] = p->uCare[0] | (p->uCare[0] << 8) | (p->uCare[0] << 16) | (p->uCare[0] << 24);
if ( p->nFanins == 2 )
p->uCare[0] = p->uCare[0] | (p->uCare[0] << 4) | (p->uCare[0] << 8) | (p->uCare[0] << 12) |
(p->uCare[0] << 16) | (p->uCare[0] << 20) | (p->uCare[0] << 24) | (p->uCare[0] << 28);
assert( p->nFanins != 1 );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxStrash.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Structural hashing of the window with ODCs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Construct BDDs and mark AIG nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ConvertHopToAig_rec( Hop_Obj_t * pObj, Aig_Man_t * pMan )
{
assert( !Hop_IsComplement(pObj) );
if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
return;
Nwk_ConvertHopToAig_rec( Hop_ObjFanin0(pObj), pMan );
Nwk_ConvertHopToAig_rec( Hop_ObjFanin1(pObj), pMan );
pObj->pData = Aig_And( pMan, (Aig_Obj_t *)Hop_ObjChild0Copy(pObj), (Aig_Obj_t *)Hop_ObjChild1Copy(pObj) );
assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
Hop_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Converts the network from AIG to BDD representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ConvertHopToAig( Nwk_Obj_t * pObjOld, Aig_Man_t * pMan )
{
Hop_Man_t * pHopMan;
Hop_Obj_t * pRoot;
Nwk_Obj_t * pFanin;
int i;
// get the local AIG
pHopMan = pObjOld->pMan->pManHop;
pRoot = pObjOld->pFunc;
// check the case of a constant
if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
{
pObjOld->pCopy = (Nwk_Obj_t *)Aig_NotCond( Aig_ManConst1(pMan), Hop_IsComplement(pRoot) );
pObjOld->pNext = pObjOld->pCopy;
return;
}
// assign the fanin nodes
Nwk_ObjForEachFanin( pObjOld, pFanin, i )
Hop_ManPi(pHopMan, i)->pData = pFanin->pCopy;
// construct the AIG
Nwk_ConvertHopToAig_rec( Hop_Regular(pRoot), pMan );
pObjOld->pCopy = (Nwk_Obj_t *)Aig_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
// assign the fanin nodes
Nwk_ObjForEachFanin( pObjOld, pFanin, i )
Hop_ManPi(pHopMan, i)->pData = pFanin->pNext;
// construct the AIG
Nwk_ConvertHopToAig_rec( Hop_Regular(pRoot), pMan );
pObjOld->pNext = (Nwk_Obj_t *)Aig_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
}
/**Function*************************************************************
Synopsis [Computes the care set of the node under ODCs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Mfx_ConstructAig_rec( Mfx_Man_t * p, Nwk_Obj_t * pNode, Aig_Man_t * pMan )
{
Aig_Obj_t * pRoot, * pExor;
Nwk_Obj_t * pObj;
int i;
// assign AIG nodes to the leaves
Vec_PtrForEachEntry( p->vSupp, pObj, i )
pObj->pCopy = pObj->pNext = (Nwk_Obj_t *)Aig_ObjCreatePi( pMan );
// strash intermediate nodes
Nwk_ManIncrementTravId( pNode->pMan );
Vec_PtrForEachEntry( p->vNodes, pObj, i )
{
Nwk_ConvertHopToAig( pObj, pMan );
if ( pObj == pNode )
pObj->pNext = Aig_Not(pObj->pNext);
}
// create the observability condition
pRoot = Aig_ManConst0(pMan);
Vec_PtrForEachEntry( p->vRoots, pObj, i )
{
pExor = Aig_Exor( pMan, (Aig_Obj_t *)pObj->pCopy, (Aig_Obj_t *)pObj->pNext );
pRoot = Aig_Or( pMan, pRoot, pExor );
}
return pRoot;
}
/**Function*************************************************************
Synopsis [Adds relevant constraints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Mfx_ConstructCare_rec( Aig_Man_t * pCare, Aig_Obj_t * pObj, Aig_Man_t * pMan )
{
Aig_Obj_t * pObj0, * pObj1;
if ( Aig_ObjIsTravIdCurrent( pCare, pObj ) )
return pObj->pData;
Aig_ObjSetTravIdCurrent( pCare, pObj );
if ( Aig_ObjIsPi(pObj) )
return pObj->pData = NULL;
pObj0 = Mfx_ConstructCare_rec( pCare, Aig_ObjFanin0(pObj), pMan );
if ( pObj0 == NULL )
return pObj->pData = NULL;
pObj1 = Mfx_ConstructCare_rec( pCare, Aig_ObjFanin1(pObj), pMan );
if ( pObj1 == NULL )
return pObj->pData = NULL;
pObj0 = Aig_NotCond( pObj0, Aig_ObjFaninC0(pObj) );
pObj1 = Aig_NotCond( pObj1, Aig_ObjFaninC1(pObj) );
return pObj->pData = Aig_And( pMan, pObj0, pObj1 );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManVerifyManager( Nwk_Man_t * pNtk )
{
Nwk_Obj_t * pObj;
int i;
Nwk_ManForEachObj( pNtk, pObj, i )
{
assert( pObj->pMan == pNtk );
}
}
/**Function*************************************************************
Synopsis [Creates AIG for the window with constraints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Mfx_ConstructAig( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Aig_Man_t * pMan;
Nwk_Obj_t * pFanin;
Aig_Obj_t * pObjAig, * pPi, * pPo;
Vec_Int_t * vOuts;
int i, k, iOut;
// Nwk_ManVerifyManager( p->pNtk );
// start the new manager
pMan = Aig_ManStart( 1000 );
// construct the root node's AIG cone
pObjAig = Mfx_ConstructAig_rec( p, pNode, pMan );
// assert( Aig_ManConst1(pMan) == pObjAig );
Aig_ObjCreatePo( pMan, pObjAig );
if ( p->pCare )
{
// mark the care set
Aig_ManIncrementTravId( p->pCare );
Vec_PtrForEachEntry( p->vSupp, pFanin, i )
{
pPi = Aig_ManPi( p->pCare, pFanin->PioId );
Aig_ObjSetTravIdCurrent( p->pCare, pPi );
pPi->pData = pFanin->pCopy;
}
// construct the constraints
Vec_PtrForEachEntry( p->vSupp, pFanin, i )
{
vOuts = Vec_PtrEntry( p->vSuppsInv, pFanin->PioId );
Vec_IntForEachEntry( vOuts, iOut, k )
{
pPo = Aig_ManPo( p->pCare, iOut );
if ( Aig_ObjIsTravIdCurrent( p->pCare, pPo ) )
continue;
Aig_ObjSetTravIdCurrent( p->pCare, pPo );
if ( Aig_ObjFanin0(pPo) == Aig_ManConst1(p->pCare) )
continue;
pObjAig = Mfx_ConstructCare_rec( p->pCare, Aig_ObjFanin0(pPo), pMan );
if ( pObjAig == NULL )
continue;
pObjAig = Aig_NotCond( pObjAig, Aig_ObjFaninC0(pPo) );
Aig_ObjCreatePo( pMan, pObjAig );
}
}
/*
Aig_ManForEachPo( p->pCare, pPo, i )
{
// assert( Aig_ObjFanin0(pPo) != Aig_ManConst1(p->pCare) );
if ( Aig_ObjFanin0(pPo) == Aig_ManConst1(p->pCare) )
continue;
pObjAig = Mfx_ConstructCare_rec( p->pCare, Aig_ObjFanin0(pPo), pMan );
if ( pObjAig == NULL )
continue;
pObjAig = Aig_NotCond( pObjAig, Aig_ObjFaninC0(pPo) );
Aig_ObjCreatePo( pMan, pObjAig );
}
*/
}
if ( p->pPars->fResub )
{
// construct the node
pObjAig = (Aig_Obj_t *)pNode->pCopy;
Aig_ObjCreatePo( pMan, pObjAig );
// construct the divisors
Vec_PtrForEachEntry( p->vDivs, pFanin, i )
{
pObjAig = (Aig_Obj_t *)pFanin->pCopy;
Aig_ObjCreatePo( pMan, pObjAig );
}
}
else
{
// construct the fanins
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
pObjAig = (Aig_Obj_t *)pFanin->pCopy;
Aig_ObjCreatePo( pMan, pObjAig );
}
}
Aig_ManCleanup( pMan );
return pMan;
}
/**Function*************************************************************
Synopsis [Creates AIG for the window with constraints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Nwk_AigForConstraints( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
Aig_Man_t * pMan;
Aig_Obj_t * pPi, * pPo, * pObjAig, * pObjRoot;
Vec_Int_t * vOuts;
int i, k, iOut;
if ( p->pCare == NULL )
return NULL;
pMan = Aig_ManStart( 1000 );
// mark the care set
Aig_ManIncrementTravId( p->pCare );
Vec_PtrForEachEntry( p->vSupp, pFanin, i )
{
pPi = Aig_ManPi( p->pCare, pFanin->PioId );
Aig_ObjSetTravIdCurrent( p->pCare, pPi );
pPi->pData = Aig_ObjCreatePi(pMan);
}
// construct the constraints
pObjRoot = Aig_ManConst1(pMan);
Vec_PtrForEachEntry( p->vSupp, pFanin, i )
{
vOuts = Vec_PtrEntry( p->vSuppsInv, pFanin->PioId );
Vec_IntForEachEntry( vOuts, iOut, k )
{
pPo = Aig_ManPo( p->pCare, iOut );
if ( Aig_ObjIsTravIdCurrent( p->pCare, pPo ) )
continue;
Aig_ObjSetTravIdCurrent( p->pCare, pPo );
if ( Aig_ObjFanin0(pPo) == Aig_ManConst1(p->pCare) )
continue;
pObjAig = Mfx_ConstructCare_rec( p->pCare, Aig_ObjFanin0(pPo), pMan );
if ( pObjAig == NULL )
continue;
pObjAig = Aig_NotCond( pObjAig, Aig_ObjFaninC0(pPo) );
pObjRoot = Aig_And( pMan, pObjRoot, pObjAig );
}
}
Aig_ObjCreatePo( pMan, pObjRoot );
Aig_ManCleanup( pMan );
return pMan;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [mfxWin.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis [Procedures to compute windows stretching to the PIs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: mfxWin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mfxInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns 1 if the node should be a root.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Mfx_ComputeRootsCheck( Nwk_Obj_t * pNode, int nLevelMax, int nFanoutLimit )
{
Nwk_Obj_t * pFanout;
int i;
// the node is the root if one of the following is true:
// (1) the node has more than fanouts than the limit
if ( Nwk_ObjFanoutNum(pNode) > nFanoutLimit )
return 1;
// (2) the node has CO fanouts
// (3) the node has fanouts above the cutoff level
Nwk_ObjForEachFanout( pNode, pFanout, i )
if ( Nwk_ObjIsCo(pFanout) || pFanout->Level > nLevelMax )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Recursively collects the root candidates.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Mfx_ComputeRoots_rec( Nwk_Obj_t * pNode, int nLevelMax, int nFanoutLimit, Vec_Ptr_t * vRoots )
{
Nwk_Obj_t * pFanout;
int i;
assert( Nwk_ObjIsNode(pNode) );
if ( Nwk_ObjIsTravIdCurrent(pNode) )
return;
Nwk_ObjSetTravIdCurrent( pNode );
// check if the node should be the root
if ( Mfx_ComputeRootsCheck( pNode, nLevelMax, nFanoutLimit ) )
Vec_PtrPush( vRoots, pNode );
else // if not, explore its fanouts
Nwk_ObjForEachFanout( pNode, pFanout, i )
Mfx_ComputeRoots_rec( pFanout, nLevelMax, nFanoutLimit, vRoots );
}
/**Function*************************************************************
Synopsis [Recursively collects the root candidates.]
Description [Returns 1 if the only root is this node.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Mfx_ComputeRoots( Nwk_Obj_t * pNode, int nWinTfoMax, int nFanoutLimit )
{
Vec_Ptr_t * vRoots;
vRoots = Vec_PtrAlloc( 10 );
Nwk_ManIncrementTravId( pNode->pMan );
Mfx_ComputeRoots_rec( pNode, pNode->Level + nWinTfoMax, nFanoutLimit, vRoots );
assert( Vec_PtrSize(vRoots) > 0 );
// if ( Vec_PtrSize(vRoots) == 1 && Vec_PtrEntry(vRoots, 0) == pNode )
// return 0;
return vRoots;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntk_.c]
FileName [mfs_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [The good old minimization with complete don't-cares.]
Synopsis []
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: mfs_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "mfsInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
SRC += src/aig/mfx/mfxCore.c \
src/aig/mfx/mfxDiv.c \
src/aig/mfx/mfxInter.c \
src/aig/mfx/mfxMan.c \
src/aig/mfx/mfxResub.c \
src/aig/mfx/mfxSat.c \
src/aig/mfx/mfxStrash.c \
src/aig/mfx/mfxWin.c
SRC += src/aig/ntk/ntkCheck.c \
src/aig/ntk/ntkBidec.c \
src/aig/ntk/ntkDfs.c \
src/aig/ntk/ntkFanio.c \
src/aig/ntk/ntkMan.c \
src/aig/ntk/ntkMap.c \
src/aig/ntk/ntkObj.c \
src/aig/ntk/ntkTiming.c \
src/aig/ntk/ntkUtil.c
/**CFile****************************************************************
FileName [ntk.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntk.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __NTK_H__
#define __NTK_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "aig.h"
#include "hop.h"
#include "tim.h"
#include "if.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Ntk_Man_t_ Ntk_Man_t;
typedef struct Ntk_Obj_t_ Ntk_Obj_t;
// object types
typedef enum {
NTK_OBJ_NONE, // 0: non-existant object
NTK_OBJ_CI, // 1: combinational input
NTK_OBJ_CO, // 2: combinational output
NTK_OBJ_NODE, // 3: logic node
NTK_OBJ_BOX, // 4: white box
NTK_OBJ_LATCH, // 5: register
NTK_OBJ_VOID // 6: unused object
} Ntk_Type_t;
struct Ntk_Man_t_
{
// models of this design
char * pName; // the name of this design
char * pSpec; // the name of input file
// node representation
Vec_Ptr_t * vCis; // the primary inputs of the extracted part
Vec_Ptr_t * vCos; // the primary outputs of the extracted part
Vec_Ptr_t * vObjs; // the objects in the topological order
int nObjs[NTK_OBJ_VOID]; // counter of objects of each type
int nFanioPlus; // the number of extra fanins/fanouts alloc by default
// functionality, timing, memory, etc
Hop_Man_t * pManHop; // the functionality representation
Tim_Man_t * pManTime; // the timing manager
Aig_MmFlex_t * pMemObjs; // memory for objects
Vec_Ptr_t * vTemp; // array used for incremental updates
unsigned nTravIds; // the counter of traversal IDs
};
struct Ntk_Obj_t_
{
Ntk_Man_t * pMan; // the manager
void * pCopy; // temporary pointer
Hop_Obj_t * pFunc; // functionality
// node information
int Id; // unique ID
int PioId; // number of this node in the PI/PO list
unsigned Type : 3; // object type
unsigned fCompl : 1; // complemented attribute
unsigned MarkA : 1; // temporary mark
unsigned MarkB : 1; // temporary mark
unsigned TravId : 26; // traversal ID
// timing information
float tArrival; // the arrival time
float tRequired; // the required time
float tSlack; // the slack
// fanin/fanout representation
unsigned nFanins : 6; // the number of fanins
unsigned nFanouts : 26; // the number of fanouts
int nFanioAlloc; // the number of allocated fanins/fanouts
Ntk_Obj_t * pFanio[0]; // fanins/fanouts
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// INLINED FUNCTIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Ntk_ManCiNum( Ntk_Man_t * p ) { return p->nObjs[NTK_OBJ_CI]; }
static inline int Ntk_ManCoNum( Ntk_Man_t * p ) { return p->nObjs[NTK_OBJ_CO]; }
static inline int Ntk_ManNodeNum( Ntk_Man_t * p ) { return p->nObjs[NTK_OBJ_NODE]; }
static inline int Ntk_ManLatchNum( Ntk_Man_t * p ) { return p->nObjs[NTK_OBJ_LATCH]; }
static inline int Ntk_ManBoxNum( Ntk_Man_t * p ) { return p->nObjs[NTK_OBJ_BOX]; }
static inline int Ntk_ManObjNumMax( Ntk_Man_t * p ) { return Vec_PtrSize(p->vObjs); }
static inline Ntk_Obj_t * Ntk_ManCi( Ntk_Man_t * p, int i ) { return Vec_PtrEntry( p->vCis, i ); }
static inline Ntk_Obj_t * Ntk_ManCo( Ntk_Man_t * p, int i ) { return Vec_PtrEntry( p->vCos, i ); }
static inline Ntk_Obj_t * Ntk_ManObj( Ntk_Man_t * p, int i ) { return Vec_PtrEntry( p->vObjs, i ); }
static inline int Ntk_ObjFaninNum( Ntk_Obj_t * p ) { return p->nFanins; }
static inline int Ntk_ObjFanoutNum( Ntk_Obj_t * p ) { return p->nFanouts; }
static inline Ntk_Obj_t * Ntk_ObjFanin0( Ntk_Obj_t * p ) { return p->pFanio[0]; }
static inline Ntk_Obj_t * Ntk_ObjFanout0( Ntk_Obj_t * p ) { return p->pFanio[p->nFanins]; }
static inline Ntk_Obj_t * Ntk_ObjFanin( Ntk_Obj_t * p, int i ) { return p->pFanio[i]; }
static inline Ntk_Obj_t * Ntk_ObjFanout( Ntk_Obj_t * p, int i ) { return p->pFanio[p->nFanins+1]; }
static inline int Ntk_ObjIsCi( Ntk_Obj_t * p ) { return p->Type == NTK_OBJ_CI; }
static inline int Ntk_ObjIsCo( Ntk_Obj_t * p ) { return p->Type == NTK_OBJ_CO; }
static inline int Ntk_ObjIsNode( Ntk_Obj_t * p ) { return p->Type == NTK_OBJ_NODE; }
static inline int Ntk_ObjIsLatch( Ntk_Obj_t * p ) { return p->Type == NTK_OBJ_LATCH; }
static inline int Ntk_ObjIsBox( Ntk_Obj_t * p ) { return p->Type == NTK_OBJ_BOX; }
static inline int Ntk_ObjIsPi( Ntk_Obj_t * p ) { return Ntk_ObjIsCi(p) && Tim_ManBoxForCi(p->pMan->pManTime, p->PioId) == -1; }
static inline int Ntk_ObjIsPo( Ntk_Obj_t * p ) { return Ntk_ObjIsCo(p) && Tim_ManBoxForCo(p->pMan->pManTime, p->PioId) == -1; }
static inline float Ntk_ObjArrival( Ntk_Obj_t * pObj ) { return pObj->tArrival; }
static inline float Ntk_ObjRequired( Ntk_Obj_t * pObj ) { return pObj->tRequired; }
static inline float Ntk_ObjSlack( Ntk_Obj_t * pObj ) { return pObj->tSlack; }
static inline void Ntk_ObjSetArrival( Ntk_Obj_t * pObj, float Time ) { pObj->tArrival = Time; }
static inline void Ntk_ObjSetRequired( Ntk_Obj_t * pObj, float Time ) { pObj->tRequired = Time; }
static inline void Ntk_ObjSetSlack( Ntk_Obj_t * pObj, float Time ) { pObj->tSlack = Time; }
static inline int Ntk_ObjLevel( Ntk_Obj_t * pObj ) { return (int)pObj->tArrival; }
static inline void Ntk_ObjSetLevel( Ntk_Obj_t * pObj, int Lev ) { pObj->tArrival = (float)Lev; }
static inline void Ntk_ObjSetTravId( Ntk_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; }
static inline void Ntk_ObjSetTravIdCurrent( Ntk_Obj_t * pObj ) { pObj->TravId = pObj->pMan->nTravIds; }
static inline void Ntk_ObjSetTravIdPrevious( Ntk_Obj_t * pObj ) { pObj->TravId = pObj->pMan->nTravIds - 1; }
static inline int Ntk_ObjIsTravIdCurrent( Ntk_Obj_t * pObj ) { return pObj->TravId == pObj->pMan->nTravIds; }
static inline int Ntk_ObjIsTravIdPrevious( Ntk_Obj_t * pObj ) { return pObj->TravId == pObj->pMan->nTravIds - 1; }
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
#define Ntk_ManForEachCi( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCis, pObj, i )
#define Ntk_ManForEachCo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCos, pObj, i )
#define Ntk_ManForEachPi( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCis, pObj, i ) \
if ( !Ntk_ObjIsPi(pObj) ) {} else
#define Ntk_ManForEachPo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCos, pObj, i ) \
if ( !Ntk_ObjIsPo(pObj) ) {} else
#define Ntk_ManForEachObj( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( pObj == NULL ) {} else
#define Ntk_ManForEachNode( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( !Ntk_ObjIsNode(pObj) ) {} else
#define Ntk_ManForEachBox( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( !Ntk_ObjIsBox(pObj) ) {} else
#define Ntk_ManForEachLatch( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( !Ntk_ObjIsLatch(pObj) ) {} else
#define Ntk_ObjForEachFanin( pObj, pFanin, i ) \
for ( i = 0; (i < (int)(pObj)->nFanins) && ((pFanin) = (pObj)->pFanio[i]); i++ )
#define Ntk_ObjForEachFanout( pObj, pFanout, i ) \
for ( i = 0; (i < (int)(pObj)->nFanouts) && ((pFanout) = (pObj)->pFanio[(pObj)->nFanins+i]); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== ntkDfs.c ==========================================================*/
extern int Ntk_ManLevel( Ntk_Man_t * pNtk );
extern int Ntk_ManLevel2( Ntk_Man_t * pNtk );
extern Vec_Ptr_t * Ntk_ManDfs( Ntk_Man_t * pNtk );
extern Vec_Ptr_t * Ntk_ManDfsReverse( Ntk_Man_t * pNtk );
/*=== ntkFanio.c ==========================================================*/
extern void Ntk_ObjCollectFanins( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern void Ntk_ObjCollectFanouts( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern void Ntk_ObjAddFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin );
extern void Ntk_ObjDeleteFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin );
extern void Ntk_ObjPatchFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFaninOld, Ntk_Obj_t * pFaninNew );
extern void Ntk_ObjReplace( Ntk_Obj_t * pNodeOld, Ntk_Obj_t * pNodeNew );
/*=== ntkMan.c ============================================================*/
extern Ntk_Man_t * Ntk_ManAlloc();
extern void Ntk_ManFree( Ntk_Man_t * p );
extern void Ntk_ManPrintStats( Ntk_Man_t * p, If_Lib_t * pLutLib );
/*=== ntkMap.c ============================================================*/
/*=== ntkObj.c ============================================================*/
extern Ntk_Obj_t * Ntk_ManCreateCi( Ntk_Man_t * pMan, int nFanouts );
extern Ntk_Obj_t * Ntk_ManCreateCo( Ntk_Man_t * pMan );
extern Ntk_Obj_t * Ntk_ManCreateNode( Ntk_Man_t * pMan, int nFanins, int nFanouts );
extern Ntk_Obj_t * Ntk_ManCreateBox( Ntk_Man_t * pMan, int nFanins, int nFanouts );
extern Ntk_Obj_t * Ntk_ManCreateLatch( Ntk_Man_t * pMan );
extern void Ntk_ManDeleteNode( Ntk_Obj_t * pObj );
extern void Ntk_ManDeleteNode_rec( Ntk_Obj_t * pObj );
/*=== ntkTiming.c ============================================================*/
extern float Ntk_ManDelayTraceLut( Ntk_Man_t * pNtk, If_Lib_t * pLutLib );
extern void Ntk_ManDelayTracePrint( Ntk_Man_t * pNtk, If_Lib_t * pLutLib );
/*=== ntkUtil.c ============================================================*/
extern void Ntk_ManIncrementTravId( Ntk_Man_t * pNtk );
extern int Ntk_ManGetFaninMax( Ntk_Man_t * pNtk );
extern int Ntk_ManGetTotalFanins( Ntk_Man_t * pNtk );
extern int Ntk_ManPiNum( Ntk_Man_t * pNtk );
extern int Ntk_ManPoNum( Ntk_Man_t * pNtk );
extern int Ntk_ManGetAigNodeNum( Ntk_Man_t * pNtk );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkDfs.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [DFS traversals.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes the number of logic levels not counting PIs/POs.]
Description [Assumes that white boxes have unit level.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManLevel( Ntk_Man_t * pNtk )
{
Tim_Man_t * pManTimeUnit;
Ntk_Obj_t * pObj, * pFanin;
int i, k, LevelMax, Level;
// clean the levels
Ntk_ManForEachObj( pNtk, pObj, i )
Ntk_ObjSetLevel( pObj, 0 );
// perform level computation
LevelMax = 0;
pManTimeUnit = Tim_ManDupUnit( pNtk->pManTime );
Tim_ManIncrementTravId( pManTimeUnit );
Ntk_ManForEachObj( pNtk, pObj, i )
{
if ( Ntk_ObjIsCi(pObj) )
{
Level = (int)Tim_ManGetPiArrival( pManTimeUnit, pObj->PioId );
Ntk_ObjSetLevel( pObj, Level );
}
else if ( Ntk_ObjIsCo(pObj) )
{
Level = Ntk_ObjLevel( Ntk_ObjFanin0(pObj) );
Tim_ManSetPoArrival( pManTimeUnit, pObj->PioId, (float)Level );
Ntk_ObjSetLevel( pObj, Level );
if ( LevelMax < Ntk_ObjLevel(pObj) )
LevelMax = Ntk_ObjLevel(pObj);
}
else if ( Ntk_ObjIsNode(pObj) )
{
Level = 0;
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( Level < Ntk_ObjLevel(pFanin) )
Level = Ntk_ObjLevel(pFanin);
Ntk_ObjSetLevel( pObj, Level + 1 );
}
else
assert( 0 );
}
// set the old timing manager
Tim_ManStop( pManTimeUnit );
return LevelMax;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManLevel2_rec( Ntk_Obj_t * pObj )
{
Ntk_Obj_t * pNext;
int i, iBox, iTerm1, nTerms, LevelMax = 0;
if ( Ntk_ObjIsTravIdCurrent( pObj ) )
return;
Ntk_ObjSetTravIdCurrent( pObj );
if ( Ntk_ObjIsCi(pObj) )
{
iBox = Tim_ManBoxForCi( pObj->pMan->pManTime, pObj->PioId );
if ( iBox >= 0 ) // this is not a true PI
{
iTerm1 = Tim_ManBoxInputFirst( pObj->pMan->pManTime, iBox );
nTerms = Tim_ManBoxInputNum( pObj->pMan->pManTime, iBox );
for ( i = 0; i < nTerms; i++ )
{
pNext = Ntk_ManCo(pObj->pMan, iTerm1 + i);
Ntk_ManLevel2_rec( pNext );
if ( LevelMax < Ntk_ObjLevel(pNext) )
LevelMax = Ntk_ObjLevel(pNext);
}
LevelMax++;
}
}
else if ( Ntk_ObjIsNode(pObj) || Ntk_ObjIsCo(pObj) )
{
Ntk_ObjForEachFanin( pObj, pNext, i )
{
Ntk_ManLevel2_rec( pNext );
if ( LevelMax < Ntk_ObjLevel(pNext) )
LevelMax = Ntk_ObjLevel(pNext);
}
if ( Ntk_ObjIsNode(pObj) )
LevelMax++;
}
else
assert( 0 );
Ntk_ObjSetLevel( pObj, LevelMax );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManLevel2( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pObj;
int i, LevelMax = 0;
Ntk_ManForEachObj( pNtk, pObj, i )
Ntk_ObjSetLevel( pObj, 0 );
Ntk_ManIncrementTravId( pNtk );
Ntk_ManForEachPo( pNtk, pObj, i )
{
Ntk_ManLevel2_rec( pObj );
if ( LevelMax < Ntk_ObjLevel(pObj) )
LevelMax = Ntk_ObjLevel(pObj);
}
return LevelMax;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDfs_rec( Ntk_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
Ntk_Obj_t * pNext;
int i;
if ( Ntk_ObjIsTravIdCurrent( pObj ) )
return;
Ntk_ObjSetTravIdCurrent( pObj );
Ntk_ObjForEachFanin( pObj, pNext, i )
Ntk_ManDfs_rec( pNext, vNodes );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ntk_ManDfs( Ntk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Ntk_Obj_t * pObj;
int i;
Ntk_ManIncrementTravId( pNtk );
vNodes = Vec_PtrAlloc( 100 );
Ntk_ManForEachObj( pNtk, pObj, i )
{
if ( Ntk_ObjIsCi(pObj) )
{
Ntk_ObjSetTravIdCurrent( pObj );
Vec_PtrPush( vNodes, pObj );
}
else if ( Ntk_ObjIsCo(pObj) )
Ntk_ManDfs_rec( pObj, vNodes );
}
return vNodes;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDfsReverse_rec( Ntk_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
Ntk_Obj_t * pNext;
int i, iBox, iTerm1, nTerms;
if ( Ntk_ObjIsTravIdCurrent( pObj ) )
return;
Ntk_ObjSetTravIdCurrent( pObj );
if ( Ntk_ObjIsCo(pObj) )
{
iBox = Tim_ManBoxForCo( pObj->pMan->pManTime, pObj->PioId );
if ( iBox >= 0 ) // this is not a true PO
{
iTerm1 = Tim_ManBoxOutputFirst( pObj->pMan->pManTime, iBox );
nTerms = Tim_ManBoxOutputNum( pObj->pMan->pManTime, iBox );
for ( i = 0; i < nTerms; i++ )
{
pNext = Ntk_ManCi(pObj->pMan, iTerm1 + i);
Ntk_ManDfsReverse_rec( pNext, vNodes );
}
}
}
else if ( Ntk_ObjIsNode(pObj) || Ntk_ObjIsCi(pObj) )
{
Ntk_ObjForEachFanout( pObj, pNext, i )
Ntk_ManDfsReverse_rec( pNext, vNodes );
}
else
assert( 0 );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ntk_ManDfsReverse( Ntk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Ntk_Obj_t * pObj;
int i;
Ntk_ManIncrementTravId( pNtk );
vNodes = Vec_PtrAlloc( 100 );
Ntk_ManForEachPi( pNtk, pObj, i )
Ntk_ManDfsReverse_rec( pObj, vNodes );
return vNodes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkTiming.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Manipulation of timing information.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern void * Abc_FrameReadLibLut();
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrepareTiming( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pObj;
int i;
Ntk_ManForEachObj( pNtk, pObj, i )
{
pObj->tArrival = pObj->tSlack = 0.0;
pObj->tRequired = AIG_INFINITY;
}
}
/**Function*************************************************************
Synopsis [Sorts the pins in the decreasing order of delays.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDelayTraceSortPins( Ntk_Obj_t * pNode, int * pPinPerm, float * pPinDelays )
{
Ntk_Obj_t * pFanin;
int i, j, best_i, temp;
// start the trivial permutation and collect pin delays
Ntk_ObjForEachFanin( pNode, pFanin, i )
{
pPinPerm[i] = i;
pPinDelays[i] = Ntk_ObjArrival(pFanin);
}
// selection sort the pins in the decreasible order of delays
// this order will match the increasing order of LUT input pins
for ( i = 0; i < Ntk_ObjFaninNum(pNode)-1; i++ )
{
best_i = i;
for ( j = i+1; j < Ntk_ObjFaninNum(pNode); j++ )
if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] )
best_i = j;
if ( best_i == i )
continue;
temp = pPinPerm[i];
pPinPerm[i] = pPinPerm[best_i];
pPinPerm[best_i] = temp;
}
// verify
assert( Ntk_ObjFaninNum(pNode) == 0 || pPinPerm[0] < Ntk_ObjFaninNum(pNode) );
for ( i = 1; i < Ntk_ObjFaninNum(pNode); i++ )
{
assert( pPinPerm[i] < Ntk_ObjFaninNum(pNode) );
assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Ntk_ManDelayTraceLut( Ntk_Man_t * pNtk, If_Lib_t * pLutLib )
{
int fUseSorting = 1;
int pPinPerm[32];
float pPinDelays[32];
Ntk_Obj_t * pObj, * pFanin;
Vec_Ptr_t * vNodes;
float tArrival, tRequired, tSlack, * pDelays;
int i, k;
// get the library
if ( pLutLib && pLutLib->LutMax < Ntk_ManGetFaninMax(pNtk) )
{
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
pLutLib->LutMax, Ntk_ManGetFaninMax(pNtk) );
return -AIG_INFINITY;
}
// compute the reverse order of all objects
vNodes = Ntk_ManDfsReverse( pNtk );
// initialize the arrival times
Abc_NtkPrepareTiming( pNtk );
// propagate arrival times
Tim_ManIncrementTravId( pNtk->pManTime );
Ntk_ManForEachObj( pNtk, pObj, i )
{
if ( Ntk_ObjIsNode(pObj) )
{
tArrival = -AIG_INFINITY;
if ( pLutLib == NULL )
{
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Ntk_ObjArrival(pFanin) + 1.0 )
tArrival = Ntk_ObjArrival(pFanin) + 1.0;
}
else if ( !pLutLib->fVarPinDelays )
{
pDelays = pLutLib->pLutDelays[Ntk_ObjFaninNum(pObj)];
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Ntk_ObjArrival(pFanin) + pDelays[0] )
tArrival = Ntk_ObjArrival(pFanin) + pDelays[0];
}
else
{
pDelays = pLutLib->pLutDelays[Ntk_ObjFaninNum(pObj)];
if ( fUseSorting )
{
Ntk_ManDelayTraceSortPins( pObj, pPinPerm, pPinDelays );
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Ntk_ObjArrival(Ntk_ObjFanin(pObj,pPinPerm[k])) + pDelays[k] )
tArrival = Ntk_ObjArrival(Ntk_ObjFanin(pObj,pPinPerm[k])) + pDelays[k];
}
else
{
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Ntk_ObjArrival(pFanin) + pDelays[k] )
tArrival = Ntk_ObjArrival(pFanin) + pDelays[k];
}
}
if ( Ntk_ObjFaninNum(pObj) == 0 )
tArrival = 0.0;
}
else if ( Ntk_ObjIsCi(pObj) )
{
tArrival = Tim_ManGetPiArrival( pNtk->pManTime, pObj->PioId );
}
else if ( Ntk_ObjIsCo(pObj) )
{
tArrival = Ntk_ObjArrival( Ntk_ObjFanin0(pObj) );
Tim_ManSetPoArrival( pNtk->pManTime, pObj->PioId, tArrival );
}
else
assert( 0 );
Ntk_ObjSetArrival( pObj, tArrival );
}
// get the latest arrival times
tArrival = -AIG_INFINITY;
Ntk_ManForEachPo( pNtk, pObj, i )
if ( tArrival < Ntk_ObjArrival(Ntk_ObjFanin0(pObj)) )
tArrival = Ntk_ObjArrival(Ntk_ObjFanin0(pObj));
// initialize the required times
Ntk_ManForEachPo( pNtk, pObj, i )
if ( Ntk_ObjRequired(Ntk_ObjFanin0(pObj)) > tArrival )
Ntk_ObjSetRequired( Ntk_ObjFanin0(pObj), tArrival );
// propagate the required times
Tim_ManIncrementTravId( pNtk->pManTime );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( Ntk_ObjIsNode(pObj) )
{
if ( pLutLib == NULL )
{
tRequired = Ntk_ObjRequired(pObj) - (float)1.0;
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( Ntk_ObjRequired(pFanin) > tRequired )
Ntk_ObjSetRequired( pFanin, tRequired );
}
else if ( !pLutLib->fVarPinDelays )
{
pDelays = pLutLib->pLutDelays[Ntk_ObjFaninNum(pObj)];
tRequired = Ntk_ObjRequired(pObj) - pDelays[0];
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( Ntk_ObjRequired(pFanin) > tRequired )
Ntk_ObjSetRequired( pFanin, tRequired );
}
else
{
pDelays = pLutLib->pLutDelays[Ntk_ObjFaninNum(pObj)];
if ( fUseSorting )
{
Ntk_ManDelayTraceSortPins( pObj, pPinPerm, pPinDelays );
Ntk_ObjForEachFanin( pObj, pFanin, k )
{
tRequired = Ntk_ObjRequired(pObj) - pDelays[k];
if ( Ntk_ObjRequired(Ntk_ObjFanin(pObj,pPinPerm[k])) > tRequired )
Ntk_ObjSetRequired( Ntk_ObjFanin(pObj,pPinPerm[k]), tRequired );
}
}
else
{
Ntk_ObjForEachFanin( pObj, pFanin, k )
{
tRequired = Ntk_ObjRequired(pObj) - pDelays[k];
if ( Ntk_ObjRequired(pFanin) > tRequired )
Ntk_ObjSetRequired( pFanin, tRequired );
}
}
}
}
else if ( Ntk_ObjIsCi(pObj) )
{
tRequired = Ntk_ObjRequired(pObj);
Tim_ManSetPiRequired( pNtk->pManTime, pObj->PioId, tRequired );
}
else if ( Ntk_ObjIsCo(pObj) )
{
tRequired = Tim_ManGetPoRequired( pNtk->pManTime, pObj->PioId );
if ( Ntk_ObjRequired(Ntk_ObjFanin0(pObj)) > tRequired )
Ntk_ObjSetRequired( Ntk_ObjFanin0(pObj), tRequired );
}
// set slack for this object
tSlack = Ntk_ObjRequired(pObj) - Ntk_ObjArrival(pObj);
assert( tSlack + 0.001 > 0.0 );
Ntk_ObjSetSlack( pObj, tSlack < 0.0 ? 0.0 : tSlack );
}
Vec_PtrFree( vNodes );
return tArrival;
}
/**Function*************************************************************
Synopsis [Delay tracing of the LUT mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDelayTracePrint( Ntk_Man_t * pNtk, If_Lib_t * pLutLib )
{
Ntk_Obj_t * pNode;
int i, Nodes, * pCounters;
float tArrival, tDelta, nSteps, Num;
// get the library
if ( pLutLib && pLutLib->LutMax < Ntk_ManGetFaninMax(pNtk) )
{
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
pLutLib->LutMax, Ntk_ManGetFaninMax(pNtk) );
return;
}
// decide how many steps
nSteps = pLutLib ? 20 : Ntk_ManLevel(pNtk);
pCounters = ALLOC( int, nSteps + 1 );
memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
// perform delay trace
tArrival = Ntk_ManDelayTraceLut( pNtk, pLutLib );
tDelta = tArrival / nSteps;
// count how many nodes have slack in the corresponding intervals
Ntk_ManForEachNode( pNtk, pNode, i )
{
if ( Ntk_ObjFaninNum(pNode) == 0 )
continue;
Num = Ntk_ObjSlack(pNode) / tDelta;
if ( Num > nSteps )
continue;
assert( Num >=0 && Num <= nSteps );
pCounters[(int)Num]++;
}
// print the results
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
Nodes = 0;
for ( i = 0; i < nSteps; i++ )
{
Nodes += pCounters[i];
printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
pLutLib? "%":"lev", Nodes, 100.0*Nodes/Ntk_ManNodeNum(pNtk) );
}
free( pCounters );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -31,7 +31,7 @@ extern "C" {
#include "aig.h"
#include "tim.h"
#include "ntk.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
......@@ -94,11 +94,14 @@ struct Ntl_Mod_t_
Vec_Int_t * vArrivals;
Vec_Int_t * vRequireds;
float * pDelayTable;
// other data members
void * pCopy;
};
struct Ntl_Obj_t_
{
Ntl_Mod_t * pModel; // the model
void * pCopy; // the copy of this object
unsigned Type : 3; // object type
unsigned Id : 27; // object ID
unsigned MarkA : 1; // temporary mark
......@@ -115,9 +118,9 @@ struct Ntl_Obj_t_
struct Ntl_Net_t_
{
Ntl_Obj_t * pDriver; // driver of the net
Ntl_Net_t * pNext; // next net in the hash table
Aig_Obj_t * pFunc; // the AIG representation
void * pCopy; // the copy of this object
Ntl_Obj_t * pDriver; // driver of the net
char nVisits; // the number of times the net is visited
char fMark; // temporary mark
char pName[0]; // the name of this net
......@@ -140,6 +143,8 @@ struct Ntl_Lut_t_
/// INLINED FUNCTIONS ///
////////////////////////////////////////////////////////////////////////
static inline Ntl_Mod_t * Ntl_ManRootModel( Ntl_Man_t * p ) { return Vec_PtrEntry( p->vModels, 0 ); }
static inline int Ntl_ModelPiNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PI]; }
static inline int Ntl_ModelPoNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PO]; }
static inline int Ntl_ModelNodeNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_NODE]; }
......@@ -169,7 +174,7 @@ static inline Ntl_Net_t * Ntl_ObjFanin0( Ntl_Obj_t * p ) { return p->pF
static inline Ntl_Net_t * Ntl_ObjFanout0( Ntl_Obj_t * p ) { return p->pFanio[p->nFanins]; }
static inline Ntl_Net_t * Ntl_ObjFanin( Ntl_Obj_t * p, int i ) { return p->pFanio[i]; }
static inline Ntl_Net_t * Ntl_ObjFanout( Ntl_Obj_t * p, int i ) { return p->pFanio[p->nFanins+1]; }
static inline Ntl_Net_t * Ntl_ObjFanout( Ntl_Obj_t * p, int i ) { return p->pFanio[p->nFanins+i]; }
static inline void Ntl_ObjSetFanin( Ntl_Obj_t * p, Ntl_Net_t * pNet, int i ) { p->pFanio[i] = pNet; }
static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int i ) { p->pFanio[p->nFanins+i] = pNet; pNet->pDriver = p; }
......@@ -186,10 +191,10 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int
Vec_PtrForEachEntry( p->vCos, pNtl, i )
#define Ntl_ManForEachNode( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vNodes)) && (((pObj) = Vec_PtrEntry(p->vNodes, i)), 1); i++ ) \
if ( !Ntl_ObjIsNode(pObj) ) {} else
if ( (pObj) == NULL || !Ntl_ObjIsNode(pObj) ) {} else
#define Ntl_ManForEachBox( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vNodes)) && (((pObj) = Vec_PtrEntry(p->vNodes, i)), 1); i++ ) \
if ( !Ntl_ObjIsBox(pObj) ) {} else
if ( (pObj) == NULL || !Ntl_ObjIsBox(pObj) ) {} else
#define Ntl_ModelForEachPi( pNtl, pObj, i ) \
Vec_PtrForEachEntry( pNtl->vPis, pObj, i )
......@@ -200,13 +205,13 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int
if ( pObj == NULL ) {} else
#define Ntl_ModelForEachLatch( pNtl, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(pNtl->vObjs)) && (((pObj) = Vec_PtrEntry(pNtl->vObjs, i)), 1); i++ ) \
if ( !Ntl_ObjIsLatch(pObj) ) {} else
if ( (pObj) == NULL || !Ntl_ObjIsLatch(pObj) ) {} else
#define Ntl_ModelForEachNode( pNtl, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(pNtl->vObjs)) && (((pObj) = Vec_PtrEntry(pNtl->vObjs, i)), 1); i++ ) \
if ( !Ntl_ObjIsNode(pObj) ) {} else
if ( (pObj) == NULL || !Ntl_ObjIsNode(pObj) ) {} else
#define Ntl_ModelForEachBox( pNtl, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(pNtl->vObjs)) && (((pObj) = Vec_PtrEntry(pNtl->vObjs, i)), 1); i++ ) \
if ( !Ntl_ObjIsBox(pObj) ) {} else
if ( (pObj) == NULL || !Ntl_ObjIsBox(pObj) ) {} else
#define Ntl_ModelForEachNet( pNtl, pNet, i ) \
for ( i = 0; i < pNtl->nTableSize; i++ ) \
for ( pNet = pNtl->pTable[i]; pNet; pNet = pNet->pNext )
......@@ -225,21 +230,25 @@ extern int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig );
/*=== ntlExtract.c ==========================================================*/
extern Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p );
extern Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p );
extern char * Ntl_SopFromTruth( Ntl_Man_t * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover );
/*=== ntlInsert.c ==========================================================*/
extern int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig );
extern int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk );
extern int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk );
/*=== ntlCheck.c ==========================================================*/
extern int Ntl_ManCheck( Ntl_Man_t * pMan );
extern int Ntl_ModelCheck( Ntl_Mod_t * pModel );
extern void Ntl_ModelFixNonDrivenNets( Ntl_Mod_t * pModel );
/*=== ntlMan.c ============================================================*/
extern Ntl_Man_t * Ntl_ManAlloc( char * pFileName );
extern Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * p );
extern Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * p );
extern void Ntl_ManFree( Ntl_Man_t * p );
extern Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, char * pName );
extern void Ntl_ManPrintStats( Ntl_Man_t * p );
extern Tim_Man_t * Ntl_ManReadTimeMan( Ntl_Man_t * p );
extern Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName );
extern Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld );
extern void Ntl_ModelFree( Ntl_Mod_t * p );
/*=== ntlMap.c ============================================================*/
extern Vec_Ptr_t * Ntl_MappingAlloc( int nLuts, int nVars );
......@@ -252,14 +261,15 @@ extern Ntl_Obj_t * Ntl_ModelCreatePo( Ntl_Mod_t * pModel, Ntl_Net_t * pNet )
extern Ntl_Obj_t * Ntl_ModelCreateLatch( Ntl_Mod_t * pModel );
extern Ntl_Obj_t * Ntl_ModelCreateNode( Ntl_Mod_t * pModel, int nFanins );
extern Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts );
extern Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld );
extern char * Ntl_ManStoreName( Ntl_Man_t * p, char * pName );
extern char * Ntl_ManStoreSop( Ntl_Man_t * p, char * pSop );
extern char * Ntl_ManStoreFileName( Ntl_Man_t * p, char * pFileName );
/*=== ntlTable.c ==========================================================*/
extern Ntl_Net_t * Ntl_ModelFindNet( Ntl_Mod_t * p, char * pName );
extern Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName );
extern int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
extern int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber );
extern int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
/*=== ntlTime.c ==========================================================*/
extern Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p );
/*=== ntlReadBlif.c ==========================================================*/
......
......@@ -40,11 +40,40 @@
SeeAlso []
***********************************************************************/
int Ntl_ManCheck( Ntl_Man_t * pMan )
int Ntl_ModelCheck( Ntl_Mod_t * pModel )
{
// check that the models have unique names
// check that the models (except the first one) do not have boxes
return 1;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i, k, fStatus = 1;
Ntl_ModelForEachNet( pModel, pNet, i )
{
if ( pNet->pName == NULL )
{
printf( "Net %d does not have a name\n", i );
fStatus = 0;
}
if ( pNet->pDriver == NULL )
{
printf( "Net %d (%s) does not have a driver\n", i, pNet->pName );
fStatus = 0;
}
}
Ntl_ModelForEachObj( pModel, pObj, i )
{
Ntl_ObjForEachFanin( pObj, pNet, k )
if ( pNet == NULL )
{
printf( "Object %d does not have fanin net %d\n", i, k );
fStatus = 0;
}
Ntl_ObjForEachFanout( pObj, pNet, k )
if ( pNet == NULL )
{
printf( "Object %d does not have fanout net %d\n", i, k );
fStatus = 0;
}
}
return fStatus;
}
/**Function*************************************************************
......@@ -58,9 +87,45 @@ int Ntl_ManCheck( Ntl_Man_t * pMan )
SeeAlso []
***********************************************************************/
int Ntl_ModelCheck( Ntl_Mod_t * pModel )
int Ntl_ManCheck( Ntl_Man_t * pMan )
{
return 1;
Ntl_Mod_t * pMod1, * pMod2;
int i, k, fStatus = 1;
// check that the models have unique names
Ntl_ManForEachModel( pMan, pMod1, i )
{
if ( pMod1->pName == NULL )
{
printf( "Model %d does not have a name\n", i );
fStatus = 0;
}
Ntl_ManForEachModel( pMan, pMod2, k )
{
if ( i >= k )
continue;
if ( strcmp(pMod1->pName, pMod2->pName) == 0 )
{
printf( "Models %d and %d have the same name (%s).\n", i, k, pMod1->pName );
fStatus = 0;
}
}
}
// check that the models (except the first one) do not have boxes
Ntl_ManForEachModel( pMan, pMod1, i )
{
if ( i == 0 )
continue;
if ( Ntl_ModelBoxNum(pMod1) > 0 )
{
printf( "Non-root model %d (%s) has %d boxes.\n", i, pMod1->pName, Ntl_ModelBoxNum(pMod1) );
fStatus = 0;
}
}
// check models
Ntl_ManForEachModel( pMan, pMod1, i )
if ( !Ntl_ModelCheck( pMod1 ) )
fStatus = 0;
return fStatus;
}
......
......@@ -269,9 +269,9 @@ Aig_Obj_t * Ntl_ConvertSopToAigInternal( Aig_Man_t * pMan, Ntl_Obj_t * pNode, ch
{
pNet = Ntl_ObjFanin( pNode, i );
if ( Value == '1' )
pAnd = Aig_And( pMan, pAnd, pNet->pFunc );
pAnd = Aig_And( pMan, pAnd, pNet->pCopy );
else if ( Value == '0' )
pAnd = Aig_And( pMan, pAnd, Aig_Not(pNet->pFunc) );
pAnd = Aig_And( pMan, pAnd, Aig_Not(pNet->pCopy) );
}
// add to the sum of cubes
pSum = Aig_Or( pMan, pSum, pAnd );
......@@ -326,7 +326,7 @@ Aig_Obj_t * Ntl_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
SeeAlso []
***********************************************************************/
Aig_Obj_t * Ntl_ManExtractAigNode( Ntl_Obj_t * pNode )
Aig_Obj_t * Ntl_ManBuildNodeAig( Ntl_Obj_t * pNode )
{
Aig_Man_t * pMan = pNode->pModel->pMan->pAig;
int fUseFactor = 0;
......@@ -344,7 +344,7 @@ Aig_Obj_t * Ntl_ManExtractAigNode( Ntl_Obj_t * pNode )
pFForm = Dec_Factor( pNode->pSop );
// collect the fanins
Dec_GraphForEachLeaf( pFForm, pFFNode, i )
pFFNode->pFunc = Ntl_ObjFanin(pNode, i)->pFunc;
pFFNode->pFunc = Ntl_ObjFanin(pNode, i)->pCopy;
// perform strashing
pFunc = Ntl_GraphToNetworkAig( pMan, pFForm );
Dec_GraphFree( pFForm );
......@@ -391,23 +391,23 @@ int Ntl_ManExtract_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
Vec_IntPush( p->vBox1Cos, Aig_ManPoNum(p->pAig) );
Ntl_ObjForEachFanin( pObj, pNetFanin, i )
{
LevelCur = Aig_ObjLevel( Aig_Regular(pNetFanin->pFunc) );
LevelCur = Aig_ObjLevel( Aig_Regular(pNetFanin->pCopy) );
LevelMax = AIG_MAX( LevelMax, LevelCur );
Vec_PtrPush( p->vCos, pNetFanin );
Aig_ObjCreatePo( p->pAig, pNetFanin->pFunc );
Aig_ObjCreatePo( p->pAig, pNetFanin->pCopy );
}
Ntl_ObjForEachFanout( pObj, pNetFanin, i )
{
Vec_PtrPush( p->vCis, pNetFanin );
pNetFanin->pFunc = Aig_ObjCreatePi( p->pAig );
Aig_ObjSetLevel( pNetFanin->pFunc, LevelMax + 1 );
pNetFanin->pCopy = Aig_ObjCreatePi( p->pAig );
Aig_ObjSetLevel( pNetFanin->pCopy, LevelMax + 1 );
}
//printf( "Creating fake PO with ID = %d.\n", Aig_ManPo(p->pAig, Vec_IntEntryLast(p->vBox1Cos))->Id );
}
// store the node
Vec_PtrPush( p->vNodes, pObj );
if ( Ntl_ObjIsNode(pObj) )
pNet->pFunc = Ntl_ManExtractAigNode( pObj );
pNet->pCopy = Ntl_ManBuildNodeAig( pObj );
pNet->nVisits = 2;
return 1;
}
......@@ -441,14 +441,17 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
p->pAig->pName = Aig_UtilStrsav( p->pName );
p->pAig->pSpec = Aig_UtilStrsav( p->pSpec );
// get the root model
pRoot = Vec_PtrEntry( p->vModels, 0 );
pRoot = Ntl_ManRootModel( p );
// clear net visited flags
Ntl_ModelForEachNet( pRoot, pNet, i )
pNet->nVisits = 0;
// collect primary inputs
Ntl_ModelForEachPi( pRoot, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
Vec_PtrPush( p->vCis, pNet );
pNet->pFunc = Aig_ObjCreatePi( p->pAig );
pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManExtract(): Primary input appears twice in the list.\n" );
......@@ -462,7 +465,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
Vec_PtrPush( p->vCis, pNet );
pNet->pFunc = Aig_ObjCreatePi( p->pAig );
pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManExtract(): Latch output is duplicated or defined as a primary input.\n" );
......@@ -483,7 +486,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
return 0;
}
Vec_PtrPush( p->vCos, pNet );
Aig_ObjCreatePo( p->pAig, pNet->pFunc );
Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// visit the nodes starting from latch inputs outputs
Ntl_ModelForEachLatch( pRoot, pObj, i )
......@@ -498,7 +501,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
return 0;
}
Vec_PtrPush( p->vCos, pNet );
Aig_ObjCreatePo( p->pAig, pNet->pFunc );
Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// report the number of dangling objects
nUselessObjects = Ntl_ModelNodeNum(pRoot) + Ntl_ModelBoxNum(pRoot) - Vec_PtrSize(p->vNodes);
......@@ -517,12 +520,54 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
/**Function*************************************************************
Synopsis [Collects the nodes in a topological order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManBuildModelAig( Ntl_Man_t * p, Ntl_Obj_t * pBox )
{
extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet );
Ntl_Mod_t * pModel = pBox->pImplem;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet, * pNetBox;
int i;
assert( Ntl_ObjFaninNum(pBox) == Ntl_ModelPiNum(pModel) );
assert( Ntl_ObjFanoutNum(pBox) == Ntl_ModelPoNum(pModel) );
// clear net visited flags
Ntl_ModelForEachNet( pModel, pNet, i )
pNet->nVisits = 0;
// transfer from the box to the PIs of the model
Ntl_ModelForEachPi( pModel, pObj, i )
{
pNet = Ntl_ObjFanout0(pObj);
pNetBox = Ntl_ObjFanin( pBox, i );
pNet->pCopy = pNetBox->pCopy;
pNet->nVisits = 2;
}
// compute AIG for the internal nodes
Ntl_ModelForEachPo( pModel, pObj, i )
if ( !Ntl_ManCollapse_rec( p, Ntl_ObjFanin0(pObj) ) )
return 0;
// transfer from the POs of the model to the box
Ntl_ModelForEachPo( pModel, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
pNetBox = Ntl_ObjFanout( pBox, i );
pNetBox->pCopy = pNet->pCopy;
}
return 1;
}
/**Function*************************************************************
Synopsis [Extracts AIG from the netlist.]
Synopsis [Collects the nodes in a topological order.]
Description []
......@@ -531,32 +576,121 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
SeeAlso []
***********************************************************************/
/*
int Ntl_ManExtract_old( Ntl_Man_t * p )
int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
{
Ntl_Obj_t * pObj;
Ntl_Net_t * pNetFanin;
int i;
// skip visited
if ( pNet->nVisits == 2 )
return 1;
// if the node is on the path, this is a combinational loop
if ( pNet->nVisits == 1 )
return 0;
// mark the node as the one on the path
pNet->nVisits = 1;
// derive the box
pObj = pNet->pDriver;
assert( Ntl_ObjIsNode(pObj) || Ntl_ObjIsBox(pObj) );
// visit the input nets of the box
Ntl_ObjForEachFanin( pObj, pNetFanin, i )
if ( !Ntl_ManCollapse_rec( p, pNetFanin ) )
return 0;
// add box inputs/outputs to COs/CIs
if ( Ntl_ObjIsBox(pObj) )
{
if ( !Ntl_ManBuildModelAig( p, pObj ) )
return 0;
}
// store the node
if ( Ntl_ObjIsNode(pObj) )
pNet->pCopy = Ntl_ManBuildNodeAig( pObj );
pNet->nVisits = 2;
return 1;
}
/**Function*************************************************************
Synopsis [Performs DFS.]
Description [Checks for combinational loops. Collects PI/PO nets.
Collects nodes in the topological order.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
{
Ntl_Obj_t * pNode;
Aig_Man_t * pAig;
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
// check the DFS traversal
if ( !Ntl_ManDfs( p ) )
return 0;
// start the AIG manager
assert( p->pAig == NULL );
p->pAig = Aig_ManStart( 10000 );
// create the primary inputs
Ntl_ManForEachCiNet( p, pNet, i )
pNet->pFunc = Aig_ObjCreatePi( p->pAig );
// convert internal nodes to AIGs
Ntl_ManForEachNode( p, pNode, i )
Ntl_ObjFanout0(pNode)->pFunc = Ntl_ManExtractAigNode( pNode );
// create the primary outputs
Ntl_ManForEachCoNet( p, pNet, i )
Aig_ObjCreatePo( p->pAig, pNet->pFunc );
p->pAig->pName = Aig_UtilStrsav( p->pName );
p->pAig->pSpec = Aig_UtilStrsav( p->pSpec );
// get the root model
pRoot = Ntl_ManRootModel( p );
// clear net visited flags
Ntl_ModelForEachNet( pRoot, pNet, i )
pNet->nVisits = 0;
// collect primary inputs
Ntl_ModelForEachPi( pRoot, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapse(): Primary input appears twice in the list.\n" );
return 0;
}
pNet->nVisits = 2;
}
// collect latch outputs
Ntl_ModelForEachLatch( pRoot, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapse(): Latch output is duplicated or defined as a primary input.\n" );
return 0;
}
pNet->nVisits = 2;
}
// visit the nodes starting from primary outputs
Ntl_ModelForEachPo( pRoot, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p, pNet ) )
{
printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" );
return 0;
}
Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// visit the nodes starting from latch inputs outputs
Ntl_ModelForEachLatch( pRoot, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p, pNet ) )
{
printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" );
return 0;
}
Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// cleanup the AIG
Aig_ManCleanup( p->pAig );
return 1;
pAig = p->pAig; p->pAig = NULL;
return pAig;
}
*/
////////////////////////////////////////////////////////////////////////
......
......@@ -52,17 +52,17 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
int i, k, nDigits;
// map the AIG back onto the design
Ntl_ManForEachCiNet( p, pNet, i )
pNet->pFunc = Aig_ManPi( pAig, i );
pNet->pCopy = Aig_ManPi( pAig, i );
Ntl_ManForEachCoNet( p, pNet, i )
pNet->pFunc = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
pNet->pCopy = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
// remove old nodes
pRoot = Vec_PtrEntry( p->vModels, 0 );
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
// start mapping of AIG nodes into their copies
vCopies = Vec_PtrStart( Aig_ManObjNumMax(pAig) );
Ntl_ManForEachCiNet( p, pNet, i )
Vec_PtrWriteEntry( vCopies, pNet->pFunc->Id, pNet );
Vec_PtrWriteEntry( vCopies, ((Aig_Obj_t *)pNet->pCopy)->Id, pNet );
// create a new node for each LUT
vCover = Vec_IntAlloc( 1 << 16 );
nDigits = Aig_Base10Log( Vec_PtrSize(vMapping) );
......@@ -100,16 +100,16 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
Vec_IntFree( vCover );
// mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101;
pNetCo->nVisits = 101; // using "101" is harmless because nVisits can only be 0, 1 or 2
// update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i )
{
if ( pNetCo->nVisits == 101 )
continue;
pNetCo->nVisits = 101;
pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pFunc)->Id );
pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = Aig_IsComplement(pNetCo->pFunc)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
pNode->pSop = Aig_IsComplement(pNetCo->pCopy)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net
pNetCo->pDriver = NULL;
......@@ -134,7 +134,7 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
SeeAlso []
***********************************************************************/
int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
{
char Buffer[100];
Vec_Int_t * vTruth;
......@@ -142,32 +142,34 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode;
Ntl_Net_t * pNet, * pNetCo;
Ntk_Obj_t * pObj, * pFanin;
Nwk_Obj_t * pObj, * pFanin;
int i, k, nDigits;
unsigned * pTruth;
assert( Vec_PtrSize(p->vCis) == Ntk_ManCiNum(pNtk) );
assert( Vec_PtrSize(p->vCos) == Ntk_ManCoNum(pNtk) );
assert( Vec_PtrSize(p->vCis) == Nwk_ManCiNum(pNtk) );
assert( Vec_PtrSize(p->vCos) == Nwk_ManCoNum(pNtk) );
// set the correspondence between the PI/PO nodes
Ntl_ManForEachCiNet( p, pNet, i )
Ntk_ManCi( pNtk, i )->pCopy = pNet;
Nwk_ManCi( pNtk, i )->pCopy = pNet;
// Ntl_ManForEachCoNet( p, pNet, i )
// Ntk_ManCo( pNtk, i )->pCopy = pNet;
// Nwk_ManCo( pNtk, i )->pCopy = pNet;
// remove old nodes
pRoot = Vec_PtrEntry( p->vModels, 0 );
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
// create a new node for each LUT
vTruth = Vec_IntAlloc( 1 << 16 );
vCover = Vec_IntAlloc( 1 << 16 );
nDigits = Aig_Base10Log( Ntk_ManNodeNum(pNtk) );
Ntk_ManForEachNode( pNtk, pObj, i )
nDigits = Aig_Base10Log( Nwk_ManNodeNum(pNtk) );
Nwk_ManForEachNode( pNtk, pObj, i )
{
pNode = Ntl_ModelCreateNode( pRoot, Ntk_ObjFaninNum(pObj) );
pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, pObj->pFunc, Ntk_ObjFaninNum(pObj), vTruth, 0 );
pNode->pSop = Ntl_SopFromTruth( p, pTruth, Ntk_ObjFaninNum(pObj), vCover );
if ( !Kit_TruthIsConst0(pTruth, Ntk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Ntk_ObjFaninNum(pObj)) )
pNode = Ntl_ModelCreateNode( pRoot, Nwk_ObjFaninNum(pObj) );
pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 );
if ( Hop_IsComplement(pObj->pFunc) )
Kit_TruthNot( pTruth, pTruth, Nwk_ObjFaninNum(pObj) );
pNode->pSop = Ntl_SopFromTruth( p, pTruth, Nwk_ObjFaninNum(pObj), vCover );
if ( !Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) )
{
Ntk_ObjForEachFanin( pObj, pFanin, k )
Nwk_ObjForEachFanin( pObj, pFanin, k )
{
pNet = pFanin->pCopy;
if ( pNet == NULL )
......@@ -204,12 +206,12 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
continue;
pNetCo->nVisits = 101;
// get the corresponding PO and its driver
pObj = Ntk_ManCo( pNtk, i );
pFanin = Ntk_ObjFanin0( pObj );
pObj = Nwk_ManCo( pNtk, i );
pFanin = Nwk_ObjFanin0( pObj );
// get the net driving the driver
pNet = pFanin->pCopy; //Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pFunc)->Id );
pNet = pFanin->pCopy; //Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = pObj->fCompl /*Aig_IsComplement(pNetCo->pFunc)*/? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
pNode->pSop = pObj->fCompl /*Aig_IsComplement(pNetCo->pCopy)*/? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net
pNetCo->pDriver = NULL;
......
......@@ -61,6 +61,57 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName )
/**Function*************************************************************
Synopsis [Duplicates the interface of the top level model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
{
return NULL;
}
/**Function*************************************************************
Synopsis [Duplicates the interface of the top level model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * pOld )
{
Ntl_Man_t * pNew;
Ntl_Mod_t * pModel;
Ntl_Obj_t * pBox;
Ntl_Net_t * pNet;
int i, k;
pNew = Ntl_ManAlloc( pOld->pSpec );
Vec_PtrForEachEntry( pOld->vModels, pModel, i )
pModel->pCopy = Ntl_ModelDup( pNew, pModel );
Vec_PtrForEachEntry( pOld->vModels, pModel, i )
Ntl_ModelForEachBox( pModel, pBox, k )
((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy;
Ntl_ManForEachCiNet( pOld, pNet, i )
Vec_PtrPush( pNew->vCis, pNet->pCopy );
Ntl_ManForEachCoNet( pOld, pNet, i )
Vec_PtrPush( pNew->vCos, pNet->pCopy );
if ( pOld->pManTime )
pNew->pManTime = Tim_ManDup( pOld->pManTime, 0 );
if ( !Ntl_ManCheck( pNew ) )
printf( "Ntl_ManDup: The check has failed for design %s.\n", pNew->pName );
return pNew;
}
/**Function*************************************************************
Synopsis [Deallocates the netlist manager.]
Description []
......@@ -126,15 +177,16 @@ Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, char * pName )
void Ntl_ManPrintStats( Ntl_Man_t * p )
{
Ntl_Mod_t * pRoot;
pRoot = Vec_PtrEntry( p->vModels, 0 );
pRoot = Ntl_ManRootModel( p );
printf( "%-15s : ", p->pName );
printf( "pi = %5d ", Ntl_ModelPiNum(pRoot) );
printf( "po = %5d ", Ntl_ModelPoNum(pRoot) );
printf( "latch = %5d ", Ntl_ModelLatchNum(pRoot) );
printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) );
printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) );
printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) );
printf( "model = %3d", Vec_PtrSize(p->vModels) );
printf( "mod = %3d", Vec_PtrSize(p->vModels) );
printf( "\n" );
fflush( stdout );
}
/**Function*************************************************************
......@@ -173,11 +225,11 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
p->pMan = pMan;
p->pName = Ntl_ManStoreName( p->pMan, pName );
Vec_PtrPush( pMan->vModels, p );
p->vObjs = Vec_PtrAlloc( 10000 );
p->vPis = Vec_PtrAlloc( 1000 );
p->vPos = Vec_PtrAlloc( 1000 );
p->vObjs = Vec_PtrAlloc( 1000 );
p->vPis = Vec_PtrAlloc( 100 );
p->vPos = Vec_PtrAlloc( 100 );
// start the table
p->nTableSize = Aig_PrimeCudd( 10000 );
p->nTableSize = Aig_PrimeCudd( 1000 );
p->pTable = ALLOC( Ntl_Net_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Ntl_Net_t *) * p->nTableSize );
return p;
......@@ -185,6 +237,41 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
/**Function*************************************************************
Synopsis [Duplicates the model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld )
{
Ntl_Mod_t * pModelNew;
Ntl_Net_t * pNet;
Ntl_Obj_t * pObj;
int i, k;
pModelNew = Ntl_ModelAlloc( pManNew, pModelOld->pName );
Ntl_ModelForEachNet( pModelOld, pNet, i )
pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName );
Ntl_ModelForEachObj( pModelOld, pObj, i )
{
pObj->pCopy = Ntl_ModelDupObj( pModelNew, pObj );
Ntl_ObjForEachFanin( pObj, pNet, k )
Ntl_ObjSetFanin( pObj->pCopy, pNet->pCopy, k );
Ntl_ObjForEachFanout( pObj, pNet, k )
Ntl_ObjSetFanout( pObj->pCopy, pNet->pCopy, k );
if ( Ntl_ObjIsLatch(pObj) )
((Ntl_Obj_t *)pObj->pCopy)->LatchId = pObj->LatchId;
if ( Ntl_ObjIsNode(pObj) )
((Ntl_Obj_t *)pObj->pCopy)->pSop = Ntl_ManStoreSop( pManNew, pObj->pSop );
}
return pModelNew;
}
/**Function*************************************************************
Synopsis [Deallocates the model.]
Description []
......
......@@ -136,7 +136,7 @@ void Ntl_ManSetIfParsDefault( If_Par_t * pPars )
pPars->fExpRed = 0;
pPars->fLatchPaths = 0;
pPars->fEdge = 1;
pPars->fCutMin = 1;
pPars->fCutMin = 0;
pPars->fSeqMap = 0;
pPars->fVerbose = 1;
// internal parameters
......
......@@ -163,6 +163,33 @@ Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts )
/**Function*************************************************************
Synopsis [Create the latch.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld )
{
Ntl_Obj_t * pNew;
if ( Ntl_ObjIsPi( pOld ) )
pNew = Ntl_ModelCreatePi( pModel );
else if ( Ntl_ObjIsPo( pOld ) )
pNew = Ntl_ModelCreatePo( pModel, NULL );
else if ( Ntl_ObjIsLatch( pOld ) )
pNew = Ntl_ModelCreateLatch( pModel );
else if ( Ntl_ObjIsNode( pOld ) )
pNew = Ntl_ModelCreateNode( pModel, Ntl_ObjFaninNum(pOld) );
else if ( Ntl_ObjIsBox( pOld ) )
pNew = Ntl_ModelCreateBox( pModel, Ntl_ObjFaninNum(pOld), Ntl_ObjFanoutNum(pOld) );
return pNew;
}
/**Function*************************************************************
Synopsis [Allocates memory and copies the name into it.]
Description []
......
......@@ -108,9 +108,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
{
FILE * pFile;
Ioa_ReadMan_t * p;
Ntl_Mod_t * pNtk;
Ntl_Man_t * pDesign;
int i;
// check that the file is available
pFile = fopen( pFileName, "rb" );
......@@ -158,20 +156,9 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
// make sure that everything is okay with the network structure
if ( fCheck )
{
// check individual models
Vec_PtrForEachEntry( pDesign->vModels, pNtk, i )
{
if ( !Ntl_ModelCheck( pNtk ) )
{
printf( "Ioa_ReadBlif: The network check has failed for network %s.\n", pNtk->pName );
Ntl_ManFree( pDesign );
return NULL;
}
}
// check the hierarchy
if ( !Ntl_ManCheck( pDesign ) )
{
printf( "Ioa_ReadBlif: The hierarchy check has failed for design %s.\n", pDesign->pName );
printf( "Ioa_ReadBlif: The check has failed for design %s.\n", pDesign->pName );
Ntl_ManFree( pDesign );
return NULL;
}
......
......@@ -151,28 +151,6 @@ Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName )
/**Function*************************************************************
Synopsis [Finds or creates the net.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet )
{
if ( pObj->pFanio[pObj->nFanins] != NULL )
return 0;
if ( pNet->pDriver != NULL )
return 0;
pObj->pFanio[pObj->nFanins] = pNet;
pNet->pDriver = pObj;
return 1;
}
/**Function*************************************************************
Synopsis [Returns -1, 0, +1 (when it is PI, not found, or PO).]
Description []
......@@ -210,6 +188,28 @@ int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber )
return 0;
}
/**Function*************************************************************
Synopsis [Finds or creates the net.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet )
{
if ( pObj->pFanio[pObj->nFanins] != NULL )
return 0;
if ( pNet->pDriver != NULL )
return 0;
pObj->pFanio[pObj->nFanins] = pNet;
pNet->pDriver = pObj;
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -84,7 +84,7 @@ Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p )
Ntl_Obj_t * pObj;
int i, curPi, iBox, Entry;
assert( p->pAig != NULL );
pRoot = Vec_PtrEntry( p->vModels, 0 );
pRoot = Ntl_ManRootModel( p );
// start the timing manager
pMan = Tim_ManStart( Aig_ManPiNum(p->pAig), Aig_ManPoNum(p->pAig) );
// unpack the data in the arrival times
......
SRC += src/aig/nwk/nwkCheck.c \
src/aig/nwk/nwkBidec.c \
src/aig/nwk/nwkDfs.c \
src/aig/nwk/nwkFanio.c \
src/aig/nwk/nwkMan.c \
src/aig/nwk/nwkMap.c \
src/aig/nwk/nwkObj.c \
src/aig/nwk/nwkSpeedup.c \
src/aig/nwk/nwkStrash.c \
src/aig/nwk/nwkTiming.c \
src/aig/nwk/nwkUtil.c
/**CFile****************************************************************
FileName [nwk.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Logic network representation.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwk.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __NWK_H__
#define __NWK_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "aig.h"
#include "hop.h"
#include "tim.h"
#include "if.h"
#include "bdc.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Nwk_Man_t_ Nwk_Man_t;
typedef struct Nwk_Obj_t_ Nwk_Obj_t;
// object types
typedef enum {
NWK_OBJ_NONE, // 0: non-existant object
NWK_OBJ_CI, // 1: combinational input
NWK_OBJ_CO, // 2: combinational output
NWK_OBJ_NODE, // 3: logic node
NWK_OBJ_LATCH, // 4: register
NWK_OBJ_VOID // 5: unused object
} Nwk_Type_t;
struct Nwk_Man_t_
{
// models of this design
char * pName; // the name of this design
char * pSpec; // the name of input file
// node representation
Vec_Ptr_t * vCis; // the primary inputs of the extracted part
Vec_Ptr_t * vCos; // the primary outputs of the extracted part
Vec_Ptr_t * vObjs; // the objects in the topological order
int nObjs[NWK_OBJ_VOID]; // counter of objects of each type
int nFanioPlus; // the number of extra fanins/fanouts alloc by default
// functionality, timing, memory, etc
Hop_Man_t * pManHop; // the functionality representation
Tim_Man_t * pManTime; // the timing manager
If_Lib_t * pLutLib; // the LUT library
Aig_MmFlex_t * pMemObjs; // memory for objects
Vec_Ptr_t * vTemp; // array used for incremental updates
int nTravIds; // the counter of traversal IDs
int nRealloced; // the number of realloced nodes
};
struct Nwk_Obj_t_
{
Nwk_Man_t * pMan; // the manager
Hop_Obj_t * pFunc; // functionality
void * pCopy; // temporary pointer
void * pNext; // temporary pointer
// node information
unsigned Type : 3; // object type
unsigned fCompl : 1; // complemented attribute
unsigned MarkA : 1; // temporary mark
unsigned MarkB : 1; // temporary mark
unsigned PioId : 26; // number of this node in the PI/PO list
int Id; // unique ID
int TravId; // traversal ID
// timing information
int Level; // the topological level
float tArrival; // the arrival time
float tRequired; // the required time
float tSlack; // the slack
// fanin/fanout representation
int nFanins; // the number of fanins
int nFanouts; // the number of fanouts
int nFanioAlloc; // the number of allocated fanins/fanouts
Nwk_Obj_t ** pFanio; // fanins/fanouts
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// INLINED FUNCTIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Nwk_ManCiNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_CI]; }
static inline int Nwk_ManCoNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_CO]; }
static inline int Nwk_ManNodeNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_NODE]; }
static inline int Nwk_ManLatchNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_LATCH]; }
static inline int Nwk_ManObjNumMax( Nwk_Man_t * p ) { return Vec_PtrSize(p->vObjs); }
static inline Nwk_Obj_t * Nwk_ManCi( Nwk_Man_t * p, int i ) { return Vec_PtrEntry( p->vCis, i ); }
static inline Nwk_Obj_t * Nwk_ManCo( Nwk_Man_t * p, int i ) { return Vec_PtrEntry( p->vCos, i ); }
static inline Nwk_Obj_t * Nwk_ManObj( Nwk_Man_t * p, int i ) { return Vec_PtrEntry( p->vObjs, i ); }
static inline int Nwk_ObjFaninNum( Nwk_Obj_t * p ) { return p->nFanins; }
static inline int Nwk_ObjFanoutNum( Nwk_Obj_t * p ) { return p->nFanouts; }
static inline Nwk_Obj_t * Nwk_ObjFanin0( Nwk_Obj_t * p ) { return p->pFanio[0]; }
static inline Nwk_Obj_t * Nwk_ObjFanout0( Nwk_Obj_t * p ) { return p->pFanio[p->nFanins]; }
static inline Nwk_Obj_t * Nwk_ObjFanin( Nwk_Obj_t * p, int i ) { return p->pFanio[i]; }
static inline Nwk_Obj_t * Nwk_ObjFanout( Nwk_Obj_t * p, int i ) { return p->pFanio[p->nFanins+1]; }
static inline int Nwk_ObjIsCi( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_CI; }
static inline int Nwk_ObjIsCo( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_CO; }
static inline int Nwk_ObjIsNode( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_NODE; }
static inline int Nwk_ObjIsLatch( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_LATCH; }
static inline int Nwk_ObjIsPi( Nwk_Obj_t * p ) { return Nwk_ObjIsCi(p) && (p->pMan->pManTime == NULL || Tim_ManBoxForCi(p->pMan->pManTime, p->PioId) == -1); }
static inline int Nwk_ObjIsPo( Nwk_Obj_t * p ) { return Nwk_ObjIsCo(p) && (p->pMan->pManTime == NULL || Tim_ManBoxForCo(p->pMan->pManTime, p->PioId) == -1); }
static inline float Nwk_ObjArrival( Nwk_Obj_t * pObj ) { return pObj->tArrival; }
static inline float Nwk_ObjRequired( Nwk_Obj_t * pObj ) { return pObj->tRequired; }
static inline float Nwk_ObjSlack( Nwk_Obj_t * pObj ) { return pObj->tSlack; }
static inline void Nwk_ObjSetArrival( Nwk_Obj_t * pObj, float Time ) { pObj->tArrival = Time; }
static inline void Nwk_ObjSetRequired( Nwk_Obj_t * pObj, float Time ) { pObj->tRequired = Time; }
static inline void Nwk_ObjSetSlack( Nwk_Obj_t * pObj, float Time ) { pObj->tSlack = Time; }
static inline int Nwk_ObjLevel( Nwk_Obj_t * pObj ) { return pObj->Level; }
static inline void Nwk_ObjSetLevel( Nwk_Obj_t * pObj, int Level ) { pObj->Level = Level; }
static inline void Nwk_ObjSetTravId( Nwk_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; }
static inline void Nwk_ObjSetTravIdCurrent( Nwk_Obj_t * pObj ) { pObj->TravId = pObj->pMan->nTravIds; }
static inline void Nwk_ObjSetTravIdPrevious( Nwk_Obj_t * pObj ) { pObj->TravId = pObj->pMan->nTravIds - 1; }
static inline int Nwk_ObjIsTravIdCurrent( Nwk_Obj_t * pObj ) { return pObj->TravId == pObj->pMan->nTravIds; }
static inline int Nwk_ObjIsTravIdPrevious( Nwk_Obj_t * pObj ) { return pObj->TravId == pObj->pMan->nTravIds - 1; }
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
#define Nwk_ManForEachCi( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCis, pObj, i )
#define Nwk_ManForEachCo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCos, pObj, i )
#define Nwk_ManForEachPi( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCis, pObj, i ) \
if ( !Nwk_ObjIsPi(pObj) ) {} else
#define Nwk_ManForEachPo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCos, pObj, i ) \
if ( !Nwk_ObjIsPo(pObj) ) {} else
#define Nwk_ManForEachObj( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( pObj == NULL ) {} else
#define Nwk_ManForEachNode( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( (pObj) == NULL || !Nwk_ObjIsNode(pObj) ) {} else
#define Nwk_ManForEachLatch( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \
if ( (pObj) == NULL || !Nwk_ObjIsLatch(pObj) ) {} else
#define Nwk_ObjForEachFanin( pObj, pFanin, i ) \
for ( i = 0; (i < (int)(pObj)->nFanins) && ((pFanin) = (pObj)->pFanio[i]); i++ )
#define Nwk_ObjForEachFanout( pObj, pFanout, i ) \
for ( i = 0; (i < (int)(pObj)->nFanouts) && ((pFanout) = (pObj)->pFanio[(pObj)->nFanins+i]); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== nwkBidec.c ==========================================================*/
extern void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose );
extern Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare );
/*=== nwkDfs.c ==========================================================*/
extern int Nwk_ManLevel( Nwk_Man_t * pNtk );
extern int Nwk_ManLevel2( Nwk_Man_t * pNtk );
extern Vec_Vec_t * Nwk_ManLevelize( Nwk_Man_t * pNtk );
extern Vec_Ptr_t * Nwk_ManDfs( Nwk_Man_t * pNtk );
extern Vec_Ptr_t * Nwk_ManDfsNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes );
extern Vec_Ptr_t * Nwk_ManDfsReverse( Nwk_Man_t * pNtk );
extern Vec_Ptr_t * Nwk_ManSupportNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes );
extern void Nwk_ManSupportSum( Nwk_Man_t * pNtk );
extern int Nwk_ObjMffcLabel( Nwk_Obj_t * pNode );
/*=== nwkFanio.c ==========================================================*/
extern void Nwk_ObjCollectFanins( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern void Nwk_ObjCollectFanouts( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern void Nwk_ObjAddFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin );
extern void Nwk_ObjDeleteFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin );
extern void Nwk_ObjPatchFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFaninOld, Nwk_Obj_t * pFaninNew );
extern void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew );
/*=== nwkMan.c ============================================================*/
extern Nwk_Man_t * Nwk_ManAlloc();
extern void Nwk_ManFree( Nwk_Man_t * p );
extern void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib );
/*=== nwkMap.c ============================================================*/
extern Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars );
/*=== nwkObj.c ============================================================*/
extern Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * pMan, int nFanouts );
extern Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * pMan );
extern Nwk_Obj_t * Nwk_ManCreateNode( Nwk_Man_t * pMan, int nFanins, int nFanouts );
extern Nwk_Obj_t * Nwk_ManCreateBox( Nwk_Man_t * pMan, int nFanins, int nFanouts );
extern Nwk_Obj_t * Nwk_ManCreateLatch( Nwk_Man_t * pMan );
extern void Nwk_ManDeleteNode( Nwk_Obj_t * pObj );
extern void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj );
/*=== nwkTiming.c ============================================================*/
extern float Nwk_ManDelayTraceLut( Nwk_Man_t * pNtk, If_Lib_t * pLutLib );
extern void Nwk_ManDelayTracePrint( Nwk_Man_t * pNtk, If_Lib_t * pLutLib );
extern void Nwk_ManUpdate( Nwk_Obj_t * pObj, Nwk_Obj_t * pObjNew, Vec_Vec_t * vLevels );
extern void Nwk_ManVerifyLevel( Nwk_Man_t * pNtk );
/*=== nwkUtil.c ============================================================*/
extern void Nwk_ManIncrementTravId( Nwk_Man_t * pNtk );
extern int Nwk_ManGetFaninMax( Nwk_Man_t * pNtk );
extern int Nwk_ManGetTotalFanins( Nwk_Man_t * pNtk );
extern int Nwk_ManPiNum( Nwk_Man_t * pNtk );
extern int Nwk_ManPoNum( Nwk_Man_t * pNtk );
extern int Nwk_ManGetAigNodeNum( Nwk_Man_t * pNtk );
extern int Nwk_NodeCompareLevelsIncrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 );
extern int Nwk_NodeCompareLevelsDecrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkBidec.c]
FileName [nwkBidec.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [Logic network representation.]
Synopsis [Bi-decomposition of local functions.]
......@@ -14,12 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwkBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "bdc.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -42,7 +41,7 @@ static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCo
SeeAlso []
***********************************************************************/
Hop_Obj_t * Ntk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare )
Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare )
{
unsigned * pTruth;
Bdc_Fun_t * pFunc;
......@@ -79,15 +78,15 @@ Hop_Obj_t * Ntk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pR
SeeAlso []
***********************************************************************/
void Ntk_ManBidecResyn( Ntk_Man_t * pNtk, int fVerbose )
void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose )
{
Bdc_Par_t Pars = {0}, * pPars = &Pars;
Bdc_Man_t * p;
Ntk_Obj_t * pObj;
Nwk_Obj_t * pObj;
Vec_Int_t * vTruth;
int i, nGainTotal = 0, nNodes1, nNodes2;
int clk = clock();
pPars->nVarsMax = Ntk_ManGetFaninMax( pNtk );
pPars->nVarsMax = Nwk_ManGetFaninMax( pNtk );
pPars->fVerbose = fVerbose;
if ( pPars->nVarsMax > 15 )
{
......@@ -97,12 +96,12 @@ void Ntk_ManBidecResyn( Ntk_Man_t * pNtk, int fVerbose )
}
vTruth = Vec_IntAlloc( 0 );
p = Bdc_ManAlloc( pPars );
Ntk_ManForEachNode( pNtk, pObj, i )
Nwk_ManForEachNode( pNtk, pObj, i )
{
if ( Ntk_ObjFaninNum(pObj) > 15 )
if ( Nwk_ObjFaninNum(pObj) > 15 )
continue;
nNodes1 = Hop_DagSize(pObj->pFunc);
pObj->pFunc = Ntk_NodeIfNodeResyn( p, pNtk->pManHop, pObj->pFunc, Ntk_ObjFaninNum(pObj), vTruth, NULL );
pObj->pFunc = Nwk_NodeIfNodeResyn( p, pNtk->pManHop, pObj->pFunc, Nwk_ObjFaninNum(pObj), vTruth, NULL );
nNodes2 = Hop_DagSize(pObj->pFunc);
nGainTotal += nNodes1 - nNodes2;
}
......
/**CFile****************************************************************
FileName [nwkCheck.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Logic network representation.]
Synopsis [Consistency checking procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwkCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [nwkDfs.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Logic network representation.]
Synopsis [DFS traversals.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwkDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes the number of logic levels not counting PIs/POs.]
Description [Assumes that white boxes have unit level.]
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_ManLevel( Nwk_Man_t * pNtk )
{
Tim_Man_t * pManTimeUnit;
Nwk_Obj_t * pObj, * pFanin;
int i, k, LevelMax, Level;
// clean the levels
Nwk_ManForEachObj( pNtk, pObj, i )
Nwk_ObjSetLevel( pObj, 0 );
// perform level computation
LevelMax = 0;
pManTimeUnit = pNtk->pManTime ? Tim_ManDupUnit( pNtk->pManTime ) : NULL;
if ( pManTimeUnit )
Tim_ManIncrementTravId( pManTimeUnit );
Nwk_ManForEachObj( pNtk, pObj, i )
{
if ( Nwk_ObjIsCi(pObj) )
{
Level = pManTimeUnit? (int)Tim_ManGetPiArrival( pManTimeUnit, pObj->PioId ) : 0;
Nwk_ObjSetLevel( pObj, Level );
}
else if ( Nwk_ObjIsCo(pObj) )
{
Level = Nwk_ObjLevel( Nwk_ObjFanin0(pObj) );
if ( pManTimeUnit )
Tim_ManSetPoArrival( pManTimeUnit, pObj->PioId, (float)Level );
Nwk_ObjSetLevel( pObj, Level );
if ( LevelMax < Nwk_ObjLevel(pObj) )
LevelMax = Nwk_ObjLevel(pObj);
}
else if ( Nwk_ObjIsNode(pObj) )
{
Level = 0;
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( Level < Nwk_ObjLevel(pFanin) )
Level = Nwk_ObjLevel(pFanin);
Nwk_ObjSetLevel( pObj, Level + 1 );
}
else
assert( 0 );
}
// set the old timing manager
if ( pManTimeUnit )
Tim_ManStop( pManTimeUnit );
return LevelMax;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManLevel2_rec( Nwk_Obj_t * pObj )
{
Nwk_Obj_t * pNext;
int i, iBox, iTerm1, nTerms, LevelMax = 0;
if ( Nwk_ObjIsTravIdCurrent( pObj ) )
return;
Nwk_ObjSetTravIdCurrent( pObj );
if ( Nwk_ObjIsCi(pObj) )
{
iBox = Tim_ManBoxForCi( pObj->pMan->pManTime, pObj->PioId );
if ( iBox >= 0 ) // this is not a true PI
{
iTerm1 = Tim_ManBoxInputFirst( pObj->pMan->pManTime, iBox );
nTerms = Tim_ManBoxInputNum( pObj->pMan->pManTime, iBox );
for ( i = 0; i < nTerms; i++ )
{
pNext = Nwk_ManCo(pObj->pMan, iTerm1 + i);
Nwk_ManLevel2_rec( pNext );
if ( LevelMax < Nwk_ObjLevel(pNext) )
LevelMax = Nwk_ObjLevel(pNext);
}
LevelMax++;
}
}
else if ( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCo(pObj) )
{
Nwk_ObjForEachFanin( pObj, pNext, i )
{
Nwk_ManLevel2_rec( pNext );
if ( LevelMax < Nwk_ObjLevel(pNext) )
LevelMax = Nwk_ObjLevel(pNext);
}
if ( Nwk_ObjIsNode(pObj) )
LevelMax++;
}
else
assert( 0 );
Nwk_ObjSetLevel( pObj, LevelMax );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_ManLevel2( Nwk_Man_t * pNtk )
{
Nwk_Obj_t * pObj;
int i, LevelMax = 0;
Nwk_ManForEachObj( pNtk, pObj, i )
Nwk_ObjSetLevel( pObj, 0 );
Nwk_ManIncrementTravId( pNtk );
Nwk_ManForEachPo( pNtk, pObj, i )
{
Nwk_ManLevel2_rec( pObj );
if ( LevelMax < Nwk_ObjLevel(pObj) )
LevelMax = Nwk_ObjLevel(pObj);
}
return LevelMax;
}
/**Function*************************************************************
Synopsis [Computes the number of logic levels not counting PIs/POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Vec_t * Nwk_ManLevelize( Nwk_Man_t * pNtk )
{
Nwk_Obj_t * pObj;
Vec_Vec_t * vLevels;
int nLevels, i;
nLevels = Nwk_ManLevel( pNtk );
vLevels = Vec_VecStart( nLevels + 1 );
Nwk_ManForEachNode( pNtk, pObj, i )
{
assert( (int)pObj->tArrival <= nLevels );
Vec_VecPush( vLevels, (int)pObj->tArrival, pObj );
}
return vLevels;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManDfs_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
Nwk_Obj_t * pNext;
int i;
if ( Nwk_ObjIsTravIdCurrent( pObj ) )
return;
Nwk_ObjSetTravIdCurrent( pObj );
Nwk_ObjForEachFanin( pObj, pNext, i )
Nwk_ManDfs_rec( pNext, vNodes );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Nwk_ManDfs( Nwk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Nwk_Obj_t * pObj;
int i;
Nwk_ManIncrementTravId( pNtk );
vNodes = Vec_PtrAlloc( 100 );
Nwk_ManForEachObj( pNtk, pObj, i )
{
if ( Nwk_ObjIsCi(pObj) )
{
Nwk_ObjSetTravIdCurrent( pObj );
Vec_PtrPush( vNodes, pObj );
}
else if ( Nwk_ObjIsCo(pObj) )
Nwk_ManDfs_rec( pObj, vNodes );
}
return vNodes;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManDfsNodes_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
Nwk_Obj_t * pNext;
int i;
if ( Nwk_ObjIsTravIdCurrent( pObj ) )
return;
Nwk_ObjSetTravIdCurrent( pObj );
if ( Nwk_ObjIsCi(pObj) )
return;
assert( Nwk_ObjIsNode(pObj) );
Nwk_ObjForEachFanin( pObj, pNext, i )
Nwk_ManDfsNodes_rec( pNext, vNodes );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Returns the set of internal nodes rooted in the given nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Nwk_ManDfsNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes )
{
Vec_Ptr_t * vNodes;
int i;
// set the traversal ID
Nwk_ManIncrementTravId( pNtk );
// start the array of nodes
vNodes = Vec_PtrAlloc( 100 );
// go through the PO nodes and call for each of them
for ( i = 0; i < nNodes; i++ )
if ( Nwk_ObjIsCo(ppNodes[i]) )
Nwk_ManDfsNodes_rec( Nwk_ObjFanin0(ppNodes[i]), vNodes );
else
Nwk_ManDfsNodes_rec( ppNodes[i], vNodes );
return vNodes;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManDfsReverse_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
Nwk_Obj_t * pNext;
int i, iBox, iTerm1, nTerms;
if ( Nwk_ObjIsTravIdCurrent( pObj ) )
return;
Nwk_ObjSetTravIdCurrent( pObj );
if ( Nwk_ObjIsCo(pObj) )
{
if ( pObj->pMan->pManTime )
{
iBox = Tim_ManBoxForCo( pObj->pMan->pManTime, pObj->PioId );
if ( iBox >= 0 ) // this is not a true PO
{
iTerm1 = Tim_ManBoxOutputFirst( pObj->pMan->pManTime, iBox );
nTerms = Tim_ManBoxOutputNum( pObj->pMan->pManTime, iBox );
for ( i = 0; i < nTerms; i++ )
{
pNext = Nwk_ManCi(pObj->pMan, iTerm1 + i);
Nwk_ManDfsReverse_rec( pNext, vNodes );
}
}
}
}
else if ( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCi(pObj) )
{
Nwk_ObjForEachFanout( pObj, pNext, i )
Nwk_ManDfsReverse_rec( pNext, vNodes );
}
else
assert( 0 );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Nwk_ManDfsReverse( Nwk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Nwk_Obj_t * pObj;
int i;
Nwk_ManIncrementTravId( pNtk );
vNodes = Vec_PtrAlloc( 100 );
Nwk_ManForEachPi( pNtk, pObj, i )
Nwk_ManDfsReverse_rec( pObj, vNodes );
return vNodes;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManSupportNodes_rec( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Nwk_Obj_t * pFanin;
int i;
// if this node is already visited, skip
if ( Nwk_ObjIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Nwk_ObjSetTravIdCurrent( pNode );
// collect the CI
if ( Nwk_ObjIsCi(pNode) )
{
Vec_PtrPush( vNodes, pNode );
return;
}
assert( Nwk_ObjIsNode( pNode ) );
// visit the transitive fanin of the node
Nwk_ObjForEachFanin( pNode, pFanin, i )
Nwk_ManSupportNodes_rec( pFanin, vNodes );
}
/**Function*************************************************************
Synopsis [Returns the set of CI nodes in the support of the given nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Nwk_ManSupportNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes )
{
Vec_Ptr_t * vNodes;
int i;
// set the traversal ID
Nwk_ManIncrementTravId( pNtk );
// start the array of nodes
vNodes = Vec_PtrAlloc( 100 );
// go through the PO nodes and call for each of them
for ( i = 0; i < nNodes; i++ )
if ( Nwk_ObjIsCo(ppNodes[i]) )
Nwk_ManSupportNodes_rec( Nwk_ObjFanin0(ppNodes[i]), vNodes );
else
Nwk_ManSupportNodes_rec( ppNodes[i], vNodes );
return vNodes;
}
/**Function*************************************************************
Synopsis [Computes the sum total of supports of all outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManSupportSum( Nwk_Man_t * pNtk )
{
Vec_Ptr_t * vSupp;
Nwk_Obj_t * pObj;
int i, nTotalSupps = 0;
Nwk_ManForEachCo( pNtk, pObj, i )
{
vSupp = Nwk_ManSupportNodes( pNtk, &pObj, 1 );
nTotalSupps += Vec_PtrSize( vSupp );
Vec_PtrFree( vSupp );
}
printf( "Total supports = %d.\n", nTotalSupps );
}
/**Function*************************************************************
Synopsis [Dereferences the node's MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_ObjDeref_rec( Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
int i, Counter = 1;
if ( Nwk_ObjIsCi(pNode) )
return 0;
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
assert( pFanin->nFanouts > 0 );
if ( --pFanin->nFanouts == 0 )
Counter += Nwk_ObjDeref_rec( pFanin );
}
return Counter;
}
/**Function*************************************************************
Synopsis [References the node's MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_ObjRef_rec( Nwk_Obj_t * pNode )
{
Nwk_Obj_t * pFanin;
int i, Counter = 1;
if ( Nwk_ObjIsCi(pNode) )
return 0;
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
if ( pFanin->nFanouts++ == 0 )
Counter += Nwk_ObjRef_rec( pFanin );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Collects the internal and boundary nodes in the derefed MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ObjMffcLabel_rec( Nwk_Obj_t * pNode, int fTopmost )
{
Nwk_Obj_t * pFanin;
int i;
// add to the new support nodes
if ( !fTopmost && (Nwk_ObjIsCi(pNode) || pNode->nFanouts > 0) )
return;
// skip visited nodes
if ( Nwk_ObjIsTravIdCurrent(pNode) )
return;
Nwk_ObjSetTravIdCurrent(pNode);
// recur on the children
Nwk_ObjForEachFanin( pNode, pFanin, i )
Nwk_ObjMffcLabel_rec( pFanin, 0 );
// collect the internal node
// printf( "%d ", pNode->Id );
}
/**Function*************************************************************
Synopsis [Collects the internal nodes of the MFFC limited by cut.]
Description []
SideEffects [Increments the trav ID and marks visited nodes.]
SeeAlso []
***********************************************************************/
int Nwk_ObjMffcLabel( Nwk_Obj_t * pNode )
{
int Count1, Count2;
// dereference the node
Count1 = Nwk_ObjDeref_rec( pNode );
// collect the nodes inside the MFFC
Nwk_ManIncrementTravId( pNode->pMan );
Nwk_ObjMffcLabel_rec( pNode, 1 );
// reference it back
Count2 = Nwk_ObjRef_rec( pNode );
assert( Count1 == Count2 );
return Count1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkFanio.c]
FileName [nwkFanio.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [Logic network representation.]
Synopsis [Manipulation of fanins/fanouts.]
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwkFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -30,7 +30,7 @@
/**Function*************************************************************
Synopsis [Returns 1 if it is an AIG with choice nodes.]
Synopsis [Collects fanins of the node.]
Description []
......@@ -39,18 +39,18 @@
SeeAlso []
***********************************************************************/
void Ntk_ObjCollectFanins( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes )
void Nwk_ObjCollectFanins( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Ntk_Obj_t * pFanin;
Nwk_Obj_t * pFanin;
int i;
Vec_PtrClear(vNodes);
Ntk_ObjForEachFanin( pNode, pFanin, i )
Nwk_ObjForEachFanin( pNode, pFanin, i )
Vec_PtrPush( vNodes, pFanin );
}
/**Function*************************************************************
Synopsis [Returns 1 if it is an AIG with choice nodes.]
Synopsis [Collects fanouts of the node.]
Description []
......@@ -59,12 +59,12 @@ void Ntk_ObjCollectFanins( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes )
SeeAlso []
***********************************************************************/
void Ntk_ObjCollectFanouts( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes )
void Nwk_ObjCollectFanouts( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Ntk_Obj_t * pFanout;
Nwk_Obj_t * pFanout;
int i;
Vec_PtrClear(vNodes);
Ntk_ObjForEachFanout( pNode, pFanout, i )
Nwk_ObjForEachFanout( pNode, pFanout, i )
Vec_PtrPush( vNodes, pFanout );
}
......@@ -79,11 +79,11 @@ void Ntk_ObjCollectFanouts( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes )
SeeAlso []
***********************************************************************/
int Ntk_ObjFindFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
int Nwk_ObjFindFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin )
{
Ntk_Obj_t * pTemp;
Nwk_Obj_t * pTemp;
int i;
Ntk_ObjForEachFanin( pObj, pTemp, i )
Nwk_ObjForEachFanin( pObj, pTemp, i )
if ( pTemp == pFanin )
return i;
return -1;
......@@ -91,7 +91,7 @@ int Ntk_ObjFindFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
/**Function*************************************************************
Synopsis [Returns the number of the fanin of the node.]
Synopsis [Returns the number of the fanout of the node.]
Description []
......@@ -100,11 +100,11 @@ int Ntk_ObjFindFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
SeeAlso []
***********************************************************************/
int Ntk_ObjFindFanout( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanout )
int Nwk_ObjFindFanout( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanout )
{
Ntk_Obj_t * pTemp;
Nwk_Obj_t * pTemp;
int i;
Ntk_ObjForEachFanout( pObj, pTemp, i )
Nwk_ObjForEachFanout( pObj, pTemp, i )
if ( pTemp == pFanout )
return i;
return -1;
......@@ -112,7 +112,7 @@ int Ntk_ObjFindFanout( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanout )
/**Function*************************************************************
Synopsis [Returns 1 if the object has to be reallocated.]
Synopsis [Returns 1 if the node has to be reallocated.]
Description []
......@@ -121,14 +121,14 @@ int Ntk_ObjFindFanout( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanout )
SeeAlso []
***********************************************************************/
static inline int Ntk_ObjReallocIsNeeded( Ntk_Obj_t * pObj )
static inline int Nwk_ObjReallocIsNeeded( Nwk_Obj_t * pObj )
{
return pObj->nFanins + pObj->nFanouts == (unsigned)pObj->nFanioAlloc;
return pObj->nFanins + pObj->nFanouts == pObj->nFanioAlloc;
}
/**Function*************************************************************
Synopsis [Deletes the node.]
Synopsis [Reallocates the object.]
Description []
......@@ -137,32 +137,68 @@ static inline int Ntk_ObjReallocIsNeeded( Ntk_Obj_t * pObj )
SeeAlso []
***********************************************************************/
static Ntk_Obj_t * Ntk_ManReallocNode( Ntk_Obj_t * pObj )
static Nwk_Obj_t * Nwk_ManReallocNode_old( Nwk_Obj_t * pObj )
{
Ntk_Obj_t * pObjNew, * pTemp;
Nwk_Obj_t * pObjNew, * pTemp;
int i, iNum;
assert( Ntk_ObjReallocIsNeeded(pObj) );
pObjNew = (Ntk_Obj_t *)Aig_MmFlexEntryFetch( pObj->pMan->pMemObjs, sizeof(Ntk_Obj_t) + 2 * pObj->nFanioAlloc * sizeof(Ntk_Obj_t *) );
memmove( pObjNew, pObj, sizeof(Ntk_Obj_t) + pObj->nFanioAlloc * sizeof(Ntk_Obj_t *) );
pObjNew->nFanioAlloc = pObj->nFanioAlloc;
assert( Nwk_ObjReallocIsNeeded(pObj) );
pObjNew = (Nwk_Obj_t *)Aig_MmFlexEntryFetch( pObj->pMan->pMemObjs, sizeof(Nwk_Obj_t) + 2 * pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) );
memmove( pObjNew, pObj, sizeof(Nwk_Obj_t) + pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) );
pObjNew->nFanioAlloc = 2 * pObj->nFanioAlloc;
// update the fanouts' fanins
Ntk_ObjForEachFanout( pObj, pTemp, i )
Nwk_ObjForEachFanout( pObj, pTemp, i )
{
iNum = Ntk_ObjFindFanin( pTemp, pObj );
iNum = Nwk_ObjFindFanin( pTemp, pObj );
if ( iNum == -1 )
printf( "Ntk_ManReallocNode(): Error! Fanin cannot be found.\n" );
printf( "Nwk_ManReallocNode(): Error! Fanin cannot be found.\n" );
pTemp->pFanio[iNum] = pObjNew;
}
// update the fanins' fanouts
Ntk_ObjForEachFanin( pObj, pTemp, i )
Nwk_ObjForEachFanin( pObj, pTemp, i )
{
iNum = Ntk_ObjFindFanout( pTemp, pObj );
iNum = Nwk_ObjFindFanout( pTemp, pObj );
if ( iNum == -1 )
printf( "Ntk_ManReallocNode(): Error! Fanout cannot be found.\n" );
printf( "Nwk_ManReallocNode(): Error! Fanout cannot be found.\n" );
pTemp->pFanio[pTemp->nFanins+iNum] = pObjNew;
}
memset( pObj, 0, sizeof(Nwk_Obj_t) + pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) );
assert( Nwk_ManObj(pObjNew->pMan, pObjNew->Id) == pObj );
Vec_PtrWriteEntry( pObjNew->pMan->vObjs, pObjNew->Id, pObjNew );
if ( Nwk_ObjIsCi(pObjNew) )
{
assert( Nwk_ManCi(pObjNew->pMan, pObjNew->PioId) == pObj );
Vec_PtrWriteEntry( pObjNew->pMan->vCis, pObjNew->PioId, pObjNew );
}
if ( Nwk_ObjIsCo(pObjNew) )
{
assert( Nwk_ManCo(pObjNew->pMan, pObjNew->PioId) == pObj );
Vec_PtrWriteEntry( pObjNew->pMan->vCos, pObjNew->PioId, pObjNew );
}
pObjNew->pMan->nRealloced++;
return pObjNew;
}
/**Function*************************************************************
Synopsis [Reallocates the object.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static Nwk_Obj_t * Nwk_ManReallocNode( Nwk_Obj_t * pObj )
{
Nwk_Obj_t ** pFanioOld = pObj->pFanio;
assert( Nwk_ObjReallocIsNeeded(pObj) );
pObj->pFanio = (Nwk_Obj_t **)Aig_MmFlexEntryFetch( pObj->pMan->pMemObjs, 2 * pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) );
memmove( pObj->pFanio, pFanioOld, pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) );
pObj->nFanioAlloc *= 2;
pObj->pMan->nRealloced++;
return NULL;
}
/**Function*************************************************************
......@@ -176,19 +212,20 @@ static Ntk_Obj_t * Ntk_ManReallocNode( Ntk_Obj_t * pObj )
SeeAlso []
***********************************************************************/
void Ntk_ObjAddFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
void Nwk_ObjAddFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin )
{
int i;
assert( pObj->pMan == pFanin->pMan );
assert( pObj->Id >= 0 && pFanin->Id >= 0 );
if ( Ntk_ObjReallocIsNeeded(pObj) )
Ntk_ManReallocNode( pObj );
if ( Ntk_ObjReallocIsNeeded(pFanin) )
Ntk_ManReallocNode( pFanin );
if ( Nwk_ObjReallocIsNeeded(pObj) )
Nwk_ManReallocNode( pObj );
if ( Nwk_ObjReallocIsNeeded(pFanin) )
Nwk_ManReallocNode( pFanin );
for ( i = pObj->nFanins + pObj->nFanouts; i > (int)pObj->nFanins; i-- )
pObj->pFanio[i] = pObj->pFanio[i-1];
pObj->pFanio[pObj->nFanins++] = pFanin;
pFanin->pFanio[pFanin->nFanins + pFanin->nFanouts++] = pObj;
pObj->Level = AIG_MAX( pObj->Level, pFanin->Level + Nwk_ObjIsNode(pObj) );
}
/**Function*************************************************************
......@@ -202,7 +239,7 @@ void Ntk_ObjAddFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
SeeAlso []
***********************************************************************/
void Ntk_ObjDeleteFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
void Nwk_ObjDeleteFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin )
{
int i, k, Limit;
// remove pFanin from the fanin list of pObj
......@@ -210,12 +247,14 @@ void Ntk_ObjDeleteFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
for ( k = i = 0; i < Limit; i++ )
if ( pObj->pFanio[i] != pFanin )
pObj->pFanio[k++] = pObj->pFanio[i];
assert( i == k + 1 );
pObj->nFanins--;
// remove pObj from the fanout list of pFanin
Limit = pFanin->nFanins + pFanin->nFanouts;
for ( k = i = pFanin->nFanins; i < Limit; i++ )
if ( pFanin->pFanio[i] != pObj )
pFanin->pFanio[k++] = pFanin->pFanio[i];
assert( i == k + 1 );
pFanin->nFanouts--;
}
......@@ -233,7 +272,7 @@ void Ntk_ObjDeleteFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin )
SeeAlso []
***********************************************************************/
void Ntk_ObjPatchFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFaninOld, Ntk_Obj_t * pFaninNew )
void Nwk_ObjPatchFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFaninOld, Nwk_Obj_t * pFaninNew )
{
int i, k, iFanin, Limit;
assert( pFaninOld != pFaninNew );
......@@ -242,10 +281,10 @@ void Ntk_ObjPatchFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFaninOld, Ntk_Obj_t * pFa
assert( pObj->pMan == pFaninOld->pMan );
assert( pObj->pMan == pFaninNew->pMan );
// update the fanin
iFanin = Ntk_ObjFindFanin( pObj, pFaninOld );
iFanin = Nwk_ObjFindFanin( pObj, pFaninOld );
if ( iFanin == -1 )
{
printf( "Ntk_ObjPatchFanin(); Error! Node %d is not among", pFaninOld->Id );
printf( "Nwk_ObjPatchFanin(); Error! Node %d is not among", pFaninOld->Id );
printf( " the fanins of node %s...\n", pObj->Id );
return;
}
......@@ -257,8 +296,8 @@ void Ntk_ObjPatchFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFaninOld, Ntk_Obj_t * pFa
pFaninOld->pFanio[k++] = pFaninOld->pFanio[i];
pFaninOld->nFanouts--;
// add pObj to the fanout list of pFaninNew
if ( Ntk_ObjReallocIsNeeded(pFaninNew) )
Ntk_ManReallocNode( pFaninNew );
if ( Nwk_ObjReallocIsNeeded(pFaninNew) )
Nwk_ManReallocNode( pFaninNew );
pFaninNew->pFanio[pFaninNew->nFanins + pFaninNew->nFanouts++] = pObj;
}
......@@ -274,23 +313,23 @@ void Ntk_ObjPatchFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFaninOld, Ntk_Obj_t * pFa
SeeAlso []
***********************************************************************/
void Ntk_ObjTransferFanout( Ntk_Obj_t * pNodeFrom, Ntk_Obj_t * pNodeTo )
void Nwk_ObjTransferFanout( Nwk_Obj_t * pNodeFrom, Nwk_Obj_t * pNodeTo )
{
Vec_Ptr_t * vFanouts = pNodeFrom->pMan->vTemp;
Ntk_Obj_t * pTemp;
Nwk_Obj_t * pTemp;
int nFanoutsOld, i;
assert( !Ntk_ObjIsCo(pNodeFrom) && !Ntk_ObjIsCo(pNodeTo) );
assert( !Nwk_ObjIsCo(pNodeFrom) && !Nwk_ObjIsCo(pNodeTo) );
assert( pNodeFrom->pMan == pNodeTo->pMan );
assert( pNodeFrom != pNodeTo );
assert( Ntk_ObjFanoutNum(pNodeFrom) > 0 );
assert( Nwk_ObjFanoutNum(pNodeFrom) > 0 );
// get the fanouts of the old node
nFanoutsOld = Ntk_ObjFanoutNum(pNodeTo);
Ntk_ObjCollectFanouts( pNodeFrom, vFanouts );
nFanoutsOld = Nwk_ObjFanoutNum(pNodeTo);
Nwk_ObjCollectFanouts( pNodeFrom, vFanouts );
// patch the fanin of each of them
Vec_PtrForEachEntry( vFanouts, pTemp, i )
Ntk_ObjPatchFanin( pTemp, pNodeFrom, pNodeTo );
assert( Ntk_ObjFanoutNum(pNodeFrom) == 0 );
assert( Ntk_ObjFanoutNum(pNodeTo) == nFanoutsOld + Vec_PtrSize(vFanouts) );
Nwk_ObjPatchFanin( pTemp, pNodeFrom, pNodeTo );
assert( Nwk_ObjFanoutNum(pNodeFrom) == 0 );
assert( Nwk_ObjFanoutNum(pNodeTo) == nFanoutsOld + Vec_PtrSize(vFanouts) );
}
/**Function*************************************************************
......@@ -304,15 +343,15 @@ void Ntk_ObjTransferFanout( Ntk_Obj_t * pNodeFrom, Ntk_Obj_t * pNodeTo )
SeeAlso []
***********************************************************************/
void Ntk_ObjReplace( Ntk_Obj_t * pNodeOld, Ntk_Obj_t * pNodeNew )
void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew )
{
assert( pNodeOld->pMan == pNodeNew->pMan );
assert( pNodeOld != pNodeNew );
assert( Ntk_ObjFanoutNum(pNodeOld) > 0 );
assert( Nwk_ObjFanoutNum(pNodeOld) > 0 );
// transfer the fanouts to the old node
Ntk_ObjTransferFanout( pNodeOld, pNodeNew );
Nwk_ObjTransferFanout( pNodeOld, pNodeNew );
// remove the old node
Ntk_ManDeleteNode_rec( pNodeOld );
Nwk_ManDeleteNode_rec( pNodeOld );
}
......
/**CFile****************************************************************
FileName [ntkMan.c]
FileName [nwkMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [Logic network representation.]
Synopsis [Network manager.]
Author [Alan Mishchenko]
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwkMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -30,7 +30,7 @@
/**Function*************************************************************
Synopsis [Allocates the netlist manager.]
Synopsis [Allocates the manager.]
Description []
......@@ -39,16 +39,16 @@
SeeAlso []
***********************************************************************/
Ntk_Man_t * Ntk_ManAlloc()
Nwk_Man_t * Nwk_ManAlloc()
{
Ntk_Man_t * p;
p = ALLOC( Ntk_Man_t, 1 );
memset( p, 0, sizeof(Ntk_Man_t) );
Nwk_Man_t * p;
p = ALLOC( Nwk_Man_t, 1 );
memset( p, 0, sizeof(Nwk_Man_t) );
p->vCis = Vec_PtrAlloc( 1000 );
p->vCos = Vec_PtrAlloc( 1000 );
p->vObjs = Vec_PtrAlloc( 1000 );
p->vTemp = Vec_PtrAlloc( 1000 );
p->nFanioPlus = 4;
p->nFanioPlus = 2;
p->pMemObjs = Aig_MmFlexStart();
p->pManHop = Hop_ManStart();
return p;
......@@ -56,7 +56,7 @@ Ntk_Man_t * Ntk_ManAlloc()
/**Function*************************************************************
Synopsis [Deallocates the netlist manager.]
Synopsis [Deallocates the manager.]
Description []
......@@ -65,8 +65,9 @@ Ntk_Man_t * Ntk_ManAlloc()
SeeAlso []
***********************************************************************/
void Ntk_ManFree( Ntk_Man_t * p )
void Nwk_ManFree( Nwk_Man_t * p )
{
// printf( "The number of realloced nodes = %d.\n", p->nRealloced );
if ( p->pName ) free( p->pName );
if ( p->pSpec ) free( p->pSpec );
if ( p->vCis ) Vec_PtrFree( p->vCis );
......@@ -81,7 +82,7 @@ void Ntk_ManFree( Ntk_Man_t * p )
/**Function*************************************************************
Synopsis [Deallocates the netlist manager.]
Synopsis [Prints stats of the manager.]
Description []
......@@ -90,23 +91,22 @@ void Ntk_ManFree( Ntk_Man_t * p )
SeeAlso []
***********************************************************************/
void Ntk_ManPrintStats( Ntk_Man_t * p, If_Lib_t * pLutLib )
void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib )
{
printf( "%-15s : ", p->pName );
printf( "pi = %5d ", Ntk_ManPiNum(p) );
printf( "po = %5d ", Ntk_ManPoNum(p) );
printf( "ci = %5d ", Ntk_ManCiNum(p) );
printf( "co = %5d ", Ntk_ManCoNum(p) );
printf( "lat = %5d ", Ntk_ManLatchNum(p) );
// printf( "box = %5d ", Ntk_ManBoxNum(p) );
printf( "node = %5d ", Ntk_ManNodeNum(p) );
printf( "aig = %6d ", Ntk_ManGetAigNodeNum(p) );
printf( "lev = %3d ", Ntk_ManLevel(p) );
printf( "lev2 = %3d ", Ntk_ManLevel2(p) );
printf( "delay = %5.2f", Ntk_ManDelayTraceLut(p, pLutLib) );
printf( "pi = %5d ", Nwk_ManPiNum(p) );
printf( "po = %5d ", Nwk_ManPoNum(p) );
printf( "ci = %5d ", Nwk_ManCiNum(p) );
printf( "co = %5d ", Nwk_ManCoNum(p) );
printf( "lat = %5d ", Nwk_ManLatchNum(p) );
printf( "node = %5d ", Nwk_ManNodeNum(p) );
printf( "aig = %6d ", Nwk_ManGetAigNodeNum(p) );
printf( "lev = %3d ", Nwk_ManLevel(p) );
// printf( "lev2 = %3d ", Nwk_ManLevel2(p) );
printf( "delay = %5.2f", Nwk_ManDelayTraceLut(p, pLutLib) );
printf( "\n" );
Ntk_ManDelayTracePrint( p, pLutLib );
// Nwk_ManDelayTracePrint( p, pLutLib );
fflush( stdout );
}
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [ntkMap.c]
FileName [nwkMap.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [Logic network representation.]
Synopsis [Interface to technology mapping.]
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwkMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "nwk.h"
#include "if.h"
////////////////////////////////////////////////////////////////////////
......@@ -40,7 +40,7 @@
SeeAlso []
***********************************************************************/
void Ntk_ManSetIfParsDefault( If_Par_t * pPars )
void Nwk_ManSetIfParsDefault( If_Par_t * pPars )
{
// extern void * Abc_FrameReadLibLut();
// set defaults
......@@ -59,9 +59,9 @@ void Ntk_ManSetIfParsDefault( If_Par_t * pPars )
pPars->fExpRed = 0;
pPars->fLatchPaths = 0;
pPars->fEdge = 1;
pPars->fCutMin = 1;
pPars->fCutMin = 0;
pPars->fSeqMap = 0;
pPars->fVerbose = 1;
pPars->fVerbose = 0;
// internal parameters
pPars->fTruth = 0;
pPars->nLatches = 0;
......@@ -96,7 +96,7 @@ void Ntk_ManSetIfParsDefault( If_Par_t * pPars )
SeeAlso []
***********************************************************************/
If_Man_t * Ntk_ManToIf( Aig_Man_t * p, If_Par_t * pPars )
If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars )
{
If_Man_t * pIfMan;
Aig_Obj_t * pNode;//, * pFanin, * pPrev;
......@@ -156,7 +156,7 @@ If_Man_t * Ntk_ManToIf( Aig_Man_t * p, If_Par_t * pPars )
SeeAlso []
***********************************************************************/
Hop_Obj_t * Ntk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited )
Hop_Obj_t * Nwk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited )
{
If_Cut_t * pCut;
If_Obj_t * pTemp;
......@@ -176,10 +176,10 @@ Hop_Obj_t * Ntk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj
// compute the functions of the children
for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv )
{
gFunc0 = Ntk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited );
gFunc0 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited );
if ( gFunc0 == (void *)1 )
continue;
gFunc1 = Ntk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited );
gFunc1 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited );
if ( gFunc1 == (void *)1 )
continue;
// both branches are solved
......@@ -203,7 +203,7 @@ Hop_Obj_t * Ntk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj
SeeAlso []
***********************************************************************/
Hop_Obj_t * Ntk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj )
Hop_Obj_t * Nwk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj )
{
If_Cut_t * pCut;
Hop_Obj_t * gFunc;
......@@ -217,10 +217,10 @@ Hop_Obj_t * Ntk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t *
If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) );
// recursively compute the function while collecting visited cuts
Vec_PtrClear( pIfMan->vTemp );
gFunc = Ntk_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp );
gFunc = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp );
if ( gFunc == (void *)1 )
{
printf( "Ntk_NodeIfToHop(): Computing local AIG has failed.\n" );
printf( "Nwk_NodeIfToHop(): Computing local AIG has failed.\n" );
return NULL;
}
// printf( "%d ", Vec_PtrSize(p->vTemp) );
......@@ -243,10 +243,10 @@ Hop_Obj_t * Ntk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t *
SeeAlso []
***********************************************************************/
Ntk_Man_t * Ntk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p )
Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p )
{
Ntk_Man_t * pNtk;
Ntk_Obj_t * pObjNew;
Nwk_Man_t * pNtk;
Nwk_Obj_t * pObjNew;
Aig_Obj_t * pObj;
If_Obj_t * pIfObj;
If_Cut_t * pCutBest;
......@@ -256,7 +256,7 @@ Ntk_Man_t * Ntk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p )
assert( Aig_ManNodeNum(p) == If_ManAndNum(pIfMan) );
If_ManCleanCutData( pIfMan );
// construct the network
pNtk = Ntk_ManAlloc();
pNtk = Nwk_ManAlloc();
pNtk->pName = Aig_UtilStrsav( p->pName );
pNtk->pSpec = Aig_UtilStrsav( p->pSpec );
Aig_ManForEachObj( p, pObj, i )
......@@ -270,23 +270,23 @@ Ntk_Man_t * Ntk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p )
nLeaves = If_CutLeaveNum( pCutBest );
ppLeaves = If_CutLeaves( pCutBest );
// create node
pObjNew = Ntk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs );
pObjNew = Nwk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs );
for ( k = 0; k < nLeaves; k++ )
Ntk_ObjAddFanin( pObjNew, Aig_ManObj(p, ppLeaves[k])->pData );
Nwk_ObjAddFanin( pObjNew, Aig_ManObj(p, ppLeaves[k])->pData );
// get the functionality
pObjNew->pFunc = Ntk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj );
pObjNew->pFunc = Nwk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj );
}
else if ( Aig_ObjIsPi(pObj) )
pObjNew = Ntk_ManCreateCi( pNtk, pIfObj->nRefs );
pObjNew = Nwk_ManCreateCi( pNtk, pIfObj->nRefs );
else if ( Aig_ObjIsPo(pObj) )
{
pObjNew = Ntk_ManCreateCo( pNtk );
pObjNew = Nwk_ManCreateCo( pNtk );
pObjNew->fCompl = Aig_ObjFaninC0(pObj);
Ntk_ObjAddFanin( pObjNew, Aig_ObjFanin0(pObj)->pData );
Nwk_ObjAddFanin( pObjNew, Aig_ObjFanin0(pObj)->pData );
}
else if ( Aig_ObjIsConst1(pObj) )
{
pObjNew = Ntk_ManCreateNode( pNtk, 0, pIfObj->nRefs );
pObjNew = Nwk_ManCreateNode( pNtk, 0, pIfObj->nRefs );
pObjNew->pFunc = Hop_ManConst1( pNtk->pManHop );
}
else
......@@ -308,16 +308,16 @@ Ntk_Man_t * Ntk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p )
SeeAlso []
***********************************************************************/
Ntk_Man_t * Ntk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars )
Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars )
{
Ntk_Man_t * pNtk;
Nwk_Man_t * pNtk;
If_Man_t * pIfMan;
// perform FPGA mapping
// set the arrival times
pPars->pTimesArr = ALLOC( float, Aig_ManPiNum(p) );
memset( pPars->pTimesArr, 0, sizeof(float) * Aig_ManPiNum(p) );
// translate into the mapper
pIfMan = Ntk_ManToIf( p, pPars );
pIfMan = Nwk_ManToIf( p, pPars );
if ( pIfMan == NULL )
return NULL;
pIfMan->pManTim = Tim_ManDup( pManTime, 0 );
......@@ -327,7 +327,7 @@ Ntk_Man_t * Ntk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars
return NULL;
}
// transform the result of mapping into the new network
pNtk = Ntk_ManFromIf( pIfMan, p );
pNtk = Nwk_ManFromIf( pIfMan, p );
If_ManStop( pIfMan );
return pNtk;
}
......
/**CFile****************************************************************
FileName [ntkObj.c]
FileName [nwkObj.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [Logic network representation.]
Synopsis [Manipulation of objects.]
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkObj.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwkObj.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -39,11 +39,12 @@
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateObj( Ntk_Man_t * p, int nFanins, int nFanouts )
Nwk_Obj_t * Nwk_ManCreateObj( Nwk_Man_t * p, int nFanins, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = (Ntk_Obj_t *)Aig_MmFlexEntryFetch( p->pMemObjs, sizeof(Ntk_Obj_t) + (nFanins + nFanouts + p->nFanioPlus) * sizeof(Ntk_Obj_t *) );
memset( pObj, 0, sizeof(Ntk_Obj_t) );
Nwk_Obj_t * pObj;
pObj = (Nwk_Obj_t *)Aig_MmFlexEntryFetch( p->pMemObjs, sizeof(Nwk_Obj_t) + (nFanins + nFanouts + p->nFanioPlus) * sizeof(Nwk_Obj_t *) );
memset( pObj, 0, sizeof(Nwk_Obj_t) );
pObj->pFanio = (Nwk_Obj_t **)((char *)pObj + sizeof(Nwk_Obj_t));
pObj->Id = Vec_PtrSize( p->vObjs );
Vec_PtrPush( p->vObjs, pObj );
pObj->pMan = p;
......@@ -63,14 +64,14 @@ Ntk_Obj_t * Ntk_ManCreateObj( Ntk_Man_t * p, int nFanins, int nFanouts )
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateCi( Ntk_Man_t * p, int nFanouts )
Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * p, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, 1, nFanouts );
Nwk_Obj_t * pObj;
pObj = Nwk_ManCreateObj( p, 1, nFanouts );
pObj->PioId = Vec_PtrSize( p->vCis );
Vec_PtrPush( p->vCis, pObj );
pObj->Type = NTK_OBJ_CI;
p->nObjs[NTK_OBJ_CI]++;
pObj->Type = NWK_OBJ_CI;
p->nObjs[NWK_OBJ_CI]++;
return pObj;
}
......@@ -85,14 +86,14 @@ Ntk_Obj_t * Ntk_ManCreateCi( Ntk_Man_t * p, int nFanouts )
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateCo( Ntk_Man_t * p )
Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * p )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, 1, 1 );
Nwk_Obj_t * pObj;
pObj = Nwk_ManCreateObj( p, 1, 1 );
pObj->PioId = Vec_PtrSize( p->vCos );
Vec_PtrPush( p->vCos, pObj );
pObj->Type = NTK_OBJ_CO;
p->nObjs[NTK_OBJ_CO]++;
pObj->Type = NWK_OBJ_CO;
p->nObjs[NWK_OBJ_CO]++;
return pObj;
}
......@@ -107,12 +108,12 @@ Ntk_Obj_t * Ntk_ManCreateCo( Ntk_Man_t * p )
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateLatch( Ntk_Man_t * p )
Nwk_Obj_t * Nwk_ManCreateLatch( Nwk_Man_t * p )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, 1, 1 );
pObj->Type = NTK_OBJ_LATCH;
p->nObjs[NTK_OBJ_LATCH]++;
Nwk_Obj_t * pObj;
pObj = Nwk_ManCreateObj( p, 1, 1 );
pObj->Type = NWK_OBJ_LATCH;
p->nObjs[NWK_OBJ_LATCH]++;
return pObj;
}
......@@ -127,32 +128,12 @@ Ntk_Obj_t * Ntk_ManCreateLatch( Ntk_Man_t * p )
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateNode( Ntk_Man_t * p, int nFanins, int nFanouts )
Nwk_Obj_t * Nwk_ManCreateNode( Nwk_Man_t * p, int nFanins, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, nFanins, nFanouts );
pObj->Type = NTK_OBJ_NODE;
p->nObjs[NTK_OBJ_NODE]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates a box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateBox( Ntk_Man_t * p, int nFanins, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, nFanins, nFanouts );
pObj->Type = NTK_OBJ_BOX;
p->nObjs[NTK_OBJ_BOX]++;
Nwk_Obj_t * pObj;
pObj = Nwk_ManCreateObj( p, nFanins, nFanouts );
pObj->Type = NWK_OBJ_NODE;
p->nObjs[NWK_OBJ_NODE]++;
return pObj;
}
......@@ -168,22 +149,22 @@ Ntk_Obj_t * Ntk_ManCreateBox( Ntk_Man_t * p, int nFanins, int nFanouts )
SeeAlso []
***********************************************************************/
void Ntk_ManDeleteNode( Ntk_Obj_t * pObj )
void Nwk_ManDeleteNode( Nwk_Obj_t * pObj )
{
Vec_Ptr_t * vNodes = pObj->pMan->vTemp;
Ntk_Obj_t * pTemp;
Nwk_Obj_t * pTemp;
int i;
// delete fanins and fanouts
Ntk_ObjCollectFanouts( pObj, vNodes );
Nwk_ObjCollectFanouts( pObj, vNodes );
Vec_PtrForEachEntry( vNodes, pTemp, i )
Ntk_ObjDeleteFanin( pTemp, pObj );
Ntk_ObjCollectFanins( pObj, vNodes );
Nwk_ObjDeleteFanin( pTemp, pObj );
Nwk_ObjCollectFanins( pObj, vNodes );
Vec_PtrForEachEntry( vNodes, pTemp, i )
Ntk_ObjDeleteFanin( pObj, pTemp );
Nwk_ObjDeleteFanin( pObj, pTemp );
// remove from the list of objects
Vec_PtrWriteEntry( pObj->pMan->vObjs, pObj->Id, NULL );
pObj->pMan->nObjs[pObj->Type]--;
memset( pObj, 0, sizeof(Ntk_Obj_t) );
memset( pObj, 0, sizeof(Nwk_Obj_t) );
pObj->Id = -1;
}
......@@ -198,18 +179,18 @@ void Ntk_ManDeleteNode( Ntk_Obj_t * pObj )
SeeAlso []
***********************************************************************/
void Ntk_ManDeleteNode_rec( Ntk_Obj_t * pObj )
void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj )
{
Vec_Ptr_t * vNodes;
int i;
assert( !Ntk_ObjIsCi(pObj) );
assert( Ntk_ObjFanoutNum(pObj) == 0 );
assert( !Nwk_ObjIsCi(pObj) );
assert( Nwk_ObjFanoutNum(pObj) == 0 );
vNodes = Vec_PtrAlloc( 100 );
Ntk_ObjCollectFanins( pObj, vNodes );
Ntk_ManDeleteNode( pObj );
Nwk_ObjCollectFanins( pObj, vNodes );
Nwk_ManDeleteNode( pObj );
Vec_PtrForEachEntry( vNodes, pObj, i )
if ( Ntk_ObjIsNode(pObj) && Ntk_ObjFanoutNum(pObj) == 0 )
Ntk_ManDeleteNode_rec( pObj );
if ( Nwk_ObjIsNode(pObj) && Nwk_ObjFanoutNum(pObj) == 0 )
Nwk_ManDeleteNode_rec( pObj );
Vec_PtrFree( vNodes );
}
......
/**CFile****************************************************************
FileName [nwkSpeedup.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Global delay optimization using structural choices.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwkSpeedup.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * pNtk )
{
return NULL;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [nwkStrash.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Logic network representation.]
Synopsis [Performs structural hashing for the network.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwkStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Derives AIG from the local functions of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManStrashNode_rec( Aig_Man_t * p, Hop_Obj_t * pObj )
{
assert( !Hop_IsComplement(pObj) );
if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
return;
Nwk_ManStrashNode_rec( p, Hop_ObjFanin0(pObj) );
Nwk_ManStrashNode_rec( p, Hop_ObjFanin1(pObj) );
pObj->pData = Aig_And( p, (Aig_Obj_t *)Hop_ObjChild0Copy(pObj), (Aig_Obj_t *)Hop_ObjChild1Copy(pObj) );
assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
Hop_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Derives AIG from the local functions of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Nwk_ManStrashNode( Aig_Man_t * p, Nwk_Obj_t * pObj )
{
Hop_Man_t * pMan = pObj->pMan->pManHop;
Hop_Obj_t * pRoot = pObj->pFunc;
Nwk_Obj_t * pFanin;
int i;
assert( Nwk_ObjIsNode(pObj) );
// check the constant case
if ( Hop_Regular(pRoot) == Hop_ManConst1(pMan) )
return Aig_NotCond( Aig_ManConst1(p), Hop_IsComplement(pRoot) );
// set elementary variables
Nwk_ObjForEachFanin( pObj, pFanin, i )
Hop_IthVar(pMan, i)->pData = pFanin->pCopy;
// strash the AIG of this node
Nwk_ManStrashNode_rec( p, Hop_Regular(pRoot) );
Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
// return the final node
return Aig_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
}
/**Function*************************************************************
Synopsis [Derives AIG from the logic network.]
Description [Assumes topological ordering of nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Nwk_ManStrash( Nwk_Man_t * pNtk )
{
Aig_Man_t * pMan;
Aig_Obj_t * pObjNew;
Nwk_Obj_t * pObj;
int i, Level;
pMan = Aig_ManStart( Nwk_ManGetAigNodeNum(pNtk) );
pMan->pManTime = Tim_ManDup( pNtk->pManTime, 1 );
Tim_ManIncrementTravId( pMan->pManTime );
Nwk_ManForEachObj( pNtk, pObj, i )
{
if ( Nwk_ObjIsCi(pObj) )
{
pObjNew = Aig_ObjCreatePi(pMan);
Level = Tim_ManGetPiArrival( pMan->pManTime, pObj->PioId );
Aig_ObjSetLevel( pObjNew, Level );
}
else if ( Nwk_ObjIsCo(pObj) )
{
pObjNew = Aig_ObjCreatePo( pMan, Aig_NotCond(Nwk_ObjFanin0(pObj)->pCopy, pObj->fCompl) );
Level = Aig_ObjLevel( pObjNew );
Tim_ManSetPoArrival( pMan->pManTime, pObj->PioId, (float)Level );
}
else if ( Nwk_ObjIsNode(pObj) )
{
pObjNew = Nwk_ManStrashNode( pMan, pObj );
}
else
assert( 0 );
pObj->pCopy = pObjNew;
}
Aig_ManCleanup( pMan );
return pMan;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [nwkTiming.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Logic network representation.]
Synopsis [Manipulation of timing information.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwkTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Nwk_ManTimeEqual( float f1, float f2, float Eps ) { return (f1 < f2 + Eps) && (f2 < f1 + Eps); }
static inline int Nwk_ManTimeLess( float f1, float f2, float Eps ) { return (f1 < f2 + Eps); }
static inline int Nwk_ManTimeMore( float f1, float f2, float Eps ) { return (f1 + Eps > f2); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Cleans timing information for all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManCleanTiming( Nwk_Man_t * pNtk )
{
Nwk_Obj_t * pObj;
int i;
Nwk_ManForEachObj( pNtk, pObj, i )
{
pObj->tArrival = pObj->tSlack = 0.0;
pObj->tRequired = AIG_INFINITY;
}
}
/**Function*************************************************************
Synopsis [Sorts the pins in the decreasing order of delays.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManDelayTraceSortPins( Nwk_Obj_t * pNode, int * pPinPerm, float * pPinDelays )
{
Nwk_Obj_t * pFanin;
int i, j, best_i, temp;
// start the trivial permutation and collect pin delays
Nwk_ObjForEachFanin( pNode, pFanin, i )
{
pPinPerm[i] = i;
pPinDelays[i] = Nwk_ObjArrival(pFanin);
}
// selection sort the pins in the decreasible order of delays
// this order will match the increasing order of LUT input pins
for ( i = 0; i < Nwk_ObjFaninNum(pNode)-1; i++ )
{
best_i = i;
for ( j = i+1; j < Nwk_ObjFaninNum(pNode); j++ )
if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] )
best_i = j;
if ( best_i == i )
continue;
temp = pPinPerm[i];
pPinPerm[i] = pPinPerm[best_i];
pPinPerm[best_i] = temp;
}
// verify
assert( Nwk_ObjFaninNum(pNode) == 0 || pPinPerm[0] < Nwk_ObjFaninNum(pNode) );
for ( i = 1; i < Nwk_ObjFaninNum(pNode); i++ )
{
assert( pPinPerm[i] < Nwk_ObjFaninNum(pNode) );
assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] );
}
}
/**Function*************************************************************
Synopsis [Computes the arrival times for the given node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Nwk_NodeComputeArrival( Nwk_Obj_t * pObj, If_Lib_t * pLutLib, int fUseSorting )
{
int pPinPerm[32];
float pPinDelays[32];
Nwk_Obj_t * pFanin;
float tArrival, * pDelays;
int k;
assert( Nwk_ObjIsNode(pObj) );
tArrival = -AIG_INFINITY;
if ( pLutLib == NULL )
{
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Nwk_ObjArrival(pFanin) + 1.0 )
tArrival = Nwk_ObjArrival(pFanin) + 1.0;
}
else if ( !pLutLib->fVarPinDelays )
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Nwk_ObjArrival(pFanin) + pDelays[0] )
tArrival = Nwk_ObjArrival(pFanin) + pDelays[0];
}
else
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
if ( fUseSorting )
{
Nwk_ManDelayTraceSortPins( pObj, pPinPerm, pPinDelays );
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Nwk_ObjArrival(Nwk_ObjFanin(pObj,pPinPerm[k])) + pDelays[k] )
tArrival = Nwk_ObjArrival(Nwk_ObjFanin(pObj,pPinPerm[k])) + pDelays[k];
}
else
{
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( tArrival < Nwk_ObjArrival(pFanin) + pDelays[k] )
tArrival = Nwk_ObjArrival(pFanin) + pDelays[k];
}
}
if ( Nwk_ObjFaninNum(pObj) == 0 )
tArrival = 0.0;
return tArrival;
}
/**Function*************************************************************
Synopsis [Computes the required times for the given node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Nwk_NodeComputeRequired( Nwk_Obj_t * pObj, If_Lib_t * pLutLib, int fUseSorting )
{
int pPinPerm[32];
float pPinDelays[32];
Nwk_Obj_t * pFanout;
float tRequired, * pDelays;
int k;
assert( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCi(pObj) );
tRequired = AIG_INFINITY;
if ( pLutLib == NULL )
{
Nwk_ObjForEachFanout( pObj, pFanout, k )
if ( tRequired > Nwk_ObjRequired(pFanout) - 1.0 )
tRequired = Nwk_ObjRequired(pFanout) - 1.0;
}
else if ( !pLutLib->fVarPinDelays )
{
Nwk_ObjForEachFanout( pObj, pFanout, k )
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pFanout)];
if ( tRequired > Nwk_ObjRequired(pFanout) - pDelays[0] )
tRequired = Nwk_ObjRequired(pFanout) - pDelays[0];
}
}
else
{
if ( fUseSorting )
{
Nwk_ObjForEachFanout( pObj, pFanout, k )
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pFanout)];
Nwk_ManDelayTraceSortPins( pFanout, pPinPerm, pPinDelays );
if ( tRequired > Nwk_ObjRequired(Nwk_ObjFanout(pObj,pPinPerm[k])) - pDelays[k] )
tRequired = Nwk_ObjRequired(Nwk_ObjFanout(pObj,pPinPerm[k])) - pDelays[k];
}
}
else
{
Nwk_ObjForEachFanout( pObj, pFanout, k )
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pFanout)];
if ( tRequired > Nwk_ObjRequired(pFanout) - pDelays[k] )
tRequired = Nwk_ObjRequired(pFanout) - pDelays[k];
}
}
}
return tRequired;
}
/**Function*************************************************************
Synopsis [Propagates the required times through the given node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Nwk_NodePropagateRequired( Nwk_Obj_t * pObj, If_Lib_t * pLutLib, int fUseSorting )
{
int pPinPerm[32];
float pPinDelays[32];
Nwk_Obj_t * pFanin;
float tRequired, * pDelays;
int k;
assert( Nwk_ObjIsNode(pObj) );
if ( pLutLib == NULL )
{
tRequired = Nwk_ObjRequired(pObj) - (float)1.0;
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( Nwk_ObjRequired(pFanin) > tRequired )
Nwk_ObjSetRequired( pFanin, tRequired );
}
else if ( !pLutLib->fVarPinDelays )
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
tRequired = Nwk_ObjRequired(pObj) - pDelays[0];
Nwk_ObjForEachFanin( pObj, pFanin, k )
if ( Nwk_ObjRequired(pFanin) > tRequired )
Nwk_ObjSetRequired( pFanin, tRequired );
}
else
{
pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
if ( fUseSorting )
{
Nwk_ManDelayTraceSortPins( pObj, pPinPerm, pPinDelays );
Nwk_ObjForEachFanin( pObj, pFanin, k )
{
tRequired = Nwk_ObjRequired(pObj) - pDelays[k];
if ( Nwk_ObjRequired(Nwk_ObjFanin(pObj,pPinPerm[k])) > tRequired )
Nwk_ObjSetRequired( Nwk_ObjFanin(pObj,pPinPerm[k]), tRequired );
}
}
else
{
Nwk_ObjForEachFanin( pObj, pFanin, k )
{
tRequired = Nwk_ObjRequired(pObj) - pDelays[k];
if ( Nwk_ObjRequired(pFanin) > tRequired )
Nwk_ObjSetRequired( pFanin, tRequired );
}
}
}
return tRequired;
}
/**Function*************************************************************
Synopsis [Computes the delay trace of the given network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Nwk_ManDelayTraceLut( Nwk_Man_t * pNtk, If_Lib_t * pLutLib )
{
int fUseSorting = 1;
Vec_Ptr_t * vNodes;
Nwk_Obj_t * pObj;
float tArrival, tRequired, tSlack;
int i;
// get the library
if ( pLutLib && pLutLib->LutMax < Nwk_ManGetFaninMax(pNtk) )
{
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
pLutLib->LutMax, Nwk_ManGetFaninMax(pNtk) );
return -AIG_INFINITY;
}
// compute the reverse order of all objects
vNodes = Nwk_ManDfsReverse( pNtk );
// initialize the arrival times
Nwk_ManCleanTiming( pNtk );
// propagate arrival times
if ( pNtk->pManTime )
Tim_ManIncrementTravId( pNtk->pManTime );
Nwk_ManForEachObj( pNtk, pObj, i )
{
if ( Nwk_ObjIsNode(pObj) )
{
tArrival = Nwk_NodeComputeArrival( pObj, pLutLib, fUseSorting );
}
else if ( Nwk_ObjIsCi(pObj) )
{
tArrival = pNtk->pManTime? Tim_ManGetPiArrival( pNtk->pManTime, pObj->PioId ) : (float)0.0;
}
else if ( Nwk_ObjIsCo(pObj) )
{
tArrival = Nwk_ObjArrival( Nwk_ObjFanin0(pObj) );
if ( pNtk->pManTime )
Tim_ManSetPoArrival( pNtk->pManTime, pObj->PioId, tArrival );
}
else
assert( 0 );
Nwk_ObjSetArrival( pObj, tArrival );
}
// get the latest arrival times
tArrival = -AIG_INFINITY;
Nwk_ManForEachPo( pNtk, pObj, i )
if ( tArrival < Nwk_ObjArrival(pObj) )
tArrival = Nwk_ObjArrival(pObj);
// initialize the required times
if ( pNtk->pManTime )
{
Tim_ManIncrementTravId( pNtk->pManTime );
Tim_ManSetPoRequiredAll( pNtk->pManTime, tArrival );
}
else
Nwk_ManForEachPo( pNtk, pObj, i )
Nwk_ObjSetRequired( pObj, tArrival );
// propagate the required times
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( Nwk_ObjIsNode(pObj) )
{
Nwk_NodePropagateRequired( pObj, pLutLib, fUseSorting );
}
else if ( Nwk_ObjIsCi(pObj) )
{
if ( pNtk->pManTime )
Tim_ManSetPiRequired( pNtk->pManTime, pObj->PioId, Nwk_ObjRequired(pObj) );
}
else if ( Nwk_ObjIsCo(pObj) )
{
if ( pNtk->pManTime )
tRequired = Tim_ManGetPoRequired( pNtk->pManTime, pObj->PioId );
else
tRequired = Nwk_ObjRequired(pObj);
if ( Nwk_ObjRequired(Nwk_ObjFanin0(pObj)) > tRequired )
Nwk_ObjSetRequired( Nwk_ObjFanin0(pObj), tRequired );
}
// set slack for this object
tSlack = Nwk_ObjRequired(pObj) - Nwk_ObjArrival(pObj);
assert( tSlack + 0.001 > 0.0 );
Nwk_ObjSetSlack( pObj, tSlack < 0.0 ? 0.0 : tSlack );
}
Vec_PtrFree( vNodes );
return tArrival;
}
/**Function*************************************************************
Synopsis [Prints the delay trace for the given network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManDelayTracePrint( Nwk_Man_t * pNtk, If_Lib_t * pLutLib )
{
Nwk_Obj_t * pNode;
int i, Nodes, * pCounters;
float tArrival, tDelta, nSteps, Num;
// get the library
if ( pLutLib && pLutLib->LutMax < Nwk_ManGetFaninMax(pNtk) )
{
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
pLutLib->LutMax, Nwk_ManGetFaninMax(pNtk) );
return;
}
// decide how many steps
nSteps = pLutLib ? 20 : Nwk_ManLevel(pNtk);
pCounters = ALLOC( int, nSteps + 1 );
memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
// perform delay trace
tArrival = Nwk_ManDelayTraceLut( pNtk, pLutLib );
tDelta = tArrival / nSteps;
// count how many nodes have slack in the corresponding intervals
Nwk_ManForEachNode( pNtk, pNode, i )
{
if ( Nwk_ObjFaninNum(pNode) == 0 )
continue;
Num = Nwk_ObjSlack(pNode) / tDelta;
if ( Num > nSteps )
continue;
assert( Num >=0 && Num <= nSteps );
pCounters[(int)Num]++;
}
// print the results
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
Nodes = 0;
for ( i = 0; i < nSteps; i++ )
{
Nodes += pCounters[i];
printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
pLutLib? "%":"lev", Nodes, 100.0*Nodes/Nwk_ManNodeNum(pNtk) );
}
free( pCounters );
}
/**Function*************************************************************
Synopsis [Inserts node into the queue of nodes sorted by level.]
Description [The inserted node should not go before the current position
given by iCurrent. If the arrival times are computed, the nodes are sorted
in the increasing order of levels. If the required times are computed,
the nodes are sorted in the decreasing order of levels.]
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_NodeUpdateAddToQueue( Vec_Ptr_t * vQueue, Nwk_Obj_t * pObj, int iCurrent, int fArrival )
{
Nwk_Obj_t * pTemp1, * pTemp2;
int i;
Vec_PtrPush( vQueue, pObj );
for ( i = Vec_PtrSize(vQueue) - 1; i > iCurrent + 1; i-- )
{
pTemp1 = vQueue->pArray[i];
pTemp2 = vQueue->pArray[i-1];
if ( fArrival )
{
if ( Nwk_ObjLevel(pTemp2) <= Nwk_ObjLevel(pTemp1) )
break;
}
else
{
if ( Nwk_ObjLevel(pTemp2) >= Nwk_ObjLevel(pTemp1) )
break;
}
// assert( i-1 > iCurrent );
vQueue->pArray[i-1] = pTemp1;
vQueue->pArray[i] = pTemp2;
}
// verification
for ( i = iCurrent + 1; i < Vec_PtrSize(vQueue) - 1; i++ )
{
pTemp1 = vQueue->pArray[i];
pTemp2 = vQueue->pArray[i+1];
if ( fArrival )
assert( Nwk_ObjLevel(pTemp1) <= Nwk_ObjLevel(pTemp2) );
else
assert( Nwk_ObjLevel(pTemp1) >= Nwk_ObjLevel(pTemp2) );
}
}
/**Function*************************************************************
Synopsis [Incrementally updates arrival times of the node.]
Description [Supports variable-pin delay model and white-boxes.]
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_NodeUpdateArrival( Nwk_Obj_t * pObj, If_Lib_t * pLutLib )
{
Tim_Man_t * pManTime = pObj->pMan->pManTime;
Vec_Ptr_t * vQueue = pObj->pMan->vTemp;
Nwk_Obj_t * pTemp, * pNext;
float tArrival;
int i, k;
assert( Nwk_ObjIsNode(pObj) );
// initialize the queue with the node
Vec_PtrClear( vQueue );
Vec_PtrPush( vQueue, pObj );
pObj->MarkA = 1;
// process objects
Tim_ManTravIdDisable( pManTime );
Vec_PtrForEachEntry( vQueue, pTemp, i )
{
pTemp->MarkA = 0;
tArrival = Nwk_NodeComputeArrival( pTemp, pLutLib, 1 );
if ( Nwk_ManTimeEqual( tArrival, Nwk_ObjArrival(pTemp), (float)0.001 ) )
continue;
Nwk_ObjSetArrival( pTemp, tArrival );
// add the fanouts to the queue
Nwk_ObjForEachFanout( pTemp, pNext, k )
{
if ( Nwk_ObjIsCo(pNext) )
{
Nwk_ObjSetArrival( pNext, tArrival );
continue;
}
if ( pNext->MarkA )
continue;
Nwk_NodeUpdateAddToQueue( vQueue, pNext, i, 1 );
pNext->MarkA = 1;
}
}
}
/**Function*************************************************************
Synopsis [Incrementally updates required times of the node.]
Description [Supports variable-pin delay model and white-boxes.]
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_NodeUpdateRequired( Nwk_Obj_t * pObj, If_Lib_t * pLutLib )
{
Tim_Man_t * pManTime = pObj->pMan->pManTime;
Vec_Ptr_t * vQueue = pObj->pMan->vTemp;
Nwk_Obj_t * pTemp, * pNext;
float tRequired;
int i, k;
assert( Nwk_ObjIsNode(pObj) );
// make sure the node's required time remained the same
tRequired = Nwk_NodeComputeRequired( pObj, pLutLib, 1 );
assert( Nwk_ManTimeEqual( tRequired, Nwk_ObjRequired(pObj), (float)0.001 ) );
// initialize the queue with the node's fanins
Vec_PtrClear( vQueue );
Nwk_ObjForEachFanin( pObj, pNext, k )
{
if ( pNext->MarkA )
continue;
Nwk_NodeUpdateAddToQueue( vQueue, pNext, -1, 0 );
pNext->MarkA = 1;
}
// process objects
Tim_ManTravIdDisable( pManTime );
Vec_PtrForEachEntry( vQueue, pTemp, i )
{
pTemp->MarkA = 0;
tRequired = Nwk_NodeComputeRequired( pTemp, pLutLib, 1 );
if ( Nwk_ManTimeEqual( tRequired, Nwk_ObjRequired(pTemp), (float)0.001 ) )
continue;
Nwk_ObjSetRequired( pTemp, tRequired );
// schedule fanins of the node
Nwk_ObjForEachFanin( pTemp, pNext, k )
{
if ( pNext->MarkA )
continue;
Nwk_NodeUpdateAddToQueue( vQueue, pNext, i, 0 );
pNext->MarkA = 1;
}
}
}
/**Function*************************************************************
Synopsis [Computes the level of the node using its fanin levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_ObjLevelNew( Nwk_Obj_t * pObj )
{
Nwk_Obj_t * pFanin;
int i, Level = 0;
if ( Nwk_ObjIsCi(pObj) || Nwk_ObjIsLatch(pObj) )
return 0;
assert( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCo(pObj) );
Nwk_ObjForEachFanin( pObj, pFanin, i )
Level = AIG_MAX( Level, Nwk_ObjLevel(pFanin) );
return Level + (Nwk_ObjIsNode(pObj) && Nwk_ObjFaninNum(pObj) > 0);
}
/**Function*************************************************************
Synopsis [Incrementally updates level of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManUpdateLevel( Nwk_Obj_t * pObj )
{
Vec_Ptr_t * vQueue = pObj->pMan->vTemp;
Nwk_Obj_t * pTemp, * pNext;
int LevelNew, i, k;
assert( Nwk_ObjIsNode(pObj) );
// initialize the queue with the node
Vec_PtrClear( vQueue );
Vec_PtrPush( vQueue, pObj );
pObj->MarkA = 1;
// process objects
Vec_PtrForEachEntry( vQueue, pTemp, i )
{
pTemp->MarkA = 0;
LevelNew = Nwk_ObjLevelNew( pTemp );
if ( LevelNew == Nwk_ObjLevel(pTemp) )
continue;
Nwk_ObjSetLevel( pTemp, LevelNew );
// add the fanouts to the queue
Nwk_ObjForEachFanout( pTemp, pNext, k )
{
if ( Nwk_ObjIsCo(pNext) )
{
Nwk_ObjSetLevel( pNext, LevelNew );
continue;
}
if ( pNext->MarkA )
continue;
Nwk_NodeUpdateAddToQueue( vQueue, pNext, i, 1 );
pNext->MarkA = 1;
}
}
}
/**Function*************************************************************
Synopsis [Computes the level of the node using its fanin levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManVerifyLevel( Nwk_Man_t * pNtk )
{
Nwk_Obj_t * pObj;
int LevelNew, i;
Nwk_ManForEachObj( pNtk, pObj, i )
{
assert( pObj->MarkA == 0 );
LevelNew = Nwk_ObjLevelNew( pObj );
if ( Nwk_ObjLevel(pObj) != LevelNew )
{
printf( "Object %6d: Mismatch betweeh levels: Actual = %d. Correct = %d.\n",
i, Nwk_ObjLevel(pObj), LevelNew );
}
}
}
/**Function*************************************************************
Synopsis [Replaces the node and incrementally updates levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManUpdate( Nwk_Obj_t * pObj, Nwk_Obj_t * pObjNew, Vec_Vec_t * vLevels )
{
// transfer the timing information
// (this is needed because updating level happens if the level has changed;
// when we set the old level, it will be recomputed by the level updating
// procedure, which will update level of other nodes if there is a difference)
pObjNew->Level = pObj->Level;
pObjNew->tArrival = pObj->tArrival;
pObjNew->tRequired = pObj->tRequired;
// replace the old node by the new node
Nwk_ObjReplace( pObj, pObjNew );
// update the level of the node
Nwk_ManUpdateLevel( pObjNew );
//Nwk_ManVerifyLevel( pObjNew->pMan );
// Nwk_NodeUpdateArrival( pObjNew, pObj->pMan->pLutLib );
// Nwk_NodeUpdateRequired( pObjNew, pObj->pMan->pLutLib );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkUtil.c]
FileName [nwkUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
PackageName [Logic network representation.]
Synopsis [Various utilities.]
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwkUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -39,14 +39,14 @@
SeeAlso []
***********************************************************************/
void Ntk_ManIncrementTravId( Ntk_Man_t * pNtk )
void Nwk_ManIncrementTravId( Nwk_Man_t * pNtk )
{
Ntk_Obj_t * pObj;
Nwk_Obj_t * pObj;
int i;
if ( pNtk->nTravIds >= (1<<26)-1 )
{
pNtk->nTravIds = 0;
Ntk_ManForEachObj( pNtk, pObj, i )
Nwk_ManForEachObj( pNtk, pObj, i )
pObj->TravId = 0;
}
pNtk->nTravIds++;
......@@ -63,14 +63,14 @@ void Ntk_ManIncrementTravId( Ntk_Man_t * pNtk )
SeeAlso []
***********************************************************************/
int Ntk_ManGetFaninMax( Ntk_Man_t * pNtk )
int Nwk_ManGetFaninMax( Nwk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
Nwk_Obj_t * pNode;
int i, nFaninsMax = 0;
Ntk_ManForEachNode( pNtk, pNode, i )
Nwk_ManForEachNode( pNtk, pNode, i )
{
if ( nFaninsMax < Ntk_ObjFaninNum(pNode) )
nFaninsMax = Ntk_ObjFaninNum(pNode);
if ( nFaninsMax < Nwk_ObjFaninNum(pNode) )
nFaninsMax = Nwk_ObjFaninNum(pNode);
}
return nFaninsMax;
}
......@@ -86,12 +86,12 @@ int Ntk_ManGetFaninMax( Ntk_Man_t * pNtk )
SeeAlso []
***********************************************************************/
int Ntk_ManGetTotalFanins( Ntk_Man_t * pNtk )
int Nwk_ManGetTotalFanins( Nwk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
Nwk_Obj_t * pNode;
int i, nFanins = 0;
Ntk_ManForEachNode( pNtk, pNode, i )
nFanins += Ntk_ObjFaninNum(pNode);
Nwk_ManForEachNode( pNtk, pNode, i )
nFanins += Nwk_ObjFaninNum(pNode);
return nFanins;
}
......@@ -107,12 +107,12 @@ int Ntk_ManGetTotalFanins( Ntk_Man_t * pNtk )
SeeAlso []
***********************************************************************/
int Ntk_ManPiNum( Ntk_Man_t * pNtk )
int Nwk_ManPiNum( Nwk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
Nwk_Obj_t * pNode;
int i, Counter = 0;
Ntk_ManForEachCi( pNtk, pNode, i )
Counter += Ntk_ObjIsPi( pNode );
Nwk_ManForEachCi( pNtk, pNode, i )
Counter += Nwk_ObjIsPi( pNode );
return Counter;
}
......@@ -127,12 +127,12 @@ int Ntk_ManPiNum( Ntk_Man_t * pNtk )
SeeAlso []
***********************************************************************/
int Ntk_ManPoNum( Ntk_Man_t * pNtk )
int Nwk_ManPoNum( Nwk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
Nwk_Obj_t * pNode;
int i, Counter = 0;
Ntk_ManForEachCo( pNtk, pNode, i )
Counter += Ntk_ObjIsPo( pNode );
Nwk_ManForEachCo( pNtk, pNode, i )
Counter += Nwk_ObjIsPo( pNode );
return Counter;
}
......@@ -147,24 +147,66 @@ int Ntk_ManPoNum( Ntk_Man_t * pNtk )
SeeAlso []
***********************************************************************/
int Ntk_ManGetAigNodeNum( Ntk_Man_t * pNtk )
int Nwk_ManGetAigNodeNum( Nwk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
Nwk_Obj_t * pNode;
int i, nNodes = 0;
Ntk_ManForEachNode( pNtk, pNode, i )
Nwk_ManForEachNode( pNtk, pNode, i )
{
if ( pNode->pFunc == NULL )
{
printf( "Ntk_ManGetAigNodeNum(): Local AIG of node %d is not assigned.\n", pNode->Id );
printf( "Nwk_ManGetAigNodeNum(): Local AIG of node %d is not assigned.\n", pNode->Id );
continue;
}
if ( Ntk_ObjFaninNum(pNode) < 2 )
if ( Nwk_ObjFaninNum(pNode) < 2 )
continue;
nNodes += Hop_DagSize( pNode->pFunc );
}
return nNodes;
}
/**Function*************************************************************
Synopsis [Procedure used for sorting the nodes in increasing order of levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_NodeCompareLevelsIncrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 )
{
int Diff = (*pp1)->Level - (*pp2)->Level;
if ( Diff < 0 )
return -1;
if ( Diff > 0 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Nwk_NodeCompareLevelsDecrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 )
{
int Diff = (*pp1)->Level - (*pp2)->Level;
if ( Diff > 0 )
return -1;
if ( Diff < 0 )
return 1;
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [ntk_.c]
FileName [nwk_.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: nwk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
......@@ -47,6 +47,7 @@ struct Tim_Man_t_
Vec_Ptr_t * vDelayTables; // pointers to the delay tables
Mem_Flex_t * pMemObj; // memory manager for boxes
int nTravIds; // traversal ID of the manager
int fUseTravId; // enables the use of traversal ID
int nPis; // the number of PIs
int nPos; // the number of POs
Tim_Obj_t * pPis; // timing info for the PIs
......@@ -143,6 +144,7 @@ Tim_Man_t * Tim_ManStart( int nPis, int nPos )
p->pPos[i].timeArr = 0.0;
p->pPos[i].TravId = 0;
}
p->fUseTravId = 1;
return p;
}
......@@ -238,6 +240,33 @@ Tim_Man_t * Tim_ManDupUnit( Tim_Man_t * p )
/**Function*************************************************************
Synopsis [Duplicates the timing manager.]
Description [Derives the approximate timing manager with realistic delays
but without white-boxes.]
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManDupApprox( Tim_Man_t * p )
{
Tim_Man_t * pNew;
int k;
pNew = Tim_ManStart( p->nPis, p->nPos );
for ( k = 0; k < p->nPis; k++ )
if ( p->pPis[k].iObj2Box == -1 )
pNew->pPis[k].timeArr = p->pPis[k].timeArr;
else
pNew->pPis[k].timeArr = p->pPis[k].timeReq;
for ( k = 0; k < p->nPos; k++ )
pNew->pPos[k].timeReq = p->pPos[k].timeReq;
return pNew;
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
......@@ -302,6 +331,38 @@ void Tim_ManPrint( Tim_Man_t * p )
/**Function*************************************************************
Synopsis [Disables the use of the traversal ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManTravIdDisable( Tim_Man_t * p )
{
p->fUseTravId = 0;
}
/**Function*************************************************************
Synopsis [Enables the use of the traversal ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManTravIdEnable( Tim_Man_t * p )
{
p->fUseTravId = 1;
}
/**Function*************************************************************
Synopsis [Sets the vector of timing tables associated with the manager.]
Description []
......@@ -459,7 +520,7 @@ void Tim_ManInitPoRequired( Tim_Man_t * p, int iPo, float Delay )
void Tim_ManSetPoArrival( Tim_Man_t * p, int iPo, float Delay )
{
assert( iPo < p->nPos );
assert( p->pPos[iPo].TravId != p->nTravIds );
assert( !p->fUseTravId || p->pPos[iPo].TravId != p->nTravIds );
p->pPos[iPo].timeArr = Delay;
p->pPos[iPo].TravId = p->nTravIds;
}
......@@ -478,7 +539,7 @@ void Tim_ManSetPoArrival( Tim_Man_t * p, int iPo, float Delay )
void Tim_ManSetPiRequired( Tim_Man_t * p, int iPi, float Delay )
{
assert( iPi < p->nPis );
assert( p->pPis[iPi].TravId != p->nTravIds );
assert( !p->fUseTravId || p->pPis[iPi].TravId != p->nTravIds );
p->pPis[iPi].timeReq = Delay;
p->pPis[iPi].TravId = p->nTravIds;
}
......@@ -497,7 +558,7 @@ void Tim_ManSetPiRequired( Tim_Man_t * p, int iPi, float Delay )
void Tim_ManSetPoRequired( Tim_Man_t * p, int iPo, float Delay )
{
assert( iPo < p->nPos );
assert( p->pPos[iPo].TravId != p->nTravIds );
assert( !p->fUseTravId || p->pPos[iPo].TravId != p->nTravIds );
p->pPos[iPo].timeReq = Delay;
p->pPos[iPo].TravId = p->nTravIds;
}
......@@ -541,7 +602,7 @@ float Tim_ManGetPiArrival( Tim_Man_t * p, int iPi )
int i, k;
// consider the already processed PI
pObjThis = Tim_ManPi( p, iPi );
if ( pObjThis->TravId == p->nTravIds )
if ( p->fUseTravId && pObjThis->TravId == p->nTravIds )
return pObjThis->timeArr;
pObjThis->TravId = p->nTravIds;
// consider the main PI
......@@ -551,9 +612,10 @@ float Tim_ManGetPiArrival( Tim_Man_t * p, int iPi )
// update box timing
pBox->TravId = p->nTravIds;
// get the arrival times of the inputs of the box (POs)
if ( p->fUseTravId )
Tim_ManBoxForEachInput( p, pBox, pObj, i )
if ( pObj->TravId != p->nTravIds )
printf( "Tim_ManGetPiArrival(): PO arrival times of the box are not up to date!\n" );
printf( "Tim_ManGetPiArrival(): Input arrival times of the box are not up to date!\n" );
// compute the arrival times for each output of the box (PIs)
Tim_ManBoxForEachOutput( p, pBox, pObjRes, i )
{
......@@ -586,7 +648,7 @@ float Tim_ManGetPoRequired( Tim_Man_t * p, int iPo )
int i, k;
// consider the already processed PO
pObjThis = Tim_ManPo( p, iPo );
if ( pObjThis->TravId == p->nTravIds )
if ( p->fUseTravId && pObjThis->TravId == p->nTravIds )
return pObjThis->timeReq;
pObjThis->TravId = p->nTravIds;
// consider the main PO
......@@ -595,11 +657,12 @@ float Tim_ManGetPoRequired( Tim_Man_t * p, int iPo )
return pObjThis->timeReq;
// update box timing
pBox->TravId = p->nTravIds;
// get the required times of the inputs of the box (POs)
// get the required times of the outputs of the box (PIs)
if ( p->fUseTravId )
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
if ( pObj->TravId != p->nTravIds )
printf( "Tim_ManGetPoRequired(): PI required times of the box are not up to date!\n" );
// compute the required times for each output of the box (PIs)
printf( "Tim_ManGetPoRequired(): Output required times of the box are not up to date!\n" );
// compute the required times for each input of the box (POs)
Tim_ManBoxForEachInput( p, pBox, pObjRes, i )
{
DelayBest = AIG_INFINITY;
......
......@@ -60,8 +60,11 @@ typedef struct Tim_Man_t_ Tim_Man_t;
extern Tim_Man_t * Tim_ManStart( int nPis, int nPos );
extern Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete );
extern Tim_Man_t * Tim_ManDupUnit( Tim_Man_t * p );
extern Tim_Man_t * Tim_ManDupApprox( Tim_Man_t * p );
extern void Tim_ManStop( Tim_Man_t * p );
extern void Tim_ManPrint( Tim_Man_t * p );
extern void Tim_ManTravIdDisable( Tim_Man_t * p );
extern void Tim_ManTravIdEnable( Tim_Man_t * p );
extern void Tim_ManSetDelayTables( Tim_Man_t * p, Vec_Ptr_t * vDelayTables );
extern void Tim_ManCreateBox( Tim_Man_t * p, int * pIns, int nIns, int * pOuts, int nOuts, float * pDelayTable );
extern void Tim_ManCreateBoxFirst( Tim_Man_t * p, int firstIn, int nIns, int firstOut, int nOuts, float * pDelayTable );
......
......@@ -67,7 +67,7 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
Synopsis [Returns the DFS ordered array of logic nodes.]
Description [Collects only the internal nodes, leaving CIs and CO.
Description [Collects only the internal nodes, leaving out CIs and CO.
However it marks with the current TravId both CIs and COs.]
SideEffects []
......@@ -749,6 +749,31 @@ Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNod
return vNodes;
}
/**Function*************************************************************
Synopsis [Computes the sum total of supports of all outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSupportSum( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vSupp;
Abc_Obj_t * pObj;
int i, nTotalSupps = 0;
Abc_NtkForEachCo( pNtk, pObj, i )
{
vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
nTotalSupps += Vec_PtrSize( vSupp );
Vec_PtrFree( vSupp );
}
printf( "Total supports = %d.\n", nTotalSupps );
}
/**Function*************************************************************
......
......@@ -30,6 +30,7 @@
#include "aig.h"
#include "dar.h"
#include "mfs.h"
#include "mfx.h"
#include "fra.h"
////////////////////////////////////////////////////////////////////////
......@@ -205,12 +206,19 @@ static int Abc_CommandAbc8Write ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandAbc8Ps ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8If ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8DChoice ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8DC2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Bidec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Strash ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8ReadLut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8PrintLut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Lutpack ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Balance ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Speedup ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Cec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Scl ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Lcorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Ssw ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Cec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8DSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
......@@ -233,7 +241,7 @@ void Abc_FrameClearDesign()
{
extern Abc_Frame_t * Abc_FrameGetGlobalFrame();
extern void Ntl_ManFree( void * );
extern void Ntk_ManFree( void * );
extern void Nwk_ManFree( void * );
Abc_Frame_t * pAbc;
pAbc = Abc_FrameGetGlobalFrame();
......@@ -247,10 +255,10 @@ void Abc_FrameClearDesign()
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = NULL;
}
if ( pAbc->pAbc8Ntk )
if ( pAbc->pAbc8Nwk )
{
Ntk_ManFree( pAbc->pAbc8Ntk );
pAbc->pAbc8Ntk = NULL;
Nwk_ManFree( pAbc->pAbc8Nwk );
pAbc->pAbc8Nwk = NULL;
}
}
......@@ -428,17 +436,24 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "indcut", Abc_CommandIndcut, 0 );
Cmd_CommandAdd( pAbc, "Verification", "enlarge", Abc_CommandEnlarge, 1 );
Cmd_CommandAdd( pAbc, "ABC8", "*read", Abc_CommandAbc8Read, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*write", Abc_CommandAbc8Write, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*r", Abc_CommandAbc8Read, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*w", Abc_CommandAbc8Write, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*ps", Abc_CommandAbc8Ps, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*if", Abc_CommandAbc8If, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*dchoice", Abc_CommandAbc8DChoice, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*read_lut", Abc_CommandAbc8ReadLut, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*print_lut", Abc_CommandAbc8PrintLut, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*dc2", Abc_CommandAbc8DC2, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*bidec", Abc_CommandAbc8Bidec, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*st", Abc_CommandAbc8Strash, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*rlut", Abc_CommandAbc8ReadLut, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*plut", Abc_CommandAbc8PrintLut, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*mfs", Abc_CommandAbc8Mfs, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*lp", Abc_CommandAbc8Lutpack, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*b", Abc_CommandAbc8Balance, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*speedup", Abc_CommandAbc8Speedup, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*cec", Abc_CommandAbc8Cec, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*scl", Abc_CommandAbc8Scl, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*lcorr", Abc_CommandAbc8Lcorr, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*ssw", Abc_CommandAbc8Ssw, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*cec", Abc_CommandAbc8Cec, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*dsec", Abc_CommandAbc8DSec, 0 );
......@@ -478,7 +493,7 @@ void Abc_End()
{
Abc_FrameClearDesign();
{
extern void If_LutLibFree( void * pLutLib );
extern void If_LutLibFree( If_Lib_t * pLutLib );
if ( Abc_FrameGetGlobalFrame()->pAbc8Lib )
If_LutLibFree( Abc_FrameGetGlobalFrame()->pAbc8Lib );
}
......@@ -3233,7 +3248,7 @@ int Abc_CommandLutpack( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pErr, "usage: lutpack [-N <num>] [-Q <num>] [-S <num>] [-L <num>] [-szfovwh]\n" );
fprintf( pErr, "\t performs \"rewriting\" for LUT networks;\n" );
fprintf( pErr, "\t performs \"rewriting\" for LUT network;\n" );
fprintf( pErr, "\t determines LUT size as the max fanin count of a node;\n" );
fprintf( pErr, "\t if the network is not LUT-mapped, packs it into 6-LUTs\n" );
fprintf( pErr, "\t (there is another command for resynthesis after LUT mapping, \"imfs\")\n" );
......@@ -3409,19 +3424,7 @@ int Abc_CommandMfs( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
pPars->nWinTfoLevs = 2;
pPars->nFanoutsMax = 10;
pPars->nDepthMax = 20;
pPars->nDivMax = 250;
pPars->nWinSizeMax = 300;
pPars->nGrowthLevel = 0;
pPars->nBTLimit = 5000;
pPars->fResub = 1;
pPars->fArea = 0;
pPars->fMoreEffort = 0;
pPars->fSwapEdge = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
Abc_NtkMfsParsDefault( pPars );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCraesvwh" ) ) != EOF )
{
......@@ -7083,7 +7086,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
// Abc_Ntk_t * pNtkRes;
Abc_Ntk_t * pNtkRes;
int c;
int fBmc;
int nFrames;
......@@ -7105,14 +7108,16 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// extern void Abc_NtkDarTestBlif( char * pFileName );
// extern Abc_Ntk_t * Abc_NtkDarPartition( Abc_Ntk_t * pNtk );
// extern Abc_Ntk_t * Abc_NtkTestExor( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_NtkNtkTest( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
printf( "This command is temporarily disabled.\n" );
return 0;
// printf( "This command is temporarily disabled.\n" );
// return 0;
// set defaults
fVeryVerbose = 0;
......@@ -7289,8 +7294,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
*/
// Abc_NtkDarPartition( pNtk );
/*
pNtkRes = Abc_NtkTestExor( pNtk, 0 );
pNtkRes = Abc_NtkNtkTest( pNtk );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Command has failed.\n" );
......@@ -7298,7 +7303,6 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
*/
return 0;
usage:
fprintf( pErr, "usage: test [-vwh]\n" );
......@@ -14761,7 +14765,7 @@ int Abc_CommandAbc8Read( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( stdout, "usage: *read [-h]\n" );
fprintf( stdout, "usage: *r [-h]\n" );
fprintf( stdout, "\t reads the design with whiteboxes\n" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
......@@ -14781,9 +14785,12 @@ usage:
int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char * pFileName;
void * pTemp;
int c;
extern void Ioa_WriteBlif( void * p, char * pFileName );
extern int Ntl_ManInsertNtk( void * p, void * pNtk );
extern void * Ntl_ManDup( void * pOld );
extern void Ntl_ManFree( void * p );
// set defaults
Extra_UtilGetoptReset();
......@@ -14802,12 +14809,11 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "Abc_CommandAbc8Write(): There is no design to write.\n" );
return 1;
}
// get the input file name
pFileName = argv[globalUtilOptind];
if ( pAbc->pAbc8Ntk != NULL )
// create the design to write
pTemp = Ntl_ManDup( pAbc->pAbc8Ntl );
if ( pAbc->pAbc8Nwk != NULL )
{
if ( !Ntl_ManInsertNtk( pAbc->pAbc8Ntl, pAbc->pAbc8Ntk ) )
if ( !Ntl_ManInsertNtk( pTemp, pAbc->pAbc8Nwk ) )
{
printf( "Abc_CommandAbc8Write(): There is no design to write.\n" );
return 1;
......@@ -14816,11 +14822,14 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv )
}
else
printf( "Writing the original design.\n" );
Ioa_WriteBlif( pAbc->pAbc8Ntl, pFileName );
// get the input file name
pFileName = argv[globalUtilOptind];
Ioa_WriteBlif( pTemp, pFileName );
Ntl_ManFree( pTemp );
return 0;
usage:
fprintf( stdout, "usage: *write [-h]\n" );
fprintf( stdout, "usage: *w [-h]\n" );
fprintf( stdout, "\t write the design with whiteboxes\n" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
......@@ -14841,7 +14850,7 @@ int Abc_CommandAbc8Ps( Abc_Frame_t * pAbc, int argc, char ** argv )
{
int c;
extern void Ntl_ManPrintStats( void * p );
extern void Ntk_ManPrintStats( void * p, void * pLutLib );
extern void Nwk_ManPrintStats( void * p, void * pLutLib );
// set defaults
Extra_UtilGetoptReset();
......@@ -14863,11 +14872,20 @@ int Abc_CommandAbc8Ps( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the input file name
if ( pAbc->pAbc8Ntl )
{
printf( "NETLIST: " );
Ntl_ManPrintStats( pAbc->pAbc8Ntl );
}
if ( pAbc->pAbc8Aig )
{
printf( "AIG: " );
Aig_ManPrintStats( pAbc->pAbc8Aig );
if ( pAbc->pAbc8Ntk )
Ntk_ManPrintStats( pAbc->pAbc8Ntk, pAbc->pAbc8Lib );
}
if ( pAbc->pAbc8Nwk )
{
printf( "MAPPED: " );
Nwk_ManPrintStats( pAbc->pAbc8Nwk, pAbc->pAbc8Lib );
}
return 0;
usage:
......@@ -14895,11 +14913,11 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
extern int Ntl_ManInsertTest( void * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertTestIf( void * p, Aig_Man_t * pAig );
extern void * Ntk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars );
extern void * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars );
extern Tim_Man_t * Ntl_ManReadTimeMan( void * p );
extern void * If_SetSimpleLutLib( int nLutSize );
extern void Ntk_ManSetIfParsDefault( If_Par_t * pPars );
extern void Ntk_ManFree( void * );
extern If_Lib_t * If_SetSimpleLutLib( int nLutSize );
extern void Nwk_ManSetIfParsDefault( If_Par_t * pPars );
extern void Nwk_ManFree( void * );
if ( pAbc->pAbc8Lib == NULL )
{
......@@ -14908,7 +14926,7 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// set defaults
Ntk_ManSetIfParsDefault( pPars );
Nwk_ManSetIfParsDefault( pPars );
pPars->pLutLib = pAbc->pAbc8Lib;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
......@@ -14935,15 +14953,15 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
*/
pNtkNew = Ntk_MappingIf( pAbc->pAbc8Aig, Ntl_ManReadTimeMan(pAbc->pAbc8Ntl), pPars );
pNtkNew = Nwk_MappingIf( pAbc->pAbc8Aig, Ntl_ManReadTimeMan(pAbc->pAbc8Ntl), pPars );
if ( pNtkNew == NULL )
{
printf( "Abc_CommandAbc8If(): Mapping of the AIG has failed.\n" );
return 1;
}
if ( pAbc->pAbc8Ntk != NULL )
Ntk_ManFree( pAbc->pAbc8Ntk );
pAbc->pAbc8Ntk = pNtkNew;
if ( pAbc->pAbc8Nwk != NULL )
Nwk_ManFree( pAbc->pAbc8Nwk );
pAbc->pAbc8Nwk = pNtkNew;
return 0;
usage:
......@@ -15002,11 +15020,180 @@ int Abc_CommandAbc8DChoice( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( stdout, "usage: *dchoice [-h]\n" );
fprintf( stdout, "\t performs AIG-based synthesis\n" );
fprintf( stdout, "\t performs AIG-based synthesis and derives choices\n" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8DC2( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Aig_Man_t * pAigNew;
int c;
int fBalance;
int fUpdateLevel;
int fVerbose;
extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fVerbose );
// set defaults
fBalance = 0;
fUpdateLevel = 1;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "blh" ) ) != EOF )
{
switch ( c )
{
case 'b':
fBalance ^= 1;
break;
case 'l':
fUpdateLevel ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8DChoice(): There is no AIG to synthesize.\n" );
return 1;
}
// get the input file name
pAigNew = Dar_ManCompress2( pAbc->pAbc8Aig, fBalance, fUpdateLevel, 1, fVerbose );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8DChoice(): Tranformation of the AIG has failed.\n" );
return 1;
}
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0;
usage:
fprintf( stdout, "usage: *dc2 [-blvh]\n" );
fprintf( stdout, "\t performs AIG-based synthesis without deriving choices\n" );
fprintf( stdout, "\t-b : toggle internal balancing [default = %s]\n", fBalance? "yes": "no" );
fprintf( stdout, "\t-l : toggle updating level [default = %s]\n", fUpdateLevel? "yes": "no" );
fprintf( stdout, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Bidec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
int c;
extern void Nwk_ManBidecResyn( void * pNtk, int fVerbose );
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Nwk == NULL )
{
printf( "Abc_CommandAbc8DChoice(): There is no mapped network to strash.\n" );
return 1;
}
Nwk_ManBidecResyn( pAbc->pAbc8Nwk, 0 );
return 0;
usage:
fprintf( stdout, "usage: *bidec [-h]\n" );
fprintf( stdout, "\t performs bi-decomposition of local functions\n" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Aig_Man_t * pAigNew;
int c;
extern Aig_Man_t * Nwk_ManStrash( void * pNtk );
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Nwk == NULL )
{
printf( "Abc_CommandAbc8DChoice(): There is no mapped network to strash.\n" );
return 1;
}
pAigNew = Nwk_ManStrash( pAbc->pAbc8Nwk );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8Strash(): Tranformation of the AIG has failed.\n" );
return 1;
}
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0;
usage:
fprintf( stdout, "usage: *st [-h]\n" );
fprintf( stdout, "\t performs structural hashing of mapped network\n" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis [Command procedure to read LUT libraries.]
......@@ -15024,8 +15211,8 @@ int Abc_CommandAbc8ReadLut( Abc_Frame_t * pAbc, int argc, char **argv )
char * FileName;
void * pLib;
int c;
extern void * If_LutLibRead( char * FileName );
extern void If_LutLibFree( void * pLutLib );
extern If_Lib_t * If_LutLibRead( char * FileName );
extern void If_LutLibFree( If_Lib_t * pLutLib );
// set the defaults
Extra_UtilGetoptReset();
......@@ -15073,7 +15260,7 @@ int Abc_CommandAbc8ReadLut( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
usage:
fprintf( stdout, "\nusage: *read_lut [-h]\n");
fprintf( stdout, "\nusage: *rlut [-h]\n");
fprintf( stdout, "\t read the LUT library from the file\n" );
fprintf( stdout, "\t-h : print the command usage\n");
fprintf( stdout, "\t \n");
......@@ -15105,7 +15292,7 @@ usage:
int Abc_CommandAbc8PrintLut( Abc_Frame_t * pAbc, int argc, char **argv )
{
int c;
extern void If_LutLibPrint( void * pLutLib );
extern void If_LutLibPrint( If_Lib_t * pLutLib );
// set the defaults
Extra_UtilGetoptReset();
......@@ -15134,42 +15321,12 @@ int Abc_CommandAbc8PrintLut( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
usage:
fprintf( stdout, "\nusage: *print_lut [-h]\n");
fprintf( stdout, "\nusage: *plut [-h]\n");
fprintf( stdout, "\t print the current LUT library\n" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1; /* error exit */
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Scl( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return 0;
}
/**Function*************************************************************
......@@ -15182,23 +15339,519 @@ int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Ssw( Abc_Frame_t * pAbc, int argc, char ** argv )
int Abc_CommandAbc8Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Mfx_Par_t Pars, * pPars = &Pars;
int c;
extern int Mfx_Perform( void * pNtk, Mfx_Par_t * pPars );
***********************************************************************/
int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Mfx_ParsDefault( pPars );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCraesvwh" ) ) != EOF )
{
switch ( c )
{
case 'W':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-W\" should be followed by an integer.\n" );
goto usage;
}
pPars->nWinTfoLevs = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nWinTfoLevs < 0 )
goto usage;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
pPars->nFanoutsMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nFanoutsMax < 1 )
goto usage;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-D\" should be followed by an integer.\n" );
goto usage;
}
pPars->nDepthMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nDepthMax < 0 )
goto usage;
break;
case 'M':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-M\" should be followed by an integer.\n" );
goto usage;
}
pPars->nWinSizeMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nWinSizeMax < 0 )
goto usage;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-L\" should be followed by an integer.\n" );
goto usage;
}
pPars->nGrowthLevel = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nGrowthLevel < 0 || pPars->nGrowthLevel > ABC_INFINITY )
goto usage;
break;
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
pPars->nBTLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nBTLimit < 0 )
goto usage;
break;
case 'r':
pPars->fResub ^= 1;
break;
case 'a':
pPars->fArea ^= 1;
break;
case 'e':
pPars->fMoreEffort ^= 1;
break;
case 's':
pPars->fSwapEdge ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
break;
case 'w':
pPars->fVeryVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Nwk == NULL )
{
printf( "Abc_CommandAbc8Mfs(): There is no mapped network to strash.\n" );
return 1;
}
// modify the current network
if ( !Mfx_Perform( pAbc->pAbc8Nwk, pPars ) )
{
fprintf( stdout, "Abc_CommandAbc8Mfs(): Command has failed.\n" );
return 1;
}
return 0;
usage:
fprintf( stdout, "usage: *mfs [-WFDMLC <num>] [-raesvh]\n" );
fprintf( stdout, "\t performs don't-care-based optimization of logic networks\n" );
fprintf( stdout, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nWinTfoLevs );
fprintf( stdout, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutsMax );
fprintf( stdout, "\t-D <num> : the max depth nodes to try (0 = no limit) [default = %d]\n", pPars->nDepthMax );
fprintf( stdout, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
fprintf( stdout, "\t-L <num> : the max increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
fprintf( stdout, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
fprintf( stdout, "\t-r : toggle resubstitution and dc-minimization [default = %s]\n", pPars->fResub? "resub": "dc-min" );
fprintf( stdout, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
fprintf( stdout, "\t-e : toggle high-effort resubstitution [default = %s]\n", pPars->fMoreEffort? "yes": "no" );
fprintf( stdout, "\t-s : toggle evaluation of edge swapping [default = %s]\n", pPars->fSwapEdge? "yes": "no" );
fprintf( stdout, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( stdout, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Lutpack( Abc_Frame_t * pAbc, int argc, char ** argv )
{
int c;
printf( "This command is temporarily disabled.\n" );
return 0;
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Nwk == NULL )
{
printf( "Abc_CommandAbc8DChoice(): There is no mapped network to strash.\n" );
return 1;
}
return 0;
usage:
/*
fprintf( stdout, "usage: *lp [-h]\n" );
fprintf( stdout, "usage: lutpack [-N <num>] [-Q <num>] [-S <num>] [-L <num>] [-szfovwh]\n" );
fprintf( stdout, "\t performs \"rewriting\" for LUT network;\n" );
fprintf( stdout, "\t determines LUT size as the max fanin count of a node;\n" );
fprintf( stdout, "\t if the network is not LUT-mapped, packs it into 6-LUTs\n" );
fprintf( stdout, "\t (there is another command for resynthesis after LUT mapping, \"imfs\")\n" );
fprintf( stdout, "\t-N <num> : the max number of LUTs in the structure (2 <= num) [default = %d]\n", pPars->nLutsMax );
fprintf( stdout, "\t-Q <num> : the max number of LUTs not in MFFC (0 <= num) [default = %d]\n", pPars->nLutsOver );
fprintf( stdout, "\t-S <num> : the max number of LUT inputs shared (0 <= num <= 3) [default = %d]\n", pPars->nVarsShared );
fprintf( stdout, "\t-L <num> : max level increase after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
fprintf( stdout, "\t-s : toggle iteration till saturation [default = %s]\n", pPars->fSatur? "yes": "no" );
fprintf( stdout, "\t-z : toggle zero-cost replacements [default = %s]\n", pPars->fZeroCost? "yes": "no" );
fprintf( stdout, "\t-f : toggle using only first node and first cut [default = %s]\n", pPars->fFirst? "yes": "no" );
fprintf( stdout, "\t-o : toggle using old implementation [default = %s]\n", pPars->fOldAlgo? "yes": "no" );
fprintf( stdout, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( stdout, "\t-w : toggle detailed printout of decomposed functions [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
*/
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Balance( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Aig_Man_t * pAigNew;
int c;
int fExor;
int fUpdateLevel;
int fVerbose;
extern Aig_Man_t * Dar_ManBalanceXor( Aig_Man_t * pAig, int fExor, int fUpdateLevel, int fVerbose );
// set defaults
fExor = 0;
fUpdateLevel = 1;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "xlh" ) ) != EOF )
{
switch ( c )
{
case 'x':
fExor ^= 1;
break;
case 'l':
fUpdateLevel ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8DChoice(): There is no AIG to synthesize.\n" );
return 1;
}
// get the input file name
pAigNew = Dar_ManBalanceXor( pAbc->pAbc8Aig, fExor, fUpdateLevel, fVerbose );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8Balance(): Tranformation of the AIG has failed.\n" );
return 1;
}
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0;
usage:
fprintf( stdout, "usage: *b [-xlvh]\n" );
fprintf( stdout, "\t performs balanacing of the AIG\n" );
fprintf( stdout, "\t-x : toggle using XOR-balancing [default = %s]\n", fExor? "yes": "no" );
fprintf( stdout, "\t-l : toggle updating level [default = %s]\n", fUpdateLevel? "yes": "no" );
fprintf( stdout, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Speedup( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Aig_Man_t * pAigNew;
int c;
int fUseLutLib;
int Percentage;
int Degree;
int fVerbose;
int fVeryVerbose;
extern Aig_Man_t * Nwk_ManSpeedup( void * pNtk );
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PNlvwh" ) ) != EOF )
{
switch ( c )
{
case 'P':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-P\" should be followed by an integer.\n" );
goto usage;
}
Percentage = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Percentage < 1 || Percentage > 100 )
goto usage;
break;
case 'N':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
Degree = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Degree < 1 || Degree > 5 )
goto usage;
break;
case 'l':
fUseLutLib ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'w':
fVeryVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Nwk == NULL )
{
printf( "Abc_CommandAbc8DChoice(): There is no mapped network to strash.\n" );
return 1;
}
pAigNew = Nwk_ManSpeedup( pAbc->pAbc8Nwk );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8Speedup(): Tranformation of the AIG has failed.\n" );
return 1;
}
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0;
usage:
fprintf( stdout, "usage: *speedup [-P num] [-N num] [-lvwh]\n" );
fprintf( stdout, "\t transforms LUT-mapped network into an AIG with choices;\n" );
fprintf( stdout, "\t the choices are added to speedup the next round of mapping\n" );
fprintf( stdout, "\t-P <num> : delay delta defining critical path for library model [default = %d%%]\n", Percentage );
fprintf( stdout, "\t-N <num> : the max critical path degree for resynthesis (0 < num < 6) [default = %d]\n", Degree );
fprintf( stdout, "\t-l : toggle using unit- or LUT-library-delay model [default = %s]\n", fUseLutLib? "lib" : "unit" );
fprintf( stdout, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-w : toggle printing detailed stats for each node [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Aig_Man_t * pAig1, * pAig2;
void * pTemp;
char ** pArgvNew;
int nArgcNew;
int c;
int fVerbose;
int nConfLimit;
int fPartition;
extern Aig_Man_t * Ntl_ManCollapse( void * p );
extern void * Ntl_ManDup( void * pOld );
extern void Ntl_ManFree( void * p );
extern int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int fPartition, int fVerbose );
// set defaults
fVerbose = 0;
nConfLimit = 10000;
fPartition = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF )
{
switch ( c )
{
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
nConfLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nConfLimit < 0 )
goto usage;
break;
case 'p':
fPartition ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
default:
goto usage;
}
}
pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind;
if ( nArgcNew != 0 )
{
printf( "Currently can only compare current network against the spec.\n" );
return 0;
}
if ( pAbc->pAbc8Ntl == NULL )
{
printf( "Abc_CommandAbc8Cec(): There is no design to verify.\n" );
return 0;
}
if ( pAbc->pAbc8Nwk == NULL )
{
printf( "Abc_CommandAbc8Cec(): There is no mapped network to verify.\n" );
return 0;
}
// derive AIGs
pAig1 = Ntl_ManCollapse( pAbc->pAbc8Ntl );
pTemp = Ntl_ManDup( pAbc->pAbc8Ntl );
if ( !Ntl_ManInsertNtk( pTemp, pAbc->pAbc8Nwk ) )
{
printf( "Abc_CommandAbc8Cec(): Inserting the design has failed.\n" );
return 1;
}
pAig2 = Ntl_ManCollapse( pTemp );
Ntl_ManFree( pTemp );
// perform verification
Fra_FraigCecTop( pAig1, pAig2, nConfLimit, fPartition, fVerbose );
Aig_ManStop( pAig1 );
Aig_ManStop( pAig2 );
return 0;
usage:
fprintf( stdout, "usage: *cec [-C num] [-pvh] <file1> <file2>\n" );
fprintf( stdout, "\t performs combinational equivalence checking\n" );
fprintf( stdout, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
fprintf( stdout, "\t-p : toggle automatic partitioning [default = %s]\n", fPartition? "yes": "no" );
fprintf( stdout, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
fprintf( stdout, "\tfile1 : (optional) the file with the first network\n");
fprintf( stdout, "\tfile2 : (optional) the file with the second network\n");
fprintf( stdout, "\t if no files are given, uses the current network and its spec\n");
fprintf( stdout, "\t if one file is given, uses the current network and the file\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Scl( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Ssw( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return 0;
}
......
/**CFile****************************************************************
FileName [abcAbc8.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcAbc8.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "nwk.h"
#include "mfx.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Converts old ABC network into new ABC network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Nwk_Man_t * Abc_NtkToNtkNew( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Nwk_Man_t * pNtkNew;
Nwk_Obj_t * pObjNew;
Abc_Obj_t * pObj, * pFanin;
int i, k;
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( stdout, "Thsi is not a logic network.\n" );
return 0;
}
// convert into the AIG
if ( !Abc_NtkToAig(pNtk) )
{
fprintf( stdout, "Converting to AIGs has failed.\n" );
return 0;
}
assert( Abc_NtkHasAig(pNtk) );
// construct the network
pNtkNew = Nwk_ManAlloc();
pNtkNew->pName = Extra_UtilStrsav( pNtk->pName );
pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pSpec );
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Nwk_ManCreateCi( pNtkNew, Abc_ObjFanoutNum(pObj) );
vNodes = Abc_NtkDfs( pNtk, 1 );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
pObjNew = Nwk_ManCreateNode( pNtkNew, Abc_ObjFaninNum(pObj), Abc_ObjFanoutNum(pObj) );
Abc_ObjForEachFanin( pObj, pFanin, k )
Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)pFanin->pCopy );
pObjNew->pFunc = Hop_Transfer( pNtk->pManFunc, pNtkNew->pManHop, pObj->pData, Abc_ObjFaninNum(pObj) );
pObj->pCopy = (Abc_Obj_t *)pObjNew;
}
Vec_PtrFree( vNodes );
Abc_NtkForEachCo( pNtk, pObj, i )
{
pObjNew = Nwk_ManCreateCo( pNtkNew );
Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)Abc_ObjFanin0(pObj)->pCopy );
}
// if ( !Nwk_ManCheck( pNtkNew ) )
// fprintf( stdout, "Abc_NtkToNtkNew(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Converts new ABC network into old ABC network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromNtkNew( Abc_Ntk_t * pNtkOld, Nwk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObjNew, * pFaninNew;
Nwk_Obj_t * pObj, * pFanin;
int i, k;
// construct the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_AIG, 1 );
pNtkNew->pName = Extra_UtilStrsav( pNtk->pName );
pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pSpec );
Nwk_ManForEachCi( pNtk, pObj, i )
{
pObjNew = Abc_NtkCreatePi( pNtkNew );
pObj->pCopy = (Nwk_Obj_t *)pObjNew;
Abc_ObjAssignName( pObjNew, Abc_ObjName( Abc_NtkCi(pNtkOld, i) ), NULL );
}
vNodes = Nwk_ManDfs( pNtk );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( !Nwk_ObjIsNode(pObj) )
continue;
pObjNew = Abc_NtkCreateNode( pNtkNew );
Nwk_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObjNew, pFanin->pCopy );
pObjNew->pData = Hop_Transfer( pNtk->pManHop, pNtkNew->pManFunc, pObj->pFunc, Nwk_ObjFaninNum(pObj) );
pObj->pCopy = (Nwk_Obj_t *)pObjNew;
}
Vec_PtrFree( vNodes );
Nwk_ManForEachCo( pNtk, pObj, i )
{
pObjNew = Abc_NtkCreatePo( pNtkNew );
if ( pObj->fCompl )
pFaninNew = Abc_NtkCreateNodeInv( pNtkNew, Nwk_ObjFanin0(pObj)->pCopy );
else
pFaninNew = Nwk_ObjFanin0(pObj)->pCopy;
Abc_ObjAddFanin( pObjNew, pFaninNew );
Abc_ObjAssignName( pObjNew, Abc_ObjName( Abc_NtkCo(pNtkOld, i) ), NULL );
}
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkFromNtkNew(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkNtkTest2( Abc_Ntk_t * pNtk )
{
extern void Abc_NtkSupportSum( Abc_Ntk_t * pNtk );
Abc_Ntk_t * pNtkNew;
Nwk_Man_t * pMan;
int clk;
clk = clock();
Abc_NtkSupportSum( pNtk );
PRT( "Time", clock() - clk );
pMan = Abc_NtkToNtkNew( pNtk );
clk = clock();
Nwk_ManSupportSum( pMan );
PRT( "Time", clock() - clk );
pNtkNew = Abc_NtkFromNtkNew( pNtk, pMan );
Nwk_ManFree( pMan );
return pNtkNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkNtkTest3( Abc_Ntk_t * pNtk )
{
extern void Abc_NtkSupportSum( Abc_Ntk_t * pNtk );
extern void * Abc_FrameReadLibLut();
Abc_Ntk_t * pNtkNew;
Nwk_Man_t * pMan;
int clk;
clk = clock();
printf( "%6.2f\n", Abc_NtkDelayTraceLut( pNtk, 1 ) );
PRT( "Time", clock() - clk );
pMan = Abc_NtkToNtkNew( pNtk );
clk = clock();
printf( "%6.2f\n", Nwk_ManDelayTraceLut( pMan, Abc_FrameReadLibLut() ) );
PRT( "Time", clock() - clk );
pNtkNew = Abc_NtkFromNtkNew( pNtk, pMan );
Nwk_ManFree( pMan );
return pNtkNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkNtkTest( Abc_Ntk_t * pNtk )
{
extern int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars );
Mfx_Par_t Pars, * pPars = &Pars;
Abc_Ntk_t * pNtkNew;
Nwk_Man_t * pMan;
pMan = Abc_NtkToNtkNew( pNtk );
Mfx_ParsDefault( pPars );
Mfx_Perform( pMan, pPars );
pNtkNew = Abc_NtkFromNtkNew( pNtk, pMan );
Nwk_ManFree( pMan );
return pNtkNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -946,7 +946,7 @@ int Abc_NtkDarCec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fPartition, int fVe
{
pMan1 = Abc_NtkToDar( pNtk1, 0, 0 );
pMan2 = Abc_NtkToDar( pNtk2, 0, 0 );
RetValue = Fra_FraigCecPartitioned( pMan1, pMan2, fVerbose );
RetValue = Fra_FraigCecPartitioned( pMan1, pMan2, 100, fVerbose );
Aig_ManStop( pMan1 );
Aig_ManStop( pMan2 );
goto finish;
......@@ -1716,43 +1716,6 @@ Abc_Ntk_t * Abc_NtkBalanceExor( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose
}
#include "ntl.h"
/**Function*************************************************************
Synopsis [Performs targe enlargement.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDarTestBlif( char * pFileName )
{
/*
char Buffer[1000];
Ntl_Man_t * p;
p = Ioa_ReadBlif( pFileName, 1 );
if ( p == NULL )
{
printf( "Abc_NtkDarTestBlif(): Reading BLIF has failed.\n" );
return;
}
Ntl_ManPrintStats( p );
// if ( !Ntl_ManInsertTest( p ) )
if ( !Ntl_ManInsertTestIf( p ) )
{
printf( "Abc_NtkDarTestBlif(): Tranformation of the netlist has failed.\n" );
return;
}
// sprintf( Buffer, "%s_.blif", p->pName );
sprintf( Buffer, "test_.blif", p->pName );
Ioa_WriteBlif( p, Buffer );
Ntl_ManFree( p );
*/
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
SRC += src/base/abci/abc.c \
src/base/abci/abcAbc8.c \
src/base/abci/abcAttach.c \
src/base/abci/abcAuto.c \
src/base/abci/abcBalance.c \
......
......@@ -76,7 +76,7 @@ struct Abc_Frame_t_
// new code
void * pAbc8Ntl; // the current design
void * pAbc8Ntk; // the current mapped network
void * pAbc8Nwk; // the current mapped network
void * pAbc8Aig; // the current AIG
void * pAbc8Lib; // the current LUT library
};
......
......@@ -357,6 +357,15 @@ extern float If_CutEdgeDeref( If_Man_t * p, If_Cut_t * pCut );
extern float If_CutEdgeRef( If_Man_t * p, If_Cut_t * pCut );
extern float If_CutEdgeDerefed( If_Man_t * p, If_Cut_t * pCut );
extern float If_CutEdgeRefed( If_Man_t * p, If_Cut_t * pCut );
/*=== ifLib.c =============================================================*/
extern If_Lib_t * If_LutLibRead( char * FileName );
extern If_Lib_t * If_LutLibDup( If_Lib_t * p );
extern void If_LutLibFree( If_Lib_t * pLutLib );
extern void If_LutLibPrint( If_Lib_t * pLutLib );
extern int If_LutLibDelaysAreDiscrete( If_Lib_t * pLutLib );
extern If_Lib_t * If_SetSimpleLutLib( int nLutSize );
extern float If_LutLibFastestPinDelay( If_Lib_t * p );
extern float If_LutLibSlowestPinDelay( If_Lib_t * p );
/*=== ifMan.c =============================================================*/
extern If_Man_t * If_ManStart( If_Par_t * pPars );
extern void If_ManRestart( If_Man_t * p );
......
......@@ -266,6 +266,38 @@ If_Lib_t * If_SetSimpleLutLib( int nLutSize )
return If_LutLibDup(pLutLib);
}
/**Function*************************************************************
Synopsis [Gets the delay of the fastest pin.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float If_LutLibFastestPinDelay( If_Lib_t * p )
{
return !p? 1.0 : p->pLutDelays[p->LutMax][0];
}
/**Function*************************************************************
Synopsis [Gets the delay of the slowest pin.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float If_LutLibSlowestPinDelay( If_Lib_t * p )
{
return !p? 1.0 : (p->fVarPinDelays? p->pLutDelays[p->LutMax][p->LutMax-1]: p->pLutDelays[p->LutMax][0]);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -66,7 +66,9 @@ struct Mfs_Par_t_
////////////////////////////////////////////////////////////////////////
/*=== mfsCore.c ==========================================================*/
extern void Abc_NtkMfsParsDefault( Mfs_Par_t * pPars );
extern int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars );
#ifdef __cplusplus
}
......
......@@ -39,6 +39,34 @@
SeeAlso []
***********************************************************************/
void Abc_NtkMfsParsDefault( Mfs_Par_t * pPars )
{
pPars->nWinTfoLevs = 2;
pPars->nFanoutsMax = 10;
pPars->nDepthMax = 20;
pPars->nDivMax = 250;
pPars->nWinSizeMax = 300;
pPars->nGrowthLevel = 0;
pPars->nBTLimit = 5000;
pPars->fResub = 1;
pPars->fArea = 0;
pPars->fMoreEffort = 0;
pPars->fSwapEdge = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkMfsResub( Mfs_Man_t * p, Abc_Obj_t * pNode )
{
int clk;
......@@ -201,7 +229,7 @@ int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
// convert into the AIG
if ( !Abc_NtkToAig(pNtk) )
{
fprintf( stdout, "Converting to BDD has failed.\n" );
fprintf( stdout, "Converting to AIGs has failed.\n" );
return 0;
}
assert( Abc_NtkHasAig(pNtk) );
......
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