From 2c7f6e39b84d29db096388459db7583c01b79b01 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 30 Mar 2008 08:01:00 -0700 Subject: Version abc80330 --- Makefile | 3 +- abc.dsp | 92 +++-- src/aig/aig/aig.h | 1 + src/aig/aig/aigMan.c | 95 ++++- src/aig/dar/dar.h | 2 + src/aig/dar/darScript.c | 33 +- src/aig/fra/fra.h | 2 +- src/aig/fra/fraCec.c | 58 +++- src/aig/mfx/mfx.h | 80 +++++ src/aig/mfx/mfxCore.c | 330 ++++++++++++++++++ src/aig/mfx/mfxDiv.c | 303 ++++++++++++++++ src/aig/mfx/mfxInt.h | 160 +++++++++ src/aig/mfx/mfxInter.c | 361 +++++++++++++++++++ src/aig/mfx/mfxMan.c | 186 ++++++++++ src/aig/mfx/mfxResub.c | 529 ++++++++++++++++++++++++++++ src/aig/mfx/mfxSat.c | 140 ++++++++ src/aig/mfx/mfxStrash.c | 339 ++++++++++++++++++ src/aig/mfx/mfxWin.c | 112 ++++++ src/aig/mfx/mfx_.c | 47 +++ src/aig/mfx/module.make | 8 + src/aig/ntk/module.make | 9 - src/aig/ntk/ntk.h | 236 ------------- src/aig/ntk/ntkBidec.c | 123 ------- src/aig/ntk/ntkCheck.c | 47 --- src/aig/ntk/ntkDfs.c | 290 ---------------- src/aig/ntk/ntkFanio.c | 323 ----------------- src/aig/ntk/ntkMan.c | 116 ------- src/aig/ntk/ntkMap.c | 340 ------------------ src/aig/ntk/ntkObj.c | 221 ------------ src/aig/ntk/ntkTiming.c | 335 ------------------ src/aig/ntk/ntkUtil.c | 172 ---------- src/aig/ntk/ntk_.c | 47 --- src/aig/ntl/ntl.h | 32 +- src/aig/ntl/ntlCheck.c | 77 ++++- src/aig/ntl/ntlExtract.c | 198 +++++++++-- src/aig/ntl/ntlInsert.c | 52 +-- src/aig/ntl/ntlMan.c | 101 +++++- src/aig/ntl/ntlMap.c | 2 +- src/aig/ntl/ntlObj.c | 27 ++ src/aig/ntl/ntlReadBlif.c | 15 +- src/aig/ntl/ntlTable.c | 44 +-- src/aig/ntl/ntlTime.c | 2 +- src/aig/nwk/module.make | 11 + src/aig/nwk/nwk.h | 248 ++++++++++++++ src/aig/nwk/nwkBidec.c | 122 +++++++ src/aig/nwk/nwkCheck.c | 47 +++ src/aig/nwk/nwkDfs.c | 567 ++++++++++++++++++++++++++++++ src/aig/nwk/nwkFanio.c | 362 ++++++++++++++++++++ src/aig/nwk/nwkMan.c | 116 +++++++ src/aig/nwk/nwkMap.c | 340 ++++++++++++++++++ src/aig/nwk/nwkObj.c | 202 +++++++++++ src/aig/nwk/nwkSpeedup.c | 51 +++ src/aig/nwk/nwkStrash.c | 135 ++++++++ src/aig/nwk/nwkTiming.c | 711 ++++++++++++++++++++++++++++++++++++++ src/aig/nwk/nwkUtil.c | 214 ++++++++++++ src/aig/nwk/nwk_.c | 47 +++ src/aig/tim/tim.c | 81 ++++- src/aig/tim/tim.h | 3 + src/base/abc/abcDfs.c | 27 +- src/base/abci/abc.c | 857 ++++++++++++++++++++++++++++++++++++++++------ src/base/abci/abcAbc8.c | 243 +++++++++++++ src/base/abci/abcDar.c | 39 +-- src/base/abci/module.make | 1 + src/base/main/mainInt.h | 2 +- src/map/if/if.h | 9 + src/map/if/ifLib.c | 32 ++ src/opt/mfs/mfs.h | 2 + src/opt/mfs/mfsCore.c | 30 +- 68 files changed, 7619 insertions(+), 2570 deletions(-) create mode 100644 src/aig/mfx/mfx.h create mode 100644 src/aig/mfx/mfxCore.c create mode 100644 src/aig/mfx/mfxDiv.c create mode 100644 src/aig/mfx/mfxInt.h create mode 100644 src/aig/mfx/mfxInter.c create mode 100644 src/aig/mfx/mfxMan.c create mode 100644 src/aig/mfx/mfxResub.c create mode 100644 src/aig/mfx/mfxSat.c create mode 100644 src/aig/mfx/mfxStrash.c create mode 100644 src/aig/mfx/mfxWin.c create mode 100644 src/aig/mfx/mfx_.c create mode 100644 src/aig/mfx/module.make delete mode 100644 src/aig/ntk/module.make delete mode 100644 src/aig/ntk/ntk.h delete mode 100644 src/aig/ntk/ntkBidec.c delete mode 100644 src/aig/ntk/ntkCheck.c delete mode 100644 src/aig/ntk/ntkDfs.c delete mode 100644 src/aig/ntk/ntkFanio.c delete mode 100644 src/aig/ntk/ntkMan.c delete mode 100644 src/aig/ntk/ntkMap.c delete mode 100644 src/aig/ntk/ntkObj.c delete mode 100644 src/aig/ntk/ntkTiming.c delete mode 100644 src/aig/ntk/ntkUtil.c delete mode 100644 src/aig/ntk/ntk_.c create mode 100644 src/aig/nwk/module.make create mode 100644 src/aig/nwk/nwk.h create mode 100644 src/aig/nwk/nwkBidec.c create mode 100644 src/aig/nwk/nwkCheck.c create mode 100644 src/aig/nwk/nwkDfs.c create mode 100644 src/aig/nwk/nwkFanio.c create mode 100644 src/aig/nwk/nwkMan.c create mode 100644 src/aig/nwk/nwkMap.c create mode 100644 src/aig/nwk/nwkObj.c create mode 100644 src/aig/nwk/nwkSpeedup.c create mode 100644 src/aig/nwk/nwkStrash.c create mode 100644 src/aig/nwk/nwkTiming.c create mode 100644 src/aig/nwk/nwkUtil.c create mode 100644 src/aig/nwk/nwk_.c create mode 100644 src/base/abci/abcAbc8.c diff --git a/Makefile b/Makefile index cce30dee..a5840ae0 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/abc.dsp b/abc.dsp index d9857389..7bd1abfd 100644 --- a/abc.dsp +++ b/abc.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/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 diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h index f58ba409..0b3abce7 100644 --- a/src/aig/aig/aig.h +++ b/src/aig/aig/aig.h @@ -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 ); diff --git a/src/aig/aig/aigMan.c b/src/aig/aig/aigMan.c index 95bacf8a..741ecc8d 100644 --- a/src/aig/aig/aigMan.c +++ b/src/aig/aig/aigMan.c @@ -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 ); } diff --git a/src/aig/dar/dar.h b/src/aig/dar/dar.h index d93af02e..1cc239b1 100644 --- a/src/aig/dar/dar.h +++ b/src/aig/dar/dar.h @@ -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 } diff --git a/src/aig/dar/darScript.c b/src/aig/dar/darScript.c index 116b1591..2a0aa7d5 100644 --- a/src/aig/dar/darScript.c +++ b/src/aig/dar/darScript.c @@ -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 /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/fra/fra.h b/src/aig/fra/fra.h index ee4e9115..dbe61522 100644 --- a/src/aig/fra/fra.h +++ b/src/aig/fra/fra.h @@ -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 ); diff --git a/src/aig/fra/fraCec.c b/src/aig/fra/fraCec.c index bdab25dd..aead8c9e 100644 --- a/src/aig/fra/fraCec.c +++ b/src/aig/fra/fraCec.c @@ -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 /// diff --git a/src/aig/mfx/mfx.h b/src/aig/mfx/mfx.h new file mode 100644 index 00000000..783de56c --- /dev/null +++ b/src/aig/mfx/mfx.h @@ -0,0 +1,80 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/mfx/mfxCore.c b/src/aig/mfx/mfxCore.c new file mode 100644 index 00000000..4c8988cc --- /dev/null +++ b/src/aig/mfx/mfxCore.c @@ -0,0 +1,330 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxDiv.c b/src/aig/mfx/mfxDiv.c new file mode 100644 index 00000000..b7b76031 --- /dev/null +++ b/src/aig/mfx/mfxDiv.c @@ -0,0 +1,303 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxInt.h b/src/aig/mfx/mfxInt.h new file mode 100644 index 00000000..88792bf2 --- /dev/null +++ b/src/aig/mfx/mfxInt.h @@ -0,0 +1,160 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/mfx/mfxInter.c b/src/aig/mfx/mfxInter.c new file mode 100644 index 00000000..a42e02fe --- /dev/null +++ b/src/aig/mfx/mfxInter.c @@ -0,0 +1,361 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxMan.c b/src/aig/mfx/mfxMan.c new file mode 100644 index 00000000..1b536f8c --- /dev/null +++ b/src/aig/mfx/mfxMan.c @@ -0,0 +1,186 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxResub.c b/src/aig/mfx/mfxResub.c new file mode 100644 index 00000000..2eafc559 --- /dev/null +++ b/src/aig/mfx/mfxResub.c @@ -0,0 +1,529 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxSat.c b/src/aig/mfx/mfxSat.c new file mode 100644 index 00000000..9dd42e8c --- /dev/null +++ b/src/aig/mfx/mfxSat.c @@ -0,0 +1,140 @@ +/**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<nFanins); + + if ( p->pPars->fVeryVerbose ) + { + printf( "Node %4d : Care = %2d. Total = %2d. ", pNode->Id, p->nCares, (1<nFanins) ); +// Kit_TruthPrintBinary( stdout, p->uCare, (1<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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxStrash.c b/src/aig/mfx/mfxStrash.c new file mode 100644 index 00000000..5cb6452f --- /dev/null +++ b/src/aig/mfx/mfxStrash.c @@ -0,0 +1,339 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfxWin.c b/src/aig/mfx/mfxWin.c new file mode 100644 index 00000000..e84a9b90 --- /dev/null +++ b/src/aig/mfx/mfxWin.c @@ -0,0 +1,112 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/mfx_.c b/src/aig/mfx/mfx_.c new file mode 100644 index 00000000..32caf7ff --- /dev/null +++ b/src/aig/mfx/mfx_.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [mfs_.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [The good old minimization with complete don't-cares.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: mfs_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "mfsInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/mfx/module.make b/src/aig/mfx/module.make new file mode 100644 index 00000000..22b9b72a --- /dev/null +++ b/src/aig/mfx/module.make @@ -0,0 +1,8 @@ +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 diff --git a/src/aig/ntk/module.make b/src/aig/ntk/module.make deleted file mode 100644 index b668de2f..00000000 --- a/src/aig/ntk/module.make +++ /dev/null @@ -1,9 +0,0 @@ -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 diff --git a/src/aig/ntk/ntk.h b/src/aig/ntk/ntk.h deleted file mode 100644 index 2fcb6ddc..00000000 --- a/src/aig/ntk/ntk.h +++ /dev/null @@ -1,236 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/ntk/ntkBidec.c b/src/aig/ntk/ntkBidec.c deleted file mode 100644 index 43426d13..00000000 --- a/src/aig/ntk/ntkBidec.c +++ /dev/null @@ -1,123 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntkBidec.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Bi-decomposition of local functions.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntkBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" -#include "bdc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCond( Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Resynthesizes nodes using bi-decomposition.] - - Description [] - - SideEffects [] - - 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 ) -{ - unsigned * pTruth; - Bdc_Fun_t * pFunc; - int nNodes, i; - assert( nVars <= 16 ); - // derive truth table - pTruth = Hop_ManConvertAigToTruth( pHop, Hop_Regular(pRoot), nVars, vTruth, 0 ); - if ( Hop_IsComplement(pRoot) ) - for ( i = Aig_TruthWordNum(nVars)-1; i >= 0; i-- ) - pTruth[i] = ~pTruth[i]; - // decompose truth table - Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 ); - // convert back into HOP - Bdc_FuncSetCopy( Bdc_ManFunc( p, 0 ), Hop_ManConst1( pHop ) ); - for ( i = 0; i < nVars; i++ ) - Bdc_FuncSetCopy( Bdc_ManFunc( p, i+1 ), Hop_ManPi( pHop, i ) ); - nNodes = Bdc_ManNodeNum(p); - for ( i = nVars + 1; i < nNodes; i++ ) - { - pFunc = Bdc_ManFunc( p, i ); - Bdc_FuncSetCopy( pFunc, Hop_And( pHop, Bdc_FunCopyHop(Bdc_FuncFanin0(pFunc)), Bdc_FunCopyHop(Bdc_FuncFanin1(pFunc)) ) ); - } - return Bdc_FunCopyHop( Bdc_ManRoot(p) ); -} - -/**Function************************************************************* - - Synopsis [Resynthesizes nodes using bi-decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManBidecResyn( Ntk_Man_t * pNtk, int fVerbose ) -{ - Bdc_Par_t Pars = {0}, * pPars = &Pars; - Bdc_Man_t * p; - Ntk_Obj_t * pObj; - Vec_Int_t * vTruth; - int i, nGainTotal = 0, nNodes1, nNodes2; - int clk = clock(); - pPars->nVarsMax = Ntk_ManGetFaninMax( pNtk ); - pPars->fVerbose = fVerbose; - if ( pPars->nVarsMax > 15 ) - { - if ( fVerbose ) - printf( "Resynthesis is not performed for nodes with more than 15 inputs.\n" ); - pPars->nVarsMax = 15; - } - vTruth = Vec_IntAlloc( 0 ); - p = Bdc_ManAlloc( pPars ); - Ntk_ManForEachNode( pNtk, pObj, i ) - { - if ( Ntk_ObjFaninNum(pObj) > 15 ) - continue; - nNodes1 = Hop_DagSize(pObj->pFunc); - pObj->pFunc = Ntk_NodeIfNodeResyn( p, pNtk->pManHop, pObj->pFunc, Ntk_ObjFaninNum(pObj), vTruth, NULL ); - nNodes2 = Hop_DagSize(pObj->pFunc); - nGainTotal += nNodes1 - nNodes2; - } - Bdc_ManFree( p ); - Vec_IntFree( vTruth ); - if ( fVerbose ) - { - printf( "Total gain in AIG nodes = %d. ", nGainTotal ); - PRT( "Total runtime", clock() - clk ); - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkCheck.c b/src/aig/ntk/ntkCheck.c deleted file mode 100644 index 6bbb67a6..00000000 --- a/src/aig/ntk/ntkCheck.c +++ /dev/null @@ -1,47 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntk_.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkDfs.c b/src/aig/ntk/ntkDfs.c deleted file mode 100644 index 263a2740..00000000 --- a/src/aig/ntk/ntkDfs.c +++ /dev/null @@ -1,290 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkFanio.c b/src/aig/ntk/ntkFanio.c deleted file mode 100644 index 135929af..00000000 --- a/src/aig/ntk/ntkFanio.c +++ /dev/null @@ -1,323 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntkFanio.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Manipulation of fanins/fanouts.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntkFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Returns 1 if it is an AIG with choice nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjCollectFanins( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Ntk_Obj_t * pFanin; - int i; - Vec_PtrClear(vNodes); - Ntk_ObjForEachFanin( pNode, pFanin, i ) - Vec_PtrPush( vNodes, pFanin ); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if it is an AIG with choice nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjCollectFanouts( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Ntk_Obj_t * pFanout; - int i; - Vec_PtrClear(vNodes); - Ntk_ObjForEachFanout( pNode, pFanout, i ) - Vec_PtrPush( vNodes, pFanout ); -} - -/**Function************************************************************* - - Synopsis [Returns the number of the fanin of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ObjFindFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin ) -{ - Ntk_Obj_t * pTemp; - int i; - Ntk_ObjForEachFanin( pObj, pTemp, i ) - if ( pTemp == pFanin ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [Returns the number of the fanin of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ObjFindFanout( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanout ) -{ - Ntk_Obj_t * pTemp; - int i; - Ntk_ObjForEachFanout( pObj, pTemp, i ) - if ( pTemp == pFanout ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the object has to be reallocated.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ntk_ObjReallocIsNeeded( Ntk_Obj_t * pObj ) -{ - return pObj->nFanins + pObj->nFanouts == (unsigned)pObj->nFanioAlloc; -} - -/**Function************************************************************* - - Synopsis [Deletes the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static Ntk_Obj_t * Ntk_ManReallocNode( Ntk_Obj_t * pObj ) -{ - Ntk_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; - // update the fanouts' fanins - Ntk_ObjForEachFanout( pObj, pTemp, i ) - { - iNum = Ntk_ObjFindFanin( pTemp, pObj ); - if ( iNum == -1 ) - printf( "Ntk_ManReallocNode(): Error! Fanin cannot be found.\n" ); - pTemp->pFanio[iNum] = pObjNew; - } - // update the fanins' fanouts - Ntk_ObjForEachFanin( pObj, pTemp, i ) - { - iNum = Ntk_ObjFindFanout( pTemp, pObj ); - if ( iNum == -1 ) - printf( "Ntk_ManReallocNode(): Error! Fanout cannot be found.\n" ); - pTemp->pFanio[pTemp->nFanins+iNum] = pObjNew; - } - return pObjNew; -} - - -/**Function************************************************************* - - Synopsis [Creates fanout/fanin relationship between the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjAddFanin( Ntk_Obj_t * pObj, Ntk_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 ); - 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; -} - -/**Function************************************************************* - - Synopsis [Removes fanout/fanin relationship between the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjDeleteFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFanin ) -{ - int i, k, Limit; - // remove pFanin from the fanin list of pObj - Limit = pObj->nFanins + pObj->nFanouts; - for ( k = i = 0; i < Limit; i++ ) - if ( pObj->pFanio[i] != pFanin ) - pObj->pFanio[k++] = pObj->pFanio[i]; - 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]; - pFanin->nFanouts--; -} - -/**Function************************************************************* - - Synopsis [Replaces a fanin of the node.] - - Description [The node is pObj. An old fanin of this node (pFaninOld) has to be - replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin - are not complemented. The new fanin can be complemented. In this case, the - polarity of the new fanin will change, compared to the polarity of the old fanin.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjPatchFanin( Ntk_Obj_t * pObj, Ntk_Obj_t * pFaninOld, Ntk_Obj_t * pFaninNew ) -{ - int i, k, iFanin, Limit; - assert( pFaninOld != pFaninNew ); - assert( pObj != pFaninOld ); - assert( pObj != pFaninNew ); - assert( pObj->pMan == pFaninOld->pMan ); - assert( pObj->pMan == pFaninNew->pMan ); - // update the fanin - iFanin = Ntk_ObjFindFanin( pObj, pFaninOld ); - if ( iFanin == -1 ) - { - printf( "Ntk_ObjPatchFanin(); Error! Node %d is not among", pFaninOld->Id ); - printf( " the fanins of node %s...\n", pObj->Id ); - return; - } - pObj->pFanio[iFanin] = pFaninNew; - // remove pObj from the fanout list of pFaninOld - Limit = pFaninOld->nFanins + pFaninOld->nFanouts; - for ( k = i = pFaninOld->nFanins; i < Limit; i++ ) - if ( pFaninOld->pFanio[i] != pObj ) - pFaninOld->pFanio[k++] = pFaninOld->pFanio[i]; - pFaninOld->nFanouts--; - // add pObj to the fanout list of pFaninNew - if ( Ntk_ObjReallocIsNeeded(pFaninNew) ) - Ntk_ManReallocNode( pFaninNew ); - pFaninNew->pFanio[pFaninNew->nFanins + pFaninNew->nFanouts++] = pObj; -} - - -/**Function************************************************************* - - Synopsis [Transfers fanout from the old node to the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjTransferFanout( Ntk_Obj_t * pNodeFrom, Ntk_Obj_t * pNodeTo ) -{ - Vec_Ptr_t * vFanouts = pNodeFrom->pMan->vTemp; - Ntk_Obj_t * pTemp; - int nFanoutsOld, i; - assert( !Ntk_ObjIsCo(pNodeFrom) && !Ntk_ObjIsCo(pNodeTo) ); - assert( pNodeFrom->pMan == pNodeTo->pMan ); - assert( pNodeFrom != pNodeTo ); - assert( Ntk_ObjFanoutNum(pNodeFrom) > 0 ); - // get the fanouts of the old node - nFanoutsOld = Ntk_ObjFanoutNum(pNodeTo); - Ntk_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) ); -} - -/**Function************************************************************* - - Synopsis [Replaces the node by a new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ObjReplace( Ntk_Obj_t * pNodeOld, Ntk_Obj_t * pNodeNew ) -{ - assert( pNodeOld->pMan == pNodeNew->pMan ); - assert( pNodeOld != pNodeNew ); - assert( Ntk_ObjFanoutNum(pNodeOld) > 0 ); - // transfer the fanouts to the old node - Ntk_ObjTransferFanout( pNodeOld, pNodeNew ); - // remove the old node - Ntk_ManDeleteNode_rec( pNodeOld ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkMan.c b/src/aig/ntk/ntkMan.c deleted file mode 100644 index 1a077495..00000000 --- a/src/aig/ntk/ntkMan.c +++ /dev/null @@ -1,116 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntkMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Network manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntkMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the netlist manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Man_t * Ntk_ManAlloc() -{ - Ntk_Man_t * p; - p = ALLOC( Ntk_Man_t, 1 ); - memset( p, 0, sizeof(Ntk_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->pMemObjs = Aig_MmFlexStart(); - p->pManHop = Hop_ManStart(); - return p; -} - -/**Function************************************************************* - - Synopsis [Deallocates the netlist manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManFree( Ntk_Man_t * p ) -{ - if ( p->pName ) free( p->pName ); - if ( p->pSpec ) free( p->pSpec ); - if ( p->vCis ) Vec_PtrFree( p->vCis ); - if ( p->vCos ) Vec_PtrFree( p->vCos ); - if ( p->vObjs ) Vec_PtrFree( p->vObjs ); - if ( p->vTemp ) Vec_PtrFree( p->vTemp ); - if ( p->pManTime ) Tim_ManStop( p->pManTime ); - if ( p->pMemObjs ) Aig_MmFlexStop( p->pMemObjs, 0 ); - if ( p->pManHop ) Hop_ManStop( p->pManHop ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Deallocates the netlist manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManPrintStats( Ntk_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( "\n" ); - - Ntk_ManDelayTracePrint( p, pLutLib ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkMap.c b/src/aig/ntk/ntkMap.c deleted file mode 100644 index 9c780498..00000000 --- a/src/aig/ntk/ntkMap.c +++ /dev/null @@ -1,340 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntkMap.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Interface to technology mapping.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntkMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" -#include "if.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Load the network into FPGA manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManSetIfParsDefault( If_Par_t * pPars ) -{ -// extern void * Abc_FrameReadLibLut(); - // set defaults - memset( pPars, 0, sizeof(If_Par_t) ); - // user-controlable paramters -// pPars->nLutSize = -1; - pPars->nLutSize = 6; - pPars->nCutsMax = 8; - pPars->nFlowIters = 1; - pPars->nAreaIters = 2; - pPars->DelayTarget = -1; - pPars->Epsilon = (float)0.01; - pPars->fPreprocess = 1; - pPars->fArea = 0; - pPars->fFancy = 0; - pPars->fExpRed = 0; - pPars->fLatchPaths = 0; - pPars->fEdge = 1; - pPars->fCutMin = 1; - pPars->fSeqMap = 0; - pPars->fVerbose = 1; - // internal parameters - pPars->fTruth = 0; - pPars->nLatches = 0; - pPars->fLiftLeaves = 0; -// pPars->pLutLib = Abc_FrameReadLibLut(); - pPars->pLutLib = NULL; - pPars->pTimesArr = NULL; - pPars->pTimesArr = NULL; - pPars->pFuncCost = NULL; -/* - if ( pPars->nLutSize == -1 ) - { - if ( pPars->pLutLib == NULL ) - { - printf( "The LUT library is not given.\n" ); - return; - } - // get LUT size from the library - pPars->nLutSize = pPars->pLutLib->LutMax; - } -*/ -} - -/**Function************************************************************* - - Synopsis [Load the network into FPGA manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Man_t * Ntk_ManToIf( Aig_Man_t * p, If_Par_t * pPars ) -{ - If_Man_t * pIfMan; - Aig_Obj_t * pNode;//, * pFanin, * pPrev; - int i; - // start the mapping manager and set its parameters - pIfMan = If_ManStart( pPars ); - // print warning about excessive memory usage -// if ( 1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30) > 1.0 ) -// printf( "Warning: The mapper will allocate %.1f Gb for to represent the subject graph with %d AIG nodes.\n", -// 1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30), Aig_ManObjNum(p) ); - // load the AIG into the mapper - Aig_ManForEachObj( p, pNode, i ) - { - if ( Aig_ObjIsAnd(pNode) ) - pNode->pData = (Aig_Obj_t *)If_ManCreateAnd( pIfMan, - If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), - If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) ); - else if ( Aig_ObjIsPi(pNode) ) - { - pNode->pData = If_ManCreateCi( pIfMan ); - ((If_Obj_t *)pNode->pData)->Level = pNode->Level; - if ( pIfMan->nLevelMax < (int)pNode->Level ) - pIfMan->nLevelMax = (int)pNode->Level; - } - else if ( Aig_ObjIsPo(pNode) ) - pNode->pData = If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); - else if ( Aig_ObjIsConst1(pNode) ) - Aig_ManConst1(p)->pData = If_ManConst1( pIfMan ); - else // add the node to the mapper - assert( 0 ); - // set up the choice node -// if ( Aig_AigNodeIsChoice( pNode ) ) -// { -// pIfMan->nChoices++; -// for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) -// If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData ); -// If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData ); -// } - { - If_Obj_t * pIfObj = pNode->pData; - assert( !If_IsComplement(pIfObj) ); - assert( pIfObj->Id == pNode->Id ); - } - } - return pIfMan; -} - - -/**Function************************************************************* - - Synopsis [Recursively derives the truth table for the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Hop_Obj_t * Ntk_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; - Hop_Obj_t * gFunc, * gFunc0, * gFunc1; - // get the best cut - pCut = If_ObjCutBest(pIfObj); - // if the cut is visited, return the result - if ( If_CutData(pCut) ) - return If_CutData(pCut); - // mark the node as visited - Vec_PtrPush( vVisited, pCut ); - // insert the worst case - If_CutSetData( pCut, (void *)1 ); - // skip in case of primary input - if ( If_ObjIsCi(pIfObj) ) - return If_CutData(pCut); - // compute the functions of the children - for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv ) - { - gFunc0 = Ntk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited ); - if ( gFunc0 == (void *)1 ) - continue; - gFunc1 = Ntk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited ); - if ( gFunc1 == (void *)1 ) - continue; - // both branches are solved - gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pTemp->fCompl0), Hop_NotCond(gFunc1, pTemp->fCompl1) ); - if ( pTemp->fPhase != pIfObj->fPhase ) - gFunc = Hop_Not(gFunc); - If_CutSetData( pCut, gFunc ); - break; - } - return If_CutData(pCut); -} - -/**Function************************************************************* - - Synopsis [Derives the truth table for one cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Hop_Obj_t * Ntk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj ) -{ - If_Cut_t * pCut; - Hop_Obj_t * gFunc; - If_Obj_t * pLeaf; - int i; - // get the best cut - pCut = If_ObjCutBest(pIfObj); - assert( pCut->nLeaves > 1 ); - // set the leaf variables - If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) - 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 ); - if ( gFunc == (void *)1 ) - { - printf( "Ntk_NodeIfToHop(): Computing local AIG has failed.\n" ); - return NULL; - } -// printf( "%d ", Vec_PtrSize(p->vTemp) ); - // clean the cuts - If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) - If_CutSetData( If_ObjCutBest(pLeaf), NULL ); - Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i ) - If_CutSetData( pCut, NULL ); - return gFunc; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Man_t * Ntk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p ) -{ - Ntk_Man_t * pNtk; - Ntk_Obj_t * pObjNew; - Aig_Obj_t * pObj; - If_Obj_t * pIfObj; - If_Cut_t * pCutBest; - int i, k, nLeaves, * ppLeaves; - assert( Aig_ManPiNum(p) == If_ManCiNum(pIfMan) ); - assert( Aig_ManPoNum(p) == If_ManCoNum(pIfMan) ); - assert( Aig_ManNodeNum(p) == If_ManAndNum(pIfMan) ); - If_ManCleanCutData( pIfMan ); - // construct the network - pNtk = Ntk_ManAlloc(); - pNtk->pName = Aig_UtilStrsav( p->pName ); - pNtk->pSpec = Aig_UtilStrsav( p->pSpec ); - Aig_ManForEachObj( p, pObj, i ) - { - pIfObj = If_ManObj( pIfMan, i ); - if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) ) - continue; - if ( Aig_ObjIsNode(pObj) ) - { - pCutBest = If_ObjCutBest( pIfObj ); - nLeaves = If_CutLeaveNum( pCutBest ); - ppLeaves = If_CutLeaves( pCutBest ); - // create node - pObjNew = Ntk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs ); - for ( k = 0; k < nLeaves; k++ ) - Ntk_ObjAddFanin( pObjNew, Aig_ManObj(p, ppLeaves[k])->pData ); - // get the functionality - pObjNew->pFunc = Ntk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj ); - } - else if ( Aig_ObjIsPi(pObj) ) - pObjNew = Ntk_ManCreateCi( pNtk, pIfObj->nRefs ); - else if ( Aig_ObjIsPo(pObj) ) - { - pObjNew = Ntk_ManCreateCo( pNtk ); - pObjNew->fCompl = Aig_ObjFaninC0(pObj); - Ntk_ObjAddFanin( pObjNew, Aig_ObjFanin0(pObj)->pData ); - } - else if ( Aig_ObjIsConst1(pObj) ) - { - pObjNew = Ntk_ManCreateNode( pNtk, 0, pIfObj->nRefs ); - pObjNew->pFunc = Hop_ManConst1( pNtk->pManHop ); - } - else - assert( 0 ); - pObj->pData = pObjNew; - } - pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 ); - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Interface with the FPGA mapping package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Man_t * Ntk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars ) -{ - Ntk_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 ); - if ( pIfMan == NULL ) - return NULL; - pIfMan->pManTim = Tim_ManDup( pManTime, 0 ); - if ( !If_ManPerformMapping( pIfMan ) ) - { - If_ManStop( pIfMan ); - return NULL; - } - // transform the result of mapping into the new network - pNtk = Ntk_ManFromIf( pIfMan, p ); - If_ManStop( pIfMan ); - return pNtk; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkObj.c b/src/aig/ntk/ntkObj.c deleted file mode 100644 index 7bd2f552..00000000 --- a/src/aig/ntk/ntkObj.c +++ /dev/null @@ -1,221 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntkObj.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Manipulation of objects.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntkObj.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates an object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Obj_t * Ntk_ManCreateObj( Ntk_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) ); - pObj->Id = Vec_PtrSize( p->vObjs ); - Vec_PtrPush( p->vObjs, pObj ); - pObj->pMan = p; - pObj->nFanioAlloc = nFanins + nFanouts + p->nFanioPlus; - return pObj; -} - - -/**Function************************************************************* - - Synopsis [Creates a primary input.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Obj_t * Ntk_ManCreateCi( Ntk_Man_t * p, int nFanouts ) -{ - Ntk_Obj_t * pObj; - pObj = Ntk_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]++; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates a primary output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Obj_t * Ntk_ManCreateCo( Ntk_Man_t * p ) -{ - Ntk_Obj_t * pObj; - pObj = Ntk_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]++; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates a latch.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Obj_t * Ntk_ManCreateLatch( Ntk_Man_t * p ) -{ - Ntk_Obj_t * pObj; - pObj = Ntk_ManCreateObj( p, 1, 1 ); - pObj->Type = NTK_OBJ_LATCH; - p->nObjs[NTK_OBJ_LATCH]++; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ntk_Obj_t * Ntk_ManCreateNode( Ntk_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]++; - return pObj; -} - - -/**Function************************************************************* - - Synopsis [Deletes the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManDeleteNode( Ntk_Obj_t * pObj ) -{ - Vec_Ptr_t * vNodes = pObj->pMan->vTemp; - Ntk_Obj_t * pTemp; - int i; - // delete fanins and fanouts - Ntk_ObjCollectFanouts( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pTemp, i ) - Ntk_ObjDeleteFanin( pTemp, pObj ); - Ntk_ObjCollectFanins( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pTemp, i ) - Ntk_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) ); - pObj->Id = -1; -} - -/**Function************************************************************* - - Synopsis [Deletes the node and MFFC of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManDeleteNode_rec( Ntk_Obj_t * pObj ) -{ - Vec_Ptr_t * vNodes; - int i; - assert( !Ntk_ObjIsCi(pObj) ); - assert( Ntk_ObjFanoutNum(pObj) == 0 ); - vNodes = Vec_PtrAlloc( 100 ); - Ntk_ObjCollectFanins( pObj, vNodes ); - Ntk_ManDeleteNode( pObj ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( Ntk_ObjIsNode(pObj) && Ntk_ObjFanoutNum(pObj) == 0 ) - Ntk_ManDeleteNode_rec( pObj ); - Vec_PtrFree( vNodes ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkTiming.c b/src/aig/ntk/ntkTiming.c deleted file mode 100644 index ff867e02..00000000 --- a/src/aig/ntk/ntkTiming.c +++ /dev/null @@ -1,335 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntkUtil.c b/src/aig/ntk/ntkUtil.c deleted file mode 100644 index 931a26ee..00000000 --- a/src/aig/ntk/ntkUtil.c +++ /dev/null @@ -1,172 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntkUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Various utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntkUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Increments the current traversal ID of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_ManIncrementTravId( Ntk_Man_t * pNtk ) -{ - Ntk_Obj_t * pObj; - int i; - if ( pNtk->nTravIds >= (1<<26)-1 ) - { - pNtk->nTravIds = 0; - Ntk_ManForEachObj( pNtk, pObj, i ) - pObj->TravId = 0; - } - pNtk->nTravIds++; -} - -/**Function************************************************************* - - Synopsis [Reads the maximum number of fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ManGetFaninMax( Ntk_Man_t * pNtk ) -{ - Ntk_Obj_t * pNode; - int i, nFaninsMax = 0; - Ntk_ManForEachNode( pNtk, pNode, i ) - { - if ( nFaninsMax < Ntk_ObjFaninNum(pNode) ) - nFaninsMax = Ntk_ObjFaninNum(pNode); - } - return nFaninsMax; -} - -/**Function************************************************************* - - Synopsis [Reads the total number of all fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ManGetTotalFanins( Ntk_Man_t * pNtk ) -{ - Ntk_Obj_t * pNode; - int i, nFanins = 0; - Ntk_ManForEachNode( pNtk, pNode, i ) - nFanins += Ntk_ObjFaninNum(pNode); - return nFanins; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ManPiNum( Ntk_Man_t * pNtk ) -{ - Ntk_Obj_t * pNode; - int i, Counter = 0; - Ntk_ManForEachCi( pNtk, pNode, i ) - Counter += Ntk_ObjIsPi( pNode ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ManPoNum( Ntk_Man_t * pNtk ) -{ - Ntk_Obj_t * pNode; - int i, Counter = 0; - Ntk_ManForEachCo( pNtk, pNode, i ) - Counter += Ntk_ObjIsPo( pNode ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Reads the number of BDD nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntk_ManGetAigNodeNum( Ntk_Man_t * pNtk ) -{ - Ntk_Obj_t * pNode; - int i, nNodes = 0; - Ntk_ManForEachNode( pNtk, pNode, i ) - { - if ( pNode->pFunc == NULL ) - { - printf( "Ntk_ManGetAigNodeNum(): Local AIG of node %d is not assigned.\n", pNode->Id ); - continue; - } - if ( Ntk_ObjFaninNum(pNode) < 2 ) - continue; - nNodes += Hop_DagSize( pNode->pFunc ); - } - return nNodes; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntk/ntk_.c b/src/aig/ntk/ntk_.c deleted file mode 100644 index 6bbb67a6..00000000 --- a/src/aig/ntk/ntk_.c +++ /dev/null @@ -1,47 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntk_.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ntl/ntl.h b/src/aig/ntl/ntl.h index 72a5674b..6d4f5c29 100644 --- a/src/aig/ntl/ntl.h +++ b/src/aig/ntl/ntl.h @@ -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 ==========================================================*/ diff --git a/src/aig/ntl/ntlCheck.c b/src/aig/ntl/ntlCheck.c index d01c7d5e..5973e967 100644 --- a/src/aig/ntl/ntlCheck.c +++ b/src/aig/ntl/ntlCheck.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; } diff --git a/src/aig/ntl/ntlExtract.c b/src/aig/ntl/ntlExtract.c index a54618e5..0654bb27 100644 --- a/src/aig/ntl/ntlExtract.c +++ b/src/aig/ntl/ntlExtract.c @@ -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; } -*/ //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/ntl/ntlInsert.c b/src/aig/ntl/ntlInsert.c index 84a7af84..2eb48e84 100644 --- a/src/aig/ntl/ntlInsert.c +++ b/src/aig/ntl/ntlInsert.c @@ -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; diff --git a/src/aig/ntl/ntlMan.c b/src/aig/ntl/ntlMan.c index 9614a423..82660263 100644 --- a/src/aig/ntl/ntlMan.c +++ b/src/aig/ntl/ntlMan.c @@ -59,6 +59,57 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName ) return p; } +/**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.] @@ -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,16 +225,51 @@ 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; } +/**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.] diff --git a/src/aig/ntl/ntlMap.c b/src/aig/ntl/ntlMap.c index 20bc79cf..faae32d2 100644 --- a/src/aig/ntl/ntlMap.c +++ b/src/aig/ntl/ntlMap.c @@ -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 diff --git a/src/aig/ntl/ntlObj.c b/src/aig/ntl/ntlObj.c index 2e39fbbf..ad43623a 100644 --- a/src/aig/ntl/ntlObj.c +++ b/src/aig/ntl/ntlObj.c @@ -161,6 +161,33 @@ Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts ) return p; } +/**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.] diff --git a/src/aig/ntl/ntlReadBlif.c b/src/aig/ntl/ntlReadBlif.c index d085b5e6..e5a94610 100644 --- a/src/aig/ntl/ntlReadBlif.c +++ b/src/aig/ntl/ntlReadBlif.c @@ -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; } diff --git a/src/aig/ntl/ntlTable.c b/src/aig/ntl/ntlTable.c index b84ac1a5..909a64fd 100644 --- a/src/aig/ntl/ntlTable.c +++ b/src/aig/ntl/ntlTable.c @@ -149,28 +149,6 @@ Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName ) return pEnt; } -/**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).] @@ -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 /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/ntl/ntlTime.c b/src/aig/ntl/ntlTime.c index 50f3d290..cf2ec0f1 100644 --- a/src/aig/ntl/ntlTime.c +++ b/src/aig/ntl/ntlTime.c @@ -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 diff --git a/src/aig/nwk/module.make b/src/aig/nwk/module.make new file mode 100644 index 00000000..3cf2acc6 --- /dev/null +++ b/src/aig/nwk/module.make @@ -0,0 +1,11 @@ +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 diff --git a/src/aig/nwk/nwk.h b/src/aig/nwk/nwk.h new file mode 100644 index 00000000..295b3a9e --- /dev/null +++ b/src/aig/nwk/nwk.h @@ -0,0 +1,248 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/nwk/nwkBidec.c b/src/aig/nwk/nwkBidec.c new file mode 100644 index 00000000..5d0b454e --- /dev/null +++ b/src/aig/nwk/nwkBidec.c @@ -0,0 +1,122 @@ +/**CFile**************************************************************** + + FileName [nwkBidec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Logic network representation.] + + Synopsis [Bi-decomposition of local functions.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwkBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "nwk.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCond( Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Resynthesizes nodes using bi-decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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; + int nNodes, i; + assert( nVars <= 16 ); + // derive truth table + pTruth = Hop_ManConvertAigToTruth( pHop, Hop_Regular(pRoot), nVars, vTruth, 0 ); + if ( Hop_IsComplement(pRoot) ) + for ( i = Aig_TruthWordNum(nVars)-1; i >= 0; i-- ) + pTruth[i] = ~pTruth[i]; + // decompose truth table + Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 ); + // convert back into HOP + Bdc_FuncSetCopy( Bdc_ManFunc( p, 0 ), Hop_ManConst1( pHop ) ); + for ( i = 0; i < nVars; i++ ) + Bdc_FuncSetCopy( Bdc_ManFunc( p, i+1 ), Hop_ManPi( pHop, i ) ); + nNodes = Bdc_ManNodeNum(p); + for ( i = nVars + 1; i < nNodes; i++ ) + { + pFunc = Bdc_ManFunc( p, i ); + Bdc_FuncSetCopy( pFunc, Hop_And( pHop, Bdc_FunCopyHop(Bdc_FuncFanin0(pFunc)), Bdc_FunCopyHop(Bdc_FuncFanin1(pFunc)) ) ); + } + return Bdc_FunCopyHop( Bdc_ManRoot(p) ); +} + +/**Function************************************************************* + + Synopsis [Resynthesizes nodes using bi-decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose ) +{ + Bdc_Par_t Pars = {0}, * pPars = &Pars; + Bdc_Man_t * p; + Nwk_Obj_t * pObj; + Vec_Int_t * vTruth; + int i, nGainTotal = 0, nNodes1, nNodes2; + int clk = clock(); + pPars->nVarsMax = Nwk_ManGetFaninMax( pNtk ); + pPars->fVerbose = fVerbose; + if ( pPars->nVarsMax > 15 ) + { + if ( fVerbose ) + printf( "Resynthesis is not performed for nodes with more than 15 inputs.\n" ); + pPars->nVarsMax = 15; + } + vTruth = Vec_IntAlloc( 0 ); + p = Bdc_ManAlloc( pPars ); + Nwk_ManForEachNode( pNtk, pObj, i ) + { + if ( Nwk_ObjFaninNum(pObj) > 15 ) + continue; + nNodes1 = Hop_DagSize(pObj->pFunc); + pObj->pFunc = Nwk_NodeIfNodeResyn( p, pNtk->pManHop, pObj->pFunc, Nwk_ObjFaninNum(pObj), vTruth, NULL ); + nNodes2 = Hop_DagSize(pObj->pFunc); + nGainTotal += nNodes1 - nNodes2; + } + Bdc_ManFree( p ); + Vec_IntFree( vTruth ); + if ( fVerbose ) + { + printf( "Total gain in AIG nodes = %d. ", nGainTotal ); + PRT( "Total runtime", clock() - clk ); + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkCheck.c b/src/aig/nwk/nwkCheck.c new file mode 100644 index 00000000..5c547dbe --- /dev/null +++ b/src/aig/nwk/nwkCheck.c @@ -0,0 +1,47 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkDfs.c b/src/aig/nwk/nwkDfs.c new file mode 100644 index 00000000..a5f5a660 --- /dev/null +++ b/src/aig/nwk/nwkDfs.c @@ -0,0 +1,567 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkFanio.c b/src/aig/nwk/nwkFanio.c new file mode 100644 index 00000000..f338d07d --- /dev/null +++ b/src/aig/nwk/nwkFanio.c @@ -0,0 +1,362 @@ +/**CFile**************************************************************** + + FileName [nwkFanio.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Logic network representation.] + + Synopsis [Manipulation of fanins/fanouts.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwkFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "nwk.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collects fanins of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ObjCollectFanins( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ) +{ + Nwk_Obj_t * pFanin; + int i; + Vec_PtrClear(vNodes); + Nwk_ObjForEachFanin( pNode, pFanin, i ) + Vec_PtrPush( vNodes, pFanin ); +} + +/**Function************************************************************* + + Synopsis [Collects fanouts of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ObjCollectFanouts( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ) +{ + Nwk_Obj_t * pFanout; + int i; + Vec_PtrClear(vNodes); + Nwk_ObjForEachFanout( pNode, pFanout, i ) + Vec_PtrPush( vNodes, pFanout ); +} + +/**Function************************************************************* + + Synopsis [Returns the number of the fanin of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ObjFindFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ) +{ + Nwk_Obj_t * pTemp; + int i; + Nwk_ObjForEachFanin( pObj, pTemp, i ) + if ( pTemp == pFanin ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [Returns the number of the fanout of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ObjFindFanout( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanout ) +{ + Nwk_Obj_t * pTemp; + int i; + Nwk_ObjForEachFanout( pObj, pTemp, i ) + if ( pTemp == pFanout ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the node has to be reallocated.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Nwk_ObjReallocIsNeeded( Nwk_Obj_t * pObj ) +{ + return pObj->nFanins + pObj->nFanouts == pObj->nFanioAlloc; +} + +/**Function************************************************************* + + Synopsis [Reallocates the object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Nwk_Obj_t * Nwk_ManReallocNode_old( Nwk_Obj_t * pObj ) +{ + Nwk_Obj_t * pObjNew, * pTemp; + int i, iNum; + 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 + Nwk_ObjForEachFanout( pObj, pTemp, i ) + { + iNum = Nwk_ObjFindFanin( pTemp, pObj ); + if ( iNum == -1 ) + printf( "Nwk_ManReallocNode(): Error! Fanin cannot be found.\n" ); + pTemp->pFanio[iNum] = pObjNew; + } + // update the fanins' fanouts + Nwk_ObjForEachFanin( pObj, pTemp, i ) + { + iNum = Nwk_ObjFindFanout( pTemp, pObj ); + if ( iNum == -1 ) + 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************************************************************* + + Synopsis [Creates fanout/fanin relationship between the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ( 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************************************************************* + + Synopsis [Removes fanout/fanin relationship between the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ObjDeleteFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ) +{ + int i, k, Limit; + // remove pFanin from the fanin list of pObj + Limit = pObj->nFanins + pObj->nFanouts; + 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--; +} + +/**Function************************************************************* + + Synopsis [Replaces a fanin of the node.] + + Description [The node is pObj. An old fanin of this node (pFaninOld) has to be + replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin + are not complemented. The new fanin can be complemented. In this case, the + polarity of the new fanin will change, compared to the polarity of the old fanin.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ObjPatchFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFaninOld, Nwk_Obj_t * pFaninNew ) +{ + int i, k, iFanin, Limit; + assert( pFaninOld != pFaninNew ); + assert( pObj != pFaninOld ); + assert( pObj != pFaninNew ); + assert( pObj->pMan == pFaninOld->pMan ); + assert( pObj->pMan == pFaninNew->pMan ); + // update the fanin + iFanin = Nwk_ObjFindFanin( pObj, pFaninOld ); + if ( iFanin == -1 ) + { + printf( "Nwk_ObjPatchFanin(); Error! Node %d is not among", pFaninOld->Id ); + printf( " the fanins of node %s...\n", pObj->Id ); + return; + } + pObj->pFanio[iFanin] = pFaninNew; + // remove pObj from the fanout list of pFaninOld + Limit = pFaninOld->nFanins + pFaninOld->nFanouts; + for ( k = i = pFaninOld->nFanins; i < Limit; i++ ) + if ( pFaninOld->pFanio[i] != pObj ) + pFaninOld->pFanio[k++] = pFaninOld->pFanio[i]; + pFaninOld->nFanouts--; + // add pObj to the fanout list of pFaninNew + if ( Nwk_ObjReallocIsNeeded(pFaninNew) ) + Nwk_ManReallocNode( pFaninNew ); + pFaninNew->pFanio[pFaninNew->nFanins + pFaninNew->nFanouts++] = pObj; +} + + +/**Function************************************************************* + + Synopsis [Transfers fanout from the old node to the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ObjTransferFanout( Nwk_Obj_t * pNodeFrom, Nwk_Obj_t * pNodeTo ) +{ + Vec_Ptr_t * vFanouts = pNodeFrom->pMan->vTemp; + Nwk_Obj_t * pTemp; + int nFanoutsOld, i; + assert( !Nwk_ObjIsCo(pNodeFrom) && !Nwk_ObjIsCo(pNodeTo) ); + assert( pNodeFrom->pMan == pNodeTo->pMan ); + assert( pNodeFrom != pNodeTo ); + assert( Nwk_ObjFanoutNum(pNodeFrom) > 0 ); + // get the fanouts of the old node + nFanoutsOld = Nwk_ObjFanoutNum(pNodeTo); + Nwk_ObjCollectFanouts( pNodeFrom, vFanouts ); + // patch the fanin of each of them + Vec_PtrForEachEntry( vFanouts, pTemp, i ) + Nwk_ObjPatchFanin( pTemp, pNodeFrom, pNodeTo ); + assert( Nwk_ObjFanoutNum(pNodeFrom) == 0 ); + assert( Nwk_ObjFanoutNum(pNodeTo) == nFanoutsOld + Vec_PtrSize(vFanouts) ); +} + +/**Function************************************************************* + + Synopsis [Replaces the node by a new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew ) +{ + assert( pNodeOld->pMan == pNodeNew->pMan ); + assert( pNodeOld != pNodeNew ); + assert( Nwk_ObjFanoutNum(pNodeOld) > 0 ); + // transfer the fanouts to the old node + Nwk_ObjTransferFanout( pNodeOld, pNodeNew ); + // remove the old node + Nwk_ManDeleteNode_rec( pNodeOld ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkMan.c b/src/aig/nwk/nwkMan.c new file mode 100644 index 00000000..d05543e6 --- /dev/null +++ b/src/aig/nwk/nwkMan.c @@ -0,0 +1,116 @@ +/**CFile**************************************************************** + + FileName [nwkMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Logic network representation.] + + Synopsis [Network manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwkMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "nwk.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Man_t * Nwk_ManAlloc() +{ + 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 = 2; + p->pMemObjs = Aig_MmFlexStart(); + p->pManHop = Hop_ManStart(); + return p; +} + +/**Function************************************************************* + + Synopsis [Deallocates the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ); + if ( p->vCos ) Vec_PtrFree( p->vCos ); + if ( p->vObjs ) Vec_PtrFree( p->vObjs ); + if ( p->vTemp ) Vec_PtrFree( p->vTemp ); + if ( p->pManTime ) Tim_ManStop( p->pManTime ); + if ( p->pMemObjs ) Aig_MmFlexStop( p->pMemObjs, 0 ); + if ( p->pManHop ) Hop_ManStop( p->pManHop ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Prints stats of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib ) +{ + printf( "%-15s : ", p->pName ); + 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" ); +// Nwk_ManDelayTracePrint( p, pLutLib ); + fflush( stdout ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkMap.c b/src/aig/nwk/nwkMap.c new file mode 100644 index 00000000..ed67966e --- /dev/null +++ b/src/aig/nwk/nwkMap.c @@ -0,0 +1,340 @@ +/**CFile**************************************************************** + + FileName [nwkMap.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Logic network representation.] + + Synopsis [Interface to technology mapping.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwkMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "nwk.h" +#include "if.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ManSetIfParsDefault( If_Par_t * pPars ) +{ +// extern void * Abc_FrameReadLibLut(); + // set defaults + memset( pPars, 0, sizeof(If_Par_t) ); + // user-controlable paramters +// pPars->nLutSize = -1; + pPars->nLutSize = 6; + pPars->nCutsMax = 8; + pPars->nFlowIters = 1; + pPars->nAreaIters = 2; + pPars->DelayTarget = -1; + pPars->Epsilon = (float)0.01; + pPars->fPreprocess = 1; + pPars->fArea = 0; + pPars->fFancy = 0; + pPars->fExpRed = 0; + pPars->fLatchPaths = 0; + pPars->fEdge = 1; + pPars->fCutMin = 0; + pPars->fSeqMap = 0; + pPars->fVerbose = 0; + // internal parameters + pPars->fTruth = 0; + pPars->nLatches = 0; + pPars->fLiftLeaves = 0; +// pPars->pLutLib = Abc_FrameReadLibLut(); + pPars->pLutLib = NULL; + pPars->pTimesArr = NULL; + pPars->pTimesArr = NULL; + pPars->pFuncCost = NULL; +/* + if ( pPars->nLutSize == -1 ) + { + if ( pPars->pLutLib == NULL ) + { + printf( "The LUT library is not given.\n" ); + return; + } + // get LUT size from the library + pPars->nLutSize = pPars->pLutLib->LutMax; + } +*/ +} + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars ) +{ + If_Man_t * pIfMan; + Aig_Obj_t * pNode;//, * pFanin, * pPrev; + int i; + // start the mapping manager and set its parameters + pIfMan = If_ManStart( pPars ); + // print warning about excessive memory usage +// if ( 1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30) > 1.0 ) +// printf( "Warning: The mapper will allocate %.1f Gb for to represent the subject graph with %d AIG nodes.\n", +// 1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30), Aig_ManObjNum(p) ); + // load the AIG into the mapper + Aig_ManForEachObj( p, pNode, i ) + { + if ( Aig_ObjIsAnd(pNode) ) + pNode->pData = (Aig_Obj_t *)If_ManCreateAnd( pIfMan, + If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), + If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) ); + else if ( Aig_ObjIsPi(pNode) ) + { + pNode->pData = If_ManCreateCi( pIfMan ); + ((If_Obj_t *)pNode->pData)->Level = pNode->Level; + if ( pIfMan->nLevelMax < (int)pNode->Level ) + pIfMan->nLevelMax = (int)pNode->Level; + } + else if ( Aig_ObjIsPo(pNode) ) + pNode->pData = If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); + else if ( Aig_ObjIsConst1(pNode) ) + Aig_ManConst1(p)->pData = If_ManConst1( pIfMan ); + else // add the node to the mapper + assert( 0 ); + // set up the choice node +// if ( Aig_AigNodeIsChoice( pNode ) ) +// { +// pIfMan->nChoices++; +// for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) +// If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData ); +// If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData ); +// } + { + If_Obj_t * pIfObj = pNode->pData; + assert( !If_IsComplement(pIfObj) ); + assert( pIfObj->Id == pNode->Id ); + } + } + return pIfMan; +} + + +/**Function************************************************************* + + Synopsis [Recursively derives the truth table for the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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; + Hop_Obj_t * gFunc, * gFunc0, * gFunc1; + // get the best cut + pCut = If_ObjCutBest(pIfObj); + // if the cut is visited, return the result + if ( If_CutData(pCut) ) + return If_CutData(pCut); + // mark the node as visited + Vec_PtrPush( vVisited, pCut ); + // insert the worst case + If_CutSetData( pCut, (void *)1 ); + // skip in case of primary input + if ( If_ObjIsCi(pIfObj) ) + return If_CutData(pCut); + // compute the functions of the children + for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv ) + { + gFunc0 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited ); + if ( gFunc0 == (void *)1 ) + continue; + gFunc1 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited ); + if ( gFunc1 == (void *)1 ) + continue; + // both branches are solved + gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pTemp->fCompl0), Hop_NotCond(gFunc1, pTemp->fCompl1) ); + if ( pTemp->fPhase != pIfObj->fPhase ) + gFunc = Hop_Not(gFunc); + If_CutSetData( pCut, gFunc ); + break; + } + return If_CutData(pCut); +} + +/**Function************************************************************* + + Synopsis [Derives the truth table for one cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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; + If_Obj_t * pLeaf; + int i; + // get the best cut + pCut = If_ObjCutBest(pIfObj); + assert( pCut->nLeaves > 1 ); + // set the leaf variables + If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) + If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) ); + // recursively compute the function while collecting visited cuts + Vec_PtrClear( pIfMan->vTemp ); + gFunc = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp ); + if ( gFunc == (void *)1 ) + { + printf( "Nwk_NodeIfToHop(): Computing local AIG has failed.\n" ); + return NULL; + } +// printf( "%d ", Vec_PtrSize(p->vTemp) ); + // clean the cuts + If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) + If_CutSetData( If_ObjCutBest(pLeaf), NULL ); + Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i ) + If_CutSetData( pCut, NULL ); + return gFunc; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p ) +{ + Nwk_Man_t * pNtk; + Nwk_Obj_t * pObjNew; + Aig_Obj_t * pObj; + If_Obj_t * pIfObj; + If_Cut_t * pCutBest; + int i, k, nLeaves, * ppLeaves; + assert( Aig_ManPiNum(p) == If_ManCiNum(pIfMan) ); + assert( Aig_ManPoNum(p) == If_ManCoNum(pIfMan) ); + assert( Aig_ManNodeNum(p) == If_ManAndNum(pIfMan) ); + If_ManCleanCutData( pIfMan ); + // construct the network + pNtk = Nwk_ManAlloc(); + pNtk->pName = Aig_UtilStrsav( p->pName ); + pNtk->pSpec = Aig_UtilStrsav( p->pSpec ); + Aig_ManForEachObj( p, pObj, i ) + { + pIfObj = If_ManObj( pIfMan, i ); + if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) ) + continue; + if ( Aig_ObjIsNode(pObj) ) + { + pCutBest = If_ObjCutBest( pIfObj ); + nLeaves = If_CutLeaveNum( pCutBest ); + ppLeaves = If_CutLeaves( pCutBest ); + // create node + pObjNew = Nwk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs ); + for ( k = 0; k < nLeaves; k++ ) + Nwk_ObjAddFanin( pObjNew, Aig_ManObj(p, ppLeaves[k])->pData ); + // get the functionality + pObjNew->pFunc = Nwk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj ); + } + else if ( Aig_ObjIsPi(pObj) ) + pObjNew = Nwk_ManCreateCi( pNtk, pIfObj->nRefs ); + else if ( Aig_ObjIsPo(pObj) ) + { + pObjNew = Nwk_ManCreateCo( pNtk ); + pObjNew->fCompl = Aig_ObjFaninC0(pObj); + Nwk_ObjAddFanin( pObjNew, Aig_ObjFanin0(pObj)->pData ); + } + else if ( Aig_ObjIsConst1(pObj) ) + { + pObjNew = Nwk_ManCreateNode( pNtk, 0, pIfObj->nRefs ); + pObjNew->pFunc = Hop_ManConst1( pNtk->pManHop ); + } + else + assert( 0 ); + pObj->pData = pObjNew; + } + pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 ); + return pNtk; +} + +/**Function************************************************************* + + Synopsis [Interface with the FPGA mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars ) +{ + 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 = Nwk_ManToIf( p, pPars ); + if ( pIfMan == NULL ) + return NULL; + pIfMan->pManTim = Tim_ManDup( pManTime, 0 ); + if ( !If_ManPerformMapping( pIfMan ) ) + { + If_ManStop( pIfMan ); + return NULL; + } + // transform the result of mapping into the new network + pNtk = Nwk_ManFromIf( pIfMan, p ); + If_ManStop( pIfMan ); + return pNtk; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkObj.c b/src/aig/nwk/nwkObj.c new file mode 100644 index 00000000..0806eecf --- /dev/null +++ b/src/aig/nwk/nwkObj.c @@ -0,0 +1,202 @@ +/**CFile**************************************************************** + + FileName [nwkObj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Logic network representation.] + + Synopsis [Manipulation of objects.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwkObj.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "nwk.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates an object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Obj_t * Nwk_ManCreateObj( Nwk_Man_t * p, int nFanins, int nFanouts ) +{ + 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; + pObj->nFanioAlloc = nFanins + nFanouts + p->nFanioPlus; + return pObj; +} + + +/**Function************************************************************* + + Synopsis [Creates a primary input.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * p, int nFanouts ) +{ + Nwk_Obj_t * pObj; + pObj = Nwk_ManCreateObj( p, 1, nFanouts ); + pObj->PioId = Vec_PtrSize( p->vCis ); + Vec_PtrPush( p->vCis, pObj ); + pObj->Type = NWK_OBJ_CI; + p->nObjs[NWK_OBJ_CI]++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Creates a primary output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * p ) +{ + Nwk_Obj_t * pObj; + pObj = Nwk_ManCreateObj( p, 1, 1 ); + pObj->PioId = Vec_PtrSize( p->vCos ); + Vec_PtrPush( p->vCos, pObj ); + pObj->Type = NWK_OBJ_CO; + p->nObjs[NWK_OBJ_CO]++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Creates a latch.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Obj_t * Nwk_ManCreateLatch( Nwk_Man_t * p ) +{ + Nwk_Obj_t * pObj; + pObj = Nwk_ManCreateObj( p, 1, 1 ); + pObj->Type = NWK_OBJ_LATCH; + p->nObjs[NWK_OBJ_LATCH]++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Creates a node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Nwk_Obj_t * Nwk_ManCreateNode( Nwk_Man_t * p, int nFanins, int nFanouts ) +{ + Nwk_Obj_t * pObj; + pObj = Nwk_ManCreateObj( p, nFanins, nFanouts ); + pObj->Type = NWK_OBJ_NODE; + p->nObjs[NWK_OBJ_NODE]++; + return pObj; +} + + +/**Function************************************************************* + + Synopsis [Deletes the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ManDeleteNode( Nwk_Obj_t * pObj ) +{ + Vec_Ptr_t * vNodes = pObj->pMan->vTemp; + Nwk_Obj_t * pTemp; + int i; + // delete fanins and fanouts + Nwk_ObjCollectFanouts( pObj, vNodes ); + Vec_PtrForEachEntry( vNodes, pTemp, i ) + Nwk_ObjDeleteFanin( pTemp, pObj ); + Nwk_ObjCollectFanins( pObj, vNodes ); + Vec_PtrForEachEntry( vNodes, pTemp, i ) + 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(Nwk_Obj_t) ); + pObj->Id = -1; +} + +/**Function************************************************************* + + Synopsis [Deletes the node and MFFC of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj ) +{ + Vec_Ptr_t * vNodes; + int i; + assert( !Nwk_ObjIsCi(pObj) ); + assert( Nwk_ObjFanoutNum(pObj) == 0 ); + vNodes = Vec_PtrAlloc( 100 ); + Nwk_ObjCollectFanins( pObj, vNodes ); + Nwk_ManDeleteNode( pObj ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + if ( Nwk_ObjIsNode(pObj) && Nwk_ObjFanoutNum(pObj) == 0 ) + Nwk_ManDeleteNode_rec( pObj ); + Vec_PtrFree( vNodes ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkSpeedup.c b/src/aig/nwk/nwkSpeedup.c new file mode 100644 index 00000000..1eb7cbdd --- /dev/null +++ b/src/aig/nwk/nwkSpeedup.c @@ -0,0 +1,51 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkStrash.c b/src/aig/nwk/nwkStrash.c new file mode 100644 index 00000000..668889a6 --- /dev/null +++ b/src/aig/nwk/nwkStrash.c @@ -0,0 +1,135 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkTiming.c b/src/aig/nwk/nwkTiming.c new file mode 100644 index 00000000..0cbcb7f8 --- /dev/null +++ b/src/aig/nwk/nwkTiming.c @@ -0,0 +1,711 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwkUtil.c b/src/aig/nwk/nwkUtil.c new file mode 100644 index 00000000..47e76844 --- /dev/null +++ b/src/aig/nwk/nwkUtil.c @@ -0,0 +1,214 @@ +/**CFile**************************************************************** + + FileName [nwkUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Logic network representation.] + + Synopsis [Various utilities.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwkUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "nwk.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Increments the current traversal ID of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nwk_ManIncrementTravId( Nwk_Man_t * pNtk ) +{ + Nwk_Obj_t * pObj; + int i; + if ( pNtk->nTravIds >= (1<<26)-1 ) + { + pNtk->nTravIds = 0; + Nwk_ManForEachObj( pNtk, pObj, i ) + pObj->TravId = 0; + } + pNtk->nTravIds++; +} + +/**Function************************************************************* + + Synopsis [Reads the maximum number of fanins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ManGetFaninMax( Nwk_Man_t * pNtk ) +{ + Nwk_Obj_t * pNode; + int i, nFaninsMax = 0; + Nwk_ManForEachNode( pNtk, pNode, i ) + { + if ( nFaninsMax < Nwk_ObjFaninNum(pNode) ) + nFaninsMax = Nwk_ObjFaninNum(pNode); + } + return nFaninsMax; +} + +/**Function************************************************************* + + Synopsis [Reads the total number of all fanins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ManGetTotalFanins( Nwk_Man_t * pNtk ) +{ + Nwk_Obj_t * pNode; + int i, nFanins = 0; + Nwk_ManForEachNode( pNtk, pNode, i ) + nFanins += Nwk_ObjFaninNum(pNode); + return nFanins; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ManPiNum( Nwk_Man_t * pNtk ) +{ + Nwk_Obj_t * pNode; + int i, Counter = 0; + Nwk_ManForEachCi( pNtk, pNode, i ) + Counter += Nwk_ObjIsPi( pNode ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ManPoNum( Nwk_Man_t * pNtk ) +{ + Nwk_Obj_t * pNode; + int i, Counter = 0; + Nwk_ManForEachCo( pNtk, pNode, i ) + Counter += Nwk_ObjIsPo( pNode ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Reads the number of BDD nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Nwk_ManGetAigNodeNum( Nwk_Man_t * pNtk ) +{ + Nwk_Obj_t * pNode; + int i, nNodes = 0; + Nwk_ManForEachNode( pNtk, pNode, i ) + { + if ( pNode->pFunc == NULL ) + { + printf( "Nwk_ManGetAigNodeNum(): Local AIG of node %d is not assigned.\n", pNode->Id ); + continue; + } + 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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/nwk/nwk_.c b/src/aig/nwk/nwk_.c new file mode 100644 index 00000000..81cffbbf --- /dev/null +++ b/src/aig/nwk/nwk_.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [nwk_.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Netlist representation.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: nwk_.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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/tim/tim.c b/src/aig/tim/tim.c index 77967ef6..ea8a3df1 100644 --- a/src/aig/tim/tim.c +++ b/src/aig/tim/tim.c @@ -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; } @@ -236,6 +238,33 @@ Tim_Man_t * Tim_ManDupUnit( Tim_Man_t * p ) return pNew; } +/**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.] @@ -300,6 +329,38 @@ void Tim_ManPrint( Tim_Man_t * p ) printf( "\n" ); } +/**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.] @@ -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; diff --git a/src/aig/tim/tim.h b/src/aig/tim/tim.h index f56b0881..6904984f 100644 --- a/src/aig/tim/tim.h +++ b/src/aig/tim/tim.h @@ -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 ); diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index c82faa15..b5fb81db 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -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************************************************************* diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index c9626286..2f52248e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -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 ] [-Q ] [-S ] [-L ] [-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 ] [-raesvh]\n" ); + fprintf( stdout, "\t performs don't-care-based optimization of logic networks\n" ); + fprintf( stdout, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nWinTfoLevs ); + fprintf( stdout, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutsMax ); + fprintf( stdout, "\t-D : the max depth nodes to try (0 = no limit) [default = %d]\n", pPars->nDepthMax ); + fprintf( stdout, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); + fprintf( stdout, "\t-L : the max increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel ); + fprintf( stdout, "\t-C : 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 ] [-Q ] [-S ] [-L ] [-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 : the max number of LUTs in the structure (2 <= num) [default = %d]\n", pPars->nLutsMax ); + fprintf( stdout, "\t-Q : the max number of LUTs not in MFFC (0 <= num) [default = %d]\n", pPars->nLutsOver ); + fprintf( stdout, "\t-S : the max number of LUT inputs shared (0 <= num <= 3) [default = %d]\n", pPars->nVarsShared ); + fprintf( stdout, "\t-L : 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 : delay delta defining critical path for library model [default = %d%%]\n", Percentage ); + fprintf( stdout, "\t-N : 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] \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; } diff --git a/src/base/abci/abcAbc8.c b/src/base/abci/abcAbc8.c new file mode 100644 index 00000000..3c60bde0 --- /dev/null +++ b/src/base/abci/abcAbc8.c @@ -0,0 +1,243 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 8f28a57f..2737de32 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -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 /// diff --git a/src/base/abci/module.make b/src/base/abci/module.make index a2f879e3..716f1618 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -1,4 +1,5 @@ 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 \ diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index 7196b952..f79f9126 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -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 }; diff --git a/src/map/if/if.h b/src/map/if/if.h index d97a1154..61f81622 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -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 ); diff --git a/src/map/if/ifLib.c b/src/map/if/ifLib.c index 2089ca3c..c5353e19 100644 --- a/src/map/if/ifLib.c +++ b/src/map/if/ifLib.c @@ -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 /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/mfs/mfs.h b/src/opt/mfs/mfs.h index d3f7277d..989cd718 100644 --- a/src/opt/mfs/mfs.h +++ b/src/opt/mfs/mfs.h @@ -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 } diff --git a/src/opt/mfs/mfsCore.c b/src/opt/mfs/mfsCore.c index fed528ef..7104d3b3 100644 --- a/src/opt/mfs/mfsCore.c +++ b/src/opt/mfs/mfsCore.c @@ -28,6 +28,34 @@ /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + 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 [] @@ -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) ); -- cgit v1.2.3