Commit d0e834d1 by Alan Mishchenko

Version abc50806

parent 888e5bed
......@@ -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"
......
No preview for this file type
......@@ -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
......
......@@ -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 []
......
......@@ -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 );
......
......@@ -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];
}
}
}
......
......@@ -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;
......
/**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 ///
////////////////////////////////////////////////////////////////////////
......@@ -34,6 +34,12 @@ static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t *
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 ///
////////////////////////////////////////////////////////////////////////
......
......@@ -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 )
{
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 );
......
......@@ -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) )
......
......@@ -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 );
......
......@@ -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 []
......
......@@ -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++ )
{
......
......@@ -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;
}
......
/**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 ///
////////////////////////////////////////////////////////////////////////
......@@ -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 );
......
......@@ -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 );
......
......@@ -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 ///
////////////////////////////////////////////////////////////////////////
......@@ -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 ///
////////////////////////////////////////////////////////////////////////
......
......@@ -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 []
......
......@@ -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 );
......
......@@ -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 );
}
......
......@@ -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 );
......
......@@ -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 )
......
......@@ -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
......
......@@ -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_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,197 +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];
// add several other supergate classes derived using don't-cares
if ( pCut->uTruthDc[0] )
{
int nOnes;
nOnes = Map_TruthCountOnes( pCut->uTruthDc, pCut->nLeaves );
if ( nOnes == 1 )
unsigned uTruth1[2], uTruth2[2];
Map_Cut_t * pTemp;
int i;
// mark the cut leaves
for ( i = 0; i < pCut->nLeaves; i++ )
{
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++;
pTemp = pCut->ppLeaves[i]->pCuts;
pTemp->fMark = 1;
pTemp->M[0].uPhaseBest = p->uTruths[i][0];
pTemp->M[1].uPhaseBest = p->uTruths[i][1];
}
else if ( nOnes == 2 )
{
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 );
assert( pCut->fMark == 0 );
// 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++;
// 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;
// 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++;
}
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 tables and unmark
for ( i = 0; i < pCut->nLeaves; i++ )
{
// 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++;
pTemp = pCut->ppLeaves[i]->pCuts;
pTemp->fMark = 0;
}
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] )
for ( i = 0; i < p->vVisited->nSize; i++ )
{
// 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++;
}
}
}
}
#endif
/**Function*************************************************************
Synopsis [Recursively derives the truth table for the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruthRes[] )
{
unsigned uTruth1[2], uTruth2[2];
// if this is the elementary cut, its truth table is already available
if ( pCut->nLeaves == 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) )
{
uTruthRes[0] = pCut->uTruthTemp[0];
uTruthRes[1] = pCut->uTruthTemp[1];
return;
uTruth1[0] = ~Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
uTruth1[1] = ~Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
}
// if this node was already visited, return its computed truth table
if ( pCut->fMark )
else
{
uTruthRes[0] = pCut->uTruthTemp[0];
uTruthRes[1] = pCut->uTruthTemp[1];
return;
uTruth1[0] = Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
uTruth1[1] = Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
}
pCut->fMark = 1;
pCut->nVolume++;
assert( !Map_IsComplement(pCut) );
Map_TruthsCut_rec( Map_CutRegular(pCut->pOne), uTruth1 );
if ( Map_CutIsComplement(pCut->pOne) )
// get truth table of the second branch
if ( Map_CutIsComplement(pTemp->pTwo) )
{
uTruth1[0] = ~uTruth1[0];
uTruth1[1] = ~uTruth1[1];
uTruth2[0] = ~Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
uTruth2[1] = ~Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
}
Map_TruthsCut_rec( Map_CutRegular(pCut->pTwo), uTruth2 );
if ( Map_CutIsComplement(pCut->pTwo) )
else
{
uTruth2[0] = ~uTruth2[0];
uTruth2[1] = ~uTruth2[1];
uTruth2[0] = Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
uTruth2[1] = Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
}
if ( !pCut->Phase )
// get the truth table of the output
if ( !pTemp->Phase )
{
uTruthRes[0] = pCut->uTruthTemp[0] = uTruth1[0] & uTruth2[0];
uTruthRes[1] = pCut->uTruthTemp[1] = uTruth1[1] & uTruth2[1];
pTemp->M[0].uPhaseBest = uTruth1[0] & uTruth2[0];
pTemp->M[1].uPhaseBest = uTruth1[1] & uTruth2[1];
}
else
{
uTruthRes[0] = pCut->uTruthTemp[0] = ~(uTruth1[0] & uTruth2[0]);
uTruthRes[1] = pCut->uTruthTemp[1] = ~(uTruth1[1] & uTruth2[1]);
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;
}
/**Function*************************************************************
Synopsis [Recursively derives the truth table for the cut.]
Synopsis [Recursively collect the cuts.]
Description []
......@@ -356,91 +209,17 @@ void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruthRes[] )
SeeAlso []
***********************************************************************/
void Map_TruthsUnmark_rec( Map_Cut_t * pCut )
void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited )
{
if ( pCut->nLeaves == 1 )
return;
// if this node was already visited, return its computed truth table
if ( pCut->fMark == 0 )
if ( pCut->fMark )
return;
pCut->fMark = 0;
Map_TruthsUnmark_rec( Map_CutRegular(pCut->pOne) );
Map_TruthsUnmark_rec( Map_CutRegular(pCut->pTwo) );
}
/**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;
Map_CutsCollect_rec( Map_CutRegular(pCut->pOne), vVisited );
Map_CutsCollect_rec( Map_CutRegular(pCut->pTwo), vVisited );
assert( pCut->fMark == 0 );
pCut->fMark = 1;
Map_NodeVecPush( vVisited, (Map_Node_t *)pCut );
}
/**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 ///
......
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment