diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2005-08-06 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2005-08-06 08:01:00 -0700 |
commit | d0e834d1a615f8e0e9d04c2ac97811f63562bd0b (patch) | |
tree | 0973181bfb5ee7d556cc95bd640de16fee771e89 | |
parent | 888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc (diff) | |
download | abc-d0e834d1a615f8e0e9d04c2ac97811f63562bd0b.tar.gz abc-d0e834d1a615f8e0e9d04c2ac97811f63562bd0b.tar.bz2 abc-d0e834d1a615f8e0e9d04c2ac97811f63562bd0b.zip |
Version abc50806
43 files changed, 7344 insertions, 1259 deletions
@@ -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\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /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\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -145,6 +145,10 @@ SOURCE=.\src\base\abc\abcFunc.c # End Source File # Begin Source File +SOURCE=.\src\base\abc\abcFxu.c +# End Source File +# Begin Source File + SOURCE=.\src\base\abc\abcInt.h # End Source File # Begin Source File @@ -964,6 +968,66 @@ SOURCE=.\src\sat\fraig\fraigVec.c # PROP Default_Filter "" # End Group +# Begin Group "fxu" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\opt\fxu\fxu.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxu.h +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuCreate.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuHeapD.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuHeapS.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuInt.h +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuList.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuMatrix.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuPair.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuPrint.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuReduce.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuSelect.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuSingle.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\fxu\fxuUpdate.c +# End Source File +# End Group # End Group # Begin Group "map" @@ -3,960 +3,515 @@ <pre> <h1>Build Log</h1> <h3> ---------------------Configuration: abc - Win32 Release-------------------- +--------------------Configuration: abc - Win32 Debug-------------------- </h3> <h3>Command Lines</h3> -Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C8.tmp" with contents +Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP448.tmp" with contents [ -/nologo /ML /W3 /GX /O2 /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Release/" /Fp"Release/abc.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c -"C:\_projects\abc\src\base\abc\abc.c" -"C:\_projects\abc\src\base\abc\abcAig.c" -"C:\_projects\abc\src\base\abc\abcAttach.c" -"C:\_projects\abc\src\base\abc\abcCheck.c" -"C:\_projects\abc\src\base\abc\abcCollapse.c" -"C:\_projects\abc\src\base\abc\abcCreate.c" -"C:\_projects\abc\src\base\abc\abcDfs.c" -"C:\_projects\abc\src\base\abc\abcDsd.c" -"C:\_projects\abc\src\base\abc\abcFanio.c" -"C:\_projects\abc\src\base\abc\abcFpga.c" -"C:\_projects\abc\src\base\abc\abcFraig.c" -"C:\_projects\abc\src\base\abc\abcFunc.c" -"C:\_projects\abc\src\base\abc\abcLatch.c" -"C:\_projects\abc\src\base\abc\abcMap.c" -"C:\_projects\abc\src\base\abc\abcMinBase.c" -"C:\_projects\abc\src\base\abc\abcMiter.c" -"C:\_projects\abc\src\base\abc\abcNames.c" -"C:\_projects\abc\src\base\abc\abcNetlist.c" -"C:\_projects\abc\src\base\abc\abcPrint.c" -"C:\_projects\abc\src\base\abc\abcRefs.c" -"C:\_projects\abc\src\base\abc\abcRenode.c" -"C:\_projects\abc\src\base\abc\abcSat.c" -"C:\_projects\abc\src\base\abc\abcSop.c" -"C:\_projects\abc\src\base\abc\abcStrash.c" -"C:\_projects\abc\src\base\abc\abcSweep.c" -"C:\_projects\abc\src\base\abc\abcTiming.c" -"C:\_projects\abc\src\base\abc\abcUtil.c" -"C:\_projects\abc\src\base\abc\abcVerify.c" -"C:\_projects\abc\src\base\cmd\cmd.c" -"C:\_projects\abc\src\base\cmd\cmdAlias.c" -"C:\_projects\abc\src\base\cmd\cmdApi.c" -"C:\_projects\abc\src\base\cmd\cmdFlag.c" -"C:\_projects\abc\src\base\cmd\cmdHist.c" -"C:\_projects\abc\src\base\cmd\cmdUtils.c" -"C:\_projects\abc\src\base\io\io.c" -"C:\_projects\abc\src\base\io\ioRead.c" -"C:\_projects\abc\src\base\io\ioReadBench.c" -"C:\_projects\abc\src\base\io\ioReadBlif.c" -"C:\_projects\abc\src\base\io\ioReadVerilog.c" -"C:\_projects\abc\src\base\io\ioWriteBench.c" -"C:\_projects\abc\src\base\io\ioWriteBlif.c" -"C:\_projects\abc\src\base\io\ioWriteBlifLogic.c" -"C:\_projects\abc\src\base\io\ioWriteCnf.c" -"C:\_projects\abc\src\base\io\ioWriteGate.c" -"C:\_projects\abc\src\base\main\main.c" -"C:\_projects\abc\src\base\main\mainFrame.c" -"C:\_projects\abc\src\base\main\mainInit.c" -"C:\_projects\abc\src\base\main\mainUtils.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddAbs.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddApply.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddFind.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddInv.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddIte.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddNeg.c" -"C:\_projects\abc\src\bdd\cudd\cuddAddWalsh.c" -"C:\_projects\abc\src\bdd\cudd\cuddAndAbs.c" -"C:\_projects\abc\src\bdd\cudd\cuddAnneal.c" -"C:\_projects\abc\src\bdd\cudd\cuddApa.c" -"C:\_projects\abc\src\bdd\cudd\cuddAPI.c" -"C:\_projects\abc\src\bdd\cudd\cuddApprox.c" -"C:\_projects\abc\src\bdd\cudd\cuddBddAbs.c" -"C:\_projects\abc\src\bdd\cudd\cuddBddCorr.c" -"C:\_projects\abc\src\bdd\cudd\cuddBddIte.c" -"C:\_projects\abc\src\bdd\cudd\cuddBridge.c" -"C:\_projects\abc\src\bdd\cudd\cuddCache.c" -"C:\_projects\abc\src\bdd\cudd\cuddCheck.c" -"C:\_projects\abc\src\bdd\cudd\cuddClip.c" -"C:\_projects\abc\src\bdd\cudd\cuddCof.c" -"C:\_projects\abc\src\bdd\cudd\cuddCompose.c" -"C:\_projects\abc\src\bdd\cudd\cuddDecomp.c" -"C:\_projects\abc\src\bdd\cudd\cuddEssent.c" -"C:\_projects\abc\src\bdd\cudd\cuddExact.c" -"C:\_projects\abc\src\bdd\cudd\cuddExport.c" -"C:\_projects\abc\src\bdd\cudd\cuddGenCof.c" -"C:\_projects\abc\src\bdd\cudd\cuddGenetic.c" -"C:\_projects\abc\src\bdd\cudd\cuddGroup.c" -"C:\_projects\abc\src\bdd\cudd\cuddHarwell.c" -"C:\_projects\abc\src\bdd\cudd\cuddInit.c" -"C:\_projects\abc\src\bdd\cudd\cuddInteract.c" -"C:\_projects\abc\src\bdd\cudd\cuddLCache.c" -"C:\_projects\abc\src\bdd\cudd\cuddLevelQ.c" -"C:\_projects\abc\src\bdd\cudd\cuddLinear.c" -"C:\_projects\abc\src\bdd\cudd\cuddLiteral.c" -"C:\_projects\abc\src\bdd\cudd\cuddMatMult.c" -"C:\_projects\abc\src\bdd\cudd\cuddPriority.c" -"C:\_projects\abc\src\bdd\cudd\cuddRead.c" -"C:\_projects\abc\src\bdd\cudd\cuddRef.c" -"C:\_projects\abc\src\bdd\cudd\cuddReorder.c" -"C:\_projects\abc\src\bdd\cudd\cuddSat.c" -"C:\_projects\abc\src\bdd\cudd\cuddSign.c" -"C:\_projects\abc\src\bdd\cudd\cuddSolve.c" -"C:\_projects\abc\src\bdd\cudd\cuddSplit.c" -"C:\_projects\abc\src\bdd\cudd\cuddSubsetHB.c" -"C:\_projects\abc\src\bdd\cudd\cuddSubsetSP.c" -"C:\_projects\abc\src\bdd\cudd\cuddSymmetry.c" -"C:\_projects\abc\src\bdd\cudd\cuddTable.c" -"C:\_projects\abc\src\bdd\cudd\cuddUtil.c" -"C:\_projects\abc\src\bdd\cudd\cuddWindow.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddCount.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddFuncs.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddGroup.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddIsop.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddLin.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddMisc.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddPort.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddReord.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddSetop.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddSymm.c" -"C:\_projects\abc\src\bdd\cudd\cuddZddUtil.c" -"C:\_projects\abc\src\bdd\epd\epd.c" -"C:\_projects\abc\src\bdd\mtr\mtrBasic.c" -"C:\_projects\abc\src\bdd\mtr\mtrGroup.c" -"C:\_projects\abc\src\bdd\parse\parseCore.c" -"C:\_projects\abc\src\bdd\parse\parseStack.c" -"C:\_projects\abc\src\bdd\dsd\dsdApi.c" -"C:\_projects\abc\src\bdd\dsd\dsdCheck.c" -"C:\_projects\abc\src\bdd\dsd\dsdLocal.c" -"C:\_projects\abc\src\bdd\dsd\dsdMan.c" -"C:\_projects\abc\src\bdd\dsd\dsdProc.c" -"C:\_projects\abc\src\bdd\dsd\dsdTree.c" -"C:\_projects\abc\src\bdd\reo\reoApi.c" -"C:\_projects\abc\src\bdd\reo\reoCore.c" -"C:\_projects\abc\src\bdd\reo\reoProfile.c" -"C:\_projects\abc\src\bdd\reo\reoSift.c" -"C:\_projects\abc\src\bdd\reo\reoSwap.c" -"C:\_projects\abc\src\bdd\reo\reoTest.c" -"C:\_projects\abc\src\bdd\reo\reoTransfer.c" -"C:\_projects\abc\src\bdd\reo\reoUnits.c" -"C:\_projects\abc\src\sop\mvc\mvc.c" -"C:\_projects\abc\src\sop\mvc\mvcApi.c" -"C:\_projects\abc\src\sop\mvc\mvcCompare.c" -"C:\_projects\abc\src\sop\mvc\mvcContain.c" -"C:\_projects\abc\src\sop\mvc\mvcCover.c" -"C:\_projects\abc\src\sop\mvc\mvcCube.c" -"C:\_projects\abc\src\sop\mvc\mvcDivide.c" -"C:\_projects\abc\src\sop\mvc\mvcDivisor.c" -"C:\_projects\abc\src\sop\mvc\mvcList.c" -"C:\_projects\abc\src\sop\mvc\mvcLits.c" -"C:\_projects\abc\src\sop\mvc\mvcMan.c" -"C:\_projects\abc\src\sop\mvc\mvcOpAlg.c" -"C:\_projects\abc\src\sop\mvc\mvcOpBool.c" -"C:\_projects\abc\src\sop\mvc\mvcPrint.c" -"C:\_projects\abc\src\sop\mvc\mvcSort.c" -"C:\_projects\abc\src\sop\mvc\mvcUtils.c" -"C:\_projects\abc\src\sop\ft\ftFactor.c" -"C:\_projects\abc\src\sop\ft\ftPrint.c" -"C:\_projects\abc\src\sat\asat\added.c" -"C:\_projects\abc\src\sat\asat\solver.c" -"C:\_projects\abc\src\sat\msat\msatActivity.c" -"C:\_projects\abc\src\sat\msat\msatClause.c" -"C:\_projects\abc\src\sat\msat\msatClauseVec.c" -"C:\_projects\abc\src\sat\msat\msatMem.c" -"C:\_projects\abc\src\sat\msat\msatOrderJ.c" -"C:\_projects\abc\src\sat\msat\msatQueue.c" -"C:\_projects\abc\src\sat\msat\msatRead.c" -"C:\_projects\abc\src\sat\msat\msatSolverApi.c" -"C:\_projects\abc\src\sat\msat\msatSolverCore.c" -"C:\_projects\abc\src\sat\msat\msatSolverIo.c" -"C:\_projects\abc\src\sat\msat\msatSolverSearch.c" -"C:\_projects\abc\src\sat\msat\msatSort.c" -"C:\_projects\abc\src\sat\msat\msatVec.c" -"C:\_projects\abc\src\sat\fraig\fraigApi.c" -"C:\_projects\abc\src\sat\fraig\fraigCanon.c" -"C:\_projects\abc\src\sat\fraig\fraigFanout.c" -"C:\_projects\abc\src\sat\fraig\fraigFeed.c" -"C:\_projects\abc\src\sat\fraig\fraigMan.c" -"C:\_projects\abc\src\sat\fraig\fraigMem.c" -"C:\_projects\abc\src\sat\fraig\fraigNode.c" -"C:\_projects\abc\src\sat\fraig\fraigPrime.c" -"C:\_projects\abc\src\sat\fraig\fraigSat.c" -"C:\_projects\abc\src\sat\fraig\fraigTable.c" -"C:\_projects\abc\src\sat\fraig\fraigUtil.c" -"C:\_projects\abc\src\sat\fraig\fraigVec.c" -"C:\_projects\abc\src\map\fpga\fpga.c" -"C:\_projects\abc\src\map\fpga\fpgaCore.c" -"C:\_projects\abc\src\map\fpga\fpgaCreate.c" -"C:\_projects\abc\src\map\fpga\fpgaCut.c" -"C:\_projects\abc\src\map\fpga\fpgaCutUtils.c" -"C:\_projects\abc\src\map\fpga\fpgaFanout.c" -"C:\_projects\abc\src\map\fpga\fpgaLib.c" -"C:\_projects\abc\src\map\fpga\fpgaMatch.c" -"C:\_projects\abc\src\map\fpga\fpgaTime.c" -"C:\_projects\abc\src\map\fpga\fpgaTruth.c" -"C:\_projects\abc\src\map\fpga\fpgaUtils.c" -"C:\_projects\abc\src\map\fpga\fpgaVec.c" -"C:\_projects\abc\src\map\mapper\mapper.c" -"C:\_projects\abc\src\map\mapper\mapperCanon.c" -"C:\_projects\abc\src\map\mapper\mapperCore.c" -"C:\_projects\abc\src\map\mapper\mapperCreate.c" -"C:\_projects\abc\src\map\mapper\mapperCut.c" -"C:\_projects\abc\src\map\mapper\mapperCutUtils.c" -"C:\_projects\abc\src\map\mapper\mapperFanout.c" -"C:\_projects\abc\src\map\mapper\mapperLib.c" -"C:\_projects\abc\src\map\mapper\mapperMatch.c" -"C:\_projects\abc\src\map\mapper\mapperRefs.c" -"C:\_projects\abc\src\map\mapper\mapperSuper.c" -"C:\_projects\abc\src\map\mapper\mapperTable.c" -"C:\_projects\abc\src\map\mapper\mapperTime.c" -"C:\_projects\abc\src\map\mapper\mapperTree.c" -"C:\_projects\abc\src\map\mapper\mapperTruth.c" -"C:\_projects\abc\src\map\mapper\mapperUtils.c" -"C:\_projects\abc\src\map\mapper\mapperVec.c" -"C:\_projects\abc\src\map\mio\mio.c" -"C:\_projects\abc\src\map\mio\mioApi.c" -"C:\_projects\abc\src\map\mio\mioFunc.c" -"C:\_projects\abc\src\map\mio\mioRead.c" -"C:\_projects\abc\src\map\mio\mioUtils.c" -"C:\_projects\abc\src\map\super\super.c" -"C:\_projects\abc\src\map\super\superAnd.c" -"C:\_projects\abc\src\map\super\superGate.c" -"C:\_projects\abc\src\map\super\superWrite.c" -"C:\_projects\abc\src\misc\extra\extraUtilBdd.c" -"C:\_projects\abc\src\misc\extra\extraUtilFile.c" -"C:\_projects\abc\src\misc\extra\extraUtilMemory.c" -"C:\_projects\abc\src\misc\extra\extraUtilMisc.c" -"C:\_projects\abc\src\misc\extra\extraUtilProgress.c" -"C:\_projects\abc\src\misc\extra\extraUtilReader.c" -"C:\_projects\abc\src\misc\st\st.c" -"C:\_projects\abc\src\misc\st\stmm.c" -"C:\_projects\abc\src\misc\util\cpu_stats.c" -"C:\_projects\abc\src\misc\util\cpu_time.c" -"C:\_projects\abc\src\misc\util\datalimit.c" -"C:\_projects\abc\src\misc\util\getopt.c" -"C:\_projects\abc\src\misc\util\pathsearch.c" -"C:\_projects\abc\src\misc\util\safe_mem.c" -"C:\_projects\abc\src\misc\util\strsav.c" -"C:\_projects\abc\src\misc\util\texpand.c" +/nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Debug/" /Fp"Debug/abc.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c +"C:\_projects\abc\src\opt\fxu\fxu.c" ] -Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C8.tmp" -Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C9.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP448.tmp" +Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP449.tmp" with contents [ -kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"Release/abc.pdb" /machine:I386 /out:"_TEST/abc.exe" -.\Release\abc.obj -.\Release\abcAig.obj -.\Release\abcAttach.obj -.\Release\abcCheck.obj -.\Release\abcCollapse.obj -.\Release\abcCreate.obj -.\Release\abcDfs.obj -.\Release\abcDsd.obj -.\Release\abcFanio.obj -.\Release\abcFpga.obj -.\Release\abcFraig.obj -.\Release\abcFunc.obj -.\Release\abcLatch.obj -.\Release\abcMap.obj -.\Release\abcMinBase.obj -.\Release\abcMiter.obj -.\Release\abcNames.obj -.\Release\abcNetlist.obj -.\Release\abcPrint.obj -.\Release\abcRefs.obj -.\Release\abcRenode.obj -.\Release\abcSat.obj -.\Release\abcSop.obj -.\Release\abcStrash.obj -.\Release\abcSweep.obj -.\Release\abcTiming.obj -.\Release\abcUtil.obj -.\Release\abcVerify.obj -.\Release\cmd.obj -.\Release\cmdAlias.obj -.\Release\cmdApi.obj -.\Release\cmdFlag.obj -.\Release\cmdHist.obj -.\Release\cmdUtils.obj -.\Release\io.obj -.\Release\ioRead.obj -.\Release\ioReadBench.obj -.\Release\ioReadBlif.obj -.\Release\ioReadVerilog.obj -.\Release\ioWriteBench.obj -.\Release\ioWriteBlif.obj -.\Release\ioWriteBlifLogic.obj -.\Release\ioWriteCnf.obj -.\Release\ioWriteGate.obj -.\Release\main.obj -.\Release\mainFrame.obj -.\Release\mainInit.obj -.\Release\mainUtils.obj -.\Release\cuddAddAbs.obj -.\Release\cuddAddApply.obj -.\Release\cuddAddFind.obj -.\Release\cuddAddInv.obj -.\Release\cuddAddIte.obj -.\Release\cuddAddNeg.obj -.\Release\cuddAddWalsh.obj -.\Release\cuddAndAbs.obj -.\Release\cuddAnneal.obj -.\Release\cuddApa.obj -.\Release\cuddAPI.obj -.\Release\cuddApprox.obj -.\Release\cuddBddAbs.obj -.\Release\cuddBddCorr.obj -.\Release\cuddBddIte.obj -.\Release\cuddBridge.obj -.\Release\cuddCache.obj -.\Release\cuddCheck.obj -.\Release\cuddClip.obj -.\Release\cuddCof.obj -.\Release\cuddCompose.obj -.\Release\cuddDecomp.obj -.\Release\cuddEssent.obj -.\Release\cuddExact.obj -.\Release\cuddExport.obj -.\Release\cuddGenCof.obj -.\Release\cuddGenetic.obj -.\Release\cuddGroup.obj -.\Release\cuddHarwell.obj -.\Release\cuddInit.obj -.\Release\cuddInteract.obj -.\Release\cuddLCache.obj -.\Release\cuddLevelQ.obj -.\Release\cuddLinear.obj -.\Release\cuddLiteral.obj -.\Release\cuddMatMult.obj -.\Release\cuddPriority.obj -.\Release\cuddRead.obj -.\Release\cuddRef.obj -.\Release\cuddReorder.obj -.\Release\cuddSat.obj -.\Release\cuddSign.obj -.\Release\cuddSolve.obj -.\Release\cuddSplit.obj -.\Release\cuddSubsetHB.obj -.\Release\cuddSubsetSP.obj -.\Release\cuddSymmetry.obj -.\Release\cuddTable.obj -.\Release\cuddUtil.obj -.\Release\cuddWindow.obj -.\Release\cuddZddCount.obj -.\Release\cuddZddFuncs.obj -.\Release\cuddZddGroup.obj -.\Release\cuddZddIsop.obj -.\Release\cuddZddLin.obj -.\Release\cuddZddMisc.obj -.\Release\cuddZddPort.obj -.\Release\cuddZddReord.obj -.\Release\cuddZddSetop.obj -.\Release\cuddZddSymm.obj -.\Release\cuddZddUtil.obj -.\Release\epd.obj -.\Release\mtrBasic.obj -.\Release\mtrGroup.obj -.\Release\parseCore.obj -.\Release\parseStack.obj -.\Release\dsdApi.obj -.\Release\dsdCheck.obj -.\Release\dsdLocal.obj -.\Release\dsdMan.obj -.\Release\dsdProc.obj -.\Release\dsdTree.obj -.\Release\reoApi.obj -.\Release\reoCore.obj -.\Release\reoProfile.obj -.\Release\reoSift.obj -.\Release\reoSwap.obj -.\Release\reoTest.obj -.\Release\reoTransfer.obj -.\Release\reoUnits.obj -.\Release\mvc.obj -.\Release\mvcApi.obj -.\Release\mvcCompare.obj -.\Release\mvcContain.obj -.\Release\mvcCover.obj -.\Release\mvcCube.obj -.\Release\mvcDivide.obj -.\Release\mvcDivisor.obj -.\Release\mvcList.obj -.\Release\mvcLits.obj -.\Release\mvcMan.obj -.\Release\mvcOpAlg.obj -.\Release\mvcOpBool.obj -.\Release\mvcPrint.obj -.\Release\mvcSort.obj -.\Release\mvcUtils.obj -.\Release\ftFactor.obj -.\Release\ftPrint.obj -.\Release\added.obj -.\Release\solver.obj -.\Release\msatActivity.obj -.\Release\msatClause.obj -.\Release\msatClauseVec.obj -.\Release\msatMem.obj -.\Release\msatOrderJ.obj -.\Release\msatQueue.obj -.\Release\msatRead.obj -.\Release\msatSolverApi.obj -.\Release\msatSolverCore.obj -.\Release\msatSolverIo.obj -.\Release\msatSolverSearch.obj -.\Release\msatSort.obj -.\Release\msatVec.obj -.\Release\fraigApi.obj -.\Release\fraigCanon.obj -.\Release\fraigFanout.obj -.\Release\fraigFeed.obj -.\Release\fraigMan.obj -.\Release\fraigMem.obj -.\Release\fraigNode.obj -.\Release\fraigPrime.obj -.\Release\fraigSat.obj -.\Release\fraigTable.obj -.\Release\fraigUtil.obj -.\Release\fraigVec.obj -.\Release\fpga.obj -.\Release\fpgaCore.obj -.\Release\fpgaCreate.obj -.\Release\fpgaCut.obj -.\Release\fpgaCutUtils.obj -.\Release\fpgaFanout.obj -.\Release\fpgaLib.obj -.\Release\fpgaMatch.obj -.\Release\fpgaTime.obj -.\Release\fpgaTruth.obj -.\Release\fpgaUtils.obj -.\Release\fpgaVec.obj -.\Release\mapper.obj -.\Release\mapperCanon.obj -.\Release\mapperCore.obj -.\Release\mapperCreate.obj -.\Release\mapperCut.obj -.\Release\mapperCutUtils.obj -.\Release\mapperFanout.obj -.\Release\mapperLib.obj -.\Release\mapperMatch.obj -.\Release\mapperRefs.obj -.\Release\mapperSuper.obj -.\Release\mapperTable.obj -.\Release\mapperTime.obj -.\Release\mapperTree.obj -.\Release\mapperTruth.obj -.\Release\mapperUtils.obj -.\Release\mapperVec.obj -.\Release\mio.obj -.\Release\mioApi.obj -.\Release\mioFunc.obj -.\Release\mioRead.obj -.\Release\mioUtils.obj -.\Release\super.obj -.\Release\superAnd.obj -.\Release\superGate.obj -.\Release\superWrite.obj -.\Release\extraUtilBdd.obj -.\Release\extraUtilFile.obj -.\Release\extraUtilMemory.obj -.\Release\extraUtilMisc.obj -.\Release\extraUtilProgress.obj -.\Release\extraUtilReader.obj -.\Release\st.obj -.\Release\stmm.obj -.\Release\cpu_stats.obj -.\Release\cpu_time.obj -.\Release\datalimit.obj -.\Release\getopt.obj -.\Release\pathsearch.obj -.\Release\safe_mem.obj -.\Release\strsav.obj -.\Release\texpand.obj +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept +.\Debug\abc.obj +.\Debug\abcAig.obj +.\Debug\abcAttach.obj +.\Debug\abcCheck.obj +.\Debug\abcCollapse.obj +.\Debug\abcCreate.obj +.\Debug\abcDfs.obj +.\Debug\abcDsd.obj +.\Debug\abcFanio.obj +.\Debug\abcFpga.obj +.\Debug\abcFraig.obj +.\Debug\abcFunc.obj +.\Debug\abcLatch.obj +.\Debug\abcMap.obj +.\Debug\abcMinBase.obj +.\Debug\abcMiter.obj +.\Debug\abcNames.obj +.\Debug\abcNetlist.obj +.\Debug\abcPrint.obj +.\Debug\abcRefs.obj +.\Debug\abcRenode.obj +.\Debug\abcSat.obj +.\Debug\abcSop.obj +.\Debug\abcStrash.obj +.\Debug\abcSweep.obj +.\Debug\abcTiming.obj +.\Debug\abcUtil.obj +.\Debug\abcVerify.obj +.\Debug\cmd.obj +.\Debug\cmdAlias.obj +.\Debug\cmdApi.obj +.\Debug\cmdFlag.obj +.\Debug\cmdHist.obj +.\Debug\cmdUtils.obj +.\Debug\io.obj +.\Debug\ioRead.obj +.\Debug\ioReadBench.obj +.\Debug\ioReadBlif.obj +.\Debug\ioReadVerilog.obj +.\Debug\ioWriteBench.obj +.\Debug\ioWriteBlif.obj +.\Debug\ioWriteBlifLogic.obj +.\Debug\ioWriteCnf.obj +.\Debug\ioWriteGate.obj +.\Debug\main.obj +.\Debug\mainFrame.obj +.\Debug\mainInit.obj +.\Debug\mainUtils.obj +.\Debug\cuddAddAbs.obj +.\Debug\cuddAddApply.obj +.\Debug\cuddAddFind.obj +.\Debug\cuddAddInv.obj +.\Debug\cuddAddIte.obj +.\Debug\cuddAddNeg.obj +.\Debug\cuddAddWalsh.obj +.\Debug\cuddAndAbs.obj +.\Debug\cuddAnneal.obj +.\Debug\cuddApa.obj +.\Debug\cuddAPI.obj +.\Debug\cuddApprox.obj +.\Debug\cuddBddAbs.obj +.\Debug\cuddBddCorr.obj +.\Debug\cuddBddIte.obj +.\Debug\cuddBridge.obj +.\Debug\cuddCache.obj +.\Debug\cuddCheck.obj +.\Debug\cuddClip.obj +.\Debug\cuddCof.obj +.\Debug\cuddCompose.obj +.\Debug\cuddDecomp.obj +.\Debug\cuddEssent.obj +.\Debug\cuddExact.obj +.\Debug\cuddExport.obj +.\Debug\cuddGenCof.obj +.\Debug\cuddGenetic.obj +.\Debug\cuddGroup.obj +.\Debug\cuddHarwell.obj +.\Debug\cuddInit.obj +.\Debug\cuddInteract.obj +.\Debug\cuddLCache.obj +.\Debug\cuddLevelQ.obj +.\Debug\cuddLinear.obj +.\Debug\cuddLiteral.obj +.\Debug\cuddMatMult.obj +.\Debug\cuddPriority.obj +.\Debug\cuddRead.obj +.\Debug\cuddRef.obj +.\Debug\cuddReorder.obj +.\Debug\cuddSat.obj +.\Debug\cuddSign.obj +.\Debug\cuddSolve.obj +.\Debug\cuddSplit.obj +.\Debug\cuddSubsetHB.obj +.\Debug\cuddSubsetSP.obj +.\Debug\cuddSymmetry.obj +.\Debug\cuddTable.obj +.\Debug\cuddUtil.obj +.\Debug\cuddWindow.obj +.\Debug\cuddZddCount.obj +.\Debug\cuddZddFuncs.obj +.\Debug\cuddZddGroup.obj +.\Debug\cuddZddIsop.obj +.\Debug\cuddZddLin.obj +.\Debug\cuddZddMisc.obj +.\Debug\cuddZddPort.obj +.\Debug\cuddZddReord.obj +.\Debug\cuddZddSetop.obj +.\Debug\cuddZddSymm.obj +.\Debug\cuddZddUtil.obj +.\Debug\epd.obj +.\Debug\mtrBasic.obj +.\Debug\mtrGroup.obj +.\Debug\parseCore.obj +.\Debug\parseStack.obj +.\Debug\dsdApi.obj +.\Debug\dsdCheck.obj +.\Debug\dsdLocal.obj +.\Debug\dsdMan.obj +.\Debug\dsdProc.obj +.\Debug\dsdTree.obj +.\Debug\reoApi.obj +.\Debug\reoCore.obj +.\Debug\reoProfile.obj +.\Debug\reoSift.obj +.\Debug\reoSwap.obj +.\Debug\reoTest.obj +.\Debug\reoTransfer.obj +.\Debug\reoUnits.obj +.\Debug\mvc.obj +.\Debug\mvcApi.obj +.\Debug\mvcCompare.obj +.\Debug\mvcContain.obj +.\Debug\mvcCover.obj +.\Debug\mvcCube.obj +.\Debug\mvcDivide.obj +.\Debug\mvcDivisor.obj +.\Debug\mvcList.obj +.\Debug\mvcLits.obj +.\Debug\mvcMan.obj +.\Debug\mvcOpAlg.obj +.\Debug\mvcOpBool.obj +.\Debug\mvcPrint.obj +.\Debug\mvcSort.obj +.\Debug\mvcUtils.obj +.\Debug\ftFactor.obj +.\Debug\ftPrint.obj +.\Debug\added.obj +.\Debug\solver.obj +.\Debug\msatActivity.obj +.\Debug\msatClause.obj +.\Debug\msatClauseVec.obj +.\Debug\msatMem.obj +.\Debug\msatOrderJ.obj +.\Debug\msatQueue.obj +.\Debug\msatRead.obj +.\Debug\msatSolverApi.obj +.\Debug\msatSolverCore.obj +.\Debug\msatSolverIo.obj +.\Debug\msatSolverSearch.obj +.\Debug\msatSort.obj +.\Debug\msatVec.obj +.\Debug\fraigApi.obj +.\Debug\fraigCanon.obj +.\Debug\fraigFanout.obj +.\Debug\fraigFeed.obj +.\Debug\fraigMan.obj +.\Debug\fraigMem.obj +.\Debug\fraigNode.obj +.\Debug\fraigPrime.obj +.\Debug\fraigSat.obj +.\Debug\fraigTable.obj +.\Debug\fraigUtil.obj +.\Debug\fraigVec.obj +.\Debug\fpga.obj +.\Debug\fpgaCore.obj +.\Debug\fpgaCreate.obj +.\Debug\fpgaCut.obj +.\Debug\fpgaCutUtils.obj +.\Debug\fpgaFanout.obj +.\Debug\fpgaLib.obj +.\Debug\fpgaMatch.obj +.\Debug\fpgaTime.obj +.\Debug\fpgaTruth.obj +.\Debug\fpgaUtils.obj +.\Debug\fpgaVec.obj +.\Debug\mapper.obj +.\Debug\mapperCanon.obj +.\Debug\mapperCore.obj +.\Debug\mapperCreate.obj +.\Debug\mapperCut.obj +.\Debug\mapperCutUtils.obj +.\Debug\mapperFanout.obj +.\Debug\mapperLib.obj +.\Debug\mapperMatch.obj +.\Debug\mapperRefs.obj +.\Debug\mapperSuper.obj +.\Debug\mapperTable.obj +.\Debug\mapperTime.obj +.\Debug\mapperTree.obj +.\Debug\mapperTruth.obj +.\Debug\mapperUtils.obj +.\Debug\mapperVec.obj +.\Debug\mio.obj +.\Debug\mioApi.obj +.\Debug\mioFunc.obj +.\Debug\mioRead.obj +.\Debug\mioUtils.obj +.\Debug\super.obj +.\Debug\superAnd.obj +.\Debug\superGate.obj +.\Debug\superWrite.obj +.\Debug\extraUtilBdd.obj +.\Debug\extraUtilFile.obj +.\Debug\extraUtilMemory.obj +.\Debug\extraUtilMisc.obj +.\Debug\extraUtilProgress.obj +.\Debug\extraUtilReader.obj +.\Debug\st.obj +.\Debug\stmm.obj +.\Debug\cpu_stats.obj +.\Debug\cpu_time.obj +.\Debug\datalimit.obj +.\Debug\getopt.obj +.\Debug\pathsearch.obj +.\Debug\safe_mem.obj +.\Debug\strsav.obj +.\Debug\texpand.obj +.\Debug\fxuUpdate.obj +.\Debug\fxu.obj +.\Debug\fxuCreate.obj +.\Debug\fxuHeapD.obj +.\Debug\fxuHeapS.obj +.\Debug\fxuList.obj +.\Debug\fxuMatrix.obj +.\Debug\fxuPair.obj +.\Debug\fxuPrint.obj +.\Debug\fxuReduce.obj +.\Debug\fxuSelect.obj +.\Debug\fxuSingle.obj +.\Debug\abcFxu.obj ] -Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C9.tmp" +Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP449.tmp" <h3>Output Window</h3> Compiling... -abc.c -abcAig.c -abcAttach.c -abcCheck.c -abcCollapse.c -abcCreate.c -abcDfs.c -abcDsd.c -abcFanio.c -abcFpga.c -abcFraig.c -abcFunc.c -abcLatch.c -abcMap.c -abcMinBase.c -abcMiter.c -abcNames.c -abcNetlist.c -abcPrint.c -abcRefs.c -abcRenode.c -abcSat.c -abcSop.c -abcStrash.c -abcSweep.c -abcTiming.c -abcUtil.c -abcVerify.c -cmd.c -cmdAlias.c -cmdApi.c -cmdFlag.c -cmdHist.c -cmdUtils.c -io.c -ioRead.c -ioReadBench.c -ioReadBlif.c -ioReadVerilog.c -ioWriteBench.c -ioWriteBlif.c -ioWriteBlifLogic.c -ioWriteCnf.c -ioWriteGate.c -main.c -mainFrame.c -mainInit.c -mainUtils.c -cuddAddAbs.c -cuddAddApply.c -cuddAddFind.c -cuddAddInv.c -cuddAddIte.c -cuddAddNeg.c -cuddAddWalsh.c -cuddAndAbs.c -cuddAnneal.c -cuddApa.c -C:\_projects\abc\src\bdd\cudd\cuddApa.c(181) : warning C4244: 'return' : conversion from 'unsigned long ' to 'unsigned short ', possible loss of data -C:\_projects\abc\src\bdd\cudd\cuddApa.c(213) : warning C4244: 'return' : conversion from 'unsigned long ' to 'unsigned short ', possible loss of data -C:\_projects\abc\src\bdd\cudd\cuddApa.c(530) : warning C4244: '=' : conversion from 'unsigned short ' to 'unsigned char ', possible loss of data -C:\_projects\abc\src\bdd\cudd\cuddApa.c(588) : warning C4244: '=' : conversion from 'unsigned short ' to 'unsigned char ', possible loss of data -cuddAPI.c -cuddApprox.c -cuddBddAbs.c -cuddBddCorr.c -cuddBddIte.c -cuddBridge.c -cuddCache.c -C:\_projects\abc\src\bdd\cudd\cuddCache.c(902) : warning C4146: unary minus operator applied to unsigned type, result still unsigned -cuddCheck.c -cuddClip.c -cuddCof.c -cuddCompose.c -cuddDecomp.c -cuddEssent.c -cuddExact.c -cuddExport.c -cuddGenCof.c -cuddGenetic.c -cuddGroup.c -C:\_projects\abc\src\bdd\cudd\cuddGroup.c(2062) : warning C4018: '<=' : signed/unsigned mismatch -cuddHarwell.c -cuddInit.c -cuddInteract.c -cuddLCache.c -C:\_projects\abc\src\bdd\cudd\cuddLCache.c(1387) : warning C4146: unary minus operator applied to unsigned type, result still unsigned -cuddLevelQ.c -cuddLinear.c -cuddLiteral.c -cuddMatMult.c -cuddPriority.c -cuddRead.c -cuddRef.c -cuddReorder.c -C:\_projects\abc\src\bdd\cudd\cuddReorder.c(395) : warning C4146: unary minus operator applied to unsigned type, result still unsigned -cuddSat.c -C:\_projects\abc\src\bdd\cudd\cuddReorder.c(2016) : warning C4700: local variable 'minLevel' used without having been initialized -C:\_projects\abc\src\bdd\cudd\cuddReorder.c(2020) : warning C4700: local variable 'maxLevel' used without having been initialized -cuddSign.c -cuddSolve.c -cuddSplit.c -cuddSubsetHB.c -cuddSubsetSP.c -cuddSymmetry.c -cuddTable.c -C:\_projects\abc\src\bdd\cudd\cuddTable.c(1822) : warning C4018: '<' : signed/unsigned mismatch -C:\_projects\abc\src\bdd\cudd\cuddTable.c(1927) : warning C4018: '<' : signed/unsigned mismatch -C:\_projects\abc\src\bdd\cudd\cuddTable.c(2235) : warning C4018: '<' : signed/unsigned mismatch -C:\_projects\abc\src\bdd\cudd\cuddTable.c(2303) : warning C4018: '<' : signed/unsigned mismatch -C:\_projects\abc\src\bdd\cudd\cuddTable.c(2358) : warning C4146: unary minus operator applied to unsigned type, result still unsigned -cuddUtil.c -cuddWindow.c -cuddZddCount.c -cuddZddFuncs.c -cuddZddGroup.c -cuddZddIsop.c -cuddZddLin.c -cuddZddMisc.c -cuddZddPort.c -cuddZddReord.c -cuddZddSetop.c -cuddZddSymm.c -cuddZddUtil.c -epd.c -mtrBasic.c -mtrGroup.c -parseCore.c -parseStack.c -dsdApi.c -dsdCheck.c -dsdLocal.c -dsdMan.c -dsdProc.c -dsdTree.c -reoApi.c -reoCore.c -reoProfile.c -reoSift.c -reoSwap.c -reoTest.c -reoTransfer.c -reoUnits.c -mvc.c -mvcApi.c -mvcCompare.c -mvcContain.c -mvcCover.c -mvcCube.c -mvcDivide.c -mvcDivisor.c -mvcList.c -mvcLits.c -mvcMan.c -mvcOpAlg.c -mvcOpBool.c -mvcPrint.c -mvcSort.c -mvcUtils.c -ftFactor.c -ftPrint.c -added.c -solver.c -msatActivity.c -msatClause.c -msatClauseVec.c -msatMem.c -msatOrderJ.c -msatQueue.c -msatRead.c -msatSolverApi.c -msatSolverCore.c -msatSolverIo.c -msatSolverSearch.c -msatSort.c -msatVec.c -fraigApi.c -fraigCanon.c -fraigFanout.c -fraigFeed.c -fraigMan.c -fraigMem.c -fraigNode.c -fraigPrime.c -fraigSat.c -fraigTable.c -fraigUtil.c -fraigVec.c -fpga.c -fpgaCore.c -fpgaCreate.c -fpgaCut.c -fpgaCutUtils.c -fpgaFanout.c -fpgaLib.c -fpgaMatch.c -fpgaTime.c -fpgaTruth.c -fpgaUtils.c -fpgaVec.c -mapper.c -mapperCanon.c -mapperCore.c -mapperCreate.c -mapperCut.c -mapperCutUtils.c -mapperFanout.c -mapperLib.c -mapperMatch.c -mapperRefs.c -mapperSuper.c -mapperTable.c -mapperTime.c -mapperTree.c -mapperTruth.c -mapperUtils.c -mapperVec.c -mio.c -mioApi.c -mioFunc.c -mioRead.c -mioUtils.c -super.c -superAnd.c -superGate.c -superWrite.c -extraUtilBdd.c -extraUtilFile.c -extraUtilMemory.c -extraUtilMisc.c -extraUtilProgress.c -extraUtilReader.c -st.c -stmm.c -cpu_stats.c -cpu_time.c -datalimit.c -getopt.c -C:\_projects\abc\src\misc\util\getopt.c(64) : warning C4013: 'index' undefined; assuming extern returning int -C:\_projects\abc\src\misc\util\getopt.c(64) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int ' -pathsearch.c -C:\_projects\abc\src\misc\util\pathsearch.c(103) : warning C4013: 'index' undefined; assuming extern returning int -C:\_projects\abc\src\misc\util\pathsearch.c(103) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int ' -safe_mem.c -strsav.c -texpand.c +fxu.c Linking... -Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27CB.tmp" with contents +Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP44A.tmp" with contents [ -/nologo /o"Release/abc.bsc" -.\Release\abc.sbr -.\Release\abcAig.sbr -.\Release\abcAttach.sbr -.\Release\abcCheck.sbr -.\Release\abcCollapse.sbr -.\Release\abcCreate.sbr -.\Release\abcDfs.sbr -.\Release\abcDsd.sbr -.\Release\abcFanio.sbr -.\Release\abcFpga.sbr -.\Release\abcFraig.sbr -.\Release\abcFunc.sbr -.\Release\abcLatch.sbr -.\Release\abcMap.sbr -.\Release\abcMinBase.sbr -.\Release\abcMiter.sbr -.\Release\abcNames.sbr -.\Release\abcNetlist.sbr -.\Release\abcPrint.sbr -.\Release\abcRefs.sbr -.\Release\abcRenode.sbr -.\Release\abcSat.sbr -.\Release\abcSop.sbr -.\Release\abcStrash.sbr -.\Release\abcSweep.sbr -.\Release\abcTiming.sbr -.\Release\abcUtil.sbr -.\Release\abcVerify.sbr -.\Release\cmd.sbr -.\Release\cmdAlias.sbr -.\Release\cmdApi.sbr -.\Release\cmdFlag.sbr -.\Release\cmdHist.sbr -.\Release\cmdUtils.sbr -.\Release\io.sbr -.\Release\ioRead.sbr -.\Release\ioReadBench.sbr -.\Release\ioReadBlif.sbr -.\Release\ioReadVerilog.sbr -.\Release\ioWriteBench.sbr -.\Release\ioWriteBlif.sbr -.\Release\ioWriteBlifLogic.sbr -.\Release\ioWriteCnf.sbr -.\Release\ioWriteGate.sbr -.\Release\main.sbr -.\Release\mainFrame.sbr -.\Release\mainInit.sbr -.\Release\mainUtils.sbr -.\Release\cuddAddAbs.sbr -.\Release\cuddAddApply.sbr -.\Release\cuddAddFind.sbr -.\Release\cuddAddInv.sbr -.\Release\cuddAddIte.sbr -.\Release\cuddAddNeg.sbr -.\Release\cuddAddWalsh.sbr -.\Release\cuddAndAbs.sbr -.\Release\cuddAnneal.sbr -.\Release\cuddApa.sbr -.\Release\cuddAPI.sbr -.\Release\cuddApprox.sbr -.\Release\cuddBddAbs.sbr -.\Release\cuddBddCorr.sbr -.\Release\cuddBddIte.sbr -.\Release\cuddBridge.sbr -.\Release\cuddCache.sbr -.\Release\cuddCheck.sbr -.\Release\cuddClip.sbr -.\Release\cuddCof.sbr -.\Release\cuddCompose.sbr -.\Release\cuddDecomp.sbr -.\Release\cuddEssent.sbr -.\Release\cuddExact.sbr -.\Release\cuddExport.sbr -.\Release\cuddGenCof.sbr -.\Release\cuddGenetic.sbr -.\Release\cuddGroup.sbr -.\Release\cuddHarwell.sbr -.\Release\cuddInit.sbr -.\Release\cuddInteract.sbr -.\Release\cuddLCache.sbr -.\Release\cuddLevelQ.sbr -.\Release\cuddLinear.sbr -.\Release\cuddLiteral.sbr -.\Release\cuddMatMult.sbr -.\Release\cuddPriority.sbr -.\Release\cuddRead.sbr -.\Release\cuddRef.sbr -.\Release\cuddReorder.sbr -.\Release\cuddSat.sbr -.\Release\cuddSign.sbr -.\Release\cuddSolve.sbr -.\Release\cuddSplit.sbr -.\Release\cuddSubsetHB.sbr -.\Release\cuddSubsetSP.sbr -.\Release\cuddSymmetry.sbr -.\Release\cuddTable.sbr -.\Release\cuddUtil.sbr -.\Release\cuddWindow.sbr -.\Release\cuddZddCount.sbr -.\Release\cuddZddFuncs.sbr -.\Release\cuddZddGroup.sbr -.\Release\cuddZddIsop.sbr -.\Release\cuddZddLin.sbr -.\Release\cuddZddMisc.sbr -.\Release\cuddZddPort.sbr -.\Release\cuddZddReord.sbr -.\Release\cuddZddSetop.sbr -.\Release\cuddZddSymm.sbr -.\Release\cuddZddUtil.sbr -.\Release\epd.sbr -.\Release\mtrBasic.sbr -.\Release\mtrGroup.sbr -.\Release\parseCore.sbr -.\Release\parseStack.sbr -.\Release\dsdApi.sbr -.\Release\dsdCheck.sbr -.\Release\dsdLocal.sbr -.\Release\dsdMan.sbr -.\Release\dsdProc.sbr -.\Release\dsdTree.sbr -.\Release\reoApi.sbr -.\Release\reoCore.sbr -.\Release\reoProfile.sbr -.\Release\reoSift.sbr -.\Release\reoSwap.sbr -.\Release\reoTest.sbr -.\Release\reoTransfer.sbr -.\Release\reoUnits.sbr -.\Release\mvc.sbr -.\Release\mvcApi.sbr -.\Release\mvcCompare.sbr -.\Release\mvcContain.sbr -.\Release\mvcCover.sbr -.\Release\mvcCube.sbr -.\Release\mvcDivide.sbr -.\Release\mvcDivisor.sbr -.\Release\mvcList.sbr -.\Release\mvcLits.sbr -.\Release\mvcMan.sbr -.\Release\mvcOpAlg.sbr -.\Release\mvcOpBool.sbr -.\Release\mvcPrint.sbr -.\Release\mvcSort.sbr -.\Release\mvcUtils.sbr -.\Release\ftFactor.sbr -.\Release\ftPrint.sbr -.\Release\added.sbr -.\Release\solver.sbr -.\Release\msatActivity.sbr -.\Release\msatClause.sbr -.\Release\msatClauseVec.sbr -.\Release\msatMem.sbr -.\Release\msatOrderJ.sbr -.\Release\msatQueue.sbr -.\Release\msatRead.sbr -.\Release\msatSolverApi.sbr -.\Release\msatSolverCore.sbr -.\Release\msatSolverIo.sbr -.\Release\msatSolverSearch.sbr -.\Release\msatSort.sbr -.\Release\msatVec.sbr -.\Release\fraigApi.sbr -.\Release\fraigCanon.sbr -.\Release\fraigFanout.sbr -.\Release\fraigFeed.sbr -.\Release\fraigMan.sbr -.\Release\fraigMem.sbr -.\Release\fraigNode.sbr -.\Release\fraigPrime.sbr -.\Release\fraigSat.sbr -.\Release\fraigTable.sbr -.\Release\fraigUtil.sbr -.\Release\fraigVec.sbr -.\Release\fpga.sbr -.\Release\fpgaCore.sbr -.\Release\fpgaCreate.sbr -.\Release\fpgaCut.sbr -.\Release\fpgaCutUtils.sbr -.\Release\fpgaFanout.sbr -.\Release\fpgaLib.sbr -.\Release\fpgaMatch.sbr -.\Release\fpgaTime.sbr -.\Release\fpgaTruth.sbr -.\Release\fpgaUtils.sbr -.\Release\fpgaVec.sbr -.\Release\mapper.sbr -.\Release\mapperCanon.sbr -.\Release\mapperCore.sbr -.\Release\mapperCreate.sbr -.\Release\mapperCut.sbr -.\Release\mapperCutUtils.sbr -.\Release\mapperFanout.sbr -.\Release\mapperLib.sbr -.\Release\mapperMatch.sbr -.\Release\mapperRefs.sbr -.\Release\mapperSuper.sbr -.\Release\mapperTable.sbr -.\Release\mapperTime.sbr -.\Release\mapperTree.sbr -.\Release\mapperTruth.sbr -.\Release\mapperUtils.sbr -.\Release\mapperVec.sbr -.\Release\mio.sbr -.\Release\mioApi.sbr -.\Release\mioFunc.sbr -.\Release\mioRead.sbr -.\Release\mioUtils.sbr -.\Release\super.sbr -.\Release\superAnd.sbr -.\Release\superGate.sbr -.\Release\superWrite.sbr -.\Release\extraUtilBdd.sbr -.\Release\extraUtilFile.sbr -.\Release\extraUtilMemory.sbr -.\Release\extraUtilMisc.sbr -.\Release\extraUtilProgress.sbr -.\Release\extraUtilReader.sbr -.\Release\st.sbr -.\Release\stmm.sbr -.\Release\cpu_stats.sbr -.\Release\cpu_time.sbr -.\Release\datalimit.sbr -.\Release\getopt.sbr -.\Release\pathsearch.sbr -.\Release\safe_mem.sbr -.\Release\strsav.sbr -.\Release\texpand.sbr] -Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27CB.tmp" +/nologo /o"Debug/abc.bsc" +.\Debug\abc.sbr +.\Debug\abcAig.sbr +.\Debug\abcAttach.sbr +.\Debug\abcCheck.sbr +.\Debug\abcCollapse.sbr +.\Debug\abcCreate.sbr +.\Debug\abcDfs.sbr +.\Debug\abcDsd.sbr +.\Debug\abcFanio.sbr +.\Debug\abcFpga.sbr +.\Debug\abcFraig.sbr +.\Debug\abcFunc.sbr +.\Debug\abcLatch.sbr +.\Debug\abcMap.sbr +.\Debug\abcMinBase.sbr +.\Debug\abcMiter.sbr +.\Debug\abcNames.sbr +.\Debug\abcNetlist.sbr +.\Debug\abcPrint.sbr +.\Debug\abcRefs.sbr +.\Debug\abcRenode.sbr +.\Debug\abcSat.sbr +.\Debug\abcSop.sbr +.\Debug\abcStrash.sbr +.\Debug\abcSweep.sbr +.\Debug\abcTiming.sbr +.\Debug\abcUtil.sbr +.\Debug\abcVerify.sbr +.\Debug\cmd.sbr +.\Debug\cmdAlias.sbr +.\Debug\cmdApi.sbr +.\Debug\cmdFlag.sbr +.\Debug\cmdHist.sbr +.\Debug\cmdUtils.sbr +.\Debug\io.sbr +.\Debug\ioRead.sbr +.\Debug\ioReadBench.sbr +.\Debug\ioReadBlif.sbr +.\Debug\ioReadVerilog.sbr +.\Debug\ioWriteBench.sbr +.\Debug\ioWriteBlif.sbr +.\Debug\ioWriteBlifLogic.sbr +.\Debug\ioWriteCnf.sbr +.\Debug\ioWriteGate.sbr +.\Debug\main.sbr +.\Debug\mainFrame.sbr +.\Debug\mainInit.sbr +.\Debug\mainUtils.sbr +.\Debug\cuddAddAbs.sbr +.\Debug\cuddAddApply.sbr +.\Debug\cuddAddFind.sbr +.\Debug\cuddAddInv.sbr +.\Debug\cuddAddIte.sbr +.\Debug\cuddAddNeg.sbr +.\Debug\cuddAddWalsh.sbr +.\Debug\cuddAndAbs.sbr +.\Debug\cuddAnneal.sbr +.\Debug\cuddApa.sbr +.\Debug\cuddAPI.sbr +.\Debug\cuddApprox.sbr +.\Debug\cuddBddAbs.sbr +.\Debug\cuddBddCorr.sbr +.\Debug\cuddBddIte.sbr +.\Debug\cuddBridge.sbr +.\Debug\cuddCache.sbr +.\Debug\cuddCheck.sbr +.\Debug\cuddClip.sbr +.\Debug\cuddCof.sbr +.\Debug\cuddCompose.sbr +.\Debug\cuddDecomp.sbr +.\Debug\cuddEssent.sbr +.\Debug\cuddExact.sbr +.\Debug\cuddExport.sbr +.\Debug\cuddGenCof.sbr +.\Debug\cuddGenetic.sbr +.\Debug\cuddGroup.sbr +.\Debug\cuddHarwell.sbr +.\Debug\cuddInit.sbr +.\Debug\cuddInteract.sbr +.\Debug\cuddLCache.sbr +.\Debug\cuddLevelQ.sbr +.\Debug\cuddLinear.sbr +.\Debug\cuddLiteral.sbr +.\Debug\cuddMatMult.sbr +.\Debug\cuddPriority.sbr +.\Debug\cuddRead.sbr +.\Debug\cuddRef.sbr +.\Debug\cuddReorder.sbr +.\Debug\cuddSat.sbr +.\Debug\cuddSign.sbr +.\Debug\cuddSolve.sbr +.\Debug\cuddSplit.sbr +.\Debug\cuddSubsetHB.sbr +.\Debug\cuddSubsetSP.sbr +.\Debug\cuddSymmetry.sbr +.\Debug\cuddTable.sbr +.\Debug\cuddUtil.sbr +.\Debug\cuddWindow.sbr +.\Debug\cuddZddCount.sbr +.\Debug\cuddZddFuncs.sbr +.\Debug\cuddZddGroup.sbr +.\Debug\cuddZddIsop.sbr +.\Debug\cuddZddLin.sbr +.\Debug\cuddZddMisc.sbr +.\Debug\cuddZddPort.sbr +.\Debug\cuddZddReord.sbr +.\Debug\cuddZddSetop.sbr +.\Debug\cuddZddSymm.sbr +.\Debug\cuddZddUtil.sbr +.\Debug\epd.sbr +.\Debug\mtrBasic.sbr +.\Debug\mtrGroup.sbr +.\Debug\parseCore.sbr +.\Debug\parseStack.sbr +.\Debug\dsdApi.sbr +.\Debug\dsdCheck.sbr +.\Debug\dsdLocal.sbr +.\Debug\dsdMan.sbr +.\Debug\dsdProc.sbr +.\Debug\dsdTree.sbr +.\Debug\reoApi.sbr +.\Debug\reoCore.sbr +.\Debug\reoProfile.sbr +.\Debug\reoSift.sbr +.\Debug\reoSwap.sbr +.\Debug\reoTest.sbr +.\Debug\reoTransfer.sbr +.\Debug\reoUnits.sbr +.\Debug\mvc.sbr +.\Debug\mvcApi.sbr +.\Debug\mvcCompare.sbr +.\Debug\mvcContain.sbr +.\Debug\mvcCover.sbr +.\Debug\mvcCube.sbr +.\Debug\mvcDivide.sbr +.\Debug\mvcDivisor.sbr +.\Debug\mvcList.sbr +.\Debug\mvcLits.sbr +.\Debug\mvcMan.sbr +.\Debug\mvcOpAlg.sbr +.\Debug\mvcOpBool.sbr +.\Debug\mvcPrint.sbr +.\Debug\mvcSort.sbr +.\Debug\mvcUtils.sbr +.\Debug\ftFactor.sbr +.\Debug\ftPrint.sbr +.\Debug\added.sbr +.\Debug\solver.sbr +.\Debug\msatActivity.sbr +.\Debug\msatClause.sbr +.\Debug\msatClauseVec.sbr +.\Debug\msatMem.sbr +.\Debug\msatOrderJ.sbr +.\Debug\msatQueue.sbr +.\Debug\msatRead.sbr +.\Debug\msatSolverApi.sbr +.\Debug\msatSolverCore.sbr +.\Debug\msatSolverIo.sbr +.\Debug\msatSolverSearch.sbr +.\Debug\msatSort.sbr +.\Debug\msatVec.sbr +.\Debug\fraigApi.sbr +.\Debug\fraigCanon.sbr +.\Debug\fraigFanout.sbr +.\Debug\fraigFeed.sbr +.\Debug\fraigMan.sbr +.\Debug\fraigMem.sbr +.\Debug\fraigNode.sbr +.\Debug\fraigPrime.sbr +.\Debug\fraigSat.sbr +.\Debug\fraigTable.sbr +.\Debug\fraigUtil.sbr +.\Debug\fraigVec.sbr +.\Debug\fpga.sbr +.\Debug\fpgaCore.sbr +.\Debug\fpgaCreate.sbr +.\Debug\fpgaCut.sbr +.\Debug\fpgaCutUtils.sbr +.\Debug\fpgaFanout.sbr +.\Debug\fpgaLib.sbr +.\Debug\fpgaMatch.sbr +.\Debug\fpgaTime.sbr +.\Debug\fpgaTruth.sbr +.\Debug\fpgaUtils.sbr +.\Debug\fpgaVec.sbr +.\Debug\mapper.sbr +.\Debug\mapperCanon.sbr +.\Debug\mapperCore.sbr +.\Debug\mapperCreate.sbr +.\Debug\mapperCut.sbr +.\Debug\mapperCutUtils.sbr +.\Debug\mapperFanout.sbr +.\Debug\mapperLib.sbr +.\Debug\mapperMatch.sbr +.\Debug\mapperRefs.sbr +.\Debug\mapperSuper.sbr +.\Debug\mapperTable.sbr +.\Debug\mapperTime.sbr +.\Debug\mapperTree.sbr +.\Debug\mapperTruth.sbr +.\Debug\mapperUtils.sbr +.\Debug\mapperVec.sbr +.\Debug\mio.sbr +.\Debug\mioApi.sbr +.\Debug\mioFunc.sbr +.\Debug\mioRead.sbr +.\Debug\mioUtils.sbr +.\Debug\super.sbr +.\Debug\superAnd.sbr +.\Debug\superGate.sbr +.\Debug\superWrite.sbr +.\Debug\extraUtilBdd.sbr +.\Debug\extraUtilFile.sbr +.\Debug\extraUtilMemory.sbr +.\Debug\extraUtilMisc.sbr +.\Debug\extraUtilProgress.sbr +.\Debug\extraUtilReader.sbr +.\Debug\st.sbr +.\Debug\stmm.sbr +.\Debug\cpu_stats.sbr +.\Debug\cpu_time.sbr +.\Debug\datalimit.sbr +.\Debug\getopt.sbr +.\Debug\pathsearch.sbr +.\Debug\safe_mem.sbr +.\Debug\strsav.sbr +.\Debug\texpand.sbr +.\Debug\fxuUpdate.sbr +.\Debug\fxu.sbr +.\Debug\fxuCreate.sbr +.\Debug\fxuHeapD.sbr +.\Debug\fxuHeapS.sbr +.\Debug\fxuList.sbr +.\Debug\fxuMatrix.sbr +.\Debug\fxuPair.sbr +.\Debug\fxuPrint.sbr +.\Debug\fxuReduce.sbr +.\Debug\fxuSelect.sbr +.\Debug\fxuSingle.sbr +.\Debug\abcFxu.sbr] +Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP44A.tmp" Creating browse info file... <h3>Output Window</h3> <h3>Results</h3> -abc.exe - 0 error(s), 19 warning(s) +abc.exe - 0 error(s), 0 warning(s) </pre> </body> </html> @@ -11,7 +11,7 @@ alias r read alias rl read_blif alias rb read_bench alias rv read_verilog -alias rsup read_super +alias rsup read_super mcnc5_old.super alias rlib read_library alias sa set autoexec ps alias so source -x diff --git a/src/base/abc/abc.c b/src/base/abc/abc.c index f9bcde33..1179e400 100644 --- a/src/base/abc/abc.c +++ b/src/base/abc/abc.c @@ -22,6 +22,7 @@ #include "mainInt.h" #include "ft.h" #include "fraig.h" +#include "fxu.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -37,6 +38,7 @@ static int Ntk_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv static int Ntk_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Ntk_CommandFx ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -55,6 +57,7 @@ static int Ntk_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv static int Ntk_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Ntk_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Ntk_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -88,6 +91,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "balance", Ntk_CommandBalance, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "renode", Ntk_CommandRenode, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Ntk_CommandCleanup, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "fx", Ntk_CommandFx, 1 ); Cmd_CommandAdd( pAbc, "Various", "logic", Ntk_CommandLogic, 1 ); Cmd_CommandAdd( pAbc, "Various", "miter", Ntk_CommandMiter, 1 ); @@ -106,6 +110,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "SC mapping", "map", Ntk_CommandMap, 1 ); Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Ntk_CommandUnmap, 1 ); Cmd_CommandAdd( pAbc, "SC mapping", "attach", Ntk_CommandAttach, 1 ); + Cmd_CommandAdd( pAbc, "SC mapping", "sc", Ntk_CommandSuperChoice, 1 ); Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Ntk_CommandFpga, 1 ); @@ -750,6 +755,127 @@ usage: return 1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntk_CommandFx( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Abc_Ntk_t * pNtk; + FILE * pOut, * pErr; + Fxu_Data_t * p = NULL; + int c; + extern bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p ); + extern void Abc_NtkFxuFreeInfo( Fxu_Data_t * p ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // allocate the structure + p = ALLOC( Fxu_Data_t, 1 ); + memset( p, 0, sizeof(Fxu_Data_t) ); + // set the defaults + p->nPairsMax = 30000; + p->nNodesExt = 10000; + p->fOnlyS = 0; + p->fOnlyD = 0; + p->fUse0 = 0; + p->fUseCompl = 1; + p->fVerbose = 0; + util_getopt_reset(); + while ( (c = util_getopt(argc, argv, "lnsdzcvh")) != EOF ) + { + switch (c) + { + case 'l': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-l\" should be followed by an integer.\n" ); + goto usage; + } + p->nPairsMax = atoi(argv[util_optind]); + util_optind++; + if ( p->nPairsMax < 0 ) + goto usage; + break; + case 'n': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-n\" should be followed by an integer.\n" ); + goto usage; + } + p->nNodesExt = atoi(argv[util_optind]); + util_optind++; + if ( p->nNodesExt < 0 ) + goto usage; + break; + case 's': + p->fOnlyS ^= 1; + break; + case 'd': + p->fOnlyD ^= 1; + break; + case 'z': + p->fUse0 ^= 1; + break; + case 'c': + p->fUseCompl ^= 1; + break; + case 'v': + p->fVerbose ^= 1; + break; + case 'h': + goto usage; + break; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + Abc_NtkFxuFreeInfo( p ); + return 1; + } + + if ( Abc_NtkNodeNum(pNtk) == 0 ) + { + fprintf( pErr, "The network does not have internal nodes.\n" ); + Abc_NtkFxuFreeInfo( p ); + return 1; + } + + // the nodes to be merged are linked into the special linked list + Abc_NtkFastExtract( pNtk, p ); + Abc_NtkFxuFreeInfo( p ); + return 0; + +usage: + fprintf( pErr, "usage: fx [-n num] [-l num] [-sdzcvh]\n"); + fprintf( pErr, "\t performs unate fast extract on the current network\n"); + fprintf( pErr, "\t-n num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt ); + fprintf( pErr, "\t-l num : the maximum number of cube pairs to consider [default = %d]\n", p->nPairsMax ); + fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" ); + fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" ); + fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" ); + fprintf( pErr, "\t-c : use complement in the binary case [default = %s]\n", p->fUseCompl? "yes": "no" ); + fprintf( pErr, "\t-v : print verbose information [default = %s]\n", p->fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + Abc_NtkFxuFreeInfo( p ); + return 1; +} + + /**Function************************************************************* Synopsis [] @@ -1189,6 +1315,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) Fraig_Params_t Params; FILE * pOut, * pErr; Abc_Ntk_t * pNtk, * pNtkRes; + int fAllNodes; int c; pNtk = Abc_FrameReadNet(pAbc); @@ -1196,6 +1323,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) pErr = Abc_FrameReadErr(pAbc); // set defaults + fAllNodes = 0; Params.nPatsRand = 2048; // the number of words of random simulation info Params.nPatsDyna = 2048; // the number of words of dynamic simulation info Params.nBTLimit = 99; // the max number of backtracks to perform @@ -1208,7 +1336,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) Params.fVerbose = 0; // the verbosiness flag Params.fVerboseP = 0; // the verbosiness flag util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "RDBrscpvh" ) ) != EOF ) + while ( ( c = util_getopt( argc, argv, "RDBrscpvah" ) ) != EOF ) { switch ( c ) { @@ -1262,7 +1390,9 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'v': Params.fVerbose ^= 1; break; - + case 'a': + fAllNodes ^= 1; + break; case 'h': goto usage; default: @@ -1286,11 +1416,11 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( Abc_NtkIsAig(pNtk) ) - pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 ); + pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes ); else { pNtk = Abc_NtkStrash( pNtk ); - pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 ); + pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes ); Abc_NtkDelete( pNtk ); } if ( pNtkRes == NULL ) @@ -1308,7 +1438,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: sprintf( Buffer, "%d", Params.nBTLimit ); - fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvh]\n" ); + fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvah]\n" ); fprintf( pErr, "\t transforms a logic network into a functionally reduced AIG\n" ); fprintf( pErr, "\t-R num : number of random patterns (127 < num < 32769) [default = %d]\n", Params.nPatsRand ); fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", Params.nPatsDyna ); @@ -1318,6 +1448,7 @@ usage: fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", Params.fChoicing? "yes": "no" ); fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", Params.fTryProve? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", Params.fVerbose? "yes": "no" ); + fprintf( pErr, "\t-a : toggle between all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "dfs" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -1890,6 +2021,72 @@ usage: return 1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntk_CommandSuperChoice( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsAig(pNtk) ) + { + fprintf( pErr, "Works only for the AIG representation.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkSuperChoice( pNtk ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Superchoicing has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: sc [-h]\n" ); + fprintf( pErr, "\t performs superchoicing\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index d918cbc2..35fa85e9 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -480,6 +480,7 @@ extern bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose ); extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk ); /*=== abcSop.c ==========================================================*/ extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ); +extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ); extern int Abc_SopGetCubeNum( char * pSop ); extern int Abc_SopGetLitNum( char * pSop ); extern int Abc_SopGetVarNum( char * pSop ); diff --git a/src/base/abc/abcAttach.c b/src/base/abc/abcAttach.c index 9d9c378f..950ecc1d 100644 --- a/src/base/abc/abcAttach.c +++ b/src/base/abc/abcAttach.c @@ -267,6 +267,8 @@ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uT } uTruthRes[0] |= uSignCube[0]; } + if ( Abc_SopGetPhase(pSop) == 0 ) + uTruthRes[0] = ~uTruthRes[0]; if ( nInputs < 5 ) uTruthRes[0] &= ATTACH_MASK(1<<nInputs); } @@ -295,6 +297,13 @@ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uT uTruthRes[0] |= uSignCube[0]; uTruthRes[1] |= uSignCube[1]; } + + // complement if the SOP is complemented + if ( Abc_SopGetPhase(pSop) == 0 ) + { + uTruthRes[0] = ~uTruthRes[0]; + uTruthRes[1] = ~uTruthRes[1]; + } } } diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index 7b330b95..5c75a94c 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -223,9 +223,12 @@ int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk ) } else { - Abc_NtkForEachCo( pNtk, pNode, i ) +// Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_NtkForEachNode( pNtk, pNode, i ) { - pDriver = Abc_ObjFanin0( pNode ); +// pDriver = Abc_ObjFanin0( pNode ); + pDriver = pNode; + Abc_NtkGetLevelNum_rec( pDriver ); if ( LevelsMax < pDriver->Level ) LevelsMax = pDriver->Level; diff --git a/src/base/abc/abcFxu.c b/src/base/abc/abcFxu.c new file mode 100644 index 00000000..99f37dfc --- /dev/null +++ b/src/base/abc/abcFxu.c @@ -0,0 +1,262 @@ +/**CFile**************************************************************** + + FileName [abcFxu.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface with the fast extract package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcFxu.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fxu.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk ); +static void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p ); +static void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Performs fast_extract on the current network.] + + Description [Takes the network and the maximum number of nodes to extract. + Uses the concurrent double-cube and single cube divisor extraction procedure. + Modifies the network in the end, after extracting all nodes. Note that + Ntk_NetworkSweep() may increase the performance of this procedure because + the single-literal nodes will not be created in the sparse matrix. Returns 1 + if the network has been changed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p ) +{ + assert( Abc_NtkIsLogicBdd(pNtk) || Abc_NtkIsLogicSop(pNtk) ); + // convert nodes to SOPs + if ( Abc_NtkIsLogicBdd(pNtk) ) + Abc_NtkBddToSop(pNtk); + else + { // to make sure the SOPs are SCC-free +// Abc_NtkSopToBdd(pNtk); +// Abc_NtkBddToSop(pNtk); + } + // check if the network meets the requirements + if ( !Abc_NtkFxuCheck(pNtk) ) + { + printf( "Abc_NtkFastExtract: Nodes have duplicated or complemented fanins. FXU is not performed.\n" ); + return 0; + } + // sweep removes useless nodes + Abc_NtkCleanup( pNtk, 0 ); + // collect information about the covers + // make sure all covers are SCC free + // allocate literal array for each cover + Abc_NtkFxuCollectInfo( pNtk, p ); + // call the fast extract procedure + // returns the number of divisor extracted + if ( Fxu_FastExtract(p) > 0 ) + { + // update the network + Abc_NtkFxuReconstruct( pNtk, p ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtk ) ) + printf( "Abc_NtkFastExtract: The network check has failed.\n" ); + return 1; + } + return 0; +} + + +/**Function************************************************************* + + Synopsis [Makes sure the nodes do not have complemented and duplicated fanins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode, * pFanin1, * pFanin2; + int n, i, k; + Abc_NtkForEachNode( pNtk, pNode, n ) + { + Abc_ObjForEachFanin( pNode, pFanin1, i ) + { + if ( Abc_ObjFaninC(pNode, i) ) + return 0; + Abc_ObjForEachFanin( pNode, pFanin2, k ) + { + if ( i == k ) + continue; + if ( pFanin1 == pFanin2 ) + return 0; + } + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collect information about the network for fast_extract.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p ) +{ + Abc_Obj_t * pNode; + int i; + // add information to the manager + p->pManSop = pNtk->pManFunc; + p->vSops = Vec_PtrAlloc(0); + p->vFanins = Vec_PtrAlloc(0); + p->vSopsNew = Vec_PtrAlloc(0); + p->vFaninsNew = Vec_PtrAlloc(0); + Vec_PtrFill( p->vSops, pNtk->vObjs->nSize, NULL ); + Vec_PtrFill( p->vFanins, pNtk->vObjs->nSize, NULL ); + Vec_PtrFill( p->vSopsNew, pNtk->vObjs->nSize + p->nNodesExt, NULL ); + Vec_PtrFill( p->vFaninsNew, pNtk->vObjs->nSize + p->nNodesExt, NULL ); + // add SOPs and fanin array + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( Abc_SopGetVarNum(pNode->pData) < 2 ) + continue; + if ( Abc_SopGetCubeNum(pNode->pData) < 1 ) + continue; + p->vSops->pArray[i] = pNode->pData; + p->vFanins->pArray[i] = &pNode->vFanins; + } + p->nNodesOld = pNtk->vObjs->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFxuFreeInfo( Fxu_Data_t * p ) +{ + int i; + // free the arrays of new fanins + if ( p->vFaninsNew ) + for ( i = 0; i < p->vFaninsNew->nSize; i++ ) + if ( p->vFaninsNew->pArray[i] ) + Vec_IntFree( p->vFaninsNew->pArray[i] ); + // free the arrays + if ( p->vSops ) Vec_PtrFree( p->vSops ); + if ( p->vSopsNew ) Vec_PtrFree( p->vSopsNew ); + if ( p->vFanins ) Vec_PtrFree( p->vFanins ); + if ( p->vFaninsNew ) Vec_PtrFree( p->vFaninsNew ); + FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Recostructs the network after FX.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p ) +{ + Vec_Fan_t * vFaninsOld; + Vec_Int_t * vFanins; + Abc_Obj_t * pNode, * pFanin; + int i, k; + + assert( p->vFanins->nSize < p->vFaninsNew->nSize ); + // create the new nodes + for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ ) + { + // start the node + pNode = Abc_NtkCreateNode( pNtk ); + assert( i == (int)pNode->Id ); + } + // update the old nodes + for ( i = 0; i < p->vFanins->nSize; i++ ) + { + // the new array of fanins + vFanins = p->vFaninsNew->pArray[i]; + if ( vFanins == NULL ) + continue; + // remove old fanins + pNode = Abc_NtkObj( pNtk, i ); + vFaninsOld = &pNode->vFanins; + for ( k = vFaninsOld->nSize - 1; k >= 0; k-- ) + { + pFanin = Abc_NtkObj( pNtk, vFaninsOld->pArray[k].iFan ); + Abc_ObjDeleteFanin( pNode, pFanin ); + } + // add new fanins + vFanins = p->vFaninsNew->pArray[i]; + for ( k = 0; k < vFanins->nSize; k++ ) + { + pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] ); + Abc_ObjAddFanin( pNode, pFanin ); + } + pNode->pData = p->vSopsNew->pArray[i]; + assert( pNode->pData != NULL ); + } + // set up the new nodes + for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ ) + { + // get the new node + pNode = Abc_NtkObj( pNtk, i ); + // add the fanins + vFanins = p->vFaninsNew->pArray[i]; + for ( k = 0; k < vFanins->nSize; k++ ) + { + pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] ); + Abc_ObjAddFanin( pNode, pFanin ); + } + pNode->pData = p->vSopsNew->pArray[i]; + assert( pNode->pData != NULL ); + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abc/abcMap.c b/src/base/abc/abcMap.c index ca326ea1..7289b47b 100644 --- a/src/base/abc/abcMap.c +++ b/src/base/abc/abcMap.c @@ -33,6 +33,12 @@ static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNode static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ); static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ); static Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode ); + +static Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk ); +static void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ); +static void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase ); +static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// @@ -53,8 +59,8 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int { int fCheck = 1; Abc_Ntk_t * pNtkNew; - Map_Man_t * pMan; + int clk; assert( Abc_NtkIsAig(pNtk) ); @@ -81,11 +87,13 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, fVerbose ); if ( pMan == NULL ) return NULL; +clk = clock(); if ( !Map_Mapping( pMan ) ) { Map_ManFree( pMan ); return NULL; } + Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), clock()-clk ); // reconstruct the network after mapping pNtkNew = Abc_NtkFromMap( pMan, pNtk ); @@ -432,6 +440,265 @@ Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode ) + + + + +/**Function************************************************************* + + Synopsis [Interface with the mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + + Map_Man_t * pMan; + + assert( Abc_NtkIsAig(pNtk) ); + + // check that the library is available + if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL ) + { + printf( "The current library is not available.\n" ); + return 0; + } + + // derive the supergate library + if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) ) + { + printf( "A simple supergate library is derived from gate library \"%s\".\n", + Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) ); + Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) ); + } + + // print a warning about choice nodes + if ( Abc_NtkCountChoiceNodes( pNtk ) ) + printf( "Performing mapping with choices.\n" ); + + // perform the mapping + pMan = Abc_NtkToMap( pNtk, -1, 1, 0 ); + if ( pMan == NULL ) + return NULL; + if ( !Map_Mapping( pMan ) ) + { + Map_ManFree( pMan ); + return NULL; + } + + // reconstruct the network after mapping + pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk ); + if ( pNtkNew == NULL ) + return NULL; + Map_ManFree( pMan ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkMap: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + + +/**Function************************************************************* + + Synopsis [Creates the mapped network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) +{ + ProgressBar * pProgress; + Abc_Ntk_t * pNtkNew, * pNtkNew2; + Abc_Obj_t * pNode; + int i; + + // save the pointer to the mapped nodes + Abc_NtkForEachCi( pNtk, pNode, i ) + pNode->pNext = pNode->pCopy; + Abc_NtkForEachPo( pNtk, pNode, i ) + pNode->pNext = pNode->pCopy; + Abc_NtkForEachNode( pNtk, pNode, i ) + pNode->pNext = pNode->pCopy; + + // duplicate the network + pNtkNew2 = Abc_NtkDup( pNtk ); + pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1 ); + Abc_NtkBddToSop( pNtkNew ); + + // set the old network to point to the new network + Abc_NtkForEachCi( pNtk, pNode, i ) + pNode->pCopy = pNode->pCopy->pCopy; + Abc_NtkForEachPo( pNtk, pNode, i ) + pNode->pCopy = pNode->pCopy->pCopy; + Abc_NtkForEachNode( pNtk, pNode, i ) + pNode->pCopy = pNode->pCopy->pCopy; + Abc_NtkDelete( pNtkNew2 ); + + // set the pointers from the mapper to the new nodes + Abc_NtkForEachCi( pNtk, pNode, i ) + { + Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) ); + Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy ); + } + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( Abc_NodeIsConst(pNode) ) + continue; + Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) ); + Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy ); + } + + // assign the mapping of the required phase to the POs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( Abc_NodeIsConst(pNode) ) + continue; + Abc_NodeSuperChoice( pNtkNew, pNode ); + } + Extra_ProgressBarStop( pProgress ); + return pNtkNew; +} + + +/**Function************************************************************* + + Synopsis [Creates the mapped network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) +{ + Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext; + Map_Cut_t * pCuts, * pTemp; + + pCuts = Map_NodeReadCuts(pMapNode); + for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) ) + { + Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 ); + Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 ); + } +} + + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase ) +{ + Abc_Obj_t * pNodePIs[10]; + Map_Node_t ** ppLeaves; + Map_Super_t * pSuperBest; + unsigned uPhaseBest; + int i, fInvPin, nLeaves; + + pSuperBest = Map_CutReadSuperBest( pCut, fPhase ); + if ( pSuperBest == NULL ) + return; + + // get the information about the best cut + uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase ); + nLeaves = Map_CutReadLeavesNum( pCut ); + ppLeaves = Map_CutReadLeaves( pCut ); + + // collect the PI nodes + for ( i = 0; i < nLeaves; i++ ) + { + fInvPin = ((uPhaseBest & (1 << i)) > 0); + pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin ); + assert( pNodePIs[i] != NULL ); + } + + // implement the supergate + Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves ); +} + + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ) +{ + Mio_Gate_t * pRoot; + Map_Super_t ** ppFanins; + Abc_Obj_t * pNodeNew, * pNodeFanin; + int nFanins, Number, i; + + // get the parameters of the supergate + pRoot = Map_SuperReadRoot(pSuper); + if ( pRoot == NULL ) + { + Number = Map_SuperReadNum(pSuper); + if ( Number < nNodePis ) + { + return pNodePis[Number]; + } + else + { +// assert( 0 ); + /* It might happen that a super gate with 5 inputs is constructed that + * actually depends only on the first four variables; i.e the fifth is a + * don't care -- in that case we connect constant node for the fifth + * (since the cut only has 4 variables). An interesting question is what + * if the first variable (and not the fifth one is the redundant one; + * can that happen?) */ + return Abc_NodeCreateConst0(pNtkNew); + } + } + + // get information about the fanins of the supergate + nFanins = Map_SuperReadFaninNum( pSuper ); + ppFanins = Map_SuperReadFanins( pSuper ); + // create a new node with these fanins + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < nFanins; i++ ) + { + pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis ); + Abc_ObjAddFanin( pNodeNew, pNodeFanin ); + } + pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Mio_GateReadSop(pRoot) ); + return pNodeNew; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index 671fa9bc..0b7b44a0 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -67,7 +67,12 @@ Abc_Ntk_t * Abc_NtkLogic( Abc_Ntk_t * pNtk ) Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); // create and connect the POs Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy ); + { + if ( Abc_ObjFaninNum(pObj) == 0 ) + Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), pObj->pCopy ); + else + Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy ); + } // connect the latches Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy ); diff --git a/src/base/abc/abcPrint.c b/src/base/abc/abcPrint.c index 0c3a2b5e..49b6db72 100644 --- a/src/base/abc/abcPrint.c +++ b/src/base/abc/abcPrint.c @@ -59,7 +59,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk ) if ( Abc_NtkIsLogicSop(pNtk) ) { fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) ); -// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) ); + fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) ); fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) ); } else if ( Abc_NtkIsLogicBdd(pNtk) ) diff --git a/src/base/abc/abcRenode.c b/src/base/abc/abcRenode.c index 6a24ab80..ab1a09c3 100644 --- a/src/base/abc/abcRenode.c +++ b/src/base/abc/abcRenode.c @@ -130,6 +130,8 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) Abc_NtkForEachCo( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( Abc_ObjIsTerm(Abc_ObjFanin0(pNode)) ) + continue; Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) ); } Extra_ProgressBarStop( pProgress ); diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index 9862ea8e..aabc2660 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -61,6 +61,37 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ) /**Function************************************************************* + Synopsis [Starts the constant 1 cover with the given number of variables and cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ) +{ + char * pSopCover; + char * pCube; + int i, v; + pSopCover = Extra_MmFlexEntryFetch( pMan, nCubes * (nVars + 3) + 1 ); + for ( i = 0; i < nCubes; i++ ) + { + pCube = pSopCover + i * (nVars + 3); + for ( v = 0; v < nVars; v++ ) + pCube[v] = '-'; + pCube[nVars + 0] = ' '; + pCube[nVars + 1] = '1'; + pCube[nVars + 2] = '\n'; + } + pSopCover[nCubes * (nVars + 3)] = 0; + return pSopCover; +} + + +/**Function************************************************************* + Synopsis [Reads the number of cubes in the cover.] Description [] diff --git a/src/base/abc/abcStrash.c b/src/base/abc/abcStrash.c index eb5b3df7..fcfeefda 100644 --- a/src/base/abc/abcStrash.c +++ b/src/base/abc/abcStrash.c @@ -107,6 +107,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) // perform strashing vNodes = Abc_NtkDfs( pNtk ); +// vNodes = Abc_AigCollectAll( pNtk ); pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); for ( i = 0; i < vNodes->nSize; i++ ) { diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 1c826f95..e971ca18 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -768,6 +768,11 @@ Vec_Ptr_t * Abc_AigCollectAll( Abc_Ntk_t * pNtk ) vNodes = Vec_PtrAlloc( 100 ); Abc_NtkForEachNode( pNtk, pNode, i ) Vec_PtrPush( vNodes, pNode ); + + // works only if the levels are set!!! + if ( !Abc_NtkIsAig(pNtk) ) + Abc_NtkGetLevelNum(pNtk); + Vec_PtrSort( vNodes, Abc_NodeCompareLevelsIncrease ); return vNodes; } diff --git a/src/base/abc/abc_.c b/src/base/abc/abc_.c new file mode 100644 index 00000000..bef3836f --- /dev/null +++ b/src/base/abc/abc_.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [abc_.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: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c index 37726542..457c2384 100644 --- a/src/map/fpga/fpgaCore.c +++ b/src/map/fpga/fpgaCore.c @@ -127,12 +127,19 @@ int Fpga_MappingPostProcess( Fpga_Man_t * p ) float aSwitchTotalPrev, aSwitchTotalCur; int Iter, clk; + if ( p->fVerbose ) { printf( "Iteration %dD : Area = %11.1f ", 0, Fpga_MappingArea( p ) ); PRT( "Time", p->timeMatch ); } + +// Fpga_MappingExplore( p ); +// p->fAreaGlo = Fpga_MappingArea( p ); +// return; + + // aAreaTotalCur = FPGA_FLOAT_LARGE; aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); @@ -159,6 +166,11 @@ PRT( "Time", clock() - clk ); } while ( aAreaTotalPrev > 1.02 * aAreaTotalCur ); +// Fpga_MappingExplore( p ); +// p->fAreaGlo = Fpga_MappingArea( p ); +// return; + + /* // compute the area of each cut aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h index 0fea9ec8..63308d53 100644 --- a/src/map/fpga/fpgaInt.h +++ b/src/map/fpga/fpgaInt.h @@ -334,6 +334,7 @@ extern float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p ); extern void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p ); extern void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired ); extern void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes ); +extern void Fpga_TimePropagateArrival( Fpga_Man_t * p ); /*=== fpgaTruth.c ===============================================================*/ extern void Fpga_MappingTruths( Fpga_Man_t * pMan ); /*=== fpgaVec.c =============================================================*/ @@ -368,6 +369,7 @@ extern float Fpga_MappingGetAreaFlow( Fpga_Man_t * p ); extern float Fpga_MappingArea( Fpga_Man_t * pMan ); extern float Fpga_MappingComputeCutAreas( Fpga_Man_t * pMan ); extern float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan ); +extern Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan ); extern int Fpga_MappingCountLevels( Fpga_Man_t * pMan ); extern void Fpga_MappingUnmark( Fpga_Man_t * pMan ); extern void Fpga_MappingUnmark_rec( Fpga_Node_t * pNode ); diff --git a/src/map/fpga/fpgaMatch.c b/src/map/fpga/fpgaMatch.c index 8668ce4b..599662f7 100644 --- a/src/map/fpga/fpgaMatch.c +++ b/src/map/fpga/fpgaMatch.c @@ -724,6 +724,112 @@ clk = clock(); } #endif + + +/**function************************************************************* + + synopsis [Performs area minimization using a heuristic algorithm.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Fpga_FindBestNode( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes, Fpga_Node_t ** ppNode, Fpga_Cut_t ** ppCutBest ) +{ + Fpga_Node_t * pNode; + Fpga_Cut_t * pCut; + float Gain, CutArea1, CutArea2, CutArea3; + int i; + + Gain = 0; + for ( i = 0; i < vNodes->nSize; i++ ) + { + pNode = vNodes->pArray[i]; + // deref the current cut + CutArea1 = Fpga_CutDeref( p, pNode, pNode->pCutBest, 0 ); + + // ref all the cuts + for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext ) + { + if ( pCut == pNode->pCutBest ) + continue; + if ( pCut->tArrival > pNode->tRequired ) + continue; + + CutArea2 = Fpga_CutGetAreaDerefed( p, pCut ); + if ( Gain < CutArea1 - CutArea2 ) + { + *ppNode = pNode; + *ppCutBest = pCut; + Gain = CutArea1 - CutArea2; + } + } + // ref the old cut + CutArea3 = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 ); + assert( CutArea1 == CutArea3 ); + } + if ( Gain == 0 ) + printf( "Returning no gain.\n" ); + + return Gain; +} + +/**function************************************************************* + + synopsis [Performs area minimization using a heuristic algorithm.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +void Fpga_MappingExplore( Fpga_Man_t * p ) +{ + Fpga_Cut_t * pCutBest; + Fpga_Node_t * pNodeBest; + Fpga_NodeVec_t * vNodes; + float Area, Gain, CutArea1, CutArea2; + int i; + + // compute the arrival times + Fpga_TimePropagateArrival( p ); + p->fRequiredGlo = Fpga_TimeComputeArrivalMax( p ); + Fpga_TimeComputeRequired( p, p->fRequiredGlo ); + + // assign the refs + Area = Fpga_MappingSetRefsAndArea( p ); + // collect the nodes + vNodes = Fpga_MappingCollectRefed( p ); + // find the best node to update + for ( i = 0; Gain = Fpga_FindBestNode(p, vNodes, &pNodeBest, &pCutBest); i++ ) + { + // update the node + assert( pNodeBest->pCutBest != pCutBest ); + // deref the current cut + CutArea1 = Fpga_CutDeref( p, pNodeBest, pNodeBest->pCutBest, 0 ); + // ref the new cut + CutArea2 = Fpga_CutRef( p, pNodeBest, pCutBest, 0 ); + assert( CutArea1 - CutArea2 == Gain ); + printf( "Iteration %2d: Gain = %5.2f.\n", i, Gain ); + // update the node + pNodeBest->pCutBest = pCutBest; + // collect new nodes + Fpga_NodeVecFree( vNodes ); + vNodes = Fpga_MappingCollectRefed( p ); + // compute the arrival and required times + Fpga_TimePropagateArrival( p ); + Fpga_TimeComputeRequired( p, p->fRequiredGlo ); + } + + +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/fpga/fpgaTime.c b/src/map/fpga/fpgaTime.c index df98faa1..066ae215 100644 --- a/src/map/fpga/fpgaTime.c +++ b/src/map/fpga/fpgaTime.c @@ -182,6 +182,34 @@ void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes ) } + +/**Function************************************************************* + + Synopsis [Computes the required times of all nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fpga_TimePropagateArrival( Fpga_Man_t * p ) +{ + Fpga_Node_t * pNode; + Fpga_Cut_t * pCut; + int i; + + // clean the required times and the fanout counts for all nodes + for ( i = 0; i < p->vAnds->nSize; i++ ) + { + pNode = p->vAnds->pArray[i]; + for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext ) + pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut ); + } +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/fpga/fpgaUtils.c b/src/map/fpga/fpgaUtils.c index a5b2cb32..fc67d52b 100644 --- a/src/map/fpga/fpgaUtils.c +++ b/src/map/fpga/fpgaUtils.c @@ -493,6 +493,32 @@ float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode ) /**Function************************************************************* + Synopsis [Collect the referenced nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan ) +{ + Fpga_NodeVec_t * vNodes; + int i; + vNodes = Fpga_NodeVecAlloc( 100 ); + for ( i = 0; i < pMan->vNodesAll->nSize; i++ ) + { + if ( Fpga_NodeIsVar(pMan->vNodesAll->pArray[i]) ) + continue; + if ( pMan->vNodesAll->pArray[i]->nRefs ) + Fpga_NodeVecPush( vNodes, pMan->vNodesAll->pArray[i] ); + } + return vNodes; +} + +/**Function************************************************************* + Synopsis [Computes the number of logic levels not counting PIs/POs.] Description [] diff --git a/src/map/mapper/mapper.h b/src/map/mapper/mapper.h index a6bfccf8..9ef8ee17 100644 --- a/src/map/mapper/mapper.h +++ b/src/map/mapper/mapper.h @@ -82,6 +82,8 @@ extern Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ); extern Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ); extern Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p ); extern bool Map_ManReadVerbose( Map_Man_t * p ); +extern float Map_ManReadAreaFinal( Map_Man_t * p ); +extern float Map_ManReadRequiredGlo( Map_Man_t * p ); extern void Map_ManSetTimeToMap( Map_Man_t * p, int Time ); extern void Map_ManSetTimeToNet( Map_Man_t * p, int Time ); extern void Map_ManSetTimeSweep( Map_Man_t * p, int Time ); @@ -125,6 +127,7 @@ extern Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p ); extern unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase ); extern unsigned Map_CutReadPhase0( Map_Cut_t * p ); extern unsigned Map_CutReadPhase1( Map_Cut_t * p ); +extern Map_Cut_t * Map_CutReadNext( Map_Cut_t * p ); extern char * Map_SuperReadFormula( Map_Super_t * p ); extern Mio_Gate_t * Map_SuperReadRoot( Map_Super_t * p ); diff --git a/src/map/mapper/mapperCore.c b/src/map/mapper/mapperCore.c index 415e4974..e72b9134 100644 --- a/src/map/mapper/mapperCore.c +++ b/src/map/mapper/mapperCore.c @@ -82,8 +82,8 @@ int Map_Mapping( Map_Man_t * p ) p->AreaBase = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "Delay : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ", - 0, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 ); +printf( "Delay : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 ); PRT( "Time", p->timeMatch ); } ////////////////////////////////////////////////////////////////////// @@ -103,8 +103,8 @@ PRT( "Time", p->timeMatch ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "AreaFlow : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ", - 0, Map_MappingGetAreaFlow(p), p->AreaFinal, +printf( "AreaFlow : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); PRT( "Time", clock() - clk ); } @@ -127,8 +127,8 @@ PRT( "Time", clock() - clk ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "Area : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ", - 0, 0.0, p->AreaFinal, +printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + p->fRequiredGlo, 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); PRT( "Time", clock() - clk ); } @@ -151,8 +151,8 @@ PRT( "Time", clock() - clk ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "Area : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ", - 0, 0.0, p->AreaFinal, +printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + p->fRequiredGlo, 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); PRT( "Time", clock() - clk ); } diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c index 61c90d1c..4d7ca7d0 100644 --- a/src/map/mapper/mapperCreate.c +++ b/src/map/mapper/mapperCreate.c @@ -52,6 +52,8 @@ Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ) { return Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ) { return p->pInputArrivals;} Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p ) { return p->pSuperLib->pGenlib; } bool Map_ManReadVerbose( Map_Man_t * p ) { return p->fVerbose; } +float Map_ManReadAreaFinal( Map_Man_t * p ) { return p->AreaFinal; } +float Map_ManReadRequiredGlo( Map_Man_t * p ) { return p->fRequiredGlo; } void Map_ManSetTimeToMap( Map_Man_t * p, int Time ) { p->timeToMap = Time; } void Map_ManSetTimeToNet( Map_Man_t * p, int Time ) { p->timeToNet = Time; } void Map_ManSetTimeSweep( Map_Man_t * p, int Time ) { p->timeSweep = Time; } @@ -126,6 +128,7 @@ Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p ) { return p->pp unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].uPhaseBest;} unsigned Map_CutReadPhase0( Map_Cut_t * p ) { return p->M[0].uPhaseBest;} unsigned Map_CutReadPhase1( Map_Cut_t * p ) { return p->M[1].uPhaseBest;} +Map_Cut_t * Map_CutReadNext( Map_Cut_t * p ) { return p->pNext; } /**Function************************************************************* @@ -190,7 +193,8 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose ) p->pSuperLib = Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()); p->nVarsMax = p->pSuperLib->nVarsMax; p->fVerbose = fVerbose; - p->fEpsilon = (float)0.00001; +// p->fEpsilon = (float)0.00001; + p->fEpsilon = (float)0.001; assert( p->nVarsMax > 0 ); // start various data structures @@ -210,6 +214,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose ) p->vMapping = Map_NodeVecAlloc( 100 ); p->vInside = Map_NodeVecAlloc( 100 ); p->vFanins = Map_NodeVecAlloc( 100 ); + p->vVisited = Map_NodeVecAlloc( 100 ); // create the PI nodes p->nInputs = nInputs; @@ -253,6 +258,8 @@ void Map_ManFree( Map_Man_t * p ) Map_NodeVecFree( p->vNodesTemp ); if ( p->vMapping ) Map_NodeVecFree( p->vMapping ); + if ( p->vVisited ) + Map_NodeVecFree( p->vVisited ); Extra_MmFixedStop( p->mmNodes, 0 ); Extra_MmFixedStop( p->mmCuts, 0 ); FREE( p->pInputArrivals ); diff --git a/src/map/mapper/mapperCut.c b/src/map/mapper/mapperCut.c index 87592365..8566c819 100644 --- a/src/map/mapper/mapperCut.c +++ b/src/map/mapper/mapperCut.c @@ -23,9 +23,9 @@ //////////////////////////////////////////////////////////////////////// // the largest number of cuts considered -#define MAP_CUTS_MAX_COMPUTE 200 +#define MAP_CUTS_MAX_COMPUTE 1000 // the largest number of cuts used -#define MAP_CUTS_MAX_USE 50 +#define MAP_CUTS_MAX_USE 250 // temporary hash table to store the cuts typedef struct Map_CutTableStrutct_t Map_CutTable_t; @@ -373,6 +373,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable, pTemp1 = ppArray1[i]; pTemp2 = ppArray2[k]; + if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax ) + { + if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] ) + continue; + if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] ) + continue; + } + // check if k-feasible cut exists nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax ); if ( nNodes == 0 ) @@ -397,6 +405,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable, pTemp1 = ppArray1[k]; pTemp2 = ppArray2[i]; + if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax ) + { + if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] ) + continue; + if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] ) + continue; + } + // check if k-feasible cut exists nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax ); if ( nNodes == 0 ) @@ -424,6 +440,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable, pTemp1 = ppArray1[k]; pTemp2 = ppArray2[i]; + if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax ) + { + if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] ) + continue; + if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] ) + continue; + } + // check if k-feasible cut exists nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax ); if ( nNodes == 0 ) diff --git a/src/map/mapper/mapperInt.h b/src/map/mapper/mapperInt.h index c5ecce73..d4262abb 100644 --- a/src/map/mapper/mapperInt.h +++ b/src/map/mapper/mapperInt.h @@ -121,6 +121,7 @@ struct Map_ManStruct_t_ unsigned uTruthsLarge[10][32]; // the elementary truth tables int nCounts[32]; // the counter of minterms int nCountsBest[32];// the counter of minterms + Map_NodeVec_t * vVisited; // the visited cuts during cut computation // simulation info from the FRAIG manager int nSimRounds; // the number of words in the simulation info @@ -262,13 +263,7 @@ struct Map_CutStruct_t_ char nVolume; // the volume of this cut char fMark; // the mark to denote visited cut char Phase; // the mark to denote complemented cut -// float fLevel; // the average level of the fanins - - unsigned uTruthTemp[2]; // the temporary truth table used to derive other cuts - unsigned uTruthZero[2]; // the temporary truth table used to derive other cuts - unsigned uTruthDc[2]; // the don't-cares (SDCs) computed for this cut - - Map_Match_t M[2]; // the matches for the positive/negative phase + Map_Match_t M[2]; // the matches for positive/negative phase }; // the supergate internally represented diff --git a/src/map/mapper/mapperTruth.c b/src/map/mapper/mapperTruth.c index 9388b42f..67ef029b 100644 --- a/src/map/mapper/mapperTruth.c +++ b/src/map/mapper/mapperTruth.c @@ -22,20 +22,10 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -//static void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ); -static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut ); -static void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruth[] ); -static void Map_TruthsUnmark_rec( Map_Cut_t * pCut ); - -/* -static int s_Same = 0; -static int s_Diff = 0; -static int s_Same2 = 0; -static int s_Diff2 = 0; -static int s_Truth = 0; -static int s_Isop1 = 0; -static int s_Isop2 = 0; -*/ +static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut ); +static void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ); +static void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// @@ -85,10 +75,6 @@ void Map_MappingTruths( Map_Man_t * pMan ) Extra_ProgressBarUpdate( pProgress, i, "Tables ..." ); } Extra_ProgressBarStop( pProgress ); - -// printf( "Same = %6d. Diff = %6d.\n", s_Same, s_Diff ); -// printf( "Same2 = %6d. Diff2 = %6d.\n", s_Same2, s_Diff2 ); -// printf( "Truth = %6d. Isop1 = %6d. Isop2 = %6d.\n", s_Truth, s_Isop1, s_Isop2 ); } /**Function************************************************************* @@ -106,22 +92,11 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) { unsigned uTruth[2], uCanon[2]; unsigned char uPhases[16]; - int i; // generally speaking, 1-input cut can be matched into a wire! if ( pCut->nLeaves == 1 ) return; - // set the leaf truth tables - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pCut->ppLeaves[i]->pCuts->uTruthTemp[0] = p->uTruths[i][0]; - pCut->ppLeaves[i]->pCuts->uTruthTemp[1] = p->uTruths[i][1]; - } - // recursively compute the truth table - pCut->nVolume = 0; - Map_TruthsCut_rec( pCut, uTruth ); - // recursively unmark the visited cuts - Map_TruthsUnmark_rec( pCut ); + Map_TruthsCutOne( p, pCut, uTruth ); // compute the canonical form for the positive phase Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); @@ -140,15 +115,11 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) // restore the truth table uTruth[0] = ~uTruth[0]; uTruth[1] = ~uTruth[1]; - // enable don't-care computation -// Map_TruthsCutDcs( p, pCut, uTruth ); } -#if 0 - /**Function************************************************************* - Synopsis [Adds several other choices using SDCs.] + Synopsis [Computes the truth table of one cut.] Description [] @@ -157,141 +128,79 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ) +void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ) { - unsigned uIsop1[2], uIsop2[2], uCanon[2]; - unsigned char uPhases[16]; + unsigned uTruth1[2], uTruth2[2]; + Map_Cut_t * pTemp; + int i; + // mark the cut leaves + for ( i = 0; i < pCut->nLeaves; i++ ) + { + pTemp = pCut->ppLeaves[i]->pCuts; + pTemp->fMark = 1; + pTemp->M[0].uPhaseBest = p->uTruths[i][0]; + pTemp->M[1].uPhaseBest = p->uTruths[i][1]; + } + assert( pCut->fMark == 0 ); - // add several other supergate classes derived using don't-cares - if ( pCut->uTruthDc[0] ) + // collect the cuts in the cut cone + p->vVisited->nSize = 0; + Map_CutsCollect_rec( pCut, p->vVisited ); + assert( p->vVisited->nSize > 0 ); + pCut->nVolume = p->vVisited->nSize; + + // compute the tables and unmark + for ( i = 0; i < pCut->nLeaves; i++ ) + { + pTemp = pCut->ppLeaves[i]->pCuts; + pTemp->fMark = 0; + } + for ( i = 0; i < p->vVisited->nSize; i++ ) { - int nOnes; - nOnes = Map_TruthCountOnes( pCut->uTruthDc, pCut->nLeaves ); - if ( nOnes == 1 ) + // get the cut + pTemp = (Map_Cut_t *)p->vVisited->pArray[i]; + pTemp->fMark = 0; + // get truth table of the first branch + if ( Map_CutIsComplement(pTemp->pOne) ) + { + uTruth1[0] = ~Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest; + uTruth1[1] = ~Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest; + } + else + { + uTruth1[0] = Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest; + uTruth1[1] = Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest; + } + // get truth table of the second branch + if ( Map_CutIsComplement(pTemp->pTwo) ) + { + uTruth2[0] = ~Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest; + uTruth2[1] = ~Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest; + } + else { - uTruth[0] ^= pCut->uTruthDc[0]; - uTruth[1] ^= pCut->uTruthDc[1]; - - // compute the canonical form for the positive phase - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[1].uPhase = uPhases[0]; - p->nCanons++; - - // compute the canonical form for the negative phase - uTruth[0] = ~uTruth[0]; - uTruth[1] = ~uTruth[1]; - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[0].uPhase = uPhases[0]; - p->nCanons++; + uTruth2[0] = Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest; + uTruth2[1] = Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest; } - else if ( nOnes == 2 ) + // get the truth table of the output + if ( !pTemp->Phase ) { - int Num1, Num2, RetValue; - RetValue = Map_TruthDetectTwoFirst( pCut->uTruthDc, pCut->nLeaves ); - Num1 = RetValue & 255; - Num2 = (RetValue >> 8) & 255; - - // add the first bit - Map_InfoFlipVar( uTruth, Num1 ); - - // compute the canonical form for the positive phase - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[1].uPhase = uPhases[0]; - p->nCanons++; - - // compute the canonical form for the negative phase - uTruth[0] = ~uTruth[0]; - uTruth[1] = ~uTruth[1]; - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[0].uPhase = uPhases[0]; - p->nCanons++; - - // add the first bit - Map_InfoFlipVar( uTruth, Num2 ); - - // compute the canonical form for the positive phase - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[1].uPhase = uPhases[0]; - p->nCanons++; - - // compute the canonical form for the negative phase - uTruth[0] = ~uTruth[0]; - uTruth[1] = ~uTruth[1]; - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[0].uPhase = uPhases[0]; - p->nCanons++; - - // add the first bit - Map_InfoFlipVar( uTruth, Num1 ); - - // compute the canonical form for the positive phase - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[1].uPhase = uPhases[0]; - p->nCanons++; - - // compute the canonical form for the negative phase - uTruth[0] = ~uTruth[0]; - uTruth[1] = ~uTruth[1]; - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); - pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[0].uPhase = uPhases[0]; - p->nCanons++; + pTemp->M[0].uPhaseBest = uTruth1[0] & uTruth2[0]; + pTemp->M[1].uPhaseBest = uTruth1[1] & uTruth2[1]; } else { - // compute the ISOPs - uIsop1[0] = Map_ComputeIsop_rec( p, uTruth[0] & ~pCut->uTruthDc[0], uTruth[0] | pCut->uTruthDc[0], 0, pCut->nLeaves, 0 ); - uIsop1[1] = uIsop1[0]; - if ( uIsop1[0] != uTruth[0] ) - { - // compute the canonical form for the positive phase - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop1, uPhases, uCanon ); - pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[1].uPhase = uPhases[0]; - p->nCanons++; - - // compute the canonical form for the negative phase - uIsop1[0] = ~uIsop1[0]; - uIsop1[1] = ~uIsop1[1]; - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop1, uPhases, uCanon ); - pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[0].uPhase = uPhases[0]; - p->nCanons++; - } - - uIsop2[0] = Map_ComputeIsop_rec( p, uTruth[0] & ~pCut->uTruthDc[0], uTruth[0] | pCut->uTruthDc[0], pCut->nLeaves-1, pCut->nLeaves, 1 ); - uIsop2[1] = uIsop2[0]; - if ( uIsop2[0] != uTruth[0] && uIsop2[0] != uIsop1[0] ) - { - // compute the canonical form for the positive phase - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop2, uPhases, uCanon ); - pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - p->nCanons++; - - // compute the canonical form for the negative phase - uIsop2[0] = ~uIsop2[0]; - uIsop2[1] = ~uIsop2[1]; - Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop2, uPhases, uCanon ); - pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - pCut->M[0].uPhase = uPhases[0]; - p->nCanons++; - } + pTemp->M[0].uPhaseBest = ~(uTruth1[0] & uTruth2[0]); + pTemp->M[1].uPhaseBest = ~(uTruth1[1] & uTruth2[1]); } } + uTruth[0] = pTemp->M[0].uPhaseBest; + uTruth[1] = pTemp->M[1].uPhaseBest; } -#endif - /**Function************************************************************* - Synopsis [Recursively derives the truth table for the cut.] + Synopsis [Recursively collect the cuts.] Description [] @@ -300,147 +209,17 @@ void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ) SeeAlso [] ***********************************************************************/ -void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruthRes[] ) +void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited ) { - unsigned uTruth1[2], uTruth2[2]; - // if this is the elementary cut, its truth table is already available - if ( pCut->nLeaves == 1 ) - { - uTruthRes[0] = pCut->uTruthTemp[0]; - uTruthRes[1] = pCut->uTruthTemp[1]; - return; - } - // if this node was already visited, return its computed truth table if ( pCut->fMark ) - { - uTruthRes[0] = pCut->uTruthTemp[0]; - uTruthRes[1] = pCut->uTruthTemp[1]; return; - } + Map_CutsCollect_rec( Map_CutRegular(pCut->pOne), vVisited ); + Map_CutsCollect_rec( Map_CutRegular(pCut->pTwo), vVisited ); + assert( pCut->fMark == 0 ); pCut->fMark = 1; - pCut->nVolume++; - - assert( !Map_IsComplement(pCut) ); - Map_TruthsCut_rec( Map_CutRegular(pCut->pOne), uTruth1 ); - if ( Map_CutIsComplement(pCut->pOne) ) - { - uTruth1[0] = ~uTruth1[0]; - uTruth1[1] = ~uTruth1[1]; - } - Map_TruthsCut_rec( Map_CutRegular(pCut->pTwo), uTruth2 ); - if ( Map_CutIsComplement(pCut->pTwo) ) - { - uTruth2[0] = ~uTruth2[0]; - uTruth2[1] = ~uTruth2[1]; - } - if ( !pCut->Phase ) - { - uTruthRes[0] = pCut->uTruthTemp[0] = uTruth1[0] & uTruth2[0]; - uTruthRes[1] = pCut->uTruthTemp[1] = uTruth1[1] & uTruth2[1]; - } - else - { - uTruthRes[0] = pCut->uTruthTemp[0] = ~(uTruth1[0] & uTruth2[0]); - uTruthRes[1] = pCut->uTruthTemp[1] = ~(uTruth1[1] & uTruth2[1]); - } -} - -/**Function************************************************************* - - Synopsis [Recursively derives the truth table for the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Map_TruthsUnmark_rec( Map_Cut_t * pCut ) -{ - if ( pCut->nLeaves == 1 ) - return; - // if this node was already visited, return its computed truth table - if ( pCut->fMark == 0 ) - return; - pCut->fMark = 0; - Map_TruthsUnmark_rec( Map_CutRegular(pCut->pOne) ); - Map_TruthsUnmark_rec( Map_CutRegular(pCut->pTwo) ); + Map_NodeVecPush( vVisited, (Map_Node_t *)pCut ); } -/**Function************************************************************* - - Synopsis [Returns the truth table of the don't-care set.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Map_TruthsCutDontCare( Map_Man_t * pMan, Map_Cut_t * pCut, unsigned * uTruthDc ) -{ - if ( pCut->pOne || (pCut->uTruthZero[0] == 0 && pCut->uTruthZero[1] == 0) ) - return 0; - assert( (pCut->uTruthTemp[0] & pCut->uTruthZero[0]) == 0 ); - assert( (pCut->uTruthTemp[1] & pCut->uTruthZero[1]) == 0 ); - uTruthDc[0] = ((~0) & (~pCut->uTruthTemp[0]) & (~pCut->uTruthZero[0])); - uTruthDc[1] = ((~0) & (~pCut->uTruthTemp[1]) & (~pCut->uTruthZero[1])); - if ( uTruthDc[0] == 0 && uTruthDc[1] == 0 ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Expand the truth table] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Map_TruthCountOnes( unsigned * uTruth, int nLeaves ) -{ - int i, nMints, Counter; - nMints = (1 << nLeaves); - Counter = 0; - for ( i = 0; i < nMints; i++ ) - Counter += Map_InfoReadVar( uTruth, i ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Expand the truth table] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Map_TruthDetectTwoFirst( unsigned * uTruth, int nLeaves ) -{ - int i, nMints, Num1 = -1, Num2 = -1; - nMints = (1 << nLeaves); - for ( i = 0; i < nMints; i++ ) - if ( Map_InfoReadVar( uTruth, i ) ) - { - if ( Num1 == -1 ) - Num1 = i; - else if ( Num2 == -1 ) - Num2 = i; - else - break; - } - assert( Num1 != -1 && Num2 != -1 ); - return (Num1 << 8) | Num2; -} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/opt/fxu/fxu.c b/src/opt/fxu/fxu.c new file mode 100644 index 00000000..4b95b5a5 --- /dev/null +++ b/src/opt/fxu/fxu.c @@ -0,0 +1,260 @@ +/**CFile**************************************************************** + + FileName [fxu.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [The entrance into the fast extract module.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxu.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" +//#include "mvc.h" +#include "fxu.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*===== fxuCreate.c ====================================================*/ +extern Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ); +extern void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData ); + +static int s_MemoryTotal; +static int s_MemoryPeak; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs fast_extract on a set of covers.] + + Description [All the covers are given in the array p->ppCovers. + The resulting covers are returned in the array p->ppCoversNew. + The number of entries in both cover arrays is equal to the number + of all values in the current nodes plus the max expected number + of extracted nodes (p->nValuesCi + p->nValuesInt + p->nValuesExtMax). + The first p->nValuesCi entries, corresponding to the CI nodes, are NULL. + The next p->nValuesInt entries, corresponding to the int nodes, are covers + from which the divisors are extracted. The last p->nValuesExtMax entries + are reserved for the new covers to be extracted. The number of extracted + covers is returned. This number does not exceed the given number (p->nNodesExt). + Two other things are important for the correct operation of this procedure: + (1) The input covers should be SCC-free. (2) The literal array (pCover->pLits) + is allocated in each cover. The i-th entry in the literal array of a cover + is the number of the cover in the array p->ppCovers, which represents this + literal (variable value) in the given cover.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_FastExtract( Fxu_Data_t * pData ) +{ + Fxu_Matrix * p; + Fxu_Single * pSingle; + Fxu_Double * pDouble; + int Weight1, Weight2, Weight3; + + s_MemoryTotal = 0; + s_MemoryPeak = 0; + + // create the matrix + p = Fxu_CreateMatrix( pData ); + if ( p == NULL ) + return -1; +// if ( pData->fVerbose ) +// printf( "Memory usage after construction: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); +//Fxu_MatrixPrint( NULL, p ); + + if ( pData->fOnlyS ) + { + pData->nNodesNew = 0; + do + { + Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); + if ( pData->fVerbose ) + printf( "Best single = %3d.\n", Weight1 ); + if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 ) + Fxu_UpdateSingle( p ); + else + break; + } + while ( ++pData->nNodesNew < pData->nNodesExt ); + } + else if ( pData->fOnlyD ) + { + pData->nNodesNew = 0; + do + { + Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); + if ( pData->fVerbose ) + printf( "Best double = %3d.\n", Weight2 ); + if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 ) + Fxu_UpdateDouble( p ); + else + break; + } + while ( ++pData->nNodesNew < pData->nNodesExt ); + } + else if ( !pData->fUseCompl ) + { + pData->nNodesNew = 0; + do + { + Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); + Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); + + if ( pData->fVerbose ) + printf( "Best double = %3d. Best single = %3d.\n", Weight2, Weight1 ); +//Fxu_Select( p, &pSingle, &pDouble ); + + if ( Weight1 >= Weight2 ) + { + if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 ) + Fxu_UpdateSingle( p ); + else + break; + } + else + { + if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 ) + Fxu_UpdateDouble( p ); + else + break; + } + } + while ( ++pData->nNodesNew < pData->nNodesExt ); + } + else + { // use the complement + pData->nNodesNew = 0; + do + { + Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); + Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); + + // select the best single and double + Weight3 = Fxu_Select( p, &pSingle, &pDouble ); + if ( pData->fVerbose ) + printf( "Best double = %3d. Best single = %3d. Best complement = %3d.\n", + Weight2, Weight1, Weight3 ); + + if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 ) + Fxu_Update( p, pSingle, pDouble ); + else + break; + } + while ( ++pData->nNodesNew < pData->nNodesExt ); + } + + if ( pData->fVerbose ) + printf( "Total single = %3d. Total double = %3d. Total compl = %3d.\n", p->nDivs1, p->nDivs2, p->nDivs3 ); + + // create the new covers + if ( pData->nNodesNew ) + Fxu_CreateCovers( p, pData ); + Fxu_MatrixDelete( p ); +// printf( "Memory usage after delocation: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); + if ( pData->nNodesNew == pData->nNodesExt ) + printf( "Warning: The limit on the number of extracted divisors has been reached.\n" ); + return pData->nNodesNew; +} + + +/**Function************************************************************* + + Synopsis [Unmarks the cubes in the ring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p ) +{ + Fxu_Cube * pCube, * pCube2; + // unmark the cubes + Fxu_MatrixForEachCubeInRingSafe( p, pCube, pCube2 ) + pCube->pOrder = NULL; + Fxu_MatrixRingCubesReset( p ); +} + + +/**Function************************************************************* + + Synopsis [Unmarks the vars in the ring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p ) +{ + Fxu_Var * pVar, * pVar2; + // unmark the vars + Fxu_MatrixForEachVarInRingSafe( p, pVar, pVar2 ) + pVar->pOrder = NULL; + Fxu_MatrixRingVarsReset( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes ) +{ + s_MemoryTotal += nBytes; + if ( s_MemoryPeak < s_MemoryTotal ) + s_MemoryPeak = s_MemoryTotal; +// return malloc( nBytes ); + return Extra_MmFixedEntryFetch( p->pMemMan ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes ) +{ + s_MemoryTotal -= nBytes; +// free( pItem ); + Extra_MmFixedEntryRecycle( p->pMemMan, pItem ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h new file mode 100644 index 00000000..5bc1e75f --- /dev/null +++ b/src/opt/fxu/fxu.h @@ -0,0 +1,108 @@ +/**CFile**************************************************************** + + FileName [fxu.h] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [External declarations of fast extract for unate covers.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxu.h,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __FXU_H__ +#define __FXU_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#ifndef bool +#define bool int +#endif + +typedef struct FxuDataStruct Fxu_Data_t; + +// structure for the FX input/output data +struct FxuDataStruct +{ + // user specified parameters + bool fOnlyS; // set to 1 to have only single-cube divs + bool fOnlyD; // set to 1 to have only double-cube divs + bool fUse0; // set to 1 to have 0-weight also extracted + bool fUseCompl; // set to 1 to have complement taken into account + bool fVerbose; // set to 1 to have verbose output + int nPairsMax; // the maximum number of cube pairs to consider +/* + // parameters of the network + int fMvNetwork; // the network has some MV nodes + // the information about nodes + int nNodesCi; // the number of CI nodes of the network + int nNodesInt; // the number of internal nodes of the network + int nNodesOld; // the number of CI and int nodes + int nNodesNew; // the number of added nodes + int nNodesExt; // the max number of (binary) nodes to be added by FX + int nNodesAlloc; // the total number of all nodes + int * pNode2Value; // for each node, the number of its first value + // the information about values + int nValuesCi; // the total number of values of CI nodes + int nValuesInt; // the total number of values of int nodes + int nValuesOld; // the number of CI and int values + int nValuesNew; // the number of values added nodes + int nValuesExt; // the total number of values of the added nodes + int nValuesAlloc; // the total number of all values of all nodes + int * pValue2Node; // for each value, the number of its node + // the information about covers + Mvc_Cover_t ** ppCovers; // for each value, the corresponding cover + Mvc_Cover_t ** ppCoversNew; // for each value, the corresponding cover after FX + // the MVC manager + Mvc_Manager_t * pManMvc; +*/ + // statistics + int nNodesOld; // the old number of nodes + int nNodesExt; // the number of divisors to extract + int nNodesNew; // the number of divisors extracted + + // the input information + Vec_Ptr_t * vSops; // the SOPs for each node in the network + Vec_Ptr_t * vFanins; // the fanins of each node in the network + // output information + Vec_Ptr_t * vSopsNew; // the SOPs for each node in the network after extraction + Vec_Ptr_t * vFaninsNew; // the fanins of each node in the network after extraction + // the SOP manager + Extra_MmFlex_t * pManSop; +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/*===== fxu.c ==========================================================*/ +extern int Fxu_FastExtract( Fxu_Data_t * pData ); + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/opt/fxu/fxuCreate.c b/src/opt/fxu/fxuCreate.c new file mode 100644 index 00000000..04b23fce --- /dev/null +++ b/src/opt/fxu/fxuCreate.c @@ -0,0 +1,425 @@ +/**CFile**************************************************************** + + FileName [fxuCreate.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Create matrix from covers and covers from matrix.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuCreate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fxuInt.h" +#include "fxu.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax ); + +static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder ); +static int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY ); +static void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext ); +static Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode ); +static Abc_Fan_t * s_pLits; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the sparse matrix from the array of Sop covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) +{ + Fxu_Matrix * p; + Fxu_Var * pVar; + Fxu_Cube * pCubeFirst, * pCubeNew; + Fxu_Cube * pCube1, * pCube2; + char * pSopCover; + char * pSopCube; + int * pOrder, nBitsMax; + int i, v, c; + int nCubesTotal; + int nPairsTotal; + int nPairsStore; + int nCubes; + int iCube, iPair; + int nFanins; + Vec_Fan_t * vFanins; + + // collect all sorts of statistics + nCubesTotal = 0; + nPairsTotal = 0; + nPairsStore = 0; + nBitsMax = -1; + for ( i = 0; i < pData->nNodesOld; i++ ) + if ( pSopCover = pData->vSops->pArray[i] ) + { + nCubes = Abc_SopGetCubeNum( pSopCover ); + nFanins = Abc_SopGetVarNum( pSopCover ); + assert( nFanins > 1 && nCubes > 0 ); + + nCubesTotal += nCubes; + nPairsTotal += nCubes * (nCubes - 1) / 2; + nPairsStore += nCubes * nCubes; + if ( nBitsMax < nFanins ) + nBitsMax = nFanins; + } + if ( nBitsMax <= 0 ) + { + printf( "The current network does not have SOPs to perform extraction.\n" ); + return NULL; + } + + if ( nPairsStore > 10000000 ) + { + printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore ); + return NULL; + } + + // start the matrix + p = Fxu_MatrixAllocate(); + // create the column labels + p->ppVars = ALLOC( Fxu_Var *, 2 * (pData->nNodesOld + pData->nNodesExt) ); + for ( i = 0; i < 2 * pData->nNodesOld; i++ ) + p->ppVars[i] = Fxu_MatrixAddVar( p ); + + // allocate storage for all cube pairs at once + p->pppPairs = ALLOC( Fxu_Pair **, nCubesTotal + 100 ); + p->ppPairs = ALLOC( Fxu_Pair *, nPairsStore + 100 ); + memset( p->ppPairs, 0, sizeof(Fxu_Pair *) * nPairsStore ); + iCube = 0; + iPair = 0; + for ( i = 0; i < pData->nNodesOld; i++ ) + if ( pSopCover = pData->vSops->pArray[i] ) + { + // get the number of cubes + nCubes = Abc_SopGetCubeNum( pSopCover ); + // get the new var in the matrix + pVar = p->ppVars[2*i+1]; + // assign the pair storage + pVar->nCubes = nCubes; + if ( nCubes > 0 ) + { + pVar->ppPairs = p->pppPairs + iCube; + pVar->ppPairs[0] = p->ppPairs + iPair; + for ( v = 1; v < nCubes; v++ ) + pVar->ppPairs[v] = pVar->ppPairs[v-1] + nCubes; + } + // update + iCube += nCubes; + iPair += nCubes * nCubes; + } + assert( iCube == nCubesTotal ); + assert( iPair == nPairsStore ); + + + // allocate room for the reordered literals + pOrder = ALLOC( int, nBitsMax ); + // create the rows + for ( i = 0; i < pData->nNodesOld; i++ ) + if ( pSopCover = pData->vSops->pArray[i] ) + { + // get the new var in the matrix + pVar = p->ppVars[2*i+1]; + // here we sort the literals of the cover + // in the increasing order of the numbers of the corresponding nodes + // because literals should be added to the matrix in this order + vFanins = pData->vFanins->pArray[i]; + s_pLits = vFanins->pArray; + // start the variable order + nFanins = Abc_SopGetVarNum( pSopCover ); + for ( v = 0; v < nFanins; v++ ) + pOrder[v] = v; + // reorder the fanins + qsort( (void *)pOrder, nFanins, sizeof(int),(int (*)(const void *, const void *))Fxu_CreateMatrixLitCompare); + assert( s_pLits[ pOrder[0] ].iFan < s_pLits[ pOrder[nFanins-1] ].iFan ); + // create the corresponding cubes in the matrix + pCubeFirst = NULL; + c = 0; + Abc_SopForEachCube( pSopCover, nFanins, pSopCube ) + { + // create the cube + pCubeNew = Fxu_MatrixAddCube( p, pVar, c ); + Fxu_CreateMatrixAddCube( p, pCubeNew, pSopCube, vFanins, pOrder ); + if ( pCubeFirst == NULL ) + pCubeFirst = pCubeNew; + pCubeNew->pFirst = pCubeFirst; + c++; + } + // set the first cube of this var + pVar->pFirst = pCubeFirst; + // create the divisors without preprocessing + if ( nPairsTotal <= pData->nPairsMax ) + { + for ( pCube1 = pCubeFirst; pCube1; pCube1 = pCube1->pNext ) + for ( pCube2 = pCube1? pCube1->pNext: NULL; pCube2; pCube2 = pCube2->pNext ) + Fxu_MatrixAddDivisor( p, pCube1, pCube2 ); + } + } + FREE( pOrder ); + + // consider the case when cube pairs should be preprocessed + // before adding them to the set of divisors + if ( nPairsTotal > pData->nPairsMax ) + Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ); + + // add the var pairs to the heap + Fxu_MatrixComputeSingles( p ); + + // allocate temporary storage for pairs + if ( pData->nPairsMax < 1000 ) + pData->nPairsMax = 1000; + p->pPairsTemp = ALLOC( Fxu_Pair *, pData->nPairsMax * 10 + 100 ); + if ( pData->fVerbose ) + { + double Density; + Density = ((double)p->nEntries) / p->lVars.nItems / p->lCubes.nItems; + fprintf( stdout, "Matrix: [vars x cubes] = [%d x %d] ", + p->lVars.nItems, p->lCubes.nItems ); + fprintf( stdout, "Lits = %d Density = %.5f%%\n", + p->nEntries, Density ); + fprintf( stdout, "1-cube divisors = %6d. ", p->lSingles.nItems ); + fprintf( stdout, "2-cube divisors = %6d. ", p->nDivsTotal ); + fprintf( stdout, "Cube pairs = %6d.", nPairsTotal ); + fprintf( stdout, "\n" ); + } +// Fxu_MatrixPrint( stdout, p ); + return p; +} + +/**Function************************************************************* + + Synopsis [Adds one cube with literals to the matrix.] + + Description [Create the cube and literals in the matrix corresponding + to the given cube in the SOP cover. Co-singleton transform is performed here.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder ) +{ + Fxu_Var * pVar; + int Value, i; + // add literals to the matrix + Abc_CubeForEachVar( pSopCube, Value, i ) + { + Value = pSopCube[pOrder[i]]; + if ( Value == '0' ) + { + pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan + 1 ]; // CST + Fxu_MatrixAddLiteral( p, pCube, pVar ); + } + else if ( Value == '1' ) + { + pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan ]; // CST + Fxu_MatrixAddLiteral( p, pCube, pVar ); + } + } +} + + +/**Function************************************************************* + + Synopsis [Creates the new array of Sop covers from the sparse matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData ) +{ + Fxu_Cube * pCube, * pCubeFirst, * pCubeNext; + int iNode, n; + char * pSopCover; + + // get the first cube of the first internal node + pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 ); + + // go through the internal nodes + for ( n = 0; n < pData->nNodesOld; n++ ) + if ( pSopCover = pData->vSops->pArray[n] ) + { + // get the number of this node + iNode = n; + // get the next first cube + pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 ); + // check if there any new variables in these cubes + for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) + if ( pCube->lLits.pTail && pCube->lLits.pTail->iVar >= 2 * pData->nNodesOld ) + break; + if ( pCube != pCubeNext ) + Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext ); + // update the first cube + pCubeFirst = pCubeNext; + } + + // add the covers for the extracted nodes + for ( n = 0; n < pData->nNodesNew; n++ ) + { + // get the number of this node + iNode = pData->nNodesOld + n; + // get the next first cube + pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 ); + // the node should be added + Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext ); + // update the first cube + pCubeFirst = pCubeNext; + } +} + +/**Function************************************************************* + + Synopsis [Create Sop covers for one node that has changed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext ) +{ + Vec_Int_t * vInputsNew; + char * pSopCover; + char * pSopCube; + Fxu_Var * pVar; + Fxu_Cube * pCube; + Fxu_Lit * pLit; + int iNum, nCubes, v; + int fEmptyCube; + + // collect positive polarity variable in the cubes between pCubeFirst and pCubeNext + Fxu_MatrixRingVarsStart( p ); + for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) + for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext ) + { + pVar = p->ppVars[ 2 * (pLit->pVar->iVar/2) + 1 ]; + if ( pVar->pOrder == NULL ) + Fxu_MatrixRingVarsAdd( p, pVar ); + } + Fxu_MatrixRingVarsStop( p ); + + // collect the variable numbers + vInputsNew = Vec_IntAlloc( 4 ); + Fxu_MatrixForEachVarInRing( p, pVar ) + Vec_IntPush( vInputsNew, pVar->iVar / 2 ); + Fxu_MatrixRingVarsUnmark( p ); + + // sort the vars by their number + Vec_IntSort( vInputsNew, 0 ); + + // mark the vars with their numbers in the sorted array + for ( v = 0; v < vInputsNew->nSize; v++ ) + { + p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v; // hack - reuse lLits.nItems + p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v; // hack - reuse lLits.nItems + } + + // count the number of cubes + nCubes = 0; + for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) + if ( pCube->lLits.nItems ) + nCubes++; + + // allocate room for the new cover + pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize ); + // set the correct polarity of the cover + if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 ) + Abc_SopComplement( pSopCover ); + + // add the cubes + nCubes = 0; + for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) + { + if ( pCube->lLits.nItems == 0 ) + continue; + // get hold of the SOP cube + pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3); + // insert literals + fEmptyCube = 1; + for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext ) + { + iNum = pLit->pVar->lLits.nItems; // hack - reuse lLits.nItems + assert( iNum < vInputsNew->nSize ); + if ( pLit->pVar->iVar / 2 < pData->nNodesOld ) + pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1'; // reverse CST + else + pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0'; // no CST + fEmptyCube = 0; + } + assert( !fEmptyCube ); + // count the cube + nCubes++; + } + assert( nCubes == Abc_SopGetCubeNum(pSopCover) ); + + pData->vSopsNew->pArray[iNode] = pSopCover; + pData->vFaninsNew->pArray[iNode] = vInputsNew; +} + + +/**Function************************************************************* + + Synopsis [Adds the var to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iVar ) +{ + int v; + for ( v = iVar; v < pData->nNodesOld + pData->nNodesNew; v++ ) + if ( p->ppVars[ 2*v + 1 ]->pFirst ) + return p->ppVars[ 2*v + 1 ]->pFirst; + return NULL; +} + +/**Function************************************************************* + + Synopsis [Compares the vars by their number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY ) +{ + return s_pLits[*ptrX].iFan - s_pLits[*ptrY].iFan; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/opt/fxu/fxuHeapD.c b/src/opt/fxu/fxuHeapD.c new file mode 100644 index 00000000..7c123249 --- /dev/null +++ b/src/opt/fxu/fxuHeapD.c @@ -0,0 +1,445 @@ +/**CFile**************************************************************** + + FileName [fxuHeapD.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [The priority queue for double cube divisors.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuHeapD.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define FXU_HEAP_DOUBLE_WEIGHT(pDiv) ((pDiv)->Weight) +#define FXU_HEAP_DOUBLE_CURRENT(p, pDiv) ((p)->pTree[(pDiv)->HNum]) +#define FXU_HEAP_DOUBLE_PARENT_EXISTS(p, pDiv) ((pDiv)->HNum > 1) +#define FXU_HEAP_DOUBLE_CHILD1_EXISTS(p, pDiv) (((pDiv)->HNum << 1) <= p->nItems) +#define FXU_HEAP_DOUBLE_CHILD2_EXISTS(p, pDiv) ((((pDiv)->HNum << 1)+1) <= p->nItems) +#define FXU_HEAP_DOUBLE_PARENT(p, pDiv) ((p)->pTree[(pDiv)->HNum >> 1]) +#define FXU_HEAP_DOUBLE_CHILD1(p, pDiv) ((p)->pTree[(pDiv)->HNum << 1]) +#define FXU_HEAP_DOUBLE_CHILD2(p, pDiv) ((p)->pTree[((pDiv)->HNum << 1)+1]) +#define FXU_HEAP_DOUBLE_ASSERT(p, pDiv) assert( (pDiv)->HNum >= 1 && (pDiv)->HNum <= p->nItemsAlloc ) + +static void Fxu_HeapDoubleResize( Fxu_HeapDouble * p ); +static void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 ); +static void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ); +static void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_HeapDouble * Fxu_HeapDoubleStart() +{ + Fxu_HeapDouble * p; + p = ALLOC( Fxu_HeapDouble, 1 ); + memset( p, 0, sizeof(Fxu_HeapDouble) ); + p->nItems = 0; + p->nItemsAlloc = 10000; + p->pTree = ALLOC( Fxu_Double *, p->nItemsAlloc + 1 ); + p->pTree[0] = NULL; + return p; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleResize( Fxu_HeapDouble * p ) +{ + p->nItemsAlloc *= 2; + p->pTree = REALLOC( Fxu_Double *, p->pTree, p->nItemsAlloc + 1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleStop( Fxu_HeapDouble * p ) +{ + free( p->pTree ); + free( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p ) +{ + Fxu_Double * pDiv; + int Counter = 1; + int Degree = 1; + + Fxu_HeapDoubleCheck( p ); + fprintf( pFile, "The contents of the heap:\n" ); + fprintf( pFile, "Level %d: ", Degree ); + Fxu_HeapDoubleForEachItem( p, pDiv ) + { + assert( Counter == p->pTree[Counter]->HNum ); + fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_DOUBLE_WEIGHT(p->pTree[Counter]) ); + if ( ++Counter == (1 << Degree) ) + { + fprintf( pFile, "\n" ); + Degree++; + fprintf( pFile, "Level %d: ", Degree ); + } + } + fprintf( pFile, "\n" ); + fprintf( pFile, "End of the heap printout.\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p ) +{ + Fxu_Double * pDiv; + Fxu_HeapDoubleForEachItem( p, pDiv ) + { + assert( pDiv->HNum == p->i ); + Fxu_HeapDoubleCheckOne( p, pDiv ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv ) +{ + int Weight1, Weight2; + if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) ) + { + Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv); + Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ); + assert( Weight1 >= Weight2 ); + } + if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) ) + { + Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv); + Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ); + assert( Weight1 >= Weight2 ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv ) +{ + if ( p->nItems == p->nItemsAlloc ) + Fxu_HeapDoubleResize( p ); + // put the last entry to the last place and move up + p->pTree[++p->nItems] = pDiv; + pDiv->HNum = p->nItems; + // move the last entry up if necessary + Fxu_HeapDoubleMoveUp( p, pDiv ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv ) +{ +//printf( "Updating divisor %d.\n", pDiv->Num ); + + FXU_HEAP_DOUBLE_ASSERT(p,pDiv); + if ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,pDiv) && + FXU_HEAP_DOUBLE_WEIGHT(pDiv) > FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_PARENT(p,pDiv) ) ) + Fxu_HeapDoubleMoveUp( p, pDiv ); + else if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) && + FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ) ) + Fxu_HeapDoubleMoveDn( p, pDiv ); + else if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) && + FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ) ) + Fxu_HeapDoubleMoveDn( p, pDiv ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv ) +{ + FXU_HEAP_DOUBLE_ASSERT(p,pDiv); + // put the last entry to the deleted place + // decrement the number of entries + p->pTree[pDiv->HNum] = p->pTree[p->nItems--]; + p->pTree[pDiv->HNum]->HNum = pDiv->HNum; + // move the top entry down if necessary + Fxu_HeapDoubleUpdate( p, p->pTree[pDiv->HNum] ); + pDiv->HNum = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p ) +{ + if ( p->nItems == 0 ) + return NULL; + return p->pTree[1]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p ) +{ + Fxu_Double * pDiv; + if ( p->nItems == 0 ) + return NULL; + // prepare the return value + pDiv = p->pTree[1]; + pDiv->HNum = 0; + // put the last entry on top + // decrement the number of entries + p->pTree[1] = p->pTree[p->nItems--]; + p->pTree[1]->HNum = 1; + // move the top entry down if necessary + Fxu_HeapDoubleMoveDn( p, p->pTree[1] ); + return pDiv; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p ) +{ + if ( p->nItems == 0 ) + return -1; + else + return FXU_HEAP_DOUBLE_WEIGHT(p->pTree[1]); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 ) +{ + Fxu_Double * pDiv; + int Temp; + pDiv = *pDiv1; + *pDiv1 = *pDiv2; + *pDiv2 = pDiv; + Temp = (*pDiv1)->HNum; + (*pDiv1)->HNum = (*pDiv2)->HNum; + (*pDiv2)->HNum = Temp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ) +{ + Fxu_Double ** ppDiv, ** ppPar; + ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv); + while ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,*ppDiv) ) + { + ppPar = &FXU_HEAP_DOUBLE_PARENT(p,*ppDiv); + if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) > FXU_HEAP_DOUBLE_WEIGHT(*ppPar) ) + { + Fxu_HeapDoubleSwap( ppDiv, ppPar ); + ppDiv = ppPar; + } + else + break; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ) +{ + Fxu_Double ** ppChild1, ** ppChild2, ** ppDiv; + ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv); + while ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,*ppDiv) ) + { // if Child1 does not exist, Child2 also does not exists + + // get the children + ppChild1 = &FXU_HEAP_DOUBLE_CHILD1(p,*ppDiv); + if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,*ppDiv) ) + { + ppChild2 = &FXU_HEAP_DOUBLE_CHILD2(p,*ppDiv); + + // consider two cases + if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) && + FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) ) + { // Div is larger than both, skip + break; + } + else + { // Div is smaller than one of them, then swap it with larger + if ( FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) ) + { + Fxu_HeapDoubleSwap( ppDiv, ppChild1 ); + // update the pointer + ppDiv = ppChild1; + } + else + { + Fxu_HeapDoubleSwap( ppDiv, ppChild2 ); + // update the pointer + ppDiv = ppChild2; + } + } + } + else // Child2 does not exist + { + // consider two cases + if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) ) + { // Div is larger than Child1, skip + break; + } + else + { // Div is smaller than Child1, then swap them + Fxu_HeapDoubleSwap( ppDiv, ppChild1 ); + // update the pointer + ppDiv = ppChild1; + } + } + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuHeapS.c b/src/opt/fxu/fxuHeapS.c new file mode 100644 index 00000000..dbd66055 --- /dev/null +++ b/src/opt/fxu/fxuHeapS.c @@ -0,0 +1,444 @@ +/**CFile**************************************************************** + + FileName [fxuHeapS.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [The priority queue for variables.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuHeapS.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight) +#define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum]) +#define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1) +#define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems) +#define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems) +#define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1]) +#define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1]) +#define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1]) +#define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc ) + +static void Fxu_HeapSingleResize( Fxu_HeapSingle * p ); +static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 ); +static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle ); +static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_HeapSingle * Fxu_HeapSingleStart() +{ + Fxu_HeapSingle * p; + p = ALLOC( Fxu_HeapSingle, 1 ); + memset( p, 0, sizeof(Fxu_HeapSingle) ); + p->nItems = 0; + p->nItemsAlloc = 2000; + p->pTree = ALLOC( Fxu_Single *, p->nItemsAlloc + 10 ); + p->pTree[0] = NULL; + return p; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleResize( Fxu_HeapSingle * p ) +{ + p->nItemsAlloc *= 2; + p->pTree = REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleStop( Fxu_HeapSingle * p ) +{ + int i; + i = 0; + free( p->pTree ); + i = 1; + free( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p ) +{ + Fxu_Single * pSingle; + int Counter = 1; + int Degree = 1; + + Fxu_HeapSingleCheck( p ); + fprintf( pFile, "The contents of the heap:\n" ); + fprintf( pFile, "Level %d: ", Degree ); + Fxu_HeapSingleForEachItem( p, pSingle ) + { + assert( Counter == p->pTree[Counter]->HNum ); + fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_WEIGHT(p->pTree[Counter]) ); + if ( ++Counter == (1 << Degree) ) + { + fprintf( pFile, "\n" ); + Degree++; + fprintf( pFile, "Level %d: ", Degree ); + } + } + fprintf( pFile, "\n" ); + fprintf( pFile, "End of the heap printout.\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleCheck( Fxu_HeapSingle * p ) +{ + Fxu_Single * pSingle; + Fxu_HeapSingleForEachItem( p, pSingle ) + { + assert( pSingle->HNum == p->i ); + Fxu_HeapSingleCheckOne( p, pSingle ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle ) +{ + int Weight1, Weight2; + if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) ) + { + Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle); + Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ); + assert( Weight1 >= Weight2 ); + } + if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) ) + { + Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle); + Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ); + assert( Weight1 >= Weight2 ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle ) +{ + if ( p->nItems == p->nItemsAlloc ) + Fxu_HeapSingleResize( p ); + // put the last entry to the last place and move up + p->pTree[++p->nItems] = pSingle; + pSingle->HNum = p->nItems; + // move the last entry up if necessary + Fxu_HeapSingleMoveUp( p, pSingle ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle ) +{ + FXU_HEAP_SINGLE_ASSERT(p,pSingle); + if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) && + FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) ) + Fxu_HeapSingleMoveUp( p, pSingle ); + else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) && + FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) ) + Fxu_HeapSingleMoveDn( p, pSingle ); + else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) && + FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) ) + Fxu_HeapSingleMoveDn( p, pSingle ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle ) +{ + int Place = pSingle->HNum; + FXU_HEAP_SINGLE_ASSERT(p,pSingle); + // put the last entry to the deleted place + // decrement the number of entries + p->pTree[Place] = p->pTree[p->nItems--]; + p->pTree[Place]->HNum = Place; + // move the top entry down if necessary + Fxu_HeapSingleUpdate( p, p->pTree[Place] ); + pSingle->HNum = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p ) +{ + if ( p->nItems == 0 ) + return NULL; + return p->pTree[1]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p ) +{ + Fxu_Single * pSingle; + if ( p->nItems == 0 ) + return NULL; + // prepare the return value + pSingle = p->pTree[1]; + pSingle->HNum = 0; + // put the last entry on top + // decrement the number of entries + p->pTree[1] = p->pTree[p->nItems--]; + p->pTree[1]->HNum = 1; + // move the top entry down if necessary + Fxu_HeapSingleMoveDn( p, p->pTree[1] ); + return pSingle; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p ) +{ + if ( p->nItems == 0 ) + return -1; + return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 ) +{ + Fxu_Single * pSingle; + int Temp; + pSingle = *pSingle1; + *pSingle1 = *pSingle2; + *pSingle2 = pSingle; + Temp = (*pSingle1)->HNum; + (*pSingle1)->HNum = (*pSingle2)->HNum; + (*pSingle2)->HNum = Temp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle ) +{ + Fxu_Single ** ppSingle, ** ppPar; + ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle); + while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) ) + { + ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle); + if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) ) + { + Fxu_HeapSingleSwap( ppSingle, ppPar ); + ppSingle = ppPar; + } + else + break; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle ) +{ + Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle; + ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle); + while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) ) + { // if Child1 does not exist, Child2 also does not exists + + // get the children + ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle); + if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) ) + { + ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle); + + // consider two cases + if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) && + FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) ) + { // Var is larger than both, skip + break; + } + else + { // Var is smaller than one of them, then swap it with larger + if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) ) + { + Fxu_HeapSingleSwap( ppSingle, ppChild1 ); + // update the pointer + ppSingle = ppChild1; + } + else + { + Fxu_HeapSingleSwap( ppSingle, ppChild2 ); + // update the pointer + ppSingle = ppChild2; + } + } + } + else // Child2 does not exist + { + // consider two cases + if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) ) + { // Var is larger than Child1, skip + break; + } + else + { // Var is smaller than Child1, then swap them + Fxu_HeapSingleSwap( ppSingle, ppChild1 ); + // update the pointer + ppSingle = ppChild1; + } + } + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/opt/fxu/fxuInt.h b/src/opt/fxu/fxuInt.h new file mode 100644 index 00000000..1f5a19b8 --- /dev/null +++ b/src/opt/fxu/fxuInt.h @@ -0,0 +1,541 @@ +/**CFile**************************************************************** + + FileName [fxuInt.h] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Internal declarations of fast extract for unate covers.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuInt.h,v 1.3 2003/04/10 05:42:44 donald Exp $] + +***********************************************************************/ + +#ifndef __FXU_INT_H__ +#define __FXU_INT_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "util.h" +#include "extra.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +// uncomment this macro to switch to standard memory management +//#define USE_SYSTEM_MEMORY_MANAGEMENT + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + Here is an informal description of the FX data structure. + (1) The sparse matrix is filled with literals, associated with + cubes (row) and variables (columns). The matrix contains + all the cubes of all the nodes in the network. + (2) A cube is associated with + (a) its literals in the matrix, + (b) the output variable of the node, to which this cube belongs, + (3) A variable is associated with + (a) its literals in the matrix and + (b) the list of cube pairs in the cover, for which it is the output + (4) A cube pair is associated with two cubes and contains the counters + of literals in the base and in the cubes without the base + (5) A double-cube divisor is associated with list of all cube pairs + that produce it and its current weight (which is updated automatically + each time a new pair is added or an old pair is removed). + (6) A single-cube divisor is associated the pair of variables. +*/ + +// sparse matrix +typedef struct FxuMatrix Fxu_Matrix; // the sparse matrix + +// sparse matrix contents: cubes (rows), vars (columns), literals (entries) +typedef struct FxuCube Fxu_Cube; // one cube in the sparse matrix +typedef struct FxuVar Fxu_Var; // one literal in the sparse matrix +typedef struct FxuLit Fxu_Lit; // one entry in the sparse matrix + +// double cube divisors +typedef struct FxuPair Fxu_Pair; // the pair of cubes +typedef struct FxuDouble Fxu_Double; // the double-cube divisor +typedef struct FxuSingle Fxu_Single; // the two-literal single-cube divisor + +// various lists +typedef struct FxuListCube Fxu_ListCube; // the list of cubes +typedef struct FxuListVar Fxu_ListVar; // the list of literals +typedef struct FxuListLit Fxu_ListLit; // the list of entries +typedef struct FxuListPair Fxu_ListPair; // the list of pairs +typedef struct FxuListDouble Fxu_ListDouble; // the list of divisors +typedef struct FxuListSingle Fxu_ListSingle; // the list of single-cube divisors + +// various heaps +typedef struct FxuHeapDouble Fxu_HeapDouble; // the heap of divisors +typedef struct FxuHeapSingle Fxu_HeapSingle; // the heap of variables + + +// various lists + +// the list of cubes in the sparse matrix +struct FxuListCube +{ + Fxu_Cube * pHead; + Fxu_Cube * pTail; + int nItems; +}; + +// the list of literals in the sparse matrix +struct FxuListVar +{ + Fxu_Var * pHead; + Fxu_Var * pTail; + int nItems; +}; + +// the list of entries in the sparse matrix +struct FxuListLit +{ + Fxu_Lit * pHead; + Fxu_Lit * pTail; + int nItems; +}; + +// the list of cube pair in the sparse matrix +struct FxuListPair +{ + Fxu_Pair * pHead; + Fxu_Pair * pTail; + int nItems; +}; + +// the list of divisors in the sparse matrix +struct FxuListDouble +{ + Fxu_Double * pHead; + Fxu_Double * pTail; + int nItems; +}; + +// the list of divisors in the sparse matrix +struct FxuListSingle +{ + Fxu_Single * pHead; + Fxu_Single * pTail; + int nItems; +}; + + +// various heaps + +// the heap of double cube divisors by weight +struct FxuHeapDouble +{ + Fxu_Double ** pTree; + int nItems; + int nItemsAlloc; + int i; +}; + +// the heap of variable by their occurrence in the cubes +struct FxuHeapSingle +{ + Fxu_Single ** pTree; + int nItems; + int nItemsAlloc; + int i; +}; + + + +// sparse matrix +struct FxuMatrix // ~ 30 words +{ + // information about the network +// int fMvNetwork; // set to 1 if the network has MV nodes +// int * pValue2Node; // the mapping of values into nodes + // the cubes + Fxu_ListCube lCubes; // the double linked list of cubes + // the values (binary literals) + Fxu_ListVar lVars; // the double linked list of variables + Fxu_Var ** ppVars; // the array of variables + // the double cube divisors + Fxu_ListDouble * pTable; // the hash table of divisors + int nTableSize; // the hash table size + int nDivs; // the number of divisors in the table + int nDivsTotal; // the number of divisors in the table + Fxu_HeapDouble * pHeapDouble; // the heap of divisors by weight + // the single cube divisors + Fxu_ListSingle lSingles; // the linked list of single cube divisors + Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix + // storage for cube pairs + Fxu_Pair *** pppPairs; + Fxu_Pair ** ppPairs; + // temporary storage for cubes + Fxu_Cube * pOrderCubes; + Fxu_Cube ** ppTailCubes; + // temporary storage for variables + Fxu_Var * pOrderVars; + Fxu_Var ** ppTailVars; + // temporary storage for pairs + Fxu_Pair ** pPairsTemp; + int nPairsTemp; +// int nPairsMax; + // statistics + int nEntries; // the total number of entries in the sparse matrix + int nDivs1; // the single cube divisors taken + int nDivs2; // the double cube divisors taken + int nDivs3; // the double cube divisors with complement + // memory manager + Extra_MmFixed_t * pMemMan; // the memory manager for all small sized entries +}; + +// the cube in the sparse matrix +struct FxuCube // 9 words +{ + int iCube; // the number of this cube in the cover + Fxu_Cube * pFirst; // the pointer to the first cube of this cover + Fxu_Var * pVar; // the variable representing the output of the cover + Fxu_ListLit lLits; // the row in the table + Fxu_Cube * pPrev; // the previous cube + Fxu_Cube * pNext; // the next cube + Fxu_Cube * pOrder; // the specialized linked list of cubes +}; + +// the variable in the sparse matrix +struct FxuVar // 10 words +{ + int iVar; // the number of this variable + int nCubes; // the number of cubes assoc with this var + Fxu_Cube * pFirst; // the first cube assoc with this var + Fxu_Pair *** ppPairs; // the pairs of cubes assoc with this var + Fxu_ListLit lLits; // the column in the table + Fxu_Var * pPrev; // the previous variable + Fxu_Var * pNext; // the next variable + Fxu_Var * pOrder; // the specialized linked list of variables +}; + +// the literal entry in the sparse matrix +struct FxuLit // 8 words +{ + int iVar; // the number of this variable + int iCube; // the number of this cube + Fxu_Cube * pCube; // the cube of this literal + Fxu_Var * pVar; // the variable of this literal + Fxu_Lit * pHPrev; // prev lit in the cube + Fxu_Lit * pHNext; // next lit in the cube + Fxu_Lit * pVPrev; // prev lit of the var + Fxu_Lit * pVNext; // next lit of the var +}; + +// the cube pair +struct FxuPair // 10 words +{ + int nLits1; // the number of literals in the two cubes + int nLits2; // the number of literals in the two cubes + int nBase; // the number of literals in the base + Fxu_Double * pDiv; // the divisor of this pair + Fxu_Cube * pCube1; // the first cube of the pair + Fxu_Cube * pCube2; // the second cube of the pair + int iCube1; // the first cube of the pair + int iCube2; // the second cube of the pair + Fxu_Pair * pDPrev; // the previous pair in the divisor + Fxu_Pair * pDNext; // the next pair in the divisor +}; + +// the double cube divisor +struct FxuDouble // 10 words +{ + int Num; // the unique number of this divisor + int HNum; // the heap number of this divisor + int Weight; // the weight of this divisor + unsigned Key; // the hash key of this divisor + Fxu_ListPair lPairs; // the pairs of cubes, which produce this divisor + Fxu_Double * pPrev; // the previous divisor in the table + Fxu_Double * pNext; // the next divisor in the table + Fxu_Double * pOrder; // the specialized linked list of divisors +}; + +// the single cube divisor +struct FxuSingle // 7 words +{ + int Num; // the unique number of this divisor + int HNum; // the heap number of this divisor + int Weight; // the weight of this divisor + Fxu_Var * pVar1; // the first variable of the single-cube divisor + Fxu_Var * pVar2; // the second variable of the single-cube divisor + Fxu_Single * pPrev; // the previous divisor in the list + Fxu_Single * pNext; // the next divisor in the list +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +// minimum/maximum +#define Fxu_Min( a, b ) ( ((a)<(b))? (a):(b) ) +#define Fxu_Max( a, b ) ( ((a)>(b))? (a):(b) ) + +// selection of the minimum/maximum cube in the pair +#define Fxu_PairMinCube( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2) +#define Fxu_PairMaxCube( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2) +#define Fxu_PairMinCubeInt( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2) +#define Fxu_PairMaxCubeInt( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2) + +// iterators + +#define Fxu_MatrixForEachCube( Matrix, Cube )\ + for ( Cube = (Matrix)->lCubes.pHead;\ + Cube;\ + Cube = Cube->pNext ) +#define Fxu_MatrixForEachCubeSafe( Matrix, Cube, Cube2 )\ + for ( Cube = (Matrix)->lCubes.pHead, Cube2 = (Cube? Cube->pNext: NULL);\ + Cube;\ + Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) + +#define Fxu_MatrixForEachVariable( Matrix, Var )\ + for ( Var = (Matrix)->lVars.pHead;\ + Var;\ + Var = Var->pNext ) +#define Fxu_MatrixForEachVariableSafe( Matrix, Var, Var2 )\ + for ( Var = (Matrix)->lVars.pHead, Var2 = (Var? Var->pNext: NULL);\ + Var;\ + Var = Var2, Var2 = (Var? Var->pNext: NULL) ) + +#define Fxu_MatrixForEachSingle( Matrix, Single )\ + for ( Single = (Matrix)->lSingles.pHead;\ + Single;\ + Single = Single->pNext ) +#define Fxu_MatrixForEachSingleSafe( Matrix, Single, Single2 )\ + for ( Single = (Matrix)->lSingles.pHead, Single2 = (Single? Single->pNext: NULL);\ + Single;\ + Single = Single2, Single2 = (Single? Single->pNext: NULL) ) + +#define Fxu_TableForEachDouble( Matrix, Key, Div )\ + for ( Div = (Matrix)->pTable[Key].pHead;\ + Div;\ + Div = Div->pNext ) +#define Fxu_TableForEachDoubleSafe( Matrix, Key, Div, Div2 )\ + for ( Div = (Matrix)->pTable[Key].pHead, Div2 = (Div? Div->pNext: NULL);\ + Div;\ + Div = Div2, Div2 = (Div? Div->pNext: NULL) ) + +#define Fxu_MatrixForEachDouble( Matrix, Div, Index )\ + for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\ + Fxu_TableForEachDouble( Matrix, Index, Div ) +#define Fxu_MatrixForEachDoubleSafe( Matrix, Div, Div2, Index )\ + for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\ + Fxu_TableForEachDoubleSafe( Matrix, Index, Div, Div2 ) + + +#define Fxu_CubeForEachLiteral( Cube, Lit )\ + for ( Lit = (Cube)->lLits.pHead;\ + Lit;\ + Lit = Lit->pHNext ) +#define Fxu_CubeForEachLiteralSafe( Cube, Lit, Lit2 )\ + for ( Lit = (Cube)->lLits.pHead, Lit2 = (Lit? Lit->pHNext: NULL);\ + Lit;\ + Lit = Lit2, Lit2 = (Lit? Lit->pHNext: NULL) ) + +#define Fxu_VarForEachLiteral( Var, Lit )\ + for ( Lit = (Var)->lLits.pHead;\ + Lit;\ + Lit = Lit->pVNext ) + +#define Fxu_CubeForEachDivisor( Cube, Div )\ + for ( Div = (Cube)->lDivs.pHead;\ + Div;\ + Div = Div->pCNext ) + +#define Fxu_DoubleForEachPair( Div, Pair )\ + for ( Pair = (Div)->lPairs.pHead;\ + Pair;\ + Pair = Pair->pDNext ) +#define Fxu_DoubleForEachPairSafe( Div, Pair, Pair2 )\ + for ( Pair = (Div)->lPairs.pHead, Pair2 = (Pair? Pair->pDNext: NULL);\ + Pair;\ + Pair = Pair2, Pair2 = (Pair? Pair->pDNext: NULL) ) + + +// iterator through the cube pairs belonging to the given cube +#define Fxu_CubeForEachPair( pCube, pPair, i )\ + for ( i = 0;\ + i < pCube->pVar->nCubes &&\ + (((unsigned)(pPair = pCube->pVar->ppPairs[pCube->iCube][i])) >= 0);\ + i++ )\ + if ( pPair ) + +// iterator through all the items in the heap +#define Fxu_HeapDoubleForEachItem( Heap, Div )\ + for ( Heap->i = 1;\ + Heap->i <= Heap->nItems && (Div = Heap->pTree[Heap->i]);\ + Heap->i++ ) +#define Fxu_HeapSingleForEachItem( Heap, Single )\ + for ( Heap->i = 1;\ + Heap->i <= Heap->nItems && (Single = Heap->pTree[Heap->i]);\ + Heap->i++ ) + +// starting the rings +#define Fxu_MatrixRingCubesStart( Matrix ) (((Matrix)->ppTailCubes = &((Matrix)->pOrderCubes)), ((Matrix)->pOrderCubes = NULL)) +#define Fxu_MatrixRingVarsStart( Matrix ) (((Matrix)->ppTailVars = &((Matrix)->pOrderVars)), ((Matrix)->pOrderVars = NULL)) +// stopping the rings +#define Fxu_MatrixRingCubesStop( Matrix ) +#define Fxu_MatrixRingVarsStop( Matrix ) +// resetting the rings +#define Fxu_MatrixRingCubesReset( Matrix ) (((Matrix)->pOrderCubes = NULL), ((Matrix)->ppTailCubes = NULL)) +#define Fxu_MatrixRingVarsReset( Matrix ) (((Matrix)->pOrderVars = NULL), ((Matrix)->ppTailVars = NULL)) +// adding to the rings +#define Fxu_MatrixRingCubesAdd( Matrix, Cube) ((*((Matrix)->ppTailCubes) = Cube), ((Matrix)->ppTailCubes = &(Cube)->pOrder), ((Cube)->pOrder = (Fxu_Cube *)1)) +#define Fxu_MatrixRingVarsAdd( Matrix, Var ) ((*((Matrix)->ppTailVars ) = Var ), ((Matrix)->ppTailVars = &(Var)->pOrder ), ((Var)->pOrder = (Fxu_Var *)1)) +// iterating through the rings +#define Fxu_MatrixForEachCubeInRing( Matrix, Cube )\ + if ( (Matrix)->pOrderCubes )\ + for ( Cube = (Matrix)->pOrderCubes;\ + Cube != (Fxu_Cube *)1;\ + Cube = Cube->pOrder ) +#define Fxu_MatrixForEachCubeInRingSafe( Matrix, Cube, Cube2 )\ + if ( (Matrix)->pOrderCubes )\ + for ( Cube = (Matrix)->pOrderCubes, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1);\ + Cube != (Fxu_Cube *)1;\ + Cube = Cube2, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1) ) +#define Fxu_MatrixForEachVarInRing( Matrix, Var )\ + if ( (Matrix)->pOrderVars )\ + for ( Var = (Matrix)->pOrderVars;\ + Var != (Fxu_Var *)1;\ + Var = Var->pOrder ) +#define Fxu_MatrixForEachVarInRingSafe( Matrix, Var, Var2 )\ + if ( (Matrix)->pOrderVars )\ + for ( Var = (Matrix)->pOrderVars, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1);\ + Var != (Fxu_Var *)1;\ + Var = Var2, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1) ) +// the procedures are related to the above macros +extern void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p ); +extern void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p ); + + +// macros working with memory +// MEM_ALLOC: allocate the given number (Size) of items of type (Type) +// MEM_FREE: deallocate the pointer (Pointer) to the given number (Size) of items of type (Type) +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT +#define MEM_ALLOC_FXU( Manager, Type, Size ) ((Type *)malloc( (Size) * sizeof(Type) )) +#define MEM_FREE_FXU( Manager, Type, Size, Pointer ) if ( Pointer ) { free(Pointer); Pointer = NULL; } +#else +#define MEM_ALLOC_FXU( Manager, Type, Size )\ + ((Type *)Fxu_MemFetch( Manager, (Size) * sizeof(Type) )) +#define MEM_FREE_FXU( Manager, Type, Size, Pointer )\ + if ( Pointer ) { Fxu_MemRecycle( Manager, (char *)(Pointer), (Size) * sizeof(Type) ); Pointer = NULL; } +#endif + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/*===== fxu.c ====================================================*/ +extern char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes ); +extern void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes ); +/*===== fxuCreate.c ====================================================*/ +/*===== fxuReduce.c ====================================================*/ +/*===== fxuPrint.c ====================================================*/ +extern void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p ); +extern void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p ); +/*===== fxuSelect.c ====================================================*/ +extern int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble ); +extern int Fxu_SelectSCD( Fxu_Matrix * p, int Weight, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 ); +/*===== fxuUpdate.c ====================================================*/ +extern void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble ); +extern void Fxu_UpdateDouble( Fxu_Matrix * p ); +extern void Fxu_UpdateSingle( Fxu_Matrix * p ); +/*===== fxuPair.c ====================================================*/ +extern void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 ); +extern unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ); +extern unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 ); +extern unsigned Fxu_PairHashKeyMv( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 ); +extern int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 ); +extern void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes ); +extern void Fxu_PairFreeStorage( Fxu_Var * pVar ); +extern void Fxu_PairClearStorage( Fxu_Cube * pCube ); +extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ); +extern void Fxu_PairAdd( Fxu_Pair * pPair ); +/*===== fxuSingle.c ====================================================*/ +extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p ); +extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ); +extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 ); +/*===== fxuMatrix.c ====================================================*/ +// matrix +extern Fxu_Matrix * Fxu_MatrixAllocate(); +extern void Fxu_MatrixDelete( Fxu_Matrix * p ); +// double-cube divisor +extern void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ); +extern void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ); +// single-cube divisor +extern void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight ); +// variable +extern Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p ); +// cube +extern Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube ); +// literal +extern void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar ); +extern void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit ); +/*===== fxuList.c ====================================================*/ +// matrix -> variable +extern void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pVar ); +extern void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pVar ); +// matrix -> cube +extern void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube ); +extern void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pCube ); +// matrix -> single +extern void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pSingle ); +extern void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pSingle ); +// table -> divisor +extern void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ); +extern void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ); +// cube -> literal +extern void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit ); +extern void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit ); +// var -> literal +extern void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLit ); +extern void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLit ); +// divisor -> pair +extern void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink ); +extern void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink ); +extern void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink ); +extern void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pPair ); +/*===== fxuHeapDouble.c ====================================================*/ +extern Fxu_HeapDouble * Fxu_HeapDoubleStart(); +extern void Fxu_HeapDoubleStop( Fxu_HeapDouble * p ); +extern void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p ); +extern void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p ); +extern void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv ); + +extern void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv ); +extern void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv ); +extern void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv ); +extern int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p ); +extern Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p ); +extern Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p ); +/*===== fxuHeapSingle.c ====================================================*/ +extern Fxu_HeapSingle * Fxu_HeapSingleStart(); +extern void Fxu_HeapSingleStop( Fxu_HeapSingle * p ); +extern void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p ); +extern void Fxu_HeapSingleCheck( Fxu_HeapSingle * p ); +extern void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle ); + +extern void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle ); +extern void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle ); +extern void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle ); +extern int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p ); +extern Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p ); +extern Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p ); + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/fxu/fxuList.c b/src/opt/fxu/fxuList.c new file mode 100644 index 00000000..bb081d80 --- /dev/null +++ b/src/opt/fxu/fxuList.c @@ -0,0 +1,522 @@ +/**CFile**************************************************************** + + FileName [fxuList.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Operations on lists.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuList.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +// matrix -> var + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pLink ) +{ + Fxu_ListVar * pList = &p->lVars; + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pPrev = NULL; + pLink->pNext = NULL; + } + else + { + pLink->pNext = NULL; + pList->pTail->pNext = pLink; + pLink->pPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pLink ) +{ + Fxu_ListVar * pList = &p->lVars; + if ( pList->pHead == pLink ) + pList->pHead = pLink->pNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pPrev; + if ( pLink->pPrev ) + pLink->pPrev->pNext = pLink->pNext; + if ( pLink->pNext ) + pLink->pNext->pPrev = pLink->pPrev; + pList->nItems--; +} + + +// matrix -> cube + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pLink ) +{ + Fxu_ListCube * pList = &p->lCubes; + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pPrev = NULL; + pLink->pNext = NULL; + } + else + { + pLink->pNext = NULL; + pList->pTail->pNext = pLink; + pLink->pPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pLink ) +{ + Fxu_ListCube * pList = &p->lCubes; + if ( pList->pHead == pLink ) + pList->pHead = pLink->pNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pPrev; + if ( pLink->pPrev ) + pLink->pPrev->pNext = pLink->pNext; + if ( pLink->pNext ) + pLink->pNext->pPrev = pLink->pPrev; + pList->nItems--; +} + + +// matrix -> single + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pLink ) +{ + Fxu_ListSingle * pList = &p->lSingles; + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pPrev = NULL; + pLink->pNext = NULL; + } + else + { + pLink->pNext = NULL; + pList->pTail->pNext = pLink; + pLink->pPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pLink ) +{ + Fxu_ListSingle * pList = &p->lSingles; + if ( pList->pHead == pLink ) + pList->pHead = pLink->pNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pPrev; + if ( pLink->pPrev ) + pLink->pPrev->pNext = pLink->pNext; + if ( pLink->pNext ) + pLink->pNext->pPrev = pLink->pPrev; + pList->nItems--; +} + + +// table -> divisor + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pLink ) +{ + Fxu_ListDouble * pList = &(p->pTable[pLink->Key]); + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pPrev = NULL; + pLink->pNext = NULL; + } + else + { + pLink->pNext = NULL; + pList->pTail->pNext = pLink; + pLink->pPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; + p->nDivs++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pLink ) +{ + Fxu_ListDouble * pList = &(p->pTable[pLink->Key]); + if ( pList->pHead == pLink ) + pList->pHead = pLink->pNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pPrev; + if ( pLink->pPrev ) + pLink->pPrev->pNext = pLink->pNext; + if ( pLink->pNext ) + pLink->pNext->pPrev = pLink->pPrev; + pList->nItems--; + p->nDivs--; +} + + +// cube -> literal + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink ) +{ + Fxu_ListLit * pList = &(pCube->lLits); + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pHPrev = NULL; + pLink->pHNext = NULL; + } + else + { + pLink->pHNext = NULL; + pList->pTail->pHNext = pLink; + pLink->pHPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink ) +{ + Fxu_ListLit * pList = &(pCube->lLits); + if ( pList->pHead == pLink ) + pList->pHead = pLink->pHNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pHPrev; + if ( pLink->pHPrev ) + pLink->pHPrev->pHNext = pLink->pHNext; + if ( pLink->pHNext ) + pLink->pHNext->pHPrev = pLink->pHPrev; + pList->nItems--; +} + + +// var -> literal + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLink ) +{ + Fxu_ListLit * pList = &(pVar->lLits); + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pVPrev = NULL; + pLink->pVNext = NULL; + } + else + { + pLink->pVNext = NULL; + pList->pTail->pVNext = pLink; + pLink->pVPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLink ) +{ + Fxu_ListLit * pList = &(pVar->lLits); + if ( pList->pHead == pLink ) + pList->pHead = pLink->pVNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pVPrev; + if ( pLink->pVPrev ) + pLink->pVPrev->pVNext = pLink->pVNext; + if ( pLink->pVNext ) + pLink->pVNext->pVPrev = pLink->pVPrev; + pList->nItems--; +} + + + +// divisor -> pair + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink ) +{ + Fxu_ListPair * pList = &pDiv->lPairs; + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pDPrev = NULL; + pLink->pDNext = NULL; + } + else + { + pLink->pDNext = NULL; + pList->pTail->pDNext = pLink; + pLink->pDPrev = pList->pTail; + pList->pTail = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink ) +{ + Fxu_ListPair * pList = &pDiv->lPairs; + if ( pList->pHead == NULL ) + { + pList->pHead = pLink; + pList->pTail = pLink; + pLink->pDPrev = NULL; + pLink->pDNext = NULL; + } + else + { + pLink->pDPrev = NULL; + pList->pHead->pDPrev = pLink; + pLink->pDNext = pList->pHead; + pList->pHead = pLink; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [Adds the entry in the middle of the list after the spot.] + + Description [Assumes that spot points to the link, after which the given + link should be added. Spot cannot be NULL or the tail of the list. + Therefore, the head and the tail of the list are not changed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink ) +{ + Fxu_ListPair * pList = &pDiv->lPairs; + assert( pSpot ); + assert( pSpot != pList->pTail ); + pLink->pDPrev = pSpot; + pLink->pDNext = pSpot->pDNext; + pLink->pDPrev->pDNext = pLink; + pLink->pDNext->pDPrev = pLink; + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pLink ) +{ + Fxu_ListPair * pList = &pDiv->lPairs; + if ( pList->pHead == pLink ) + pList->pHead = pLink->pDNext; + if ( pList->pTail == pLink ) + pList->pTail = pLink->pDPrev; + if ( pLink->pDPrev ) + pLink->pDPrev->pDNext = pLink->pDNext; + if ( pLink->pDNext ) + pLink->pDNext->pDPrev = pLink->pDPrev; + pList->nItems--; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_ListDoubleAddPairPlace( Fxu_Double * pDiv, Fxu_Pair * pPair, Fxu_Pair * pPairSpot ) +{ + printf( "Fxu_ListDoubleAddPairPlace() is called!\n" ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuMatrix.c b/src/opt/fxu/fxuMatrix.c new file mode 100644 index 00000000..0b732aef --- /dev/null +++ b/src/opt/fxu/fxuMatrix.c @@ -0,0 +1,382 @@ +/**CFile**************************************************************** + + FileName [fxuMatrix.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Procedures to manipulate the sparse matrix.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuMatrix.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern unsigned int Cudd_Prime( unsigned int p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Matrix * Fxu_MatrixAllocate() +{ + Fxu_Matrix * p; + p = ALLOC( Fxu_Matrix, 1 ); + memset( p, 0, sizeof(Fxu_Matrix) ); + p->nTableSize = Cudd_Prime(10000); + p->pTable = ALLOC( Fxu_ListDouble, p->nTableSize ); + memset( p->pTable, 0, sizeof(Fxu_ListDouble) * p->nTableSize ); +#ifndef USE_SYSTEM_MEMORY_MANAGEMENT + { + // get the largest size in bytes for the following structures: + // Fxu_Cube, Fxu_Var, Fxu_Lit, Fxu_Pair, Fxu_Double, Fxu_Single + // (currently, Fxu_Var, Fxu_Pair, Fxu_Double take 10 machine words) + int nSizeMax, nSizeCur; + nSizeMax = -1; + nSizeCur = sizeof(Fxu_Cube); + if ( nSizeMax < nSizeCur ) + nSizeMax = nSizeCur; + nSizeCur = sizeof(Fxu_Var); + if ( nSizeMax < nSizeCur ) + nSizeMax = nSizeCur; + nSizeCur = sizeof(Fxu_Lit); + if ( nSizeMax < nSizeCur ) + nSizeMax = nSizeCur; + nSizeCur = sizeof(Fxu_Pair); + if ( nSizeMax < nSizeCur ) + nSizeMax = nSizeCur; + nSizeCur = sizeof(Fxu_Double); + if ( nSizeMax < nSizeCur ) + nSizeMax = nSizeCur; + nSizeCur = sizeof(Fxu_Single); + if ( nSizeMax < nSizeCur ) + nSizeMax = nSizeCur; + p->pMemMan = Extra_MmFixedStart( nSizeMax ); + } +#endif + p->pHeapDouble = Fxu_HeapDoubleStart(); + p->pHeapSingle = Fxu_HeapSingleStart(); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixDelete( Fxu_Matrix * p ) +{ + Fxu_HeapDoubleCheck( p->pHeapDouble ); + Fxu_HeapDoubleStop( p->pHeapDouble ); + Fxu_HeapSingleStop( p->pHeapSingle ); + + // delete other things +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT + // this code is not needed when the custom memory manager is used + { + Fxu_Cube * pCube, * pCube2; + Fxu_Var * pVar, * pVar2; + Fxu_Lit * pLit, * pLit2; + Fxu_Double * pDiv, * pDiv2; + Fxu_Single * pSingle, * pSingle2; + Fxu_Pair * pPair, * pPair2; + int i; + // delete the divisors + Fxu_MatrixForEachDoubleSafe( p, pDiv, pDiv2, i ) + { + Fxu_DoubleForEachPairSafe( pDiv, pPair, pPair2 ) + MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); + MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); + } + Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 ) + MEM_FREE_FXU( p, Fxu_Single, 1, pSingle ); + // delete the entries + Fxu_MatrixForEachCube( p, pCube ) + Fxu_CubeForEachLiteralSafe( pCube, pLit, pLit2 ) + MEM_FREE_FXU( p, Fxu_Lit, 1, pLit ); + // delete the cubes + Fxu_MatrixForEachCubeSafe( p, pCube, pCube2 ) + MEM_FREE_FXU( p, Fxu_Cube, 1, pCube ); + // delete the vars + Fxu_MatrixForEachVariableSafe( p, pVar, pVar2 ) + MEM_FREE_FXU( p, Fxu_Var, 1, pVar ); + } +#else + Extra_MmFixedStop( p->pMemMan, 0 ); +#endif + + FREE( p->pppPairs ); + FREE( p->ppPairs ); + FREE( p->pPairsTemp ); + FREE( p->pTable ); + FREE( p->ppVars ); + FREE( p ); +} + + + +/**Function************************************************************* + + Synopsis [Adds a variable to the matrix.] + + Description [This procedure always adds variables at the end of the matrix. + It assigns the var's node and number. It adds the var to the linked list of + all variables and to the table of all nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p ) +{ + Fxu_Var * pVar; + pVar = MEM_ALLOC_FXU( p, Fxu_Var, 1 ); + memset( pVar, 0, sizeof(Fxu_Var) ); + pVar->iVar = p->lVars.nItems; + p->ppVars[pVar->iVar] = pVar; + Fxu_ListMatrixAddVariable( p, pVar ); + return pVar; +} + +/**Function************************************************************* + + Synopsis [Adds a literal to the matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube ) +{ + Fxu_Cube * pCube; + pCube = MEM_ALLOC_FXU( p, Fxu_Cube, 1 ); + memset( pCube, 0, sizeof(Fxu_Cube) ); + pCube->pVar = pVar; + pCube->iCube = iCube; + Fxu_ListMatrixAddCube( p, pCube ); + return pCube; +} + +/**Function************************************************************* + + Synopsis [Adds a literal to the matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar ) +{ + Fxu_Lit * pLit; + pLit = MEM_ALLOC_FXU( p, Fxu_Lit, 1 ); + memset( pLit, 0, sizeof(Fxu_Lit) ); + // insert the literal into two linked lists + Fxu_ListCubeAddLiteral( pCube, pLit ); + Fxu_ListVarAddLiteral( pVar, pLit ); + // set the back pointers + pLit->pCube = pCube; + pLit->pVar = pVar; + pLit->iCube = pCube->iCube; + pLit->iVar = pVar->iVar; + // increment the literal counter + p->nEntries++; +} + +/**Function************************************************************* + + Synopsis [Deletes the divisor from the matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ) +{ + // delete divisor from the table + Fxu_ListTableDelDivisor( p, pDiv ); + // recycle the divisor + MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); +} + +/**Function************************************************************* + + Synopsis [Deletes the literal fromthe matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit ) +{ + // delete the literal + Fxu_ListCubeDelLiteral( pLit->pCube, pLit ); + Fxu_ListVarDelLiteral( pLit->pVar, pLit ); + MEM_FREE_FXU( p, Fxu_Lit, 1, pLit ); + // increment the literal counter + p->nEntries--; +} + + +/**Function************************************************************* + + Synopsis [Creates and adds a single cube divisor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight ) +{ + Fxu_Single * pSingle; + assert( pVar1->iVar < pVar2->iVar ); + pSingle = MEM_ALLOC_FXU( p, Fxu_Single, 1 ); + memset( pSingle, 0, sizeof(Fxu_Single) ); + pSingle->Num = p->lSingles.nItems; + pSingle->Weight = Weight; + pSingle->HNum = 0; + pSingle->pVar1 = pVar1; + pSingle->pVar2 = pVar2; + Fxu_ListMatrixAddSingle( p, pSingle ); + // add to the heap + Fxu_HeapSingleInsert( p->pHeapSingle, pSingle ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ) +{ + Fxu_Pair * pPair; + Fxu_Double * pDiv; + int nBase, nLits1, nLits2; + int fFound; + unsigned Key; + + // canonicize the pair + Fxu_PairCanonicize( &pCube1, &pCube2 ); + +/* + // compute the hash key + if ( p->fMvNetwork ) +// if ( 0 ) + { // in case of MV network, if all the values in the cube-free divisor + // belong to the same MV variable, this cube pair is not a divisor + Key = Fxu_PairHashKeyMv( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 ); + if ( Key == 0 ) + return; + } + else +*/ + Key = Fxu_PairHashKey( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 ); + + // create the cube pair + pPair = Fxu_PairAlloc( p, pCube1, pCube2 ); + pPair->nBase = nBase; + pPair->nLits1 = nLits1; + pPair->nLits2 = nLits2; + + // check if the divisor for this pair already exists + fFound = 0; + Key %= p->nTableSize; + Fxu_TableForEachDouble( p, Key, pDiv ) + if ( Fxu_PairCompare( pPair, pDiv->lPairs.pTail ) ) // they are equal + { + fFound = 1; + break; + } + + if ( !fFound ) + { // create the new divisor + pDiv = MEM_ALLOC_FXU( p, Fxu_Double, 1 ); + memset( pDiv, 0, sizeof(Fxu_Double) ); + pDiv->Key = Key; + // set the number of this divisor + pDiv->Num = p->nDivsTotal++; // p->nDivs; + // insert the divisor in the table + Fxu_ListTableAddDivisor( p, pDiv ); + // set the initial cost of the divisor + pDiv->Weight -= pPair->nLits1 + pPair->nLits2; + } + + // link the pair to the cubes + Fxu_PairAdd( pPair ); + // connect the pair and the divisor + pPair->pDiv = pDiv; + Fxu_ListDoubleAddPairLast( pDiv, pPair ); + // update the max number of pairs in a divisor +// if ( p->nPairsMax < pDiv->lPairs.nItems ) +// p->nPairsMax = pDiv->lPairs.nItems; + // update the divisor's weight + pDiv->Weight += pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase; + if ( fFound ) // update the divisor in the heap + Fxu_HeapDoubleUpdate( p->pHeapDouble, pDiv ); + else // add the new divisor to the heap + Fxu_HeapDoubleInsert( p->pHeapDouble, pDiv ); +} + +/* + { + int piVarsC1[100], piVarsC2[100], nVarsC1, nVarsC2; + Fxu_Double * pDivCur; + Fxu_MatrixGetDoubleVars( p, pDiv, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); + pDivCur = Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 ); + assert( pDivCur == pDiv ); + } +*/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuPair.c b/src/opt/fxu/fxuPair.c new file mode 100644 index 00000000..be6be5e9 --- /dev/null +++ b/src/opt/fxu/fxuPair.c @@ -0,0 +1,555 @@ +/**CFile**************************************************************** + + FileName [fxuPair.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Operations on cube pairs.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuPair.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_PRIMES 304 + +static s_Primes[MAX_PRIMES] = +{ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, + 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, + 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, + 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, + 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, + 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, + 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, + 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, + 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, + 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, + 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, + 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, + 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, + 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, + 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, + 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, + 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, + 1993, 1997, 1999, 2003 +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Find the canonical permutation of two cubes in the pair.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 ) +{ + Fxu_Lit * pLit1, * pLit2; + Fxu_Cube * pCubeTemp; + + // walk through the cubes to determine + // the one that has higher first variable + pLit1 = (*ppCube1)->lLits.pHead; + pLit2 = (*ppCube2)->lLits.pHead; + while ( 1 ) + { + if ( pLit1->iVar == pLit2->iVar ) + { + pLit1 = pLit1->pHNext; + pLit2 = pLit2->pHNext; + continue; + } + assert( pLit1 && pLit2 ); // this is true if the covers are SCC-free + if ( pLit1->iVar > pLit2->iVar ) + { // swap the cubes + pCubeTemp = *ppCube1; + *ppCube1 = *ppCube2; + *ppCube2 = pCubeTemp; + } + break; + } +} + +/**Function************************************************************* + + Synopsis [Find the canonical permutation of two cubes in the pair.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_PairCanonicize2( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 ) +{ + Fxu_Cube * pCubeTemp; + // canonicize the pair by ordering the cubes + if ( (*ppCube1)->iCube > (*ppCube2)->iCube ) + { // swap the cubes + pCubeTemp = *ppCube1; + *ppCube1 = *ppCube2; + *ppCube2 = pCubeTemp; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ) +{ + int Offset1 = 100, Offset2 = 200, i; + unsigned Key; + // compute the hash key + Key = 0; + for ( i = 0; i < nVarsC1; i++ ) + Key ^= s_Primes[Offset1+i] * piVarsC1[i]; + for ( i = 0; i < nVarsC2; i++ ) + Key ^= s_Primes[Offset2+i] * piVarsC2[i]; + return Key; +} + +/**Function************************************************************* + + Synopsis [Computes the hash key of the divisor represented by the pair of cubes.] + + Description [Goes through the variables in both cubes. Skips the identical + ones (this corresponds to making the cubes cube-free). Computes the hash + value of the cubes. Assigns the number of literals in the base and in the + cubes without base.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, + int * pnBase, int * pnLits1, int * pnLits2 ) +{ + int Offset1 = 100, Offset2 = 200; + int nBase, nLits1, nLits2; + Fxu_Lit * pLit1, * pLit2; + unsigned Key; + + // compute the hash key + Key = 0; + nLits1 = 0; + nLits2 = 0; + nBase = 0; + pLit1 = pCube1->lLits.pHead; + pLit2 = pCube2->lLits.pHead; + while ( 1 ) + { + if ( pLit1 && pLit2 ) + { + if ( pLit1->iVar == pLit2->iVar ) + { // ensure cube-free + pLit1 = pLit1->pHNext; + pLit2 = pLit2->pHNext; + // add this literal to the base + nBase++; + } + else if ( pLit1->iVar < pLit2->iVar ) + { + Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar; + pLit1 = pLit1->pHNext; + nLits1++; + } + else + { + Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar; + pLit2 = pLit2->pHNext; + nLits2++; + } + } + else if ( pLit1 && !pLit2 ) + { + Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar; + pLit1 = pLit1->pHNext; + nLits1++; + } + else if ( !pLit1 && pLit2 ) + { + Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar; + pLit2 = pLit2->pHNext; + nLits2++; + } + else + break; + } + *pnBase = nBase; + *pnLits1 = nLits1; + *pnLits2 = nLits2; + return Key; +} + +/**Function************************************************************* + + Synopsis [Compares the two pairs.] + + Description [Returns 1 if the divisors represented by these pairs + are equal.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 ) +{ + Fxu_Lit * pD1C1, * pD1C2; + Fxu_Lit * pD2C1, * pD2C2; + int TopVar1, TopVar2; + int Code; + + if ( pPair1->nLits1 != pPair2->nLits1 ) + return 0; + if ( pPair1->nLits2 != pPair2->nLits2 ) + return 0; + + pD1C1 = pPair1->pCube1->lLits.pHead; + pD1C2 = pPair1->pCube2->lLits.pHead; + + pD2C1 = pPair2->pCube1->lLits.pHead; + pD2C2 = pPair2->pCube2->lLits.pHead; + + Code = pD1C1? 8: 0; + Code |= pD1C2? 4: 0; + Code |= pD2C1? 2: 0; + Code |= pD2C2? 1: 0; + assert( Code == 15 ); + + while ( 1 ) + { + switch ( Code ) + { + case 0: // -- -- NULL NULL NULL NULL + return 1; + case 1: // -- -1 NULL NULL NULL pD2C2 + return 0; + case 2: // -- 1- NULL NULL pD2C1 NULL + return 0; + case 3: // -- 11 NULL NULL pD2C1 pD2C2 + if ( pD2C1->iVar != pD2C2->iVar ) + return 0; + pD2C1 = pD2C1->pHNext; + pD2C2 = pD2C2->pHNext; + break; + case 4: // -1 -- NULL pD1C2 NULL NULL + return 0; + case 5: // -1 -1 NULL pD1C2 NULL pD2C2 + if ( pD1C2->iVar != pD2C2->iVar ) + return 0; + pD1C2 = pD1C2->pHNext; + pD2C2 = pD2C2->pHNext; + break; + case 6: // -1 1- NULL pD1C2 pD2C1 NULL + return 0; + case 7: // -1 11 NULL pD1C2 pD2C1 pD2C2 + TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar ); + if ( TopVar2 == pD1C2->iVar ) + { + if ( pD2C1->iVar <= pD2C2->iVar ) + return 0; + pD1C2 = pD1C2->pHNext; + pD2C2 = pD2C2->pHNext; + } + else if ( TopVar2 < pD1C2->iVar ) + { + if ( pD2C1->iVar != pD2C2->iVar ) + return 0; + pD2C1 = pD2C1->pHNext; + pD2C2 = pD2C2->pHNext; + } + else + return 0; + break; + case 8: // 1- -- pD1C1 NULL NULL NULL + return 0; + case 9: // 1- -1 pD1C1 NULL NULL pD2C2 + return 0; + case 10: // 1- 1- pD1C1 NULL pD2C1 NULL + if ( pD1C1->iVar != pD2C1->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD2C1 = pD2C1->pHNext; + break; + case 11: // 1- 11 pD1C1 NULL pD2C1 pD2C2 + TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar ); + if ( TopVar2 == pD1C1->iVar ) + { + if ( pD2C1->iVar >= pD2C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD2C1 = pD2C1->pHNext; + } + else if ( TopVar2 < pD1C1->iVar ) + { + if ( pD2C1->iVar != pD2C2->iVar ) + return 0; + pD2C1 = pD2C1->pHNext; + pD2C2 = pD2C2->pHNext; + } + else + return 0; + break; + case 12: // 11 -- pD1C1 pD1C2 NULL NULL + if ( pD1C1->iVar != pD1C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD1C2 = pD1C2->pHNext; + break; + case 13: // 11 -1 pD1C1 pD1C2 NULL pD2C2 + TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar ); + if ( TopVar1 == pD2C2->iVar ) + { + if ( pD1C1->iVar <= pD1C2->iVar ) + return 0; + pD1C2 = pD1C2->pHNext; + pD2C2 = pD2C2->pHNext; + } + else if ( TopVar1 < pD2C2->iVar ) + { + if ( pD1C1->iVar != pD1C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD1C2 = pD1C2->pHNext; + } + else + return 0; + break; + case 14: // 11 1- pD1C1 pD1C2 pD2C1 NULL + TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar ); + if ( TopVar1 == pD2C1->iVar ) + { + if ( pD1C1->iVar >= pD1C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD2C1 = pD2C1->pHNext; + } + else if ( TopVar1 < pD2C1->iVar ) + { + if ( pD1C1->iVar != pD1C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD1C2 = pD1C2->pHNext; + } + else + return 0; + break; + case 15: // 11 11 pD1C1 pD1C2 pD2C1 pD2C2 + TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar ); + TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar ); + if ( TopVar1 == TopVar2 ) + { + if ( pD1C1->iVar == pD1C2->iVar ) + { + if ( pD2C1->iVar != pD2C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD1C2 = pD1C2->pHNext; + pD2C1 = pD2C1->pHNext; + pD2C2 = pD2C2->pHNext; + } + else + { + if ( pD2C1->iVar == pD2C2->iVar ) + return 0; + if ( pD1C1->iVar < pD1C2->iVar ) + { + if ( pD2C1->iVar > pD2C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD2C1 = pD2C1->pHNext; + } + else + { + if ( pD2C1->iVar < pD2C2->iVar ) + return 0; + pD1C2 = pD1C2->pHNext; + pD2C2 = pD2C2->pHNext; + } + } + } + else if ( TopVar1 < TopVar2 ) + { + if ( pD1C1->iVar != pD1C2->iVar ) + return 0; + pD1C1 = pD1C1->pHNext; + pD1C2 = pD1C2->pHNext; + } + else + { + if ( pD2C1->iVar != pD2C2->iVar ) + return 0; + pD2C1 = pD2C1->pHNext; + pD2C2 = pD2C2->pHNext; + } + break; + default: + assert( 0 ); + break; + } + + Code = pD1C1? 8: 0; + Code |= pD1C2? 4: 0; + Code |= pD2C1? 2: 0; + Code |= pD2C2? 1: 0; + } + return 1; +} + + +/**Function************************************************************* + + Synopsis [Allocates the storage for cubes pairs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes ) +{ + int k; +// assert( pVar->nCubes == 0 ); + pVar->nCubes = nCubes; + // allocate memory for all the pairs + pVar->ppPairs = ALLOC( Fxu_Pair **, nCubes ); + pVar->ppPairs[0] = ALLOC( Fxu_Pair *, nCubes * nCubes ); + memset( pVar->ppPairs[0], 0, sizeof(Fxu_Pair *) * nCubes * nCubes ); + for ( k = 1; k < nCubes; k++ ) + pVar->ppPairs[k] = pVar->ppPairs[k-1] + nCubes; +} + +/**Function************************************************************* + + Synopsis [Clears all pairs associated with this cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_PairClearStorage( Fxu_Cube * pCube ) +{ + Fxu_Var * pVar; + int i; + pVar = pCube->pVar; + for ( i = 0; i < pVar->nCubes; i++ ) + { + pVar->ppPairs[pCube->iCube][i] = NULL; + pVar->ppPairs[i][pCube->iCube] = NULL; + } +} + +/**Function************************************************************* + + Synopsis [Clears all pairs associated with this cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_PairFreeStorage( Fxu_Var * pVar ) +{ + if ( pVar->ppPairs ) + { + FREE( pVar->ppPairs[0] ); + FREE( pVar->ppPairs ); + } +} + +/**Function************************************************************* + + Synopsis [Adds the pair to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ) +{ + Fxu_Pair * pPair; + assert( pCube1->pVar == pCube2->pVar ); + pPair = MEM_ALLOC_FXU( p, Fxu_Pair, 1 ); + memset( pPair, 0, sizeof(Fxu_Pair) ); + pPair->pCube1 = pCube1; + pPair->pCube2 = pCube2; + pPair->iCube1 = pCube1->iCube; + pPair->iCube2 = pCube2->iCube; + return pPair; +} + +/**Function************************************************************* + + Synopsis [Adds the pair to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_PairAdd( Fxu_Pair * pPair ) +{ + Fxu_Var * pVar; + + pVar = pPair->pCube1->pVar; + assert( pVar == pPair->pCube2->pVar ); + + pVar->ppPairs[pPair->iCube1][pPair->iCube2] = pPair; + pVar->ppPairs[pPair->iCube2][pPair->iCube1] = pPair; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuPrint.c b/src/opt/fxu/fxuPrint.c new file mode 100644 index 00000000..2d25c0e9 --- /dev/null +++ b/src/opt/fxu/fxuPrint.c @@ -0,0 +1,195 @@ +/**CFile**************************************************************** + + FileName [fxuPrint.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Various printing procedures.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuPrint.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p ) +{ + Fxu_Var * pVar; + Fxu_Cube * pCube; + Fxu_Double * pDiv; + Fxu_Single * pSingle; + Fxu_Lit * pLit; + Fxu_Pair * pPair; + int i, LastNum; + int fStdout; + + fStdout = 1; + if ( pFile == NULL ) + { + pFile = fopen( "matrix.txt", "w" ); + fStdout = 0; + } + + fprintf( pFile, "Matrix has %d vars, %d cubes, %d literals, %d divisors.\n", + p->lVars.nItems, p->lCubes.nItems, p->nEntries, p->nDivs ); + fprintf( pFile, "Divisors selected so far: single = %d, double = %d.\n", + p->nDivs1, p->nDivs2 ); + fprintf( pFile, "\n" ); + + // print the numbers on top of the matrix + for ( i = 0; i < 12; i++ ) + fprintf( pFile, " " ); + Fxu_MatrixForEachVariable( p, pVar ) + fprintf( pFile, "%d", pVar->iVar % 10 ); + fprintf( pFile, "\n" ); + + // print the rows + Fxu_MatrixForEachCube( p, pCube ) + { + fprintf( pFile, "%4d", pCube->iCube ); + fprintf( pFile, " " ); + fprintf( pFile, "%4d", pCube->pVar->iVar ); + fprintf( pFile, " " ); + + // print the literals + LastNum = -1; + Fxu_CubeForEachLiteral( pCube, pLit ) + { + for ( i = LastNum + 1; i < pLit->pVar->iVar; i++ ) + fprintf( pFile, "." ); + fprintf( pFile, "1" ); + LastNum = i; + } + for ( i = LastNum + 1; i < p->lVars.nItems; i++ ) + fprintf( pFile, "." ); + fprintf( pFile, "\n" ); + } + fprintf( pFile, "\n" ); + + // print the double-cube divisors + fprintf( pFile, "The double divisors are:\n" ); + Fxu_MatrixForEachDouble( p, pDiv, i ) + { + fprintf( pFile, "Divisor #%3d (lit=%d,%d) (w=%2d): ", + pDiv->Num, pDiv->lPairs.pHead->nLits1, + pDiv->lPairs.pHead->nLits2, pDiv->Weight ); + Fxu_DoubleForEachPair( pDiv, pPair ) + fprintf( pFile, " <%d, %d> (b=%d)", + pPair->pCube1->iCube, pPair->pCube2->iCube, pPair->nBase ); + fprintf( pFile, "\n" ); + } + fprintf( pFile, "\n" ); + + // print the divisors associated with each cube + fprintf( pFile, "The cubes are:\n" ); + Fxu_MatrixForEachCube( p, pCube ) + { + fprintf( pFile, "Cube #%3d: ", pCube->iCube ); + if ( pCube->pVar->ppPairs ) + Fxu_CubeForEachPair( pCube, pPair, i ) + fprintf( pFile, " <%d %d> (d=%d) (b=%d)", + pPair->iCube1, pPair->iCube2, pPair->pDiv->Num, pPair->nBase ); + fprintf( pFile, "\n" ); + } + fprintf( pFile, "\n" ); + + // print the single-cube divisors + fprintf( pFile, "The single divisors are:\n" ); + Fxu_MatrixForEachSingle( p, pSingle ) + { + fprintf( pFile, "Single-cube divisor #%5d: Var1 = %4d. Var2 = %4d. Weight = %2d\n", + pSingle->Num, pSingle->pVar1->iVar, pSingle->pVar2->iVar, pSingle->Weight ); + } + fprintf( pFile, "\n" ); + +/* + { + int Index; + fprintf( pFile, "Distribution of divisors in the hash table:\n" ); + for ( Index = 0; Index < p->nTableSize; Index++ ) + fprintf( pFile, " %d", p->pTable[Index].nItems ); + fprintf( pFile, "\n" ); + } +*/ + if ( !fStdout ) + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p ) +{ + Fxu_Double * pDiv; + int WeightMax; + int * pProfile; + int Counter1; // the number of -1 weight + int CounterL; // the number of less than -1 weight + int i; + + WeightMax = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); + pProfile = ALLOC( int, (WeightMax + 1) ); + memset( pProfile, 0, sizeof(int) * (WeightMax + 1) ); + + Counter1 = 0; + CounterL = 0; + Fxu_MatrixForEachDouble( p, pDiv, i ) + { + assert( pDiv->Weight <= WeightMax ); + if ( pDiv->Weight == -1 ) + Counter1++; + else if ( pDiv->Weight < 0 ) + CounterL++; + else + pProfile[ pDiv->Weight ]++; + } + + fprintf( pFile, "The double divisors profile:\n" ); + fprintf( pFile, "Weight < -1 divisors = %6d\n", CounterL ); + fprintf( pFile, "Weight -1 divisors = %6d\n", Counter1 ); + for ( i = 0; i <= WeightMax; i++ ) + if ( pProfile[i] ) + fprintf( pFile, "Weight %3d divisors = %6d\n", i, pProfile[i] ); + fprintf( pFile, "End of divisor profile printout\n" ); + FREE( pProfile ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuReduce.c b/src/opt/fxu/fxuReduce.c new file mode 100644 index 00000000..652d807b --- /dev/null +++ b/src/opt/fxu/fxuReduce.c @@ -0,0 +1,194 @@ +/**CFile**************************************************************** + + FileName [fxuReduce.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Procedures to reduce the number of considered cube pairs.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuReduce.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fxuInt.h" +#include "fxu.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Precomputes the pairs to use for creating two-cube divisors.] + + Description [This procedure takes the matrix with variables and cubes + allocated (p), the original covers of the nodes (i-sets) and their number + (ppCovers,nCovers). The maximum number of pairs to compute and the total + number of pairs in existence. This procedure adds to the storage of + divisors exactly the given number of pairs (nPairsMax) while taking + first those pairs that have the smallest number of literals in their + cube-free form.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax ) +{ + unsigned char * pnLitsDiff; // storage for the counters of diff literals + int * pnPairCounters; // the counters of pairs for each number of diff literals + Fxu_Cube * pCubeFirst, * pCubeLast; + Fxu_Cube * pCube1, * pCube2; + Fxu_Var * pVar; + int nCubes, nBitsMax, nSum; + int CutOffNum, CutOffQuant; + int iPair, iQuant, k, c; + int clk = clock(); + char * pSopCover; + int nFanins; + + assert( nPairsMax < nPairsTotal ); + + // allocate storage for counter of diffs + pnLitsDiff = ALLOC( unsigned char, nPairsTotal ); + // go through the covers and precompute the distances between the pairs + iPair = 0; + nBitsMax = -1; + for ( c = 0; c < vCovers->nSize; c++ ) + if ( pSopCover = vCovers->pArray[c] ) + { + nFanins = Abc_SopGetVarNum(pSopCover); + // precompute the differences + Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair ); + // update the counter + nCubes = Abc_SopGetCubeNum( pSopCover ); + iPair += nCubes * (nCubes - 1) / 2; + if ( nBitsMax < nFanins ) + nBitsMax = nFanins; + } + assert( iPair == nPairsTotal ); + + // allocate storage for counters of cube pairs by difference + pnPairCounters = ALLOC( int, 2 * nBitsMax ); + memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax ); + // count the number of different pairs + for ( k = 0; k < nPairsTotal; k++ ) + pnPairCounters[ pnLitsDiff[k] ]++; + // determine what pairs to take starting from the lower + // so that there would be exactly pPairsMax pairs + assert( pnPairCounters[0] == 0 ); // otherwise, covers are not dup-free + assert( pnPairCounters[1] == 0 ); // otherwise, covers are not SCC-free + nSum = 0; + for ( k = 0; k < 2 * nBitsMax; k++ ) + { + nSum += pnPairCounters[k]; + if ( nSum >= nPairsMax ) + { + CutOffNum = k; + CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax); + break; + } + } + FREE( pnPairCounters ); + + // set to 0 all the pairs above the cut-off number and quantity + iQuant = 0; + iPair = 0; + for ( k = 0; k < nPairsTotal; k++ ) + if ( pnLitsDiff[k] > CutOffNum ) + pnLitsDiff[k] = 0; + else if ( pnLitsDiff[k] == CutOffNum ) + { + if ( iQuant++ >= CutOffQuant ) + pnLitsDiff[k] = 0; + else + iPair++; + } + else + iPair++; + assert( iPair == nPairsMax ); + + // collect the corresponding pairs and add the divisors + iPair = 0; + for ( c = 0; c < vCovers->nSize; c++ ) + if ( pSopCover = vCovers->pArray[c] ) + { + // get the var + pVar = p->ppVars[2*c+1]; + // get the first cube + pCubeFirst = pVar->pFirst; + // get the last cube + pCubeLast = pCubeFirst; + for ( k = 0; k < pVar->nCubes; k++ ) + pCubeLast = pCubeLast->pNext; + assert( pCubeLast == NULL || pCubeLast->pVar != pVar ); + + // go through the cube pairs + for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext ) + for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext ) + if ( pnLitsDiff[iPair++] ) + { // create the divisors for this pair + Fxu_MatrixAddDivisor( p, pCube1, pCube2 ); + } + } + assert( iPair == nPairsTotal ); + FREE( pnLitsDiff ); +//PRT( "Preprocess", clock() - clk ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Counts the differences in each cube pair in the cover.] + + Description [Takes the cover (pCover) and the array where the + diff counters go (pDiffs). The array pDiffs should have as many + entries as there are different pairs of cubes in the cover: n(n-1)/2. + Fills out the array pDiffs with the following info: For each cube + pair, included in the array is the number of literals in both cubes + after they are made cube free.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] ) +{ + char * pCube1, * pCube2; + int nOnes, nCubePairs, nFanins, v; + nCubePairs = 0; + nFanins = Abc_SopGetVarNum(pCover); + Abc_SopForEachCube( pCover, nFanins, pCube1 ) + Abc_SopForEachCube( pCube1, nFanins, pCube2 ) + { + if ( pCube1 == pCube2 ) + continue; + nOnes = 0; + for ( v = 0; v < nFanins; v++ ) + nOnes += (pCube1[v] != pCube2[v]); + pDiffs[nCubePairs++] = nOnes; + } + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuSelect.c b/src/opt/fxu/fxuSelect.c new file mode 100644 index 00000000..b56407a9 --- /dev/null +++ b/src/opt/fxu/fxuSelect.c @@ -0,0 +1,603 @@ +/**CFile**************************************************************** + + FileName [fxuSelect.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Procedures to select the best divisor/complement pair.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuSelect.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_SIZE_LOOKAHEAD 20 + +static int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar ); + +static Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle ); +static Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble ); +static Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble ); + +Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p, + int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ); +void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble, + int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 ); + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Selects the best pair (Single,Double) and returns their weight.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble ) +{ + // the top entries + Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD]; + Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD]; + // the complements + Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD]; + Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD]; + Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD]; + Fxu_Pair * pPair; + int nSingles; + int nDoubles; + int i; + int WeightBest; + int WeightCur; + int iNum, fBestS; + + // collect the top entries from the queues + for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ ) + { + pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle ); + if ( pSingles[nSingles] == NULL ) + break; + } + // put them back into the queue + for ( i = 0; i < nSingles; i++ ) + if ( pSingles[i] ) + Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] ); + + // the same for doubles + // collect the top entries from the queues + for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ ) + { + pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble ); + if ( pDoubles[nDoubles] == NULL ) + break; + } + // put them back into the queue + for ( i = 0; i < nDoubles; i++ ) + if ( pDoubles[i] ) + Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] ); + + // for each single, find the complement double (if any) + for ( i = 0; i < nSingles; i++ ) + if ( pSingles[i] ) + pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] ); + + // for each double, find the complement single or double (if any) + for ( i = 0; i < nDoubles; i++ ) + if ( pDoubles[i] ) + { + pPair = pDoubles[i]->lPairs.pHead; + if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 ) + { + pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] ); + pDComplD[i] = NULL; + } +// else if ( pPair->nLits1 == 2 && pPair->nLits2 == 2 ) +// { +// pDComplS[i] = NULL; +// pDComplD[i] = Fxu_MatrixFindComplementDouble4( p, pDoubles[i] ); +// } + else + { + pDComplS[i] = NULL; + pDComplD[i] = NULL; + } + } + + // select the best pair + WeightBest = -1; + for ( i = 0; i < nSingles; i++ ) + { + WeightCur = pSingles[i]->Weight; + if ( pSCompl[i] ) + { + // add the weight of the double + WeightCur += pSCompl[i]->Weight; + // there is no need to implement this double, so... + pPair = pSCompl[i]->lPairs.pHead; + WeightCur += pPair->nLits1 + pPair->nLits2; + } + if ( WeightBest < WeightCur ) + { + WeightBest = WeightCur; + *ppSingle = pSingles[i]; + *ppDouble = pSCompl[i]; + fBestS = 1; + iNum = i; + } + } + for ( i = 0; i < nDoubles; i++ ) + { + WeightCur = pDoubles[i]->Weight; + if ( pDComplS[i] ) + { + // add the weight of the single + WeightCur += pDComplS[i]->Weight; + // there is no need to implement this double, so... + pPair = pDoubles[i]->lPairs.pHead; + WeightCur += pPair->nLits1 + pPair->nLits2; + } + if ( WeightBest < WeightCur ) + { + WeightBest = WeightCur; + *ppSingle = pDComplS[i]; + *ppDouble = pDoubles[i]; + fBestS = 0; + iNum = i; + } + } +/* + // print the statistics + printf( "\n" ); + for ( i = 0; i < nSingles; i++ ) + { + printf( "Single #%d: Weight = %3d. ", i, pSingles[i]->Weight ); + printf( "Compl: " ); + if ( pSCompl[i] == NULL ) + printf( "None." ); + else + printf( "D Weight = %3d Sum = %3d", + pSCompl[i]->Weight, pSCompl[i]->Weight + pSingles[i]->Weight ); + printf( "\n" ); + } + printf( "\n" ); + for ( i = 0; i < nDoubles; i++ ) + { + printf( "Double #%d: Weight = %3d. ", i, pDoubles[i]->Weight ); + printf( "Compl: " ); + if ( pDComplS[i] == NULL && pDComplD[i] == NULL ) + printf( "None." ); + else if ( pDComplS[i] ) + printf( "S Weight = %3d Sum = %3d", + pDComplS[i]->Weight, pDComplS[i]->Weight + pDoubles[i]->Weight ); + else if ( pDComplD[i] ) + printf( "D Weight = %3d Sum = %3d", + pDComplD[i]->Weight, pDComplD[i]->Weight + pDoubles[i]->Weight ); + printf( "\n" ); + } + if ( WeightBest == -1 ) + printf( "Selected NONE\n" ); + else + { + printf( "Selected = %s. ", fBestS? "S": "D" ); + printf( "Number = %d. ", iNum ); + printf( "Weight = %d.\n", WeightBest ); + } + printf( "\n" ); +*/ + return WeightBest; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle ) +{ +// int * pValue2Node = p->pValue2Node; + int iVar1, iVar2; + int iVar1C, iVar2C; + // get the variables of this single div + iVar1 = pSingle->pVar1->iVar; + iVar2 = pSingle->pVar2->iVar; + iVar1C = Fxu_MatrixFindComplement( p, iVar1 ); + iVar2C = Fxu_MatrixFindComplement( p, iVar2 ); + if ( iVar1C == -1 || iVar2C == -1 ) + return NULL; + assert( iVar1C < iVar2C ); + return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble ) +{ +// int * pValue2Node = p->pValue2Node; + int piVarsC1[10], piVarsC2[10]; + int nVarsC1, nVarsC2; + int iVar1, iVar2, iVarTemp; + int iVar1C, iVar2C; + Fxu_Single * pSingle; + + // get the variables of this double div + Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); + assert( nVarsC1 == 1 ); + assert( nVarsC2 == 1 ); + iVar1 = piVarsC1[0]; + iVar2 = piVarsC2[0]; + assert( iVar1 < iVar2 ); + + iVar1C = Fxu_MatrixFindComplement( p, iVar1 ); + iVar2C = Fxu_MatrixFindComplement( p, iVar2 ); + if ( iVar1C == -1 || iVar2C == -1 ) + return NULL; + + // go through the queque and find this one +// assert( iVar1C < iVar2C ); + if ( iVar1C > iVar2C ) + { + iVarTemp = iVar1C; + iVar1C = iVar2C; + iVar2C = iVarTemp; + } + + Fxu_MatrixForEachSingle( p, pSingle ) + if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C ) + return pSingle; + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble ) +{ +// int * pValue2Node = p->pValue2Node; + int piVarsC1[10], piVarsC2[10]; + int nVarsC1, nVarsC2; + int iVar11, iVar12, iVar21, iVar22; + int iVar11C, iVar12C, iVar21C, iVar22C; + int RetValue; + + // get the variables of this double div + Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); + assert( nVarsC1 == 2 && nVarsC2 == 2 ); + + iVar11 = piVarsC1[0]; + iVar12 = piVarsC1[1]; + iVar21 = piVarsC2[0]; + iVar22 = piVarsC2[1]; + assert( iVar11 < iVar21 ); + + iVar11C = Fxu_MatrixFindComplement( p, iVar11 ); + iVar12C = Fxu_MatrixFindComplement( p, iVar12 ); + iVar21C = Fxu_MatrixFindComplement( p, iVar21 ); + iVar22C = Fxu_MatrixFindComplement( p, iVar22 ); + if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 ) + return NULL; + if ( iVar11C != iVar21 || iVar12C != iVar22 || + iVar21C != iVar11 || iVar22C != iVar12 ) + return NULL; + + // a'b' + ab => a'b + ab' + // a'b + ab' => a'b' + ab + // swap the second pair in each cube + RetValue = piVarsC1[1]; + piVarsC1[1] = piVarsC2[1]; + piVarsC2[1] = RetValue; + + return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar ) +{ + return iVar ^ 1; +/* +// int * pValue2Node = p->pValue2Node; + int iVarC; + int iNode; + int Beg, End; + + // get the nodes + iNode = pValue2Node[iVar]; + // get the first node with the same var + for ( Beg = iVar; Beg >= 0; Beg-- ) + if ( pValue2Node[Beg] != iNode ) + { + Beg++; + break; + } + // get the last node with the same var + for ( End = iVar; ; End++ ) + if ( pValue2Node[End] != iNode ) + { + End--; + break; + } + + // if one of the vars is not binary, quit + if ( End - Beg > 1 ) + return -1; + + // get the complements + if ( iVar == Beg ) + iVarC = End; + else if ( iVar == End ) + iVarC = Beg; + else + { + assert( 0 ); + } + return iVarC; +*/ +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble, + int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 ) +{ + Fxu_Pair * pPair; + Fxu_Lit * pLit1, * pLit2; + int nLits1, nLits2; + + // get the first pair + pPair = pDouble->lPairs.pHead; + // init the parameters + nLits1 = 0; + nLits2 = 0; + pLit1 = pPair->pCube1->lLits.pHead; + pLit2 = pPair->pCube2->lLits.pHead; + while ( 1 ) + { + if ( pLit1 && pLit2 ) + { + if ( pLit1->iVar == pLit2->iVar ) + { // ensure cube-free + pLit1 = pLit1->pHNext; + pLit2 = pLit2->pHNext; + } + else if ( pLit1->iVar < pLit2->iVar ) + { + piVarsC1[nLits1++] = pLit1->iVar; + pLit1 = pLit1->pHNext; + } + else + { + piVarsC2[nLits2++] = pLit2->iVar; + pLit2 = pLit2->pHNext; + } + } + else if ( pLit1 && !pLit2 ) + { + piVarsC1[nLits1++] = pLit1->iVar; + pLit1 = pLit1->pHNext; + } + else if ( !pLit1 && pLit2 ) + { + piVarsC2[nLits2++] = pLit2->iVar; + pLit2 = pLit2->pHNext; + } + else + break; + } + *pnVarsC1 = nLits1; + *pnVarsC2 = nLits2; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p, + int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ) +{ + int piVarsC1_[100], piVarsC2_[100]; + int nVarsC1_, nVarsC2_, i; + Fxu_Double * pDouble; + Fxu_Pair * pPair; + unsigned Key; + + assert( nVarsC1 > 0 ); + assert( nVarsC2 > 0 ); + assert( piVarsC1[0] < piVarsC2[0] ); + + // get the hash key + Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 ); + + // check if the divisor for this pair already exists + Key %= p->nTableSize; + Fxu_TableForEachDouble( p, Key, pDouble ) + { + pPair = pDouble->lPairs.pHead; + if ( pPair->nLits1 != nVarsC1 ) + continue; + if ( pPair->nLits2 != nVarsC2 ) + continue; + // get the cubes of this divisor + Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ ); + // compare lits of the first cube + for ( i = 0; i < nVarsC1; i++ ) + if ( piVarsC1[i] != piVarsC1_[i] ) + break; + if ( i != nVarsC1 ) + continue; + // compare lits of the second cube + for ( i = 0; i < nVarsC2; i++ ) + if ( piVarsC2[i] != piVarsC2_[i] ) + break; + if ( i != nVarsC2 ) + continue; + return pDouble; + } + return NULL; +} + + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_SelectSCD( Fxu_Matrix * p, int WeightLimit, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 ) +{ +// int * pValue2Node = p->pValue2Node; + Fxu_Var * pVar1; + Fxu_Var * pVar2, * pVarTemp; + Fxu_Lit * pLitV, * pLitH; + int Coin; + int CounterAll; + int CounterTest; + int WeightCur; + int WeightBest; + + CounterAll = 0; + CounterTest = 0; + + WeightBest = -10; + + // iterate through the columns in the matrix + Fxu_MatrixForEachVariable( p, pVar1 ) + { + // start collecting the affected vars + Fxu_MatrixRingVarsStart( p ); + + // go through all the literals of this variable + for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext ) + { + // for this literal, go through all the horizontal literals + for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext ) + { + // get another variable + pVar2 = pLitH->pVar; + CounterAll++; + // skip the var if it is already used + if ( pVar2->pOrder ) + continue; + // skip the var if it belongs to the same node +// if ( pValue2Node[pVar1->iVar] == pValue2Node[pVar2->iVar] ) +// continue; + // collect the var + Fxu_MatrixRingVarsAdd( p, pVar2 ); + } + } + // stop collecting the selected vars + Fxu_MatrixRingVarsStop( p ); + + // iterate through the selected vars + Fxu_MatrixForEachVarInRing( p, pVar2 ) + { + CounterTest++; + + // count the coincidence + Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 ); + assert( Coin > 0 ); + + // get the new weight + WeightCur = Coin - 2; + + // compare the weights + if ( WeightBest < WeightCur ) + { + WeightBest = WeightCur; + *ppVar1 = pVar1; + *ppVar2 = pVar2; + } + } + // unmark the vars + Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp ) + pVar2->pOrder = NULL; + Fxu_MatrixRingVarsReset( p ); + } + +// if ( WeightBest == WeightLimit ) +// return -1; + return WeightBest; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuSingle.c b/src/opt/fxu/fxuSingle.c new file mode 100644 index 00000000..5af5c341 --- /dev/null +++ b/src/opt/fxu/fxuSingle.c @@ -0,0 +1,166 @@ +/**CFile**************************************************************** + + FileName [fxuSingle.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Procedures to compute the set of single-cube divisors.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuSingle.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes and adds all single-cube divisors to storage.] + + Description [This procedure should be called once when the matrix is + already contructed before the process of logic extraction begins..] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixComputeSingles( Fxu_Matrix * p ) +{ + Fxu_Var * pVar; + // iterate through the columns in the matrix + Fxu_MatrixForEachVariable( p, pVar ) + Fxu_MatrixComputeSinglesOne( p, pVar ); +} + +/**Function************************************************************* + + Synopsis [Adds the single-cube divisors associated with a new column.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) +{ +// int * pValue2Node = p->pValue2Node; + Fxu_Lit * pLitV, * pLitH; + Fxu_Var * pVar2; + int Coin; +// int CounterAll; +// int CounterTest; + int WeightCur; + + // start collecting the affected vars + Fxu_MatrixRingVarsStart( p ); + // go through all the literals of this variable + for ( pLitV = pVar->lLits.pHead; pLitV; pLitV = pLitV->pVNext ) + // for this literal, go through all the horizontal literals + for ( pLitH = pLitV->pHPrev; pLitH; pLitH = pLitH->pHPrev ) + { + // get another variable + pVar2 = pLitH->pVar; +// CounterAll++; + // skip the var if it is already used + if ( pVar2->pOrder ) + continue; + // skip the var if it belongs to the same node +// if ( pValue2Node[pVar->iVar] == pValue2Node[pVar2->iVar] ) +// continue; + // collect the var + Fxu_MatrixRingVarsAdd( p, pVar2 ); + } + // stop collecting the selected vars + Fxu_MatrixRingVarsStop( p ); + + // iterate through the selected vars + Fxu_MatrixForEachVarInRing( p, pVar2 ) + { +// CounterTest++; + // count the coincidence + Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar ); + assert( Coin > 0 ); + // get the new weight + WeightCur = Coin - 2; + if ( WeightCur >= 0 ) + Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur ); + } + + // unmark the vars + Fxu_MatrixRingVarsUnmark( p ); +} + +/**Function************************************************************* + + Synopsis [Computes the coincidence count of two columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 ) +{ + Fxu_Lit * pLit1, * pLit2; + int Result; + + // compute the coincidence count + Result = 0; + pLit1 = pVar1->lLits.pHead; + pLit2 = pVar2->lLits.pHead; + while ( 1 ) + { + if ( pLit1 && pLit2 ) + { + if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar ) + { // the variables are the same + if ( pLit1->iCube == pLit2->iCube ) + { // the literals are the same + pLit1 = pLit1->pVNext; + pLit2 = pLit2->pVNext; + // add this literal to the coincidence + Result++; + } + else if ( pLit1->iCube < pLit2->iCube ) + pLit1 = pLit1->pVNext; + else + pLit2 = pLit2->pVNext; + } + else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar ) + pLit1 = pLit1->pVNext; + else + pLit2 = pLit2->pVNext; + } + else if ( pLit1 && !pLit2 ) + pLit1 = pLit1->pVNext; + else if ( !pLit1 && pLit2 ) + pLit2 = pLit2->pVNext; + else + break; + } + return Result; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/fxuUpdate.c b/src/opt/fxu/fxuUpdate.c new file mode 100644 index 00000000..b781e0b1 --- /dev/null +++ b/src/opt/fxu/fxuUpdate.c @@ -0,0 +1,802 @@ +/**CFile**************************************************************** + + FileName [fxuUpdate.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Updating the sparse matrix when divisors are accepted.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: fxuUpdate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fxuInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar ); +static void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv ); +static void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem ); +static void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew ); + +static void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes ); +static int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 ); +static void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble ); + +static void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube ); +static void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube ); +static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ); +static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Updates the matrix after selecting two divisors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble ) +{ + Fxu_Cube * pCube, * pCubeNew; + Fxu_Var * pVarC, * pVarD; + Fxu_Var * pVar1, * pVar2; + + // consider trivial cases + if ( pSingle == NULL ) + { + assert( pDouble->Weight == Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ) ); + Fxu_UpdateDouble( p ); + return; + } + if ( pDouble == NULL ) + { + assert( pSingle->Weight == Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ) ); + Fxu_UpdateSingle( p ); + return; + } + + // get the variables of the single + pVar1 = pSingle->pVar1; + pVar2 = pSingle->pVar2; + + // remove the best double from the heap + Fxu_HeapDoubleDelete( p->pHeapDouble, pDouble ); + // remove the best divisor from the table + Fxu_ListTableDelDivisor( p, pDouble ); + + // create two new columns (vars) + Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 ); + // create one new row (cube) + pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 ); + pCubeNew->pFirst = pCubeNew; + // set the first cube of the positive var + pVarD->pFirst = pCubeNew; + + // start collecting the affected vars and cubes + Fxu_MatrixRingCubesStart( p ); + Fxu_MatrixRingVarsStart( p ); + // add the vars + Fxu_MatrixRingVarsAdd( p, pVar1 ); + Fxu_MatrixRingVarsAdd( p, pVar2 ); + // remove the literals and collect the affected cubes + // remove the divisors associated with this cube + // add to the affected cube the literal corresponding to the new column + Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD ); + // replace each two cubes of the pair by one new cube + // the new cube contains the base and the new literal + Fxu_UpdateDoublePairs( p, pDouble, pVarC ); + // stop collecting the affected vars and cubes + Fxu_MatrixRingCubesStop( p ); + Fxu_MatrixRingVarsStop( p ); + + // add the literals to the new cube + assert( pVar1->iVar < pVar2->iVar ); + assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 ); + Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 ); + Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 ); + + // create new doubles; we cannot add them in the same loop + // because we first have to create *all* new cubes for each node + Fxu_MatrixForEachCubeInRing( p, pCube ) + Fxu_UpdateAddNewDoubles( p, pCube ); + // update the singles after removing some literals + Fxu_UpdateCleanOldSingles( p ); + + // undo the temporary rings with cubes and vars + Fxu_MatrixRingCubesUnmark( p ); + Fxu_MatrixRingVarsUnmark( p ); + // we should undo the rings before creating new singles + + // create new singles + Fxu_UpdateAddNewSingles( p, pVarC ); + Fxu_UpdateAddNewSingles( p, pVarD ); + + // recycle the divisor + MEM_FREE_FXU( p, Fxu_Double, 1, pDouble ); + p->nDivs3++; +} + +/**Function************************************************************* + + Synopsis [Updates after accepting single cube divisor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateSingle( Fxu_Matrix * p ) +{ + Fxu_Single * pSingle; + Fxu_Cube * pCube, * pCubeNew; + Fxu_Var * pVarC, * pVarD; + Fxu_Var * pVar1, * pVar2; + + // read the best divisor from the heap + pSingle = Fxu_HeapSingleReadMax( p->pHeapSingle ); + // get the variables of this single-cube divisor + pVar1 = pSingle->pVar1; + pVar2 = pSingle->pVar2; + + // create two new columns (vars) + Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 ); + // create one new row (cube) + pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 ); + pCubeNew->pFirst = pCubeNew; + // set the first cube + pVarD->pFirst = pCubeNew; + + // start collecting the affected vars and cubes + Fxu_MatrixRingCubesStart( p ); + Fxu_MatrixRingVarsStart( p ); + // add the vars + Fxu_MatrixRingVarsAdd( p, pVar1 ); + Fxu_MatrixRingVarsAdd( p, pVar2 ); + // remove the literals and collect the affected cubes + // remove the divisors associated with this cube + // add to the affected cube the literal corresponding to the new column + Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD ); + // stop collecting the affected vars and cubes + Fxu_MatrixRingCubesStop( p ); + Fxu_MatrixRingVarsStop( p ); + + // add the literals to the new cube + assert( pVar1->iVar < pVar2->iVar ); + assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 ); + Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 ); + Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 ); + + // create new doubles; we cannot add them in the same loop + // because we first have to create *all* new cubes for each node + Fxu_MatrixForEachCubeInRing( p, pCube ) + Fxu_UpdateAddNewDoubles( p, pCube ); + // update the singles after removing some literals + Fxu_UpdateCleanOldSingles( p ); + // we should undo the rings before creating new singles + + // unmark the cubes + Fxu_MatrixRingCubesUnmark( p ); + Fxu_MatrixRingVarsUnmark( p ); + + // create new singles + Fxu_UpdateAddNewSingles( p, pVarC ); + Fxu_UpdateAddNewSingles( p, pVarD ); + p->nDivs1++; +} + +/**Function************************************************************* + + Synopsis [Updates the matrix after accepting a double cube divisor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateDouble( Fxu_Matrix * p ) +{ + Fxu_Double * pDiv; + Fxu_Cube * pCube, * pCubeNew1, * pCubeNew2; + Fxu_Var * pVarC, * pVarD; + + // remove the best divisor from the heap + pDiv = Fxu_HeapDoubleGetMax( p->pHeapDouble ); + // remove the best divisor from the table + Fxu_ListTableDelDivisor( p, pDiv ); + + // create two new columns (vars) + Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 2 ); + // create two new rows (cubes) + pCubeNew1 = Fxu_MatrixAddCube( p, pVarD, 0 ); + pCubeNew1->pFirst = pCubeNew1; + pCubeNew2 = Fxu_MatrixAddCube( p, pVarD, 1 ); + pCubeNew2->pFirst = pCubeNew1; + // set the first cube + pVarD->pFirst = pCubeNew1; + + // add the literals to the new cubes + Fxu_UpdateMatrixDoubleCreateCubes( p, pCubeNew1, pCubeNew2, pDiv ); + + // start collecting the affected cubes and vars + Fxu_MatrixRingCubesStart( p ); + Fxu_MatrixRingVarsStart( p ); + // replace each two cubes of the pair by one new cube + // the new cube contains the base and the new literal + Fxu_UpdateDoublePairs( p, pDiv, pVarD ); + // stop collecting the affected cubes and vars + Fxu_MatrixRingCubesStop( p ); + Fxu_MatrixRingVarsStop( p ); + + // create new doubles; we cannot add them in the same loop + // because we first have to create *all* new cubes for each node + Fxu_MatrixForEachCubeInRing( p, pCube ) + Fxu_UpdateAddNewDoubles( p, pCube ); + // update the singles after removing some literals + Fxu_UpdateCleanOldSingles( p ); + + // undo the temporary rings with cubes and vars + Fxu_MatrixRingCubesUnmark( p ); + Fxu_MatrixRingVarsUnmark( p ); + // we should undo the rings before creating new singles + + // create new singles + Fxu_UpdateAddNewSingles( p, pVarC ); + Fxu_UpdateAddNewSingles( p, pVarD ); + + // recycle the divisor + MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); + p->nDivs2++; +} + +/**Function************************************************************* + + Synopsis [Update the pairs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar ) +{ + Fxu_Pair * pPair; + Fxu_Cube * pCubeUse, * pCubeRem; + int i; + + // collect and sort the pairs + Fxu_UpdatePairsSort( p, pDouble ); + for ( i = 0; i < p->nPairsTemp; i++ ) + { + // get the pair + pPair = p->pPairsTemp[i]; + // out of the two cubes, select the one which comes earlier + pCubeUse = Fxu_PairMinCube( pPair ); + pCubeRem = Fxu_PairMaxCube( pPair ); + // collect the affected cube + assert( pCubeUse->pOrder == NULL ); + Fxu_MatrixRingCubesAdd( p, pCubeUse ); + + // remove some literals from pCubeUse and all literals from pCubeRem + Fxu_UpdateMatrixDoubleClean( p, pCubeUse, pCubeRem ); + // add a literal that depends on the new variable + Fxu_MatrixAddLiteral( p, pCubeUse, pVar ); + // check the literal count + assert( pCubeUse->lLits.nItems == pPair->nBase + 1 ); + assert( pCubeRem->lLits.nItems == 0 ); + + // update the divisors by removing useless pairs + Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeUse ); + Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeRem ); + // remove the pair + MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); + } + p->nPairsTemp = 0; +} + +/**Function************************************************************* + + Synopsis [Add two cubes corresponding to the given double-cube divisor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv ) +{ + Fxu_Lit * pLit1, * pLit2; + Fxu_Pair * pPair; + int nBase, nLits1, nLits2; + + // fill in the SOP and copy the fanins + nBase = nLits1 = nLits2 = 0; + pPair = pDiv->lPairs.pHead; + pLit1 = pPair->pCube1->lLits.pHead; + pLit2 = pPair->pCube2->lLits.pHead; + while ( 1 ) + { + if ( pLit1 && pLit2 ) + { + if ( pLit1->iVar == pLit2->iVar ) + { // skip the cube free part + pLit1 = pLit1->pHNext; + pLit2 = pLit2->pHNext; + nBase++; + } + else if ( pLit1->iVar < pLit2->iVar ) + { // add literal to the first cube + Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar ); + // move to the next literal in this cube + pLit1 = pLit1->pHNext; + nLits1++; + } + else + { // add literal to the second cube + Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar ); + // move to the next literal in this cube + pLit2 = pLit2->pHNext; + nLits2++; + } + } + else if ( pLit1 && !pLit2 ) + { // add literal to the first cube + Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar ); + // move to the next literal in this cube + pLit1 = pLit1->pHNext; + nLits1++; + } + else if ( !pLit1 && pLit2 ) + { // add literal to the second cube + Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar ); + // move to the next literal in this cube + pLit2 = pLit2->pHNext; + nLits2++; + } + else + break; + } + assert( pPair->nLits1 == nLits1 ); + assert( pPair->nLits2 == nLits2 ); + assert( pPair->nBase == nBase ); +} + + +/**Function************************************************************* + + Synopsis [Create the node equal to double-cube divisor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem ) +{ + Fxu_Lit * pLit1, * bLit1Next; + Fxu_Lit * pLit2, * bLit2Next; + + // initialize the starting literals + pLit1 = pCubeUse->lLits.pHead; + pLit2 = pCubeRem->lLits.pHead; + bLit1Next = pLit1? pLit1->pHNext: NULL; + bLit2Next = pLit2? pLit2->pHNext: NULL; + // go through the pair and remove the literals in the base + // from the first cube and all literals from the second cube + while ( 1 ) + { + if ( pLit1 && pLit2 ) + { + if ( pLit1->iVar == pLit2->iVar ) + { // this literal is present in both cubes - it belongs to the base + // mark the affected var + if ( pLit1->pVar->pOrder == NULL ) + Fxu_MatrixRingVarsAdd( p, pLit1->pVar ); + // leave the base in pCubeUse; delete it from pCubeRem + Fxu_MatrixDelLiteral( p, pLit2 ); + // step to the next literals + pLit1 = bLit1Next; + pLit2 = bLit2Next; + bLit1Next = pLit1? pLit1->pHNext: NULL; + bLit2Next = pLit2? pLit2->pHNext: NULL; + } + else if ( pLit1->iVar < pLit2->iVar ) + { // this literal is present in pCubeUse - remove it + // mark the affected var + if ( pLit1->pVar->pOrder == NULL ) + Fxu_MatrixRingVarsAdd( p, pLit1->pVar ); + // delete this literal + Fxu_MatrixDelLiteral( p, pLit1 ); + // step to the next literals + pLit1 = bLit1Next; + bLit1Next = pLit1? pLit1->pHNext: NULL; + } + else + { // this literal is present in pCubeRem - remove it + // mark the affected var + if ( pLit2->pVar->pOrder == NULL ) + Fxu_MatrixRingVarsAdd( p, pLit2->pVar ); + // delete this literal + Fxu_MatrixDelLiteral( p, pLit2 ); + // step to the next literals + pLit2 = bLit2Next; + bLit2Next = pLit2? pLit2->pHNext: NULL; + } + } + else if ( pLit1 && !pLit2 ) + { // this literal is present in pCubeUse - leave it + // mark the affected var + if ( pLit1->pVar->pOrder == NULL ) + Fxu_MatrixRingVarsAdd( p, pLit1->pVar ); + // delete this literal + Fxu_MatrixDelLiteral( p, pLit1 ); + // step to the next literals + pLit1 = bLit1Next; + bLit1Next = pLit1? pLit1->pHNext: NULL; + } + else if ( !pLit1 && pLit2 ) + { // this literal is present in pCubeRem - remove it + // mark the affected var + if ( pLit2->pVar->pOrder == NULL ) + Fxu_MatrixRingVarsAdd( p, pLit2->pVar ); + // delete this literal + Fxu_MatrixDelLiteral( p, pLit2 ); + // step to the next literals + pLit2 = bLit2Next; + bLit2Next = pLit2? pLit2->pHNext: NULL; + } + else + break; + } +} + +/**Function************************************************************* + + Synopsis [Updates the matrix after selecting a single cube divisor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew ) +{ + Fxu_Lit * pLit1, * bLit1Next; + Fxu_Lit * pLit2, * bLit2Next; + + // initialize the starting literals + pLit1 = pVar1->lLits.pHead; + pLit2 = pVar2->lLits.pHead; + bLit1Next = pLit1? pLit1->pVNext: NULL; + bLit2Next = pLit2? pLit2->pVNext: NULL; + while ( 1 ) + { + if ( pLit1 && pLit2 ) + { + if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar ) + { // these literals coincide + if ( pLit1->iCube == pLit2->iCube ) + { // these literals coincide + + // collect the affected cube + assert( pLit1->pCube->pOrder == NULL ); + Fxu_MatrixRingCubesAdd( p, pLit1->pCube ); + + // add the literal to this cube corresponding to the new column + Fxu_MatrixAddLiteral( p, pLit1->pCube, pVarNew ); + // clean the old cubes + Fxu_UpdateCleanOldDoubles( p, NULL, pLit1->pCube ); + + // remove the literals + Fxu_MatrixDelLiteral( p, pLit1 ); + Fxu_MatrixDelLiteral( p, pLit2 ); + + // go to the next literals + pLit1 = bLit1Next; + pLit2 = bLit2Next; + bLit1Next = pLit1? pLit1->pVNext: NULL; + bLit2Next = pLit2? pLit2->pVNext: NULL; + } + else if ( pLit1->iCube < pLit2->iCube ) + { + pLit1 = bLit1Next; + bLit1Next = pLit1? pLit1->pVNext: NULL; + } + else + { + pLit2 = bLit2Next; + bLit2Next = pLit2? pLit2->pVNext: NULL; + } + } + else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar ) + { + pLit1 = bLit1Next; + bLit1Next = pLit1? pLit1->pVNext: NULL; + } + else + { + pLit2 = bLit2Next; + bLit2Next = pLit2? pLit2->pVNext: NULL; + } + } + else if ( pLit1 && !pLit2 ) + { + pLit1 = bLit1Next; + bLit1Next = pLit1? pLit1->pVNext: NULL; + } + else if ( !pLit1 && pLit2 ) + { + pLit2 = bLit2Next; + bLit2Next = pLit2? pLit2->pVNext: NULL; + } + else + break; + } +} + +/**Function************************************************************* + + Synopsis [Sort the pairs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble ) +{ + Fxu_Pair * pPair; + // order the pairs by the first cube to ensure that + // new literals are added to the matrix from top to bottom + // collect pairs into the array + p->nPairsTemp = 0; + Fxu_DoubleForEachPair( pDouble, pPair ) + p->pPairsTemp[ p->nPairsTemp++ ] = pPair; + if ( p->nPairsTemp > 1 ) + { // sort + qsort( (void *)p->pPairsTemp, p->nPairsTemp, sizeof(Fxu_Pair *), + (int (*)(const void *, const void *)) Fxu_UpdatePairCompare ); + assert( Fxu_UpdatePairCompare( p->pPairsTemp, p->pPairsTemp + p->nPairsTemp - 1 ) < 0 ); + } +} + +/**Function************************************************************* + + Synopsis [Compares the vars by their number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 ) +{ + Fxu_Cube * pC1 = (*ppP1)->pCube1; + Fxu_Cube * pC2 = (*ppP2)->pCube1; + int iP1CubeMin, iP2CubeMin; + if ( pC1->pVar->iVar < pC2->pVar->iVar ) + return -1; + if ( pC1->pVar->iVar > pC2->pVar->iVar ) + return 1; + iP1CubeMin = Fxu_PairMinCubeInt( *ppP1 ); + iP2CubeMin = Fxu_PairMinCubeInt( *ppP2 ); + if ( iP1CubeMin < iP2CubeMin ) + return -1; + if ( iP1CubeMin > iP2CubeMin ) + return 1; + assert( 0 ); + return 0; +} + + +/**Function************************************************************* + + Synopsis [Create new variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes ) +{ + Fxu_Var * pVarC, * pVarD; + + // add a new column for the complement + pVarC = Fxu_MatrixAddVar( p ); + pVarC->nCubes = 0; + // add a new column for the divisor + pVarD = Fxu_MatrixAddVar( p ); + pVarD->nCubes = nCubes; + + // mark this entry in the Value2Node array +// assert( p->pValue2Node[pVarC->iVar] > 0 ); +// p->pValue2Node[pVarD->iVar ] = p->pValue2Node[pVarC->iVar]; +// p->pValue2Node[pVarD->iVar+1] = p->pValue2Node[pVarC->iVar]+1; + + *ppVarC = pVarC; + *ppVarD = pVarD; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube ) +{ + Fxu_Double * pDivCur; + Fxu_Pair * pPair; + int i; + + // if the cube is a recently introduced one + // it does not have pairs allocated + // in this case, there is nothing to update + if ( pCube->pVar->ppPairs == NULL ) + return; + + // go through all the pairs of this cube + Fxu_CubeForEachPair( pCube, pPair, i ) + { + // get the divisor of this pair + pDivCur = pPair->pDiv; + // skip the current divisor + if ( pDivCur == pDiv ) + continue; + // remove this pair + Fxu_ListDoubleDelPair( pDivCur, pPair ); + // the divisor may have become useless by now + if ( pDivCur->lPairs.nItems == 0 ) + { + assert( pDivCur->Weight == pPair->nBase - 1 ); + Fxu_HeapDoubleDelete( p->pHeapDouble, pDivCur ); + Fxu_MatrixDelDivisor( p, pDivCur ); + } + else + { + // update the divisor's weight + pDivCur->Weight -= pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase; + Fxu_HeapDoubleUpdate( p->pHeapDouble, pDivCur ); + } + MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); + } + // finally erase all the pair info associated with this cube + Fxu_PairClearStorage( pCube ); +} + +/**Function************************************************************* + + Synopsis [Adds the new divisors that depend on the cube.] + + Description [Go through all the non-empty cubes of this cover + (except the given cube) and, for each of them, add the new divisor + with the given cube.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube ) +{ + Fxu_Cube * pTemp; + assert( pCube->pOrder ); + + // if the cube is a recently introduced one + // it does not have pairs allocated + // in this case, there is nothing to update + if ( pCube->pVar->ppPairs == NULL ) + return; + + for ( pTemp = pCube->pFirst; pTemp->pVar == pCube->pVar; pTemp = pTemp->pNext ) + { + // do not add pairs with the empty cubes + if ( pTemp->lLits.nItems == 0 ) + continue; + // to prevent adding duplicated pairs of the new cubes + // do not add the pair, if the current cube is marked + if ( pTemp->pOrder && pTemp >= pCube ) + continue; + Fxu_MatrixAddDivisor( p, pTemp, pCube ); + } +} + +/**Function************************************************************* + + Synopsis [Removes old single cube divisors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ) +{ + Fxu_Single * pSingle, * pSingle2; + int WeightNew; + + Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 ) + { + // if at least one of the variables is marked, recalculate + if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder ) + { + // get the new weight + WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 ); + if ( WeightNew >= 0 ) + { + pSingle->Weight = WeightNew; + Fxu_HeapSingleUpdate( p->pHeapSingle, pSingle ); + } + else + { + Fxu_HeapSingleDelete( p->pHeapSingle, pSingle ); + Fxu_ListMatrixDelSingle( p, pSingle ); + MEM_FREE_FXU( p, Fxu_Single, 1, pSingle ); + } + } + } +} + +/**Function************************************************************* + + Synopsis [Updates the single cube divisors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar ) +{ + Fxu_MatrixComputeSinglesOne( p, pVar ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/fxu/module.make b/src/opt/fxu/module.make new file mode 100644 index 00000000..331712d1 --- /dev/null +++ b/src/opt/fxu/module.make @@ -0,0 +1,12 @@ +SRC += fxu.c \ + fxuCreate.c \ + fxuHeapD.c \ + fxuHeapS.c \ + fxuList.c \ + fxuMatrix.c \ + fxuPair.c \ + fxuPrint.c \ + fxuReduce.c \ + fxuSelect.c \ + fxuSingle.c \ + fxuUpdate.c |